about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2017-06-15 13:01:34 -0400
committerRich Felker <dalias@aerifal.cx>2017-06-15 13:01:34 -0400
commit2d7d05f031e014068a61d3076c6178513395d2ae (patch)
tree533f4bd2fedea2ff59d998ebc1f6c73aabc1ac44
parent5c10c33d2a35204ee76931625a007fcc8cca3228 (diff)
downloadmusl-2d7d05f031e014068a61d3076c6178513395d2ae.tar.gz
musl-2d7d05f031e014068a61d3076c6178513395d2ae.tar.xz
musl-2d7d05f031e014068a61d3076c6178513395d2ae.zip
set errno when getpw*_r, getgr*_r, and getspnam_r fail
these functions return an error code, and are not explicitly
documented to set errno, but they are nonstandard and the historical
implementations do set errno as well, and some applications expect
this behavior. do likewise for compatibility.

patch by Rudolph Pereira.
-rw-r--r--src/passwd/getgr_r.c1
-rw-r--r--src/passwd/getpw_r.c1
-rw-r--r--src/passwd/getspnam_r.c8
3 files changed, 7 insertions, 3 deletions
diff --git a/src/passwd/getgr_r.c b/src/passwd/getgr_r.c
index 7246e8a4..f3e8f603 100644
--- a/src/passwd/getgr_r.c
+++ b/src/passwd/getgr_r.c
@@ -34,6 +34,7 @@ static int getgr_r(const char *name, gid_t gid, struct group *gr, char *buf, siz
  	free(mem);
  	free(line);
 	pthread_setcancelstate(cs, 0);
+	if (rv) errno = rv;
 	return rv;
 }
 
diff --git a/src/passwd/getpw_r.c b/src/passwd/getpw_r.c
index e8cc811e..0c87ab05 100644
--- a/src/passwd/getpw_r.c
+++ b/src/passwd/getpw_r.c
@@ -27,6 +27,7 @@ static int getpw_r(const char *name, uid_t uid, struct passwd *pw, char *buf, si
 	}
  	free(line);
 	pthread_setcancelstate(cs, 0);
+	if (rv) errno = rv;
 	return rv;
 }
 
diff --git a/src/passwd/getspnam_r.c b/src/passwd/getspnam_r.c
index 92339528..e488b67f 100644
--- a/src/passwd/getspnam_r.c
+++ b/src/passwd/getspnam_r.c
@@ -72,14 +72,15 @@ int getspnam_r(const char *name, struct spwd *sp, char *buf, size_t size, struct
 
 	/* Disallow potentially-malicious user names */
 	if (*name=='.' || strchr(name, '/') || !l)
-		return EINVAL;
+		return errno = EINVAL;
 
 	/* Buffer size must at least be able to hold name, plus some.. */
-	if (size < l+100) return ERANGE;
+	if (size < l+100)
+		return errno = EINVAL;
 
 	/* Protect against truncation */
 	if (snprintf(path, sizeof path, "/etc/tcb/%s/shadow", name) >= sizeof path)
-		return EINVAL;
+		return errno = EINVAL;
 
 	fd = open(path, O_RDONLY|O_NOFOLLOW|O_NONBLOCK|O_CLOEXEC);
 	if (fd >= 0) {
@@ -112,5 +113,6 @@ int getspnam_r(const char *name, struct spwd *sp, char *buf, size_t size, struct
 		break;
 	}
 	pthread_cleanup_pop(1);
+	if (rv) errno = rv;
 	return rv;
 }