The ypproto buffer (which supports + lines in master.passwd) was correct
authorderaadt <deraadt@openbsd.org>
Tue, 7 Dec 2021 18:13:45 +0000 (18:13 +0000)
committerderaadt <deraadt@openbsd.org>
Tue, 7 Dec 2021 18:13:45 +0000 (18:13 +0000)
length for maximum amount of strings, but forgot about the struct passwd
taken from the start, and it isn't clear if the missing non-string elements
cover for that shortage.  It would require misconfiguration by root to
exceed the buffer.  As well, the strings don't need to be aligned, and
thus sys/param.h isn't needed for ALIGN()
ok millert

lib/libc/gen/getpwent.c

index 7803999..435a9c4 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: getpwent.c,v 1.63 2019/07/02 15:54:05 deraadt Exp $ */
+/*     $OpenBSD: getpwent.c,v 1.64 2021/12/07 18:13:45 deraadt Exp $ */
 /*
  * Copyright (c) 2008 Theo de Raadt
  * Copyright (c) 1988, 1993
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  */
 
-#include <sys/param.h> /* ALIGN */
+#include <sys/types.h>
 #include <sys/mman.h>
 #include <fcntl.h>
 #include <db.h>
@@ -90,13 +90,11 @@ static enum _ypmode __ypmode;
 static char    *__ypcurrent;
 static int     __ypcurrentlen;
 static int     __yp_pw_flags;
-static struct passwd *__ypproto;
 static int     __getpwent_has_yppw = -1;
 static struct _ypexclude *__ypexhead;
 
 static int __has_yppw(void);
 static int __has_ypmaster(void);
-static void __ypproto_set(struct passwd *, long long *, int, int *);
 static int __ypparse(struct passwd *pw, char *s, int);
 
 #define LOOKUP_BYNAME 0
@@ -110,21 +108,19 @@ static struct passwd *__yppwlookup(int, char *, uid_t, struct passwd *,
 #define PASSWD_BYUID \
        (__has_ypmaster() ? "master.passwd.byuid" : "passwd.byuid")
 
-static void
-__ypproto_set(struct passwd *pw, long long *buf, int flags, int *yp_pw_flagsp)
-{
-       char *ptr;
+static struct passwd *__ypproto;
 
-       /* make this the new prototype */
-       ptr = (char *)buf;
+static void __ypproto_set(struct passwd *, struct pw_storage *, int, int *);
 
-       /* first allocate the struct. */
-       __ypproto = (struct passwd *)ptr;
-       ptr += sizeof(struct passwd);
+static void
+__ypproto_set(struct passwd *pw, struct pw_storage *buf, int flags,
+    int *yp_pw_flagsp)
+{
+       char *ptr = buf->pwbuf;
+       __ypproto = &buf->pw;
 
        /* name */
        if (pw->pw_name && (pw->pw_name)[0]) {
-               ptr = (char *)ALIGN(ptr);
                bcopy(pw->pw_name, ptr, strlen(pw->pw_name) + 1);
                __ypproto->pw_name = ptr;
                ptr += (strlen(pw->pw_name) + 1);
@@ -133,7 +129,6 @@ __ypproto_set(struct passwd *pw, long long *buf, int flags, int *yp_pw_flagsp)
 
        /* password */
        if (pw->pw_passwd && (pw->pw_passwd)[0]) {
-               ptr = (char *)ALIGN(ptr);
                bcopy(pw->pw_passwd, ptr, strlen(pw->pw_passwd) + 1);
                __ypproto->pw_passwd = ptr;
                ptr += (strlen(pw->pw_passwd) + 1);
@@ -154,7 +149,6 @@ __ypproto_set(struct passwd *pw, long long *buf, int flags, int *yp_pw_flagsp)
 
        /* gecos */
        if (pw->pw_gecos && (pw->pw_gecos)[0]) {
-               ptr = (char *)ALIGN(ptr);
                bcopy(pw->pw_gecos, ptr, strlen(pw->pw_gecos) + 1);
                __ypproto->pw_gecos = ptr;
                ptr += (strlen(pw->pw_gecos) + 1);
@@ -163,7 +157,6 @@ __ypproto_set(struct passwd *pw, long long *buf, int flags, int *yp_pw_flagsp)
 
        /* dir */
        if (pw->pw_dir && (pw->pw_dir)[0]) {
-               ptr = (char *)ALIGN(ptr);
                bcopy(pw->pw_dir, ptr, strlen(pw->pw_dir) + 1);
                __ypproto->pw_dir = ptr;
                ptr += (strlen(pw->pw_dir) + 1);
@@ -172,7 +165,6 @@ __ypproto_set(struct passwd *pw, long long *buf, int flags, int *yp_pw_flagsp)
 
        /* shell */
        if (pw->pw_shell && (pw->pw_shell)[0]) {
-               ptr = (char *)ALIGN(ptr);
                bcopy(pw->pw_shell, ptr, strlen(pw->pw_shell) + 1);
                __ypproto->pw_shell = ptr;
                ptr += (strlen(pw->pw_shell) + 1);
@@ -438,7 +430,7 @@ again:
        key.size = 1 + sizeof(_pw_keynum);
        if (__hashpw(&key, pwbuf, buflen, pw, &_pw_flags)) {
 #ifdef YP
-               static long long __yppbuf[_PW_BUF_LEN / sizeof(long long)];
+               static struct pw_storage __yppbuf;
                const char *user, *host, *dom;
 
                /* if we don't have YP at all, don't bother. */
@@ -459,7 +451,7 @@ again:
                                        break;
                                }
 
-                               __ypproto_set(pw, __yppbuf, _pw_flags,
+                               __ypproto_set(pw, &__yppbuf, _pw_flags,
                                    &__yp_pw_flags);
                                goto again;
                        } else if (pw->pw_name[0] == '-') {
@@ -577,7 +569,7 @@ __yppwlookup(int lookup, char *name, uid_t uid, struct passwd *pw,
 {
        char bf[1 + _PW_NAME_LEN], *ypcurrent = NULL, *map = NULL;
        int yp_pw_flags = 0, ypcurrentlen, r, s = -1, pw_keynum;
-       static long long yppbuf[_PW_BUF_LEN / sizeof(long long)];
+       static struct pw_storage __yppbuf;
        struct _ypexclude *ypexhead = NULL;
        const char *host, *user, *dom;
        DBT key;
@@ -595,7 +587,7 @@ __yppwlookup(int lookup, char *name, uid_t uid, struct passwd *pw,
                                if (_yp_check(&__ypdomain) == 0)
                                        continue;
                        }
-                       __ypproto_set(pw, yppbuf, *flagsp, &yp_pw_flags);
+                       __ypproto_set(pw, &__yppbuf, *flagsp, &yp_pw_flags);
                        if (!map) {
                                if (lookup == LOOKUP_BYNAME) {
                                        if ((name = strdup(name)) == NULL) {