Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pam_handlers: possible SEGV caused by not initialized next member of the list #475

Closed
LexPanov opened this issue Jul 12, 2022 · 0 comments · Fixed by #478
Closed

pam_handlers: possible SEGV caused by not initialized next member of the list #475

LexPanov opened this issue Jul 12, 2022 · 0 comments · Fixed by #478

Comments

@LexPanov
Copy link

While calling pam_start and using some invalid paths in the configuration file included using include/substack, a pointer of a high value address is dereferenced.

Steps to reproduce

/etc/pam.d/crash_conf

One of the following lines:

0 include crash_include
0 substack crash_include

/etc/pam.d/crash_include

One of the following lines:

0 0 /
0 0 .
0 0 ?
0 0 [

main.c

#include <security/pam_appl.h>
#include <security/pam_misc.h>
#include <stdio.h>

static struct pam_conv conv = {misc_conv, NULL};

int main() {
  pam_handle_t *pamh = NULL;
  int retval;
  const char *user = "user";

  retval = pam_start("crash_conf", user, &conv, &pamh);
  printf("pam_start: %d\n", retval);
  pam_end(pamh, retval);

  return 0;
}

ASAN output

$ gcc main.c -o main -lpam -lpam_misc
$ ./main
AddressSanitizer:DEADLYSIGNAL
=================================================================
==161965==ERROR: AddressSanitizer: SEGV on unknown address (pc 0x00000031627f bp 0x7ffe219961f0 sp 0x7ffe21996100 T0)
==161965==The signal is caused by a READ memory access.
==161965==Hint: this fault was caused by a dereference of a high value address (see register values below).  Disassemble the provided pc to learn which register was used.
    #0 0x31627f in _pam_add_handler /tmp/Linux-PAM/libpam/pam_handlers.c:888:12
    #1 0x313dbc in _pam_parse_conf_file /tmp/Linux-PAM/libpam/pam_handlers.c:264:12
    #2 0x30e712 in _pam_init_handlers /tmp/Linux-PAM/libpam/pam_handlers.c:462:12
    #3 0x3075dd in pam_start /tmp/Linux-PAM/libpam/pam_start.c:124:10
    #4 0x3075dd in main /tmp/Linux-PAM/main.c:12:12
    #5 0x7f212c7b90b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:308:16
    #6 0x254bed in _start (/tmp/Linux-PAM/main+0x25864d)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /tmp/Linux-PAM/libpam/pam_handlers.c:888:12 in _pam_add_handler
==161965==ABORTING

Analysis

Call Trace:

pam_start
|-_pam_init_handlers
|-|-_pam_open_config_file
|-|-_pam_parse_conf_file # parse /etc/pam.d/crash_conf
|-|-|-_pam_assemble_line
|-|-|-_pam_add_handler
|-|-|-|-_pam_load_module
|-|-|-|-extract_modulename # extract crash_include path
|-|-|-_pam_load_conf_file
|-|-|-|-_pam_open_config_file
|-|-|-|-_pam_parse_conf_file # parse /etc/pam.d/crash_include
|-|-|-|-|-_pam_assemble_line
|-|-|-|-|-_pam_add_handler
|-|-|-|-|-|-extract_modulename # extract invalid path
|-|-|-|-|-|-return PAM_ABORT; # pam_handlers.c:906
|-|-|-|-|-return PAM_ABORT;
|-|-|-|-return PAM_ABORT;
|-|-|-_pam_add_handler
|-|-|-|-SEGV # pam_handlers.c:888

Here we are returning from _pam_add_handler with PAM_ABORT, without initializing next with NULL

if (((*handler_p)->mod_name = extract_modulename(mod_path)) == NULL)
return PAM_ABORT;
(*handler_p)->grantor = 0;
(*handler_p)->next = NULL;

And then, we are re-entering _pam_add_handler and having crash on line 888

while (*handler_p != NULL) {
handler_p = &((*handler_p)->next);
}

Reproducing

vmuser@ubuntuvm:~$ uname -a
Linux ubuntuvm 5.15.0-33-generic #34~20.04.1-Ubuntu SMP Thu May 19 15:51:16 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

vmuser@ubuntuvm:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 20.04.4 LTS
Release:        20.04
Codename:       focal

vmuser@ubuntuvm:~$ apt list | grep libpam0g/

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

libpam0g/focal-updates,now 1.3.1-5ubuntu4.3 amd64 [installed,automatic]

vmuser@ubuntuvm:~$ cat /etc/pam.d/crash_include 
0 0 /

vmuser@ubuntuvm:~$ cat /etc/pam.d/login | head
0 include crash_include
#
# The PAM configuration file for the Shadow `login' service
#

# Enforce a minimal delay in case of failure (in microseconds).
# (Replaces the `FAIL_DELAY' setting from login.defs)
# Note that other modules may require another minimal delay. (for example,
# to disable any delay, you should add the nodelay option to pam_unix)
auth       optional   pam_faildelay.so  delay=3000000

vmuser@ubuntuvm:~$ sudo login
[sudo] password for vmuser: 
Segmentation fault

vmuser@ubuntuvm:~$ cat /var/log/syslog | grep 20:34:21 
Jul 12 20:34:21 ubuntuvm kernel: [ 1133.420447] login[3641]: segfault at 70e945f2 ip 00007fa5ca599e33 sp 00007ffd775c3e30 error 4 in libpam.so.0.84.2[7fa5ca597000+9000]
Jul 12 20:34:21 ubuntuvm kernel: [ 1133.420458] Code: 00 00 48 c7 44 24 28 00 00 00 00 45 31 db 85 d2 0f 84 61 03 00 00 49 8b 06 48 85 c0 74 1f 66 0f 1f 84 00 00 00 00 00 49 89 c2 <48> 8b 80 b0 00 00 00 48 85 c0 75 f1 4d 8d b2 b0 00 00 00 bf c8 00
LexPanov pushed a commit to LexPanov/linux-pam that referenced this issue Jul 12, 2022
Re-entering _pam_add_handler without initialization of the next member of
the list leads to SEGV caused by a dereference of a high value address.

Resolves: linux-pam#475
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
1 participant