FreeRADIUS / pam_radius

This is the PAM to RADIUS authentication module. It allows any Linux, OSX or Solaris machine to become a RADIUS client for authentication and password change requests.
GNU General Public License v2.0
102 stars 90 forks source link

Abort when configuration file is empty #66

Closed sbrahul closed 2 years ago

sbrahul commented 2 years ago

When the configuration file (/etc/pam_radius_auth.conf) file is empty, looks like there is a double free and that causes an abort. Here is the error message:

free(): double free detected in tcache 2
Aborted (core dumped)

I have faced this issue in both a real scenario and when testing using pamtester.

jpereira commented 2 years ago

Which version are you using?

alandekok commented 2 years ago

I really don't see how this is an error in the current release. If nothing is read from the file, it doesn't allocate any memory, and just returns an error.

Plus, if the configuration file is empty. the module won't do anything useful.

This bug report is essentially "I did something bad, and something bad happened". Well... don't do that.

sbrahul commented 2 years ago

The problem is that it's not returning an error. The process crashes. I am locked out of my system because the config file became empty. I agree that the config file shouldn't be empty, but that shouldn't cause me to lock me out of my system. The ssh/login process crashes. It doesn't even reach my backup pam_unix due to this.

alandekok commented 2 years ago

You can answer Jorge's question, too.

This is not an issue in the recent release. If you're running something 5-10 years old, then the issue has already been fixed.

And if you misconfigure the system, bad things happen. So... don't do that.

sbrahul commented 2 years ago

I compiled from source with the latest code. And I found the problem using gdb. The code is calling fclose() twice causing an abort:

#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x00007ffff7dce859 in __GI_abort () at abort.c:79
#2  0x00007ffff7e393ee in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7ffff7f63285 "%s\n") at ../sysdeps/posix/libc_fatal.c:155
#3  0x00007ffff7e4147c in malloc_printerr (str=str@entry=0x7ffff7f655d0 "free(): double free detected in tcache 2") at malloc.c:5347
#4  0x00007ffff7e430ed in _int_free (av=0x7ffff7f94b80 <main_arena>, p=0x55555555a690, have_lock=0) at malloc.c:4201
#5  0x00007ffff7e2e043 in _IO_deallocate_file (fp=0x55555555a6a0) at libioP.h:863
#6  _IO_new_fclose (fp=0x55555555a6a0) at iofclose.c:74
#7  0x00007ffff7fc0a8b in initialize (conf=0x7fffffffb850, accounting=0) at pam_radius_auth.c:892                                                                                            
#8  0x00007ffff7fc1a3f in pam_sm_authenticate (pamh=0x55555555a340, flags=0, argc=1, argv=0x55555555b8b0) at pam_radius_auth.c:134

When the file is empty, there is an fclose in line 869 and then again in 892 causing a crash:

753             fp = fopen (conf->conf_file, "r");
(gdb) n
754             if (!fp) {
(gdb) 
762             conf->server = NULL;
(gdb) 
763             last = &conf->server;
(gdb) 
768             while (!feof(fp) && (fgets (buffer, sizeof(buffer), fp) != NULL) && (!ferror(fp))) {
(gdb) 
869             fclose(fp);
(gdb) n
871             if (!conf->server) {            /* no server found, die a horrible death */
(gdb) 
872                     _pam_log(LOG_ERR, "No RADIUS server found in configuration file %s\n",
(gdb) 
874                     goto error;
(gdb) 
892             fclose(fp);

Performing an fclose() at 896 should ideally set the fp to NULL and then at line 892 should check for NULL before closing again.