summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authornectar <nectar@FreeBSD.org>2003-04-18 17:27:05 +0000
committernectar <nectar@FreeBSD.org>2003-04-18 17:27:05 +0000
commitd53b36cf851bcc2e9e9b875e0d7f39356f15f0af (patch)
tree970d280792e7945e03e260da34da4dc8302ab937 /lib
parent83fe46be1839e24062ca7d8914d86a3a2142e114 (diff)
downloadFreeBSD-src-d53b36cf851bcc2e9e9b875e0d7f39356f15f0af.zip
FreeBSD-src-d53b36cf851bcc2e9e9b875e0d7f39356f15f0af.tar.gz
Don't use `memset' to initialize a struct passwd. A module
may not fill in all fields, and in the case of string fields, this could cause trouble for applications. (The only likely example is `pw_class', because this field is not used by all modules in all cases.) Move initialization of struct passwd from module-specific code to the dispatch code. The problem of a NULL pw_class was Noticed by: Philip Paeps <philip@paeps.cx> and the c^Htrusty ssh(1) command. Déjà vu by: getpwent.c revision 1.56 Sponsored by: DARPA, Network Associates Laboratories
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/gen/getpwent.c37
1 files changed, 31 insertions, 6 deletions
diff --git a/lib/libc/gen/getpwent.c b/lib/libc/gen/getpwent.c
index f00b20b..a38483b 100644
--- a/lib/libc/gen/getpwent.c
+++ b/lib/libc/gen/getpwent.c
@@ -91,6 +91,8 @@ int __pw_match_entry(const char *, size_t, enum nss_lookup_type,
const char *, uid_t);
int __pw_parse_entry(char *, size_t, struct passwd *, int, int *errnop);
+static int pwd_init(struct passwd *, char *, size_t);
+
union key {
const char *name;
uid_t uid;
@@ -266,8 +268,10 @@ getpwent_r(struct passwd *pwd, char *buffer, size_t bufsize,
};
int rv, ret_errno;
- ret_errno = 0;
*result = NULL;
+ ret_errno = pwd_init(pwd, buffer, bufsize);
+ if (ret_errno != 0)
+ return (ret_errno);
rv = _nsdispatch(result, dtab, NSDB_PASSWD, "getpwent_r", defaultsrc,
pwd, buffer, bufsize, &ret_errno);
if (rv == NS_SUCCESS)
@@ -294,8 +298,10 @@ getpwnam_r(const char *name, struct passwd *pwd, char *buffer, size_t bufsize,
};
int rv, ret_errno;
- ret_errno = 0;
*result = NULL;
+ ret_errno = pwd_init(pwd, buffer, bufsize);
+ if (ret_errno != 0)
+ return (ret_errno);
rv = _nsdispatch(result, dtab, NSDB_PASSWD, "getpwnam_r", defaultsrc,
name, pwd, buffer, bufsize, &ret_errno);
if (rv == NS_SUCCESS)
@@ -322,8 +328,10 @@ getpwuid_r(uid_t uid, struct passwd *pwd, char *buffer, size_t bufsize,
};
int rv, ret_errno;
- ret_errno = 0;
*result = NULL;
+ ret_errno = pwd_init(pwd, buffer, bufsize);
+ if (ret_errno != 0)
+ return (ret_errno);
rv = _nsdispatch(result, dtab, NSDB_PASSWD, "getpwuid_r", defaultsrc,
uid, pwd, buffer, bufsize, &ret_errno);
if (rv == NS_SUCCESS)
@@ -333,6 +341,26 @@ getpwuid_r(uid_t uid, struct passwd *pwd, char *buffer, size_t bufsize,
}
+static int
+pwd_init(struct passwd *pwd, char *buffer, size_t bufsize)
+{
+
+ if (bufsize < 1)
+ return (ERANGE);
+ buffer[0] = '\0';
+ memset(pwd, 0, sizeof(*pwd));
+ pwd->pw_uid = (uid_t)-1; /* Considered least likely to lead to */
+ pwd->pw_gid = (gid_t)-1; /* a security issue. */
+ pwd->pw_name = buffer;
+ pwd->pw_passwd = buffer;
+ pwd->pw_class = buffer;
+ pwd->pw_gecos = buffer;
+ pwd->pw_dir = buffer;
+ pwd->pw_shell = buffer;
+ return (0);
+}
+
+
static struct passwd pwd;
static char *pwd_storage;
static size_t pwd_storage_size;
@@ -667,7 +695,6 @@ pwdb_parse_entry_v3(char *buffer, size_t bufsize, struct passwd *pwd,
char *p, *eom;
int32_t pw_change, pw_expire;
- memset(pwd, 0, sizeof(*pwd));
/* THIS CODE MUST MATCH THAT IN pwd_mkdb. */
p = buffer;
eom = &buffer[bufsize];
@@ -739,7 +766,6 @@ pwdb_parse_entry_v4(char *buffer, size_t bufsize, struct passwd *pwd,
char *p, *eom;
uint32_t n;
- memset(pwd, 0, sizeof(*pwd));
/* THIS CODE MUST MATCH THAT IN pwd_mkdb. */
p = buffer;
eom = &buffer[bufsize];
@@ -1652,7 +1678,6 @@ __pw_parse_entry(char *buffer, size_t bufsize __unused, struct passwd *pwd,
int master, int *errnop __unused)
{
- memset(pwd, 0, sizeof(*pwd));
if (__pw_scan(buffer, pwd, master ? _PWSCAN_MASTER : 0) == 0)
return (NS_NOTFOUND);
else
OpenPOWER on IntegriCloud