Bug 1227878

Summary: econf_readDirs crashes if one of the paths is NULL
Product: [openSUSE] openSUSE Tumbleweed Reporter: Stanislav Brabec <sbrabec>
Component: BasesystemAssignee: Stefan Schubert <schubi>
Status: NEW --- QA Contact: E-mail List <qa-bugs>
Severity: Normal    
Priority: P5 - None    
Version: Slowroll   
Target Milestone: ---   
Hardware: Other   
OS: Other   
Whiteboard:
Found By: --- Services Priority:
Business Priority: Blocker: ---
Marketing QA Status: --- IT Deployment: ---

Description Stanislav Brabec 2024-07-16 00:09:21 UTC
If util-linux is configured with a plain ./configure, agetty crashes.

The reason is simple:
If ./configure is called without --with-vendordir=DIR on a system with libeconf, 
econf_readDirs is called with dist_conf_dir=0x0. And the code does not check for it before calling strdup().

Reading the code, the same is apparently valid for etc_conf_dir.

And there are more occurrences of unsanitized strdup() calls on directory names.


(gdb) bt
#0  __strlen_evex () at ../sysdeps/x86_64/multiarch/strlen-evex-base.S:81
#1  0x00007f06d54aa752 in __GI___strdup (s=s@entry=0x0) at strdup.c:41
#2  0x00007f06d56fa26b in econf_readDirs (comment=0x41260f "#", delim=0x412601 "= \t", config_suffix=0x412605 "defs", config_name=0x412537 "login", etc_conf_dir=0x41260a "/etc", 
    dist_conf_dir=0x0, result=0x41b630 <file>) at ../lib/libeconf.c:510
#3  econf_readDirs (result=result@entry=0x41b630 <file>, dist_conf_dir=dist_conf_dir@entry=0x0, etc_conf_dir=etc_conf_dir@entry=0x41260a "/etc", 
    config_name=config_name@entry=0x412537 "login", config_suffix=config_suffix@entry=0x412605 "defs", delim=delim@entry=0x412601 "= \t", comment=0x41260f "#") at ../lib/libeconf.c:495
#4  0x0000000000409a18 in load_defaults () at lib/logindefs.c:257
#5  0x0000000000409cb5 in getlogindefs_bool (name=name@entry=0x41241a "LOGIN_PLAIN_PROMPT", dflt=dflt@entry=0) at lib/logindefs.c:326
#6  0x0000000000406b11 in main (argc=<optimized out>, argv=<optimized out>) at term-utils/agetty.c:490
(gdb) up
#1  0x00007f06d54aa752 in __GI___strdup (s=s@entry=0x0) at strdup.c:41
41	  size_t len = strlen (s) + 1;
(gdb) up
#2  0x00007f06d56fa26b in econf_readDirs (comment=0x41260f "#", delim=0x412601 "= \t", config_suffix=0x412605 "defs", config_name=0x412537 "login", etc_conf_dir=0x41260a "/etc", 
    dist_conf_dir=0x0, result=0x41b630 <file>) at ../lib/libeconf.c:510
510	  (*result)->parse_dirs[0] = strdup(dist_conf_dir);
(gdb) l
505	    return ret;
506	
507	  (*result)->parse_dirs_count = 2;
508	  (*result)->parse_dirs = calloc((*result)->parse_dirs_count+1, sizeof(char *));
509	  (*result)->parse_dirs[(*result)->parse_dirs_count] = NULL;
510	  (*result)->parse_dirs[0] = strdup(dist_conf_dir);
511	  (*result)->parse_dirs[1] = strdup(etc_conf_dir);
512	
513	  return readConfigWithCallback(result,
514					config_name,
(gdb) p dist_conf_dir
$1 = 0x0