]> git.ipfire.org Git - thirdparty/shadow.git/commitdiff
Raise limit for passwd and shadow entry length
authorIker Pedrosa <ipedrosa@redhat.com>
Fri, 7 Oct 2022 10:36:59 +0000 (12:36 +0200)
committerIker Pedrosa <ikerpedrosam@gmail.com>
Fri, 14 Oct 2022 08:41:40 +0000 (10:41 +0200)
Moreover, include checks to prevent writing entries longer than the
length limit.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1422497

Signed-off-by: Tomáš Mráz <tm@t8m.info>
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
lib/defines.h
lib/pwio.c
lib/sgetpwent.c
lib/sgetspent.c
lib/shadowio.c

index 6a6bf73e59b7b1d938e1476248965c725262d980..d01f691e04769929c9af7fdbd00caa17509f763f 100644 (file)
@@ -327,6 +327,9 @@ extern char *strerror ();
 # endif
 #endif
 
+/* Maximum length of passwd entry */
+#define PASSWD_ENTRY_MAX_LENGTH 32768
+
 #ifdef HAVE_SECURE_GETENV
 #  define shadow_getenv(name) secure_getenv(name)
 # else
index 2efecfbffb09d5413e9e9c92c9b6692b12218e8b..e59b473c0b993ed45cd7e4b53a98c8c0ce321fb2 100644 (file)
@@ -56,7 +56,10 @@ static int passwd_put (const void *ent, FILE * file)
            || (pw->pw_gid == (gid_t)-1)
            || (valid_field (pw->pw_gecos, ":\n") == -1)
            || (valid_field (pw->pw_dir, ":\n") == -1)
-           || (valid_field (pw->pw_shell, ":\n") == -1)) {
+           || (valid_field (pw->pw_shell, ":\n") == -1)
+           || (strlen (pw->pw_name) + strlen (pw->pw_passwd) +
+               strlen (pw->pw_gecos) + strlen (pw->pw_dir) +
+               strlen (pw->pw_shell) + 100 > PASSWD_ENTRY_MAX_LENGTH)) {
                return -1;
        }
 
index c6e5944c6d5a3f1972d4fcd541765eba4658c3c1..1c8c63e0c676a853f777b0c178f702937a1a4a6b 100644 (file)
@@ -16,6 +16,7 @@
 #include <stdio.h>
 #include <pwd.h>
 #include "prototypes.h"
+#include "shadowlog_internal.h"
 
 #define        NFIELDS 7
 
@@ -34,7 +35,7 @@
 struct passwd *sgetpwent (const char *buf)
 {
        static struct passwd pwent;
-       static char pwdbuf[1024];
+       static char pwdbuf[PASSWD_ENTRY_MAX_LENGTH];
        int i;
        char *cp;
        char *fields[NFIELDS];
@@ -44,8 +45,12 @@ struct passwd *sgetpwent (const char *buf)
         * the password structure remain valid.
         */
 
-       if (strlen (buf) >= sizeof pwdbuf)
+       if (strlen (buf) >= sizeof pwdbuf) {
+               fprintf (shadow_logfd,
+                        "%s: Too long passwd entry encountered, file corruption?\n",
+                        shadow_progname);
                return 0;       /* fail if too long */
+       }
        strcpy (pwdbuf, buf);
 
        /*
index cbadb7e6d9f2a6d8508914359bef53258c528447..f1d4b20172de8cce5c835adb4c753e87d8dbecf6 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <sys/types.h>
 #include "prototypes.h"
+#include "shadowlog_internal.h"
 #include "defines.h"
 #include <stdio.h>
 #define        FIELDS  9
@@ -25,7 +26,7 @@
  */
 struct spwd *sgetspent (const char *string)
 {
-       static char spwbuf[1024];
+       static char spwbuf[PASSWD_ENTRY_MAX_LENGTH];
        static struct spwd spwd;
        char *fields[FIELDS];
        char *cp;
@@ -37,6 +38,9 @@ struct spwd *sgetspent (const char *string)
         */
 
        if (strlen (string) >= sizeof spwbuf) {
+               fprintf (shadow_logfd,
+                        "%s: Too long passwd entry encountered, file corruption?\n",
+                        shadow_progname);
                return 0;       /* fail if too long */
        }
        strcpy (spwbuf, string);
index 340760405e0f3d463a512a92f1d95fc5d06598ed..683b6c8169f5bdfd4fbaf713e185f7dded482c18 100644 (file)
@@ -56,7 +56,9 @@ static int shadow_put (const void *ent, FILE * file)
 
        if (   (NULL == sp)
            || (valid_field (sp->sp_namp, ":\n") == -1)
-           || (valid_field (sp->sp_pwdp, ":\n") == -1)) {
+           || (valid_field (sp->sp_pwdp, ":\n") == -1)
+           || (strlen (sp->sp_namp) + strlen (sp->sp_pwdp) +
+               1000 > PASSWD_ENTRY_MAX_LENGTH)) {
                return -1;
        }