On Monday 03 February 2014 17:50:00 Lauri Kasanen wrote: > Hi, > > As with many other software, busybox was also broken by the glibc >= > 2.17 behavior change. Now crypt() returns NULL if either salt or > password is invalid. > > This causes busybox 1.21, 1.22, and git su to segfault, when you just > press enter at the password prompt (configured to use system crypt() of > course). > > Program terminated with signal 11, Segmentation fault. > #0 0xb760cb84 in strcmp () from /lib/libc.so.6 > (gdb) bt full > #0 0xb760cb84 in strcmp () from /lib/libc.so.6 > No symbol table info available. > #1 0x080493d3 in ask_and_check_password_extended () > No symbol table info available. > > The attached patch fixes su. You may want to check every other call to > crypt() in busybox. > > - Lauri > > Hi, other users of crypt():
1) call pw_encrypt directly: busybox/loginutils/chpasswd.c busybox/loginutils/cryptpw.c busybox/loginutils/passwd.c these 3 could be fixed by adding a new pw_encrypt_or_die() function like: char* FAST_FUNC pw_encrypt_or_die(const char *clear, const char *salt, int cleanup) { char * s = crypt(clear, salt); if (! s) bb_simple_perror_msg_and_die("crypt"); return xstrdup(s); } in case we use bb internal crypt function erroring out maybe is not needed so in this case we could define pw_encrypt_or_die = pw_encrypt. 2) using ask_and_check_password or ask_and_check_password_extended fixed by Lauri's patch busybox/loginutils/login.c busybox/loginutils/su.c busybox/loginutils/sulogin.c busybox/loginutils/vlock.c 3) needs separate fix (as daemon could not be killed) (untested): busybox/networking/httpd.c at line 1874 if (passwd[0] == '$' && isdigit(passwd[1])) { char *encrypted; # if !ENABLE_PAM check_encrypted: # endif /* encrypt pwd from peer and check match with local one */ encrypted = pw_encrypt( /* pwd (from peer): */ colon_after_user + 1, /* salt: */ passwd, /* cleanup: */ 0 ); + if (!encrypted) + r = 1; + else { r = strcmp(encrypted, passwd); free(encrypted); + } } else { /* local passwd is from httpd.conf and it's plaintext */ r = strcmp(colon_after_user + 1, passwd); } goto end_check_passwd; } Hope this helps. Ciao, Tito _______________________________________________ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox