Raise limit for passwd and shadow entry length

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>
This commit is contained in:
Iker Pedrosa 2022-10-07 12:36:59 +02:00 committed by Iker Pedrosa
parent fbf275da19
commit 16afe18142
5 changed files with 22 additions and 5 deletions

View File

@ -327,6 +327,9 @@ extern char *strerror ();
# endif # endif
#endif #endif
/* Maximum length of passwd entry */
#define PASSWD_ENTRY_MAX_LENGTH 32768
#ifdef HAVE_SECURE_GETENV #ifdef HAVE_SECURE_GETENV
# define shadow_getenv(name) secure_getenv(name) # define shadow_getenv(name) secure_getenv(name)
# else # else

View File

@ -56,7 +56,10 @@ static int passwd_put (const void *ent, FILE * file)
|| (pw->pw_gid == (gid_t)-1) || (pw->pw_gid == (gid_t)-1)
|| (valid_field (pw->pw_gecos, ":\n") == -1) || (valid_field (pw->pw_gecos, ":\n") == -1)
|| (valid_field (pw->pw_dir, ":\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; return -1;
} }

View File

@ -16,6 +16,7 @@
#include <stdio.h> #include <stdio.h>
#include <pwd.h> #include <pwd.h>
#include "prototypes.h" #include "prototypes.h"
#include "shadowlog_internal.h"
#define NFIELDS 7 #define NFIELDS 7
@ -34,7 +35,7 @@
struct passwd *sgetpwent (const char *buf) struct passwd *sgetpwent (const char *buf)
{ {
static struct passwd pwent; static struct passwd pwent;
static char pwdbuf[1024]; static char pwdbuf[PASSWD_ENTRY_MAX_LENGTH];
int i; int i;
char *cp; char *cp;
char *fields[NFIELDS]; char *fields[NFIELDS];
@ -44,8 +45,12 @@ struct passwd *sgetpwent (const char *buf)
* the password structure remain valid. * 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 */ return 0; /* fail if too long */
}
strcpy (pwdbuf, buf); strcpy (pwdbuf, buf);
/* /*

View File

@ -16,6 +16,7 @@
#include <sys/types.h> #include <sys/types.h>
#include "prototypes.h" #include "prototypes.h"
#include "shadowlog_internal.h"
#include "defines.h" #include "defines.h"
#include <stdio.h> #include <stdio.h>
#define FIELDS 9 #define FIELDS 9
@ -25,7 +26,7 @@
*/ */
struct spwd *sgetspent (const char *string) struct spwd *sgetspent (const char *string)
{ {
static char spwbuf[1024]; static char spwbuf[PASSWD_ENTRY_MAX_LENGTH];
static struct spwd spwd; static struct spwd spwd;
char *fields[FIELDS]; char *fields[FIELDS];
char *cp; char *cp;
@ -37,6 +38,9 @@ struct spwd *sgetspent (const char *string)
*/ */
if (strlen (string) >= sizeof spwbuf) { 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 */ return 0; /* fail if too long */
} }
strcpy (spwbuf, string); strcpy (spwbuf, string);

View File

@ -56,7 +56,9 @@ static int shadow_put (const void *ent, FILE * file)
if ( (NULL == sp) if ( (NULL == sp)
|| (valid_field (sp->sp_namp, ":\n") == -1) || (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; return -1;
} }