Page MenuHomePhabricator

ssh_get_user_home_dir does not check for no match
Closed, ResolvedPublic

Description

in src/misc.c's ssh_get_user_home_dir, under non-_WIN32, we find the following bit of code:

rc = getpwuid_r(getuid(), &pwd, buf, NSS_BUFLEN_PASSWD, &pwdbuf);
if (rc != 0) {
  /* look up user in $HOME*/
}
/* return pwd.pwd_dir */

however, getpwuid_r(3) says

On success, getpwnam_r() and getpwuid_r() return zero, and set *result
to pwd. If no matching password record was found, these functions
return 0 and store NULL in *result. In case of error, an error number
is returned, and NULL is stored in *result.

which means that if the result of getuid() is not found, pwd.pwd_dir will be returned in error.
(Before you say "that can't happen", we tracked this down from a user's bug report...)

The fix is very simple:

diff --git a/src/misc.c b/src/misc.c
index 402ece41..98246332 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -221,7 +221,7 @@ char *ssh_get_user_home_dir(void) {
   int rc;
 
   rc = getpwuid_r(getuid(), &pwd, buf, NSS_BUFLEN_PASSWD, &pwdbuf);
-  if (rc != 0) {
+  if (rc != 0 || pwdbuf == NULL) {
       szPath = getenv("HOME");
       if (szPath == NULL) {
           return NULL;