Bugs in rlm_perl config {} section handling #1675

Closed
haegar opened this Issue Aug 10, 2016 · 4 comments

Projects

None yet

3 participants

@haegar
haegar commented Aug 10, 2016 edited

Issue type

  • Defect - Crash or memory corruption.

Defect/Feature description

Using two perl {} sections, if the second one contains a config {} section freeradius crashes.

How to reproduce issue

System: Git snapshot from today, including the fix for #1674 Debian Jessie, perl 5.20.2-3+deb8u6

To reproduce the stock configfiles without any change and the following addition are enough:

Create a /etc/freeradius/mods-enabled/zzz-perl-crash:

 perl a {  
        filename = ${modconfdir}/perl/example.pl
 }
 perl b {
        filename = ${modconfdir}/perl/example.pl
        config {
                three = "three"
        }
 }

(No need to use them anywhere to reproduce a crash)

Restart freeradius. (In my case using systemd, with default service file)

Depending on "luck" sometimes results in:

 freeradius[5665]: Configuration appears to be OK
 kernel: [2008172.003054] freeradius[5665]: segfault at c131200 ip 00007f9884a768a9 sp 00007ffff968edb0 error 4 in libperl.so.5.20.2[7f98849b8000+1b7000]

or

 freeradius[5002]: Configuration appears to be OK
 freeradius[5002]: *** Error in `/usr/sbin/freeradius': corrupted double-linked list: 0x0000000000b3fa40 ***

or

 freeradius[5716]: Configuration appears to be OK
 freeradius[5716]: Attempt to free nonexistent shared string 'three', Perl interpreter: 0x1d022a0 during global destruction.
 freeradius[5716]: Unbalanced string table refcount: (1) for "three" during global destruction.
 freeradius[5716]: Scalars leaked: 1

Output of [radiusd|freeradius] -X showing issue ocurring

This bug does NOT occur if running as "freeradius -X" ! There (with my full config instead of the reduced reproduction settings) it completely works.

Full backtrace from LLDB or GDB

Starting program: /usr/sbin/freeradius -Cxm -lstdout
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff15e58a9 in ?? () from /usr/lib/x86_64-linux-gnu/libperl.so.5.20
  Id   Target Id         Frame 
* 1    Thread 0x7ffff7fe4740 (LWP 6070) "freeradius" 0x00007ffff15e58a9 in ??
    () from /usr/lib/x86_64-linux-gnu/libperl.so.5.20

Thread 1 (Thread 0x7ffff7fe4740 (LWP 6070)):
#0  0x00007ffff15e58a9 in ?? () from /usr/lib/x86_64-linux-gnu/libperl.so.5.20
No symbol table info available.
#1  0x00007ffff15e67bb in ?? () from /usr/lib/x86_64-linux-gnu/libperl.so.5.20
No symbol table info available.
#2  0x00007ffff15e6a1e in Perl_hfree_next_entry ()
   from /usr/lib/x86_64-linux-gnu/libperl.so.5.20
No symbol table info available.
#3  0x00007ffff15e6c4e in ?? () from /usr/lib/x86_64-linux-gnu/libperl.so.5.20
No symbol table info available.
#4  0x00007ffff15e9f64 in Perl_hv_undef_flags ()
   from /usr/lib/x86_64-linux-gnu/libperl.so.5.20
No symbol table info available.
#5  0x00007ffff18eae62 in mod_detach (instance=0x8f58c0)
    at src/modules/rlm_perl/rlm_perl.c:1003
        inst = 0x8f58c0
        exitstatus = 0
        count = 0
#6  0x00007ffff6ef6650 in ?? () from /usr/lib/x86_64-linux-gnu/libtalloc.so.2
No symbol table info available.
#7  0x00007ffff6eef39b in _talloc_free ()
   from /usr/lib/x86_64-linux-gnu/libtalloc.so.2
No symbol table info available.
#8  0x00007ffff798b847 in free_walker (tree=0x8ca300, x=0x8f7de0)
    at src/lib/rbtree.c:80
No locals.
#9  0x00007ffff798b838 in free_walker (tree=0x8ca300, x=0x8ea030)
    at src/lib/rbtree.c:78
No locals.
#10 0x00007ffff798b827 in free_walker (tree=0x8ca300, x=0x8e6c50)
    at src/lib/rbtree.c:77
No locals.
#11 0x00007ffff798b838 in free_walker (tree=0x8ca300, x=0x8de820)
    at src/lib/rbtree.c:78
No locals.
#12 0x00007ffff798b827 in free_walker (tree=0x8ca300, x=0x8d6a40)
    at src/lib/rbtree.c:77
No locals.
#13 0x00007ffff798b827 in free_walker (tree=0x8ca300, x=0x8cf620)
    at src/lib/rbtree.c:77
No locals.
#14 0x00007ffff798bdfb in rbtree_free (tree=0x8ca300) at src/lib/rbtree.c:93
No locals.
#15 0x0000000000421400 in modules_free () at src/main/modules.c:485
No locals.
#16 0x000000000040f94a in main (argc=<optimized out>, argv=<optimized out>)
    at src/main/radiusd.c:623
        rcode = 0
        status = <optimized out>
        argval = <optimized out>
        spawn_flag = false
        display_version = false
        flag = 0
        from_child = {-1, -1}
        state = 0x0
        autofree = 0x66c070
A debugging session is active.

        Inferior 1 [process 6070] will be killed.

Quit anyway? (y or n) 
@herwinw
Member
herwinw commented Aug 12, 2016

It took me some time to reproduce this: on my build the mod_detach is first called for section b, then for section a. If I add a config section in a, I get the segfault with a slightly better backtrace:

Program received signal SIGSEGV, Segmentation fault.
S_unshare_hek_or_pvn (my_perl=0x835e2c8, hek=0x8356134, str=str@entry=0x0, len=0, hash=873518612) at hv.c:2812
2812    hv.c: No such file or directory.
(gdb) bt full
#0  S_unshare_hek_or_pvn (my_perl=0x835e2c8, hek=0x8356134, str=str@entry=0x0, len=0, hash=873518612) at hv.c:2812
        he_he = 0x8356128
        xhv = 0x842a63c
        entry = <optimized out>
        oentry = 0x0
        is_utf8 = false
        k_flags = 0
        save = 0x0
        he = 0x8356128
#1  0xf722553f in Perl_unshare_hek (my_perl=<optimized out>, hek=<optimized out>) at hv.c:2756
No locals.
#2  0xf72255a2 in S_hv_free_ent_ret (my_perl=0x835e2c8, hv=0x833fb88, entry=0x83527b4) at hv.c:1555
        val = 0x83597c0
#3  0xf7225853 in Perl_hfree_next_entry (my_perl=0x835e2c8, hv=0x833fb88, indexp=0xffffd728) at hv.c:1820
        iter = <optimized out>
        entry = 0x83527b4
        array = <optimized out>
#4  0xf7225a89 in S_hfreeentries (my_perl=0x835e2c8, hv=0x833fb88) at hv.c:1741
        index = 4
        xhv = 0x8346768
        sv = <optimized out>
#5  0xf7229058 in Perl_hv_undef_flags (my_perl=0x835e2c8, hv=0x833fb88, flags=0) at hv.c:1872
        xhv = 0x8346768
        save = true
#6  0xf73b667c in mod_detach (instance=0x8325dc8) at src/modules/rlm_perl/rlm_perl.c:1045
        inst = 0x8325dc8
        exitstatus = 0
        count = 0
#7  0xf7cade58 in _talloc_free_internal (location=0xf7cb3042 "../talloc.c:1571", ptr=0x8325dc8) at ../talloc.c:1046
        d = 0xf73b6504 <mod_detach>
        ptr_to_free = <optimized out>
#8  _talloc_free_children_internal (location=0xf7cb3042 "../talloc.c:1571", ptr=0x8325d68, tc=0x8325d38) at ../talloc.c:1525
        child = 0x8325dc8
        new_parent = 0x0
#9  talloc_free_children (ptr=0x8325d68) at ../talloc.c:1571
        tc_name = 0x0
#10 0x08069cb0 in _module_instance_free (instance=0x8325d68) at src/main/modules.c:144
No locals.
#11 0xf7cacb85 in _talloc_free_internal (ptr=0x8325d68, location=0x80a09a2 "src/main/modules.c:99") at ../talloc.c:1046
        d = 0x8069c10 <_module_instance_free>
        ptr_to_free = <optimized out>
#12 0xf7ca690b in _talloc_free_children_internal (location=0x80a09a2 "src/main/modules.c:99", ptr=0x82b7818, tc=0x82b77e8) at ../talloc.c:1525
        child = 0x8325d68
        new_parent = 0x0
#13 _talloc_free_internal (location=<optimized out>, ptr=<optimized out>) at ../talloc.c:1072
        ptr_to_free = <optimized out>
#14 _talloc_free (ptr=0x82b7818, location=0x80a09a2 "src/main/modules.c:99") at ../talloc.c:1647
No locals.
#15 0x08069bf9 in modules_free () at src/main/modules.c:99
No locals.
#16 0x080723c7 in main (argc=2, argv=0xffffda74) at src/main/radiusd.c:652
        rcode = 0
        status = 2
        argval = -1
        display_version = false
        from_child = {-1, -1}
        p = 0xffffdbf8 "/radiusd"
        autofree = 0x80c3038

Of course the line numbers don't match with any hv.c I could find. I can even reproduce this when running radiusd -X, so it's probably not a threading issue as I would have expected by the bug report. I'll try to have a better look at it tomorrow

In unrelated news: found this in the Perl source:

    /* The name must be deleted before the call to hfreeeeentries so that

eeeeeeeeee?

@herwinw
Member
herwinw commented Aug 12, 2016

Btw: I've added some debugging stuff in rlm_perl.c, so the line numbers there don't match up either

@arr2036
Member
arr2036 commented Aug 21, 2016

any progress on this? I tend not to work on rlm_perl due to religious objections :)

@herwinw
Member
herwinw commented Aug 22, 2016

Not really, the hash looks perfectly fine in freeradius context before we try to free it, so I guess it's some incorrect usage of the Perl internals.

@herwinw herwinw pushed a commit to herwinw/freeradius-server that referenced this issue Aug 22, 2016
Herwin Weststrate Free rad_perlconf_hv in correct perl context
This should fix #1675
79a5406
@herwinw herwinw pushed a commit to herwinw/freeradius-server that referenced this issue Aug 22, 2016
Herwin Weststrate Free rad_perlconf_hv in correct perl context
This should fix #1675
ef56000
@arr2036 arr2036 closed this in #1681 Aug 23, 2016
@arr2036 arr2036 added a commit that referenced this issue Aug 23, 2016
@arr2036 Herwin Weststrate + arr2036 Free rad_perlconf_hv in correct perl context
This should fix #1675
77d2ace
@alandekok alandekok added a commit that referenced this issue Aug 23, 2016
@alandekok Herwin Weststrate + alandekok Free rad_perlconf_hv in correct perl context
This should fix #1675
daf05fc
@arr2036 arr2036 added a commit that referenced this issue Aug 28, 2016
@arr2036 Herwin Weststrate + arr2036 Free rad_perlconf_hv in correct perl context
This should fix #1675
cd77189
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment