From 6512aaf03ddf7a67f1bf6096313eab6953995a9e Mon Sep 17 00:00:00 2001 From: fly_fzc <2385803914@qq.com> Date: Wed, 20 Dec 2023 11:54:58 +0800 Subject: [PATCH] backport patches from upstream --- backport-Fix-covscan-BUFFER_SIZE.patch | 134 ++++++++ backport-Fix-covscan-RESOURCE_LEAK.patch | 323 ++++++++++++++++++ ...ort-Fix-useradd-with-SUB_UID_COUNT-0.patch | 44 +++ ...-create-relative-home-path-correctly.patch | 71 ++++ ...turns-element-count-not-element-size.patch | 25 ++ ...Obtain-random-bytes-from-dev-urandom.patch | 128 +++++++ ...se-secure-system-ressources-to-obtai.patch | 126 +++++++ ...-useradd.c-fix-covscan-RESOURCE_LEAK.patch | 122 +++++++ ...-usermod.c-fix-covscan-RESOURCE_LEAK.patch | 157 +++++++++ shadow.spec | 14 +- 10 files changed, 1143 insertions(+), 1 deletion(-) create mode 100644 backport-Fix-covscan-BUFFER_SIZE.patch create mode 100644 backport-Fix-covscan-RESOURCE_LEAK.patch create mode 100644 backport-Fix-useradd-with-SUB_UID_COUNT-0.patch create mode 100644 backport-fix-create-relative-home-path-correctly.patch create mode 100644 backport-fread-returns-element-count-not-element-size.patch create mode 100644 backport-libmisc-salt.c-Obtain-random-bytes-from-dev-urandom.patch create mode 100644 backport-libmisc-salt.c-Use-secure-system-ressources-to-obtai.patch create mode 100644 backport-useradd.c-fix-covscan-RESOURCE_LEAK.patch create mode 100644 backport-usermod.c-fix-covscan-RESOURCE_LEAK.patch diff --git a/backport-Fix-covscan-BUFFER_SIZE.patch b/backport-Fix-covscan-BUFFER_SIZE.patch new file mode 100644 index 0000000..6cc15b4 --- /dev/null +++ b/backport-Fix-covscan-BUFFER_SIZE.patch @@ -0,0 +1,134 @@ +From 5d0d7841971cc53d9a9d1aefe12f00204115bf6a Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Wed, 16 Jun 2021 09:50:53 +0200 +Subject: [PATCH] Fix covscan BUFFER_SIZE + +Error: BUFFER_SIZE (CWE-170): [#def6] +shadow-4.8.1/libmisc/failure.c:101: buffer_size_warning: Calling "strncpy" with a maximum size argument of 12 bytes on destination array "fl->fail_line" of size 12 bytes might leave the destination string unterminated. + 99| } + 100| + 101|-> strncpy (fl->fail_line, tty, sizeof fl->fail_line); + 102| (void) time (&fl->fail_time); + 103| + +Error: BUFFER_SIZE (CWE-170): [#def9] +shadow-4.8.1/libmisc/log.c:103: buffer_size_warning: Calling "strncpy" with a maximum size argument of 32 bytes on destination array "newlog.ll_line" of size 32 bytes might leave the destination string unterminated. + 101| (void) time (&ll_time); + 102| newlog.ll_time = ll_time; + 103|-> strncpy (newlog.ll_line, line, sizeof newlog.ll_line); + 104| #if HAVE_LL_HOST + 105| strncpy (newlog.ll_host, host, sizeof newlog.ll_host); + +Error: BUFFER_SIZE (CWE-170): [#def10] +shadow-4.8.1/libmisc/log.c:105: buffer_size_warning: Calling "strncpy" with a maximum size argument of 256 bytes on destination array "newlog.ll_host" of size 256 bytes might leave the destination string unterminated. + 103| strncpy (newlog.ll_line, line, sizeof newlog.ll_line); + 104| #if HAVE_LL_HOST + 105|-> strncpy (newlog.ll_host, host, sizeof newlog.ll_host); + 106| #endif + 107| if ( (lseek (fd, offset, SEEK_SET) != offset) + +Error: BUFFER_SIZE (CWE-170): [#def13] +shadow-4.8.1/libmisc/utmp.c:260: buffer_size_warning: Calling "strncpy" with a maximum size argument of 32 bytes on destination array "utent->ut_line" of size 32 bytes might leave the destination string unterminated. + 258| #endif /* HAVE_STRUCT_UTMP_UT_TYPE */ + 259| utent->ut_pid = getpid (); + 260|-> strncpy (utent->ut_line, line, sizeof (utent->ut_line)); + 261| #ifdef HAVE_STRUCT_UTMP_UT_ID + 262| if (NULL != ut) { + +Error: BUFFER_SIZE (CWE-170): [#def14] +shadow-4.8.1/libmisc/utmp.c:266: buffer_size_warning: Calling "strncpy" with a maximum size argument of 4 bytes on destination array "utent->ut_id" of size 4 bytes might leave the destination string unterminated. + 264| } else { + 265| /* XXX - assumes /dev/tty?? */ + 266|-> strncpy (utent->ut_id, line + 3, sizeof (utent->ut_id)); + 267| } + 268| #endif /* HAVE_STRUCT_UTMP_UT_ID */ + +Error: BUFFER_SIZE (CWE-170): [#def15] +shadow-4.8.1/libmisc/utmp.c:273: buffer_size_warning: Calling "strncpy" with a maximum size argument of 32 bytes on destination array "utent->ut_user" of size 32 bytes might leave the destination string unterminated. + 271| #endif /* HAVE_STRUCT_UTMP_UT_NAME */ + 272| #ifdef HAVE_STRUCT_UTMP_UT_USER + 273|-> strncpy (utent->ut_user, name, sizeof (utent->ut_user)); + 274| #endif /* HAVE_STRUCT_UTMP_UT_USER */ + 275| if (NULL != hostname) { + +Error: BUFFER_SIZE (CWE-170): [#def16] +shadow-4.8.1/libmisc/utmp.c:278: buffer_size_warning: Calling "strncpy" with a maximum size argument of 256 bytes on destination array "utent->ut_host" of size 256 bytes might leave the destination string unterminated. + 276| struct addrinfo *info = NULL; + 277| #ifdef HAVE_STRUCT_UTMP_UT_HOST + 278|-> strncpy (utent->ut_host, hostname, sizeof (utent->ut_host)); + 279| #endif /* HAVE_STRUCT_UTMP_UT_HOST */ + 280| #ifdef HAVE_STRUCT_UTMP_UT_SYSLEN + +Signed-off-by: Iker Pedrosa +--- + libmisc/failure.c | 2 +- + libmisc/log.c | 4 ++-- + libmisc/utmp.c | 8 ++++---- + 3 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/libmisc/failure.c b/libmisc/failure.c +index f6390a79..a1f3ec79 100644 +--- a/libmisc/failure.c ++++ b/libmisc/failure.c +@@ -98,7 +98,7 @@ void failure (uid_t uid, const char *tty, struct faillog *fl) + fl->fail_cnt++; + } + +- strncpy (fl->fail_line, tty, sizeof fl->fail_line); ++ strncpy (fl->fail_line, tty, sizeof (fl->fail_line) - 1); + (void) time (&fl->fail_time); + + /* +diff --git a/libmisc/log.c b/libmisc/log.c +index eb84859e..68a9d7e2 100644 +--- a/libmisc/log.c ++++ b/libmisc/log.c +@@ -100,9 +100,9 @@ void dolastlog ( + ll_time = newlog.ll_time; + (void) time (&ll_time); + newlog.ll_time = ll_time; +- strncpy (newlog.ll_line, line, sizeof newlog.ll_line); ++ strncpy (newlog.ll_line, line, sizeof (newlog.ll_line) - 1); + #if HAVE_LL_HOST +- strncpy (newlog.ll_host, host, sizeof newlog.ll_host); ++ strncpy (newlog.ll_host, host, sizeof (newlog.ll_host) - 1); + #endif + if ( (lseek (fd, offset, SEEK_SET) != offset) + || (write (fd, (const void *) &newlog, sizeof newlog) != (ssize_t) sizeof newlog) +diff --git a/libmisc/utmp.c b/libmisc/utmp.c +index ba69cf61..5dcd419f 100644 +--- a/libmisc/utmp.c ++++ b/libmisc/utmp.c +@@ -257,25 +257,25 @@ static void updwtmpx (const char *filename, const struct utmpx *utx) + utent->ut_type = USER_PROCESS; + #endif /* HAVE_STRUCT_UTMP_UT_TYPE */ + utent->ut_pid = getpid (); +- strncpy (utent->ut_line, line, sizeof (utent->ut_line)); ++ strncpy (utent->ut_line, line, sizeof (utent->ut_line) - 1); + #ifdef HAVE_STRUCT_UTMP_UT_ID + if (NULL != ut) { + strncpy (utent->ut_id, ut->ut_id, sizeof (utent->ut_id)); + } else { + /* XXX - assumes /dev/tty?? */ +- strncpy (utent->ut_id, line + 3, sizeof (utent->ut_id)); ++ strncpy (utent->ut_id, line + 3, sizeof (utent->ut_id) - 1); + } + #endif /* HAVE_STRUCT_UTMP_UT_ID */ + #ifdef HAVE_STRUCT_UTMP_UT_NAME + strncpy (utent->ut_name, name, sizeof (utent->ut_name)); + #endif /* HAVE_STRUCT_UTMP_UT_NAME */ + #ifdef HAVE_STRUCT_UTMP_UT_USER +- strncpy (utent->ut_user, name, sizeof (utent->ut_user)); ++ strncpy (utent->ut_user, name, sizeof (utent->ut_user) - 1); + #endif /* HAVE_STRUCT_UTMP_UT_USER */ + if (NULL != hostname) { + struct addrinfo *info = NULL; + #ifdef HAVE_STRUCT_UTMP_UT_HOST +- strncpy (utent->ut_host, hostname, sizeof (utent->ut_host)); ++ strncpy (utent->ut_host, hostname, sizeof (utent->ut_host) - 1); + #endif /* HAVE_STRUCT_UTMP_UT_HOST */ + #ifdef HAVE_STRUCT_UTMP_UT_SYSLEN + utent->ut_syslen = MIN (strlen (hostname), +-- +2.27.0 + diff --git a/backport-Fix-covscan-RESOURCE_LEAK.patch b/backport-Fix-covscan-RESOURCE_LEAK.patch new file mode 100644 index 0000000..909fcae --- /dev/null +++ b/backport-Fix-covscan-RESOURCE_LEAK.patch @@ -0,0 +1,323 @@ +From e65cc6aebcb4132fa413f00a905216a5b35b3d57 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Mon, 14 Jun 2021 12:39:48 +0200 +Subject: [PATCH] Fix covscan RESOURCE_LEAK + +Error: RESOURCE_LEAK (CWE-772): [#def1] +shadow-4.8.1/lib/commonio.c:320: alloc_fn: Storage is returned from allocation function "fopen_set_perms". +shadow-4.8.1/lib/commonio.c:320: var_assign: Assigning: "bkfp" = storage returned from "fopen_set_perms(backup, "w", &sb)". +shadow-4.8.1/lib/commonio.c:329: noescape: Resource "bkfp" is not freed or pointed-to in "putc". +shadow-4.8.1/lib/commonio.c:334: noescape: Resource "bkfp" is not freed or pointed-to in "fflush". +shadow-4.8.1/lib/commonio.c:339: noescape: Resource "bkfp" is not freed or pointed-to in "fileno". +shadow-4.8.1/lib/commonio.c:342: leaked_storage: Variable "bkfp" going out of scope leaks the storage it points to. + 340| || (fclose (bkfp) != 0)) { + 341| /* FIXME: unlink the backup file? */ + 342|-> return -1; + 343| } + 344| + +Error: RESOURCE_LEAK (CWE-772): [#def2] +shadow-4.8.1/libmisc/addgrps.c:69: alloc_fn: Storage is returned from allocation function "malloc". +shadow-4.8.1/libmisc/addgrps.c:69: var_assign: Assigning: "grouplist" = storage returned from "malloc(i * 4UL)". +shadow-4.8.1/libmisc/addgrps.c:73: noescape: Resource "grouplist" is not freed or pointed-to in "getgroups". [Note: The source code implementation of the function has been overridden by a builtin model.] +shadow-4.8.1/libmisc/addgrps.c:126: leaked_storage: Variable "grouplist" going out of scope leaks the storage it points to. + 124| } + 125| + 126|-> return 0; + 127| } + 128| #else /* HAVE_SETGROUPS && !USE_PAM */ + +Error: RESOURCE_LEAK (CWE-772): [#def3] +shadow-4.8.1/libmisc/chowntty.c:62: alloc_fn: Storage is returned from allocation function "getgr_nam_gid". +shadow-4.8.1/libmisc/chowntty.c:62: var_assign: Assigning: "grent" = storage returned from "getgr_nam_gid(getdef_str("TTYGROUP"))". +shadow-4.8.1/libmisc/chowntty.c:98: leaked_storage: Variable "grent" going out of scope leaks the storage it points to. + 96| */ + 97| #endif + 98|-> } + 99| + +Error: RESOURCE_LEAK (CWE-772): [#def4] +shadow-4.8.1/libmisc/copydir.c:742: open_fn: Returning handle opened by "open". [Note: The source code implementation of the function has been overridden by a user model.] +shadow-4.8.1/libmisc/copydir.c:742: var_assign: Assigning: "ifd" = handle returned from "open(src, 0)". +shadow-4.8.1/libmisc/copydir.c:748: leaked_handle: Handle variable "ifd" going out of scope leaks the handle. + 746| #ifdef WITH_SELINUX + 747| if (set_selinux_file_context (dst, NULL) != 0) { + 748|-> return -1; + 749| } + 750| #endif /* WITH_SELINUX */ + +Error: RESOURCE_LEAK (CWE-772): [#def5] +shadow-4.8.1/libmisc/copydir.c:751: open_fn: Returning handle opened by "open". [Note: The source code implementation of the function has been overridden by a user model.] +shadow-4.8.1/libmisc/copydir.c:751: var_assign: Assigning: "ofd" = handle returned from "open(dst, 577, statp->st_mode & 0xfffU)". +shadow-4.8.1/libmisc/copydir.c:752: noescape: Resource "ofd" is not freed or pointed-to in "fchown_if_needed". +shadow-4.8.1/libmisc/copydir.c:775: leaked_handle: Handle variable "ofd" going out of scope leaks the handle. + 773| ) { + 774| (void) close (ifd); + 775|-> return -1; + 776| } + 777| + +Error: RESOURCE_LEAK (CWE-772): [#def7] +shadow-4.8.1/libmisc/idmapping.c:188: alloc_fn: Storage is returned from allocation function "xmalloc". +shadow-4.8.1/libmisc/idmapping.c:188: var_assign: Assigning: "buf" = storage returned from "xmalloc(bufsize)". +shadow-4.8.1/libmisc/idmapping.c:188: var_assign: Assigning: "pos" = "buf". +shadow-4.8.1/libmisc/idmapping.c:213: noescape: Resource "buf" is not freed or pointed-to in "write". +shadow-4.8.1/libmisc/idmapping.c:219: leaked_storage: Variable "pos" going out of scope leaks the storage it points to. +shadow-4.8.1/libmisc/idmapping.c:219: leaked_storage: Variable "buf" going out of scope leaks the storage it points to. + 217| } + 218| close(fd); + 219|-> } + +Error: RESOURCE_LEAK (CWE-772): [#def8] +shadow-4.8.1/libmisc/list.c:211: alloc_fn: Storage is returned from allocation function "xstrdup". +shadow-4.8.1/libmisc/list.c:211: var_assign: Assigning: "members" = storage returned from "xstrdup(comma)". +shadow-4.8.1/libmisc/list.c:217: var_assign: Assigning: "cp" = "members". +shadow-4.8.1/libmisc/list.c:218: noescape: Resource "cp" is not freed or pointed-to in "strchr". +shadow-4.8.1/libmisc/list.c:244: leaked_storage: Variable "cp" going out of scope leaks the storage it points to. +shadow-4.8.1/libmisc/list.c:244: leaked_storage: Variable "members" going out of scope leaks the storage it points to. + 242| if ('\0' == *members) { + 243| *array = (char *) 0; + 244|-> return array; + 245| } + 246| + +Error: RESOURCE_LEAK (CWE-772): [#def11] +shadow-4.8.1/libmisc/myname.c:61: alloc_fn: Storage is returned from allocation function "xgetpwnam". +shadow-4.8.1/libmisc/myname.c:61: var_assign: Assigning: "pw" = storage returned from "xgetpwnam(cp)". +shadow-4.8.1/libmisc/myname.c:67: leaked_storage: Variable "pw" going out of scope leaks the storage it points to. + 65| } + 66| + 67|-> return xgetpwuid (ruid); + 68| } + 69| + +Error: RESOURCE_LEAK (CWE-772): [#def12] +shadow-4.8.1/libmisc/user_busy.c:260: alloc_fn: Storage is returned from allocation function "opendir". +shadow-4.8.1/libmisc/user_busy.c:260: var_assign: Assigning: "task_dir" = storage returned from "opendir(task_path)". +shadow-4.8.1/libmisc/user_busy.c:262: noescape: Resource "task_dir" is not freed or pointed-to in "readdir". +shadow-4.8.1/libmisc/user_busy.c:278: leaked_storage: Variable "task_dir" going out of scope leaks the storage it points to. + 276| _("%s: user %s is currently used by process %d\n"), + 277| Prog, name, pid); + 278|-> return 1; + 279| } + 280| } + +Error: RESOURCE_LEAK (CWE-772): [#def20] +shadow-4.8.1/src/newgrp.c:162: alloc_fn: Storage is returned from allocation function "xgetspnam". +shadow-4.8.1/src/newgrp.c:162: var_assign: Assigning: "spwd" = storage returned from "xgetspnam(pwd->pw_name)". +shadow-4.8.1/src/newgrp.c:234: leaked_storage: Variable "spwd" going out of scope leaks the storage it points to. + 232| } + 233| + 234|-> return; + 235| + 236| failure: + +Error: RESOURCE_LEAK (CWE-772): [#def21] +shadow-4.8.1/src/passwd.c:530: alloc_fn: Storage is returned from allocation function "xstrdup". +shadow-4.8.1/src/passwd.c:530: var_assign: Assigning: "cp" = storage returned from "xstrdup(crypt_passwd)". +shadow-4.8.1/src/passwd.c:551: noescape: Resource "cp" is not freed or pointed-to in "strlen". +shadow-4.8.1/src/passwd.c:554: noescape: Resource "cp" is not freed or pointed-to in "strcat". [Note: The source code implementation of the function has been overridden by a builtin model.] +shadow-4.8.1/src/passwd.c:555: overwrite_var: Overwriting "cp" in "cp = newpw" leaks the storage that "cp" points to. + 553| strcpy (newpw, "!"); + 554| strcat (newpw, cp); + 555|-> cp = newpw; + 556| } + 557| return cp; +--- + lib/commonio.c | 8 ++++++-- + libmisc/addgrps.c | 6 +++++- + libmisc/chowntty.c | 1 + + libmisc/copydir.c | 6 ++++++ + libmisc/idmapping.c | 1 + + libmisc/list.c | 3 +++ + libmisc/myname.c | 3 +++ + libmisc/user_busy.c | 1 + + src/newgrp.c | 3 ++- + src/passwd.c | 5 +++++ + 10 files changed, 33 insertions(+), 4 deletions(-) + +diff --git a/lib/commonio.c b/lib/commonio.c +index 23ac91f9..cef404b9 100644 +--- a/lib/commonio.c ++++ b/lib/commonio.c +@@ -336,8 +336,12 @@ static int create_backup (const char *backup, FILE * fp) + /* FIXME: unlink the backup file? */ + return -1; + } +- if ( (fsync (fileno (bkfp)) != 0) +- || (fclose (bkfp) != 0)) { ++ if (fsync (fileno (bkfp)) != 0) { ++ (void) fclose (bkfp); ++ /* FIXME: unlink the backup file? */ ++ return -1; ++ } ++ if (fclose (bkfp) != 0) { + /* FIXME: unlink the backup file? */ + return -1; + } +diff --git a/libmisc/addgrps.c b/libmisc/addgrps.c +index 2e38e340..76c172a5 100644 +--- a/libmisc/addgrps.c ++++ b/libmisc/addgrps.c +@@ -57,6 +57,7 @@ int add_groups (const char *list) + bool added; + char *token; + char buf[1024]; ++ int ret; + + if (strlen (list) >= sizeof (buf)) { + errno = EINVAL; +@@ -120,9 +121,12 @@ int add_groups (const char *list) + } + + if (added) { +- return setgroups ((size_t)ngroups, grouplist); ++ ret = setgroups ((size_t)ngroups, grouplist); ++ free (grouplist); ++ return ret; + } + ++ free (grouplist); + return 0; + } + #else /* HAVE_SETGROUPS && !USE_PAM */ +diff --git a/libmisc/chowntty.c b/libmisc/chowntty.c +index ea706c4f..a42ab622 100644 +--- a/libmisc/chowntty.c ++++ b/libmisc/chowntty.c +@@ -62,6 +62,7 @@ void chown_tty (const struct passwd *info) + grent = getgr_nam_gid (getdef_str ("TTYGROUP")); + if (NULL != grent) { + gid = grent->gr_gid; ++ gr_free (grent); + } else { + gid = info->pw_gid; + } +diff --git a/libmisc/copydir.c b/libmisc/copydir.c +index 91d391f8..015e1b68 100644 +--- a/libmisc/copydir.c ++++ b/libmisc/copydir.c +@@ -745,6 +745,7 @@ static int copy_file (const char *src, const char *dst, + } + #ifdef WITH_SELINUX + if (set_selinux_file_context (dst) != 0) { ++ (void) close (ifd); + return -1; + } + #endif /* WITH_SELINUX */ +@@ -771,12 +772,16 @@ static int copy_file (const char *src, const char *dst, + && (errno != 0)) + #endif /* WITH_ATTR */ + ) { ++ if (ofd >= 0) { ++ (void) close (ofd); ++ } + (void) close (ifd); + return -1; + } + + while ((cnt = read (ifd, buf, sizeof buf)) > 0) { + if (write (ofd, buf, (size_t)cnt) != cnt) { ++ (void) close (ofd); + (void) close (ifd); + return -1; + } +@@ -786,6 +791,7 @@ static int copy_file (const char *src, const char *dst, + + #ifdef HAVE_FUTIMES + if (futimes (ofd, mt) != 0) { ++ (void) close (ofd); + return -1; + } + #endif /* HAVE_FUTIMES */ +diff --git a/libmisc/idmapping.c b/libmisc/idmapping.c +index b0ae488c..3324f671 100644 +--- a/libmisc/idmapping.c ++++ b/libmisc/idmapping.c +@@ -241,4 +241,5 @@ void write_mapping(int proc_dir_fd, int ranges, struct map_range *mappings, + exit(EXIT_FAILURE); + } + close(fd); ++ free(buf); + } +diff --git a/libmisc/list.c b/libmisc/list.c +index 2da734a7..d85d5f20 100644 +--- a/libmisc/list.c ++++ b/libmisc/list.c +@@ -241,6 +241,7 @@ bool is_on_list (char *const *list, const char *member) + + if ('\0' == *members) { + *array = (char *) 0; ++ free (members); + return array; + } + +@@ -262,6 +263,8 @@ bool is_on_list (char *const *list, const char *member) + } + } + ++ free (members); ++ + /* + * Return the new array of pointers + */ +diff --git a/libmisc/myname.c b/libmisc/myname.c +index 05efdad3..e1b7f702 100644 +--- a/libmisc/myname.c ++++ b/libmisc/myname.c +@@ -62,6 +62,9 @@ + if ((NULL != pw) && (pw->pw_uid == ruid)) { + return pw; + } ++ if (NULL != pw) { ++ pw_free (pw); ++ } + } + + return xgetpwuid (ruid); +diff --git a/libmisc/user_busy.c b/libmisc/user_busy.c +index 4b507fe2..3deebfc3 100644 +--- a/libmisc/user_busy.c ++++ b/libmisc/user_busy.c +@@ -269,6 +269,7 @@ static int user_busy_processes (const char *name, uid_t uid) + } + if (check_status (name, task_path+6, uid) != 0) { + (void) closedir (proc); ++ (void) closedir (task_dir); + #ifdef ENABLE_SUBIDS + sub_uid_close(); + #endif +diff --git a/src/newgrp.c b/src/newgrp.c +index 2aa28b87..2b9293b4 100644 +--- a/src/newgrp.c ++++ b/src/newgrp.c +@@ -162,8 +162,9 @@ static void check_perms (const struct group *grp, + */ + spwd = xgetspnam (pwd->pw_name); + if (NULL != spwd) { +- pwd->pw_passwd = spwd->sp_pwdp; ++ pwd->pw_passwd = xstrdup (spwd->sp_pwdp); + } ++ spw_free (spwd); + + if ((pwd->pw_passwd[0] == '\0') && (grp->gr_passwd[0] != '\0')) { + needspasswd = true; +diff --git a/src/passwd.c b/src/passwd.c +index 3d4206f4..9d7df331 100644 +--- a/src/passwd.c ++++ b/src/passwd.c +@@ -553,6 +553,11 @@ static char *update_crypt_pw (char *cp) + + strcpy (newpw, "!"); + strcat (newpw, cp); ++#ifndef USE_PAM ++ if (do_update_pwd) { ++ free (cp); ++ } ++#endif /* USE_PAM */ + cp = newpw; + } + return cp; +-- +2.27.0 + diff --git a/backport-Fix-useradd-with-SUB_UID_COUNT-0.patch b/backport-Fix-useradd-with-SUB_UID_COUNT-0.patch new file mode 100644 index 0000000..729c31c --- /dev/null +++ b/backport-Fix-useradd-with-SUB_UID_COUNT-0.patch @@ -0,0 +1,44 @@ +From 663824ef4ca927aa2b4319b69e0bfa68282ec719 Mon Sep 17 00:00:00 2001 +From: Serge Hallyn +Date: Sat, 22 May 2021 11:42:02 -0500 +Subject: [PATCH] Fix useradd with SUB_UID_COUNT=0 + +Closes #298 + +Fix useradd when SUB_UID_COUNT=0 in login.defs. + +Signed-off-by: Serge Hallyn +--- + src/useradd.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/src/useradd.c b/src/useradd.c +index 06accb2f..9862ae55 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -2386,6 +2386,8 @@ int main (int argc, char **argv) + #ifdef ENABLE_SUBIDS + uid_t uid_min; + uid_t uid_max; ++ unsigned long subuid_count; ++ unsigned long subgid_count; + #endif + + /* +@@ -2427,9 +2429,11 @@ int main (int argc, char **argv) + #ifdef ENABLE_SUBIDS + uid_min = (uid_t) getdef_ulong ("UID_MIN", 1000UL); + uid_max = (uid_t) getdef_ulong ("UID_MAX", 60000UL); +- is_sub_uid = sub_uid_file_present () && !rflg && ++ subuid_count = getdef_ulong ("SUB_UID_COUNT", 65536); ++ subgid_count = getdef_ulong ("SUB_GID_COUNT", 65536); ++ is_sub_uid = subuid_count > 0 && sub_uid_file_present () && !rflg && + (!user_id || (user_id <= uid_max && user_id >= uid_min)); +- is_sub_gid = sub_gid_file_present () && !rflg && ++ is_sub_gid = subgid_count > 0 && sub_gid_file_present () && !rflg && + (!user_id || (user_id <= uid_max && user_id >= uid_min)); + #endif /* ENABLE_SUBIDS */ + +-- +2.27.0 + diff --git a/backport-fix-create-relative-home-path-correctly.patch b/backport-fix-create-relative-home-path-correctly.patch new file mode 100644 index 0000000..43b130a --- /dev/null +++ b/backport-fix-create-relative-home-path-correctly.patch @@ -0,0 +1,71 @@ +From 2c542f6c65f858b3dba20f58db4da56572f67a54 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Lucas=20Serv=C3=A9n=20Mar=C3=ADn?= +Date: Thu, 29 Apr 2021 14:09:31 +0200 +Subject: [PATCH] fix: create relative home path correctly +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Currently, supplying a relative path via the --prefix flag to the +useradd command triggers a bug in the creation of home directories. The +code seems to unintentionally prepend a leading "/" to all paths, +quietly transforming a relative prefixed home path into an absolute +path. This can be seen in the following strace logs from running +"useradd --create-home --prefix tmp/root squat": + +``` +access("tmp/root//home/squat", F_OK) = -1 ENOENT (No such file or directory) +access("/mp", F_OK) = 0 +access("/mp/root", F_OK) = 0 +access("/mp/root/home", F_OK) = 0 +access("/mp/root/home/squat", F_OK) = -1 ENOENT (No such file or directory) +mkdir("/mp/root/home/squat", 000) = 0 +chown("/mp/root/home/squat", 0, 0) = 0 +chmod("/mp/root/home/squat", 0755) = 0 +chown("tmp/root//home/squat", 1000, 1000) = -1 ENOENT (No such file or directory) +chmod("tmp/root//home/squat", 0700) = -1 ENOENT (No such file or directory) +``` + +Note that the relative path is correctly probed in the beginning and it +is only during the recursive creation that the path is turned into an +absolute path. This invocation results in the creation of a "/mp" +hierarchy in the root of the filesystem. + +Similar problems occur when using `--prefix ./tmp/root`. + +This commit fixes the handling of relative paths by not assuming that +the given path is anchored with a "/". + +Signed-off-by: Lucas Servén Marín +--- + src/useradd.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/src/useradd.c b/src/useradd.c +index a0369cd8..b8beadd8 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -2171,7 +2171,6 @@ static void create_home (void) + Prog, user_home); + fail_exit (E_HOMEDIR); + } +- ++bhome; + + #ifdef WITH_SELINUX + if (set_selinux_file_context (prefix_user_home) != 0) { +@@ -2188,7 +2187,11 @@ static void create_home (void) + */ + cp = strtok (bhome, "/"); + while (cp) { +- strcat (path, "/"); ++ /* Avoid turning a relative path into an absolute path. ++ */ ++ if (bhome[0] == '/' || strlen (path) != 0) { ++ strcat (path, "/"); ++ } + strcat (path, cp); + if (access (path, F_OK) != 0) { + /* Check if parent directory is BTRFS, fail if requesting +-- +2.27.0 + diff --git a/backport-fread-returns-element-count-not-element-size.patch b/backport-fread-returns-element-count-not-element-size.patch new file mode 100644 index 0000000..8079fad --- /dev/null +++ b/backport-fread-returns-element-count-not-element-size.patch @@ -0,0 +1,25 @@ +From ffd35d89021a9b8375a9246082afc6fc270a93ee Mon Sep 17 00:00:00 2001 +From: steven Y Gui +Date: Wed, 14 Jul 2021 16:17:48 +0800 +Subject: [PATCH] fread returns element count, not element size + +--- + libmisc/salt.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmisc/salt.c b/libmisc/salt.c +index 9fd34332..91d528fd 100644 +--- a/libmisc/salt.c ++++ b/libmisc/salt.c +@@ -168,7 +168,7 @@ static long read_random_bytes (void) + #else + FILE *f = fopen ("/dev/urandom", "r"); + +- if (fread (&randval, sizeof (randval), 1, f) != sizeof (randval)) { ++ if (fread (&randval, sizeof (randval), 1, f) != 1) { + fclose(f); + goto fail; + } +-- +2.27.0 + diff --git a/backport-libmisc-salt.c-Obtain-random-bytes-from-dev-urandom.patch b/backport-libmisc-salt.c-Obtain-random-bytes-from-dev-urandom.patch new file mode 100644 index 0000000..bed0299 --- /dev/null +++ b/backport-libmisc-salt.c-Obtain-random-bytes-from-dev-urandom.patch @@ -0,0 +1,128 @@ +From bc8257cf73328e450511b13cbd35e1994feccb30 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= +Date: Wed, 23 Jun 2021 16:06:47 +0200 +Subject: [PATCH] libmisc/salt.c: Obtain random bytes from /dev/urandom. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Using the random() function to obtain pseudo-random bytes +for generating salt strings is considered to be dangerous. +See CWE-327. + +We really should use a more reliable source for obtaining +pseudo-random bytes like /dev/urandom. + +Fixes #376. + +Signed-off-by: Björn Esser +--- + libmisc/salt.c | 45 ++++++++++++++++++++++++--------------------- + 1 file changed, 24 insertions(+), 21 deletions(-) + +diff --git a/libmisc/salt.c b/libmisc/salt.c +index e17093fc..af9f011f 100644 +--- a/libmisc/salt.c ++++ b/libmisc/salt.c +@@ -11,10 +11,9 @@ + + #ident "$Id$" + +-#include +-#include +-#include + #include ++#include ++#include + #include "prototypes.h" + #include "defines.h" + #include "getdef.h" +@@ -74,7 +73,7 @@ + #include "getdef.h" + + /* local function prototypes */ +-static void seedRNG (void); ++static long read_random_bytes (void); + static /*@observer@*/const char *gensalt (size_t salt_size); + #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_SM3_CRYPT) + static long shadow_random (long min, long max); +@@ -125,36 +124,40 @@ static /*@observer@*/char *l64a (long value) + } + #endif /* !HAVE_L64A */ + +-static void seedRNG (void) ++/* Read sizeof (long) random bytes from /dev/urandom. */ ++static long read_random_bytes (void) + { +- struct timeval tv; +- static int seeded = 0; ++ long randval = 0; ++ FILE *f = fopen ("/dev/urandom", "r"); + +- if (0 == seeded) { +- (void) gettimeofday (&tv, NULL); +- srandom (tv.tv_sec ^ tv.tv_usec ^ getpid ()); +- seeded = 1; ++ if (fread (&randval, sizeof (randval), 1, f) != sizeof (randval)) ++ { ++ fprintf (stderr, ++ _("Unable to read from /dev/urandom.\n")); ++ ++ fclose(f); ++ exit (1); + } ++ ++ fclose(f); ++ ++ return randval; + } + + /* + * Add the salt prefix. + */ + #define MAGNUM(array,ch) (array)[0]=(array)[2]='$',(array)[1]=(ch),(array)[3]='\0' + #ifdef USE_BCRYPT + /* + * Using the Prefix $2a$ to enable an anti-collision safety measure in musl libc. + * Negatively affects a subset of passwords containing the '\xff' character, + * which is not valid UTF-8 (so "unlikely to cause much annoyance"). + */ + #define BCRYPTMAGNUM(array) (array)[0]=(array)[3]='$',(array)[1]='2',(array)[2]='a',(array)[4]='\0' + #endif /* USE_BCRYPT */ + + #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_SM3_CRYPT) +-/* It is not clear what is the maximum value of random(). +- * We assume 2^31-1.*/ +-#define RANDOM_MAX 0x7FFFFFFF +- + /* + * Return a random number between min and max (both included). + * +@@ -151,8 +154,9 @@ static long shadow_random (long min, long max) + { + double drand; + long ret; +- seedRNG (); +- drand = (double) (max - min + 1) * random () / RANDOM_MAX; ++ ++ drand = (double) (read_random_bytes () & RAND_MAX) / (double) RAND_MAX; ++ drand *= (double) (max - min + 1); + /* On systems were this is not random() range is lower, we favor + * higher numbers of salt. */ + ret = (long) (max + 1 - drand); +@@ -354,10 +358,9 @@ static /*@observer@*/const char *gensalt (size_t salt_size) + + assert (salt_size >= MIN_SALT_SIZE && + salt_size <= MAX_SALT_SIZE); +- seedRNG (); +- strcat (salt, l64a (random())); ++ strcat (salt, l64a (read_random_bytes ())); + do { +- strcat (salt, l64a (random())); ++ strcat (salt, l64a (read_random_bytes ())); + } while (strlen (salt) < salt_size); + + salt[salt_size] = '\0'; +-- +2.27.0 + diff --git a/backport-libmisc-salt.c-Use-secure-system-ressources-to-obtai.patch b/backport-libmisc-salt.c-Use-secure-system-ressources-to-obtai.patch new file mode 100644 index 0000000..ee3b63a --- /dev/null +++ b/backport-libmisc-salt.c-Use-secure-system-ressources-to-obtai.patch @@ -0,0 +1,126 @@ +From c82ed0c15e0e9e47df0b4c22672b72e35f061a9d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= +Date: Sun, 4 Jul 2021 12:10:11 +0200 +Subject: [PATCH] libmisc/salt.c: Use secure system ressources to obtain random + bytes. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In a previous commit we introduced /dev/urandom as a source to obtain +random bytes from. This may not be available on all systems, or when +operating inside of a chroot. + +Almost all systems provide functions to obtain random bytes from +secure system ressources. Thus we should prefer to use these, and +fall back to /dev/urandom, if there is no such function present, as +a last resort. + +Signed-off-by: Björn Esser +--- + configure.ac | 17 +++++++++-------- + libmisc/salt.c | 42 ++++++++++++++++++++++++++++++++++++------ + 2 files changed, 45 insertions(+), 14 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 010072c7..111de09e 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -44,18 +44,19 @@ AC_HEADER_STDBOOL + + AC_CHECK_HEADERS(errno.h fcntl.h limits.h unistd.h sys/time.h utmp.h \ + utmpx.h termios.h termio.h sgtty.h sys/ioctl.h syslog.h paths.h \ +- utime.h ulimit.h sys/capability.h sys/resource.h gshadow.h lastlog.h \ +- locale.h rpc/key_prot.h netdb.h acl/libacl.h attr/libattr.h \ +- attr/error_context.h) ++ utime.h ulimit.h sys/capability.h sys/random.h sys/resource.h \ ++ gshadow.h lastlog.h locale.h rpc/key_prot.h netdb.h acl/libacl.h \ ++ attr/libattr.h attr/error_context.h) + + dnl shadow now uses the libc's shadow implementation + AC_CHECK_HEADER([shadow.h],,[AC_MSG_ERROR([You need a libc with shadow.h])]) + +-AC_CHECK_FUNCS(l64a fchmod fchown fsync futimes getgroups gethostname getspnam \ +- gettimeofday getusershell getutent initgroups lchown lckpwdf lstat \ +- lutimes memcpy memset setgroups sigaction strchr updwtmp updwtmpx innetgr \ +- getpwnam_r getpwuid_r getgrnam_r getgrgid_r getspnam_r getaddrinfo \ +- ruserok) ++AC_CHECK_FUNCS(arc4random_buf l64a fchmod fchown fsync futimes getgroups \ ++ gethostname getentropy getrandom getspnam gettimeofday getusershell \ ++ getutent initgroups lchown lckpwdf lstat lutimes memcpy memset \ ++ setgroups sigaction strchr updwtmp updwtmpx innetgr getpwnam_r \ ++ getpwuid_r getgrnam_r getgrgid_r getspnam_r getaddrinfo ruserok \ ++ dlopen) + AC_SYS_LARGEFILE + + dnl Checks for typedefs, structures, and compiler characteristics. +diff --git a/libmisc/salt.c b/libmisc/salt.c +index af9f011f..13408a53 100644 +--- a/libmisc/salt.c ++++ b/libmisc/salt.c +@@ -15,6 +15,9 @@ + #include + #include + #include ++#if HAVE_SYS_RANDOM_H ++#include ++#endif + #include "prototypes.h" + #include "defines.h" + #include "getdef.h" +@@ -128,19 +131,46 @@ static /*@observer@*/char *l64a (long value) + static long read_random_bytes (void) + { + long randval = 0; +- FILE *f = fopen ("/dev/urandom", "r"); + +- if (fread (&randval, sizeof (randval), 1, f) != sizeof (randval)) +- { +- fprintf (stderr, +- _("Unable to read from /dev/urandom.\n")); ++#ifdef HAVE_ARC4RANDOM_BUF ++ /* arc4random_buf, if it exists, can never fail. */ ++ arc4random_buf (&randval, sizeof (randval)); ++ goto end; + ++#elif defined(HAVE_GETENTROPY) ++ /* getentropy may exist but lack kernel support. */ ++ if (getentropy (&randval, sizeof (randval))) { ++ goto fail; ++ } ++ ++ goto end; ++ ++#elif defined(HAVE_GETRANDOM) ++ /* Likewise getrandom. */ ++ if ((size_t) getrandom (&randval, sizeof (randval), 0) != sizeof (randval)) { ++ goto fail; ++ } ++ ++ goto end; ++ ++#else ++ FILE *f = fopen ("/dev/urandom", "r"); ++ ++ if (fread (&randval, sizeof (randval), 1, f) != sizeof (randval)) { + fclose(f); +- exit (1); ++ goto fail; + } + + fclose(f); ++ goto end; ++#endif ++ ++fail: ++ fprintf (stderr, ++ _("Unable to obtain random bytes.\n")); ++ exit (1); + ++end: + return randval; + } + +-- +2.27.0 + diff --git a/backport-useradd.c-fix-covscan-RESOURCE_LEAK.patch b/backport-useradd.c-fix-covscan-RESOURCE_LEAK.patch new file mode 100644 index 0000000..0a3165f --- /dev/null +++ b/backport-useradd.c-fix-covscan-RESOURCE_LEAK.patch @@ -0,0 +1,122 @@ +From 1aed7ae945aafaeb253fc89a7ecedeaedf72654e Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Thu, 10 Jun 2021 13:05:03 +0200 +Subject: [PATCH] useradd.c: fix covscan RESOURCE_LEAK + +Error: RESOURCE_LEAK (CWE-772): [#def28] +shadow-4.8.1/src/useradd.c:1905: open_fn: Returning handle opened by "open". [Note: The source code implementation of the function has been overridden by a user model.] +shadow-4.8.1/src/useradd.c:1905: var_assign: Assigning: "fd" = handle returned from "open("/var/log/faillog", 2)". +shadow-4.8.1/src/useradd.c:1906: noescape: Resource "fd" is not freed or pointed-to in "lseek". +shadow-4.8.1/src/useradd.c:1917: leaked_handle: Handle variable "fd" going out of scope leaks the handle. + 1915| /* continue */ + 1916| } + 1917|-> } + 1918| + 1919| static void lastlog_reset (uid_t uid) + +Error: RESOURCE_LEAK (CWE-772): [#def29] +shadow-4.8.1/src/useradd.c:1938: open_fn: Returning handle opened by "open". [Note: The source code implementation of the function has been overridden by a user model.] +shadow-4.8.1/src/useradd.c:1938: var_assign: Assigning: "fd" = handle returned from "open("/var/log/lastlog", 2)". +shadow-4.8.1/src/useradd.c:1939: noescape: Resource "fd" is not freed or pointed-to in "lseek". +shadow-4.8.1/src/useradd.c:1950: leaked_handle: Handle variable "fd" going out of scope leaks the handle. + 1948| /* continue */ + 1949| } + 1950|-> } + 1951| + 1952| static void tallylog_reset (const char *user_name) + +Error: RESOURCE_LEAK (CWE-772): [#def30] +shadow-4.8.1/src/useradd.c:2109: alloc_fn: Storage is returned from allocation function "strdup". +shadow-4.8.1/src/useradd.c:2109: var_assign: Assigning: "bhome" = storage returned from "strdup(prefix_user_home)". +shadow-4.8.1/src/useradd.c:2131: noescape: Resource "bhome" is not freed or pointed-to in "strtok". +shadow-4.8.1/src/useradd.c:2207: leaked_storage: Variable "bhome" going out of scope leaks the storage it points to. + 2205| } + 2206| #endif + 2207|-> } + 2208| } + 2209| +--- + src/useradd.c | 41 ++++++++++++++++++++++++++++++++--------- + 1 file changed, 32 insertions(+), 9 deletions(-) + +diff --git a/src/useradd.c b/src/useradd.c +index 4248b62c..127177e2 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -1964,16 +1964,26 @@ static void faillog_reset (uid_t uid) + memzero (&fl, sizeof (fl)); + + fd = open (FAILLOG_FILE, O_RDWR); +- if ( (-1 == fd) +- || (lseek (fd, offset_uid, SEEK_SET) != offset_uid) ++ if (-1 == fd) { ++ fprintf (stderr, ++ _("%s: failed to open the faillog file for UID %lu: %s\n"), ++ Prog, (unsigned long) uid, strerror (errno)); ++ SYSLOG ((LOG_WARN, "failed to open the faillog file for UID %lu", (unsigned long) uid)); ++ return; ++ } ++ if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid) + || (write (fd, &fl, sizeof (fl)) != (ssize_t) sizeof (fl)) +- || (fsync (fd) != 0) +- || (close (fd) != 0)) { ++ || (fsync (fd) != 0)) { + fprintf (stderr, + _("%s: failed to reset the faillog entry of UID %lu: %s\n"), + Prog, (unsigned long) uid, strerror (errno)); + SYSLOG ((LOG_WARN, "failed to reset the faillog entry of UID %lu", (unsigned long) uid)); +- /* continue */ ++ } ++ if (close (fd) != 0) { ++ fprintf (stderr, ++ _("%s: failed to close the faillog file for UID %lu: %s\n"), ++ Prog, (unsigned long) uid, strerror (errno)); ++ SYSLOG ((LOG_WARN, "failed to close the faillog file for UID %lu", (unsigned long) uid)); + } + } + +@@ -1997,17 +2007,29 @@ static void lastlog_reset (uid_t uid) + memzero (&ll, sizeof (ll)); + + fd = open (LASTLOG_FILE, O_RDWR); +- if ( (-1 == fd) +- || (lseek (fd, offset_uid, SEEK_SET) != offset_uid) ++ if (-1 == fd) { ++ fprintf (stderr, ++ _("%s: failed to open the lastlog file for UID %lu: %s\n"), ++ Prog, (unsigned long) uid, strerror (errno)); ++ SYSLOG ((LOG_WARN, "failed to open the lastlog file for UID %lu", (unsigned long) uid)); ++ return; ++ } ++ if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid) + || (write (fd, &ll, sizeof (ll)) != (ssize_t) sizeof (ll)) +- || (fsync (fd) != 0) +- || (close (fd) != 0)) { ++ || (fsync (fd) != 0)) { + fprintf (stderr, + _("%s: failed to reset the lastlog entry of UID %lu: %s\n"), + Prog, (unsigned long) uid, strerror (errno)); + SYSLOG ((LOG_WARN, "failed to reset the lastlog entry of UID %lu", (unsigned long) uid)); + /* continue */ + } ++ if (close (fd) != 0) { ++ fprintf (stderr, ++ _("%s: failed to close the lastlog file for UID %lu: %s\n"), ++ Prog, (unsigned long) uid, strerror (errno)); ++ SYSLOG ((LOG_WARN, "failed to close the lastlog file for UID %lu", (unsigned long) uid)); ++ /* continue */ ++ } + } + + static void tallylog_reset (const char *user_name) +@@ -2254,6 +2276,7 @@ static void create_home (void) + } + cp = strtok (NULL, "/"); + } ++ free (bhome); + + (void) chown (prefix_user_home, user_id, user_gid); + mode_t mode = getdef_num ("HOME_MODE", +-- +2.27.0 + diff --git a/backport-usermod.c-fix-covscan-RESOURCE_LEAK.patch b/backport-usermod.c-fix-covscan-RESOURCE_LEAK.patch new file mode 100644 index 0000000..210f82b --- /dev/null +++ b/backport-usermod.c-fix-covscan-RESOURCE_LEAK.patch @@ -0,0 +1,157 @@ +From 8281c82e324b57b3a4b520afad26b43ce128d521 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Fri, 11 Jun 2021 11:50:49 +0200 +Subject: [PATCH] usermod.c: fix covscan RESOURCE_LEAK + +Error: RESOURCE_LEAK (CWE-772): [#def31] +shadow-4.8.1/src/usermod.c:813: alloc_fn: Storage is returned from allocation function "__gr_dup". +shadow-4.8.1/src/usermod.c:813: var_assign: Assigning: "ngrp" = storage returned from "__gr_dup(grp)". +shadow-4.8.1/src/usermod.c:892: leaked_storage: Variable "ngrp" going out of scope leaks the storage it points to. + 890| } + 891| } + 892|-> } + 893| + 894| #ifdef SHADOWGRP + +Error: RESOURCE_LEAK (CWE-772): [#def32] +shadow-4.8.1/src/usermod.c:933: alloc_fn: Storage is returned from allocation function "__sgr_dup". +shadow-4.8.1/src/usermod.c:933: var_assign: Assigning: "nsgrp" = storage returned from "__sgr_dup(sgrp)". +shadow-4.8.1/src/usermod.c:1031: leaked_storage: Variable "nsgrp" going out of scope leaks the storage it points to. + 1029| } + 1030| } + 1031|-> } + 1032| #endif /* SHADOWGRP */ + 1033| + +Error: RESOURCE_LEAK (CWE-772): [#def34] +shadow-4.8.1/src/usermod.c:1161: alloc_fn: Storage is returned from allocation function "getgr_nam_gid". +shadow-4.8.1/src/usermod.c:1161: var_assign: Assigning: "grp" = storage returned from "getgr_nam_gid(optarg)". +shadow-4.8.1/src/usermod.c:1495: leaked_storage: Variable "grp" going out of scope leaks the storage it points to. + 1493| } + 1494| #endif /* ENABLE_SUBIDS */ + 1495|-> } + 1496| + 1497| /* + +Error: RESOURCE_LEAK (CWE-772): [#def35] +shadow-4.8.1/src/usermod.c:1991: open_fn: Returning handle opened by "open". [Note: The source code implementation of the function has been overridden by a user model.] +shadow-4.8.1/src/usermod.c:1991: var_assign: Assigning: "fd" = handle returned from "open("/var/log/lastlog", 2)". +shadow-4.8.1/src/usermod.c:2000: noescape: Resource "fd" is not freed or pointed-to in "lseek". +shadow-4.8.1/src/usermod.c:2000: noescape: Resource "fd" is not freed or pointed-to in "read". [Note: The source code implementation of the function has been overridden by a builtin model.] +shadow-4.8.1/src/usermod.c:2003: noescape: Resource "fd" is not freed or pointed-to in "lseek". +shadow-4.8.1/src/usermod.c:2032: leaked_handle: Handle variable "fd" going out of scope leaks the handle. + 2030| } + 2031| } + 2032|-> } + 2033| + 2034| /* + +Error: RESOURCE_LEAK (CWE-772): [#def36] +shadow-4.8.1/src/usermod.c:2052: open_fn: Returning handle opened by "open". [Note: The source code implementation of the function has been overridden by a user model.] +shadow-4.8.1/src/usermod.c:2052: var_assign: Assigning: "fd" = handle returned from "open("/var/log/faillog", 2)". +shadow-4.8.1/src/usermod.c:2061: noescape: Resource "fd" is not freed or pointed-to in "lseek". +shadow-4.8.1/src/usermod.c:2061: noescape: Resource "fd" is not freed or pointed-to in "read". [Note: The source code implementation of the function has been overridden by a builtin model.] +shadow-4.8.1/src/usermod.c:2064: noescape: Resource "fd" is not freed or pointed-to in "lseek". +shadow-4.8.1/src/usermod.c:2092: leaked_handle: Handle variable "fd" going out of scope leaks the handle. + 2090| } + 2091| } + 2092|-> } + 2093| + 2094| #ifndef NO_MOVE_MAILBOX +--- + src/usermod.c | 25 +++++++++++++------------ + 1 file changed, 13 insertions(+), 12 deletions(-) + +diff --git a/src/usermod.c b/src/usermod.c +index 7870ba57..03bb9b9d 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -871,6 +871,8 @@ static void update_group (void) + SYSLOG ((LOG_WARN, "failed to prepare the new %s entry '%s'", gr_dbname (), ngrp->gr_name)); + fail_exit (E_GRP_UPDATE); + } ++ ++ gr_free(ngrp); + } + } + +@@ -1006,6 +1008,8 @@ static void update_gshadow (void) + sgr_dbname (), nsgrp->sg_name)); + fail_exit (E_GRP_UPDATE); + } ++ ++ free (nsgrp); + } + } + #endif /* SHADOWGRP */ +@@ -1152,6 +1156,7 @@ static void process_flags (int argc, char **argv) + } + user_newgid = grp->gr_gid; + gflg = true; ++ gr_free (grp); + break; + case 'G': + if (get_groups (optarg) != 0) { +@@ -1995,8 +2000,7 @@ static void update_lastlog (void) + /* Copy the old entry to its new location */ + if ( (lseek (fd, off_newuid, SEEK_SET) != off_newuid) + || (write (fd, &ll, sizeof ll) != (ssize_t) sizeof ll) +- || (fsync (fd) != 0) +- || (close (fd) != 0)) { ++ || (fsync (fd) != 0)) { + fprintf (stderr, + _("%s: failed to copy the lastlog entry of user %lu to user %lu: %s\n"), + Prog, (unsigned long) user_id, (unsigned long) user_newid, strerror (errno)); +@@ -2012,16 +2016,15 @@ static void update_lastlog (void) + memzero (&ll, sizeof (ll)); + if ( (lseek (fd, off_newuid, SEEK_SET) != off_newuid) + || (write (fd, &ll, sizeof ll) != (ssize_t) sizeof ll) +- || (fsync (fd) != 0) +- || (close (fd) != 0)) { ++ || (fsync (fd) != 0)) { + fprintf (stderr, + _("%s: failed to copy the lastlog entry of user %lu to user %lu: %s\n"), + Prog, (unsigned long) user_id, (unsigned long) user_newid, strerror (errno)); + } +- } else { +- (void) close (fd); + } + } ++ ++ (void) close (fd); + } + + /* +@@ -2056,8 +2059,7 @@ static void update_faillog (void) + /* Copy the old entry to its new location */ + if ( (lseek (fd, off_newuid, SEEK_SET) != off_newuid) + || (write (fd, &fl, sizeof fl) != (ssize_t) sizeof fl) +- || (fsync (fd) != 0) +- || (close (fd) != 0)) { ++ || (fsync (fd) != 0)) { + fprintf (stderr, + _("%s: failed to copy the faillog entry of user %lu to user %lu: %s\n"), + Prog, (unsigned long) user_id, (unsigned long) user_newid, strerror (errno)); +@@ -2072,16 +2074,15 @@ static void update_faillog (void) + /* Reset the new uid's faillog entry */ + memzero (&fl, sizeof (fl)); + if ( (lseek (fd, off_newuid, SEEK_SET) != off_newuid) +- || (write (fd, &fl, sizeof fl) != (ssize_t) sizeof fl) +- || (close (fd) != 0)) { ++ || (write (fd, &fl, sizeof fl) != (ssize_t) sizeof fl)) { + fprintf (stderr, + _("%s: failed to copy the faillog entry of user %lu to user %lu: %s\n"), + Prog, (unsigned long) user_id, (unsigned long) user_newid, strerror (errno)); + } +- } else { +- (void) close (fd); + } + } ++ ++ (void) close (fd); + } + + #ifndef NO_MOVE_MAILBOX +-- +2.27.0 + diff --git a/shadow.spec b/shadow.spec index 8530c5a..fb77971 100644 --- a/shadow.spec +++ b/shadow.spec @@ -1,6 +1,6 @@ Name: shadow Version: 4.8.1 -Release: 10 +Release: 11 Epoch: 2 License: BSD and GPLv2+ Summary: Tools for managing accounts and shadow password files @@ -33,6 +33,15 @@ Patch14: backport-commonio-free-removed-database-entries.patch Patch15: backport-semanage-disconnect-to-free-libsemanage-internals.patch Patch16: backport-gpasswd-1-Fix-password-leak.patch Patch17: backport-CVE-2013-4235.patch +Patch18: backport-fix-create-relative-home-path-correctly.patch +Patch19: backport-Fix-useradd-with-SUB_UID_COUNT-0.patch +Patch20: backport-usermod.c-fix-covscan-RESOURCE_LEAK.patch +Patch21: backport-useradd.c-fix-covscan-RESOURCE_LEAK.patch +Patch22: backport-Fix-covscan-BUFFER_SIZE.patch +Patch23: backport-Fix-covscan-RESOURCE_LEAK.patch +Patch24: backport-libmisc-salt.c-Obtain-random-bytes-from-dev-urandom.patch +Patch25: backport-libmisc-salt.c-Use-secure-system-ressources-to-obtai.patch +Patch26: backport-fread-returns-element-count-not-element-size.patch BuildRequires: gcc, libselinux-devel, audit-libs-devel, libsemanage-devel BuildRequires: libacl-devel, libattr-devel gdb @@ -182,6 +191,9 @@ done %{_mandir}/*/* %changelog +* Wed Dec 20 2023 fuanan - 2:4.8.1-11 +- backport patches from upstream + * Thu Nov 9 2023 wangqingsan - 2:4.8.1-10 - fix CVE-2023-4641 -- Gitee