Segmentation fault on sigHUP

Milan Holub holub at thenet.ch
Wed Apr 11 15:30:11 CEST 2007


Hi all,

somewhere in this list there was already mentioned that current CVS
version causes segmentation fault when received HUP signal(kill -HUP pid) - depending on 
the configuration it may survive 1st HUP and then it dies with 1st
radius request/2nd HUP).
Reason is also known: wrong freeing of memory. I've looked into the code
for some time but I got lost in debugging of internal freeradius
data structures. Until Alan comes with clean solution I'm offering
following workaround:
Here is a patch which just comments out freeing of config memory:

Index: src/main/mainconfig.c
===================================================================
RCS file: /source/radiusd/src/main/mainconfig.c,v
retrieving revision 1.106
diff -u -r1.106 mainconfig.c
--- src/main/mainconfig.c       7 Apr 2007 14:25:12 -0000       1.106
+++ src/main/mainconfig.c       11 Apr 2007 12:44:08 -0000
@@ -804,9 +804,9 @@
         *      Note that where possible, we do atomic switch-overs,
         *      to ensure that the pointers are always valid.
         */
-       oldcs = mainconfig.config;
+       //oldcs = mainconfig.config;
        mainconfig.config = cs;
-       cf_section_free(&oldcs);
+       //cf_section_free(&oldcs);

        snprintf(buffer, sizeof(buffer), "%.200s/%.50s",
                 radius_dir, mainconfig.radiusd_conf);
@@ -942,7 +942,7 @@
         *      Clean up the configuration data
         *      structures.
         */
-       cf_section_free(&mainconfig.config);
+//     cf_section_free(&mainconfig.config);
        free(mainconfig.radiusd_conf);
        realms_free();
        listen_free(&mainconfig.listen);


Of course it leads to memory leakage! With default configuration it will
eat around 60k of memory per thread on each reload. With my configuration(rlm_sql,
65 NASes in database, some additional modules loaded) it eats something like
600k per thread/reload.

Advantages:
- HUP does not cause seqmentation fault.
- /etc/init.d/freeradius reload is working(uses HUP)
- reload using snmp is working(radiusAuthServConfigReset.0 = 2)

Disadvantages:
- serious memory leakage
- you should definitely schedule freeradius restart(daily?, off-peak) in crontab
  in order to "free" unused memory
- when using rlm_sql(as in my case) with this patch then please note
  that there will be unused open DB connections left after each reHUP
  ==> to get rid of these connections consider changing your DB
  configuration(eg. set "wait_timeout = 600" under [mysqld] section of
  my.cnf for mysql server; this causes to close unused connections older
  than 10 minutes)

Hope this helps someone.

PS: I hope freeing unused memory will be revisited and thus this
workaround won't be needed anymore.

Milan Holub
holub (at) thenet (dot) ch

--------------------------------------
 TheNet-Internet Services AG,
 im Bernertechnopark, Morgenstr. 129
 CH-3018, Bern, Switzerland
 031 998 4333, Fax 031 998 4330
 http://www.thenet.ch
 http://wlan.thenet.ch
--------------------------------------



More information about the Freeradius-Users mailing list