diff --git a/backport-cfdisk-fix-memory-leak-and-possible-NULL-dereference.patch b/backport-cfdisk-fix-memory-leak-and-possible-NULL-dereference.patch new file mode 100644 index 0000000000000000000000000000000000000000..b38faedd61f5370a126da68ca608686c05058ecd --- /dev/null +++ b/backport-cfdisk-fix-memory-leak-and-possible-NULL-dereference.patch @@ -0,0 +1,33 @@ +From 33ca468b67d34dead8fb8b41dc9f328971e5fe70 Mon Sep 17 00:00:00 2001 +From: Karel Zak +Date: Tue, 25 Mar 2025 12:14:14 +0100 +Subject: [PATCH] cfdisk: fix memory leak and possible NULL dereference + [gcc-analyzer] + +Signed-off-by: Karel Zak +--- + disk-utils/cfdisk.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/disk-utils/cfdisk.c b/disk-utils/cfdisk.c +index d0bb57aaf15..e8a8b959a0f 100644 +--- a/disk-utils/cfdisk.c ++++ b/disk-utils/cfdisk.c +@@ -947,6 +947,7 @@ static void menu_set_title(struct cfdisk_menu *m, const char *title) + m->width = len + MENU_TITLE_PADDING; + str = xstrdup(title); + } ++ free(m->title); + m->title = str; + } + +@@ -2173,7 +2174,8 @@ static int ui_create_label(struct cfdisk *cf) + nitems = fdisk_get_nlabels(cf->cxt); + cm = xcalloc(nitems + 1, sizeof(struct cfdisk_menuitem)); + +- while (fdisk_next_label(cf->cxt, &lb) == 0) { ++ while (fdisk_next_label(cf->cxt, &lb) == 0 && i < nitems) { ++ + if (fdisk_label_is_disabled(lb) || + fdisk_label_get_type(lb) == FDISK_DISKLABEL_BSD) + continue; diff --git a/backport-libblkid-befs-fix-underflow.patch b/backport-libblkid-befs-fix-underflow.patch new file mode 100644 index 0000000000000000000000000000000000000000..af1be03c66fc0ca873da8b741519c63b9975367e --- /dev/null +++ b/backport-libblkid-befs-fix-underflow.patch @@ -0,0 +1,45 @@ +From 588eed1a1de13150750e8a50d855001b27e07357 Mon Sep 17 00:00:00 2001 +From: Milan Broz +Date: Sat, 19 Apr 2025 15:54:40 +0200 +Subject: [PATCH] libblkid: befs: fix underflow + +Fix segfault caused by underflow while parsing a corrupted metadata. + +Found by OSS-Fuzz by cryptsetup project fuzzers (issue 411003898). + +Signed-off-by: Milan Broz +--- + libblkid/src/superblocks/befs.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/libblkid/src/superblocks/befs.c b/libblkid/src/superblocks/befs.c +index d501eb105d4..5d082a949a9 100644 +--- a/libblkid/src/superblocks/befs.c ++++ b/libblkid/src/superblocks/befs.c +@@ -170,12 +170,17 @@ static const unsigned char *get_tree_node(blkid_probe pr, const struct befs_supe + &ds->direct[i], + start, length, fs_le); + start -= br_len; ++ if (start < 0) ++ return NULL; /* Corrupt? */ + } + } else if (start < (int64_t) FS64_TO_CPU(ds->max_indirect_range, fs_le)) { + struct block_run *br; + int64_t max_br, br_len, i; + + start -= FS64_TO_CPU(ds->max_direct_range, fs_le); ++ if (start < 0) ++ return NULL; /* Corrupt? */ ++ + max_br = ((int64_t) FS16_TO_CPU(ds->indirect.len, fs_le) + << FS32_TO_CPU(bs->block_shift, fs_le)) + / sizeof(struct block_run); +@@ -198,6 +203,8 @@ static const unsigned char *get_tree_node(blkid_probe pr, const struct befs_supe + int64_t max_br, di_br_size, br_per_di_br, di_index, i_index; + + start -= (int64_t) FS64_TO_CPU(ds->max_indirect_range, fs_le); ++ if (start < 0) ++ return NULL; /* Corrupt? */ + + di_br_size = (int64_t) FS16_TO_CPU(ds->double_indirect.len, + fs_le) << FS32_TO_CPU(bs->block_shift, fs_le); diff --git a/backport-lslogins-remove-possible-memory-leaks-coverity-scan.patch b/backport-lslogins-remove-possible-memory-leaks-coverity-scan.patch new file mode 100644 index 0000000000000000000000000000000000000000..484b53032da03d0863562c0155ab1f54146da92b --- /dev/null +++ b/backport-lslogins-remove-possible-memory-leaks-coverity-scan.patch @@ -0,0 +1,140 @@ +From 52a6e45bfe5ddee1fed20f2f4f7542cac6bf13c9 Mon Sep 17 00:00:00 2001 +From: Karel Zak +Date: Wed, 12 Mar 2025 13:49:02 +0100 +Subject: [PATCH] lslogins: remove possible memory leaks [coverity scan] + +The column can be specified more than once. In this case, the code +will gather the column data multiple times, resulting in a memory +leak. + +Signed-off-by: Karel Zak +--- + login-utils/lslogins.c | 39 +++++++++++++++++++++++++-------------- + 1 file changed, 25 insertions(+), 14 deletions(-) + +diff --git a/login-utils/lslogins.c b/login-utils/lslogins.c +index a7152737a4c..54f668af697 100644 +--- a/login-utils/lslogins.c ++++ b/login-utils/lslogins.c +@@ -838,13 +838,15 @@ static struct lslogins_user *get_user_info(struct lslogins_control *ctl, const c + while (n < ncolumns) { + switch (columns[n++]) { + case COL_USER: +- user->login = xstrdup(pwd->pw_name); ++ if (!user->login) ++ user->login = xstrdup(pwd->pw_name); + break; + case COL_UID: + user->uid = pwd->pw_uid; + break; + case COL_GROUP: +- user->group = xstrdup(grp->gr_name); ++ if (!grp->gr_name) ++ user->group = xstrdup(grp->gr_name); + break; + case COL_GID: + user->gid = pwd->pw_gid; +@@ -856,15 +858,20 @@ static struct lslogins_user *get_user_info(struct lslogins_control *ctl, const c + err(EXIT_FAILURE, _("failed to get supplementary groups")); + break; + case COL_HOME: +- user->homedir = xstrdup(pwd->pw_dir); ++ if (!user->homedir) ++ user->homedir = xstrdup(pwd->pw_dir); + break; + case COL_SHELL: +- user->shell = xstrdup(pwd->pw_shell); ++ if (!user->shell) ++ user->shell = xstrdup(pwd->pw_shell); + break; + case COL_GECOS: +- user->gecos = xstrdup(pwd->pw_gecos); ++ if (!user->gecos) ++ user->gecos = xstrdup(pwd->pw_gecos); + break; + case COL_LAST_LOGIN: ++ if (user->last_login) ++ break; + if (user_wtmp) { + time = user_wtmp->ut_tv.tv_sec; + user->last_login = make_time(ctl->time_mode, time); +@@ -876,6 +883,8 @@ static struct lslogins_user *get_user_info(struct lslogins_control *ctl, const c + } + break; + case COL_LAST_TTY: ++ if (user->last_tty) ++ break; + user->last_tty = xcalloc(1, sizeof(user_wtmp->ut_line) + 1); + if (user_wtmp) { + mem2strcpy(user->last_tty, user_wtmp->ut_line, +@@ -885,6 +894,8 @@ static struct lslogins_user *get_user_info(struct lslogins_control *ctl, const c + get_lastlog(ctl, user->uid, user->last_tty, LASTLOG_LINE); + break; + case COL_LAST_HOSTNAME: ++ if (user->last_hostname) ++ break; + user->last_hostname = xcalloc(1, sizeof(user_wtmp->ut_host) + 1); + if (user_wtmp) { + mem2strcpy(user->last_hostname, user_wtmp->ut_host, +@@ -894,13 +905,13 @@ static struct lslogins_user *get_user_info(struct lslogins_control *ctl, const c + get_lastlog(ctl, user->uid, user->last_hostname, LASTLOG_HOST); + break; + case COL_FAILED_LOGIN: +- if (user_btmp) { ++ if (!user->failed_login && user_btmp) { + time = user_btmp->ut_tv.tv_sec; + user->failed_login = make_time(ctl->time_mode, time); + } + break; + case COL_FAILED_TTY: +- if (user_btmp) { ++ if (!user->failed_tty && user_btmp) { + user->failed_tty = xmalloc(sizeof(user_btmp->ut_line) + 1); + mem2strcpy(user->failed_tty, user_btmp->ut_line, + sizeof(user_btmp->ut_line), +@@ -972,11 +983,11 @@ static struct lslogins_user *get_user_info(struct lslogins_control *ctl, const c + access(_PATH_VAR_NOLOGIN, F_OK) == 0; + break; + case COL_PWD_WARN: +- if (shadow && shadow->sp_warn >= 0) ++ if (!user->pwd_warn && shadow && shadow->sp_warn >= 0) + xasprintf(&user->pwd_warn, "%ld", shadow->sp_warn); + break; + case COL_PWD_EXPIR: +- if (shadow && shadow->sp_expire >= 0) ++ if (!user->pwd_expire && shadow && shadow->sp_expire >= 0) + user->pwd_expire = make_time(ctl->time_mode == TIME_ISO ? + TIME_ISO_SHORT : ctl->time_mode, + shadow->sp_expire * 86400); +@@ -985,17 +996,17 @@ static struct lslogins_user *get_user_info(struct lslogins_control *ctl, const c + /* sp_lstchg is specified in days, showing hours + * (especially in non-GMT timezones) would only serve + * to confuse */ +- if (shadow) ++ if (!user->pwd_ctime && shadow) + user->pwd_ctime = make_time(ctl->time_mode == TIME_ISO ? + TIME_ISO_SHORT : ctl->time_mode, + shadow->sp_lstchg * 86400); + break; + case COL_PWD_CTIME_MIN: +- if (shadow && shadow->sp_min > 0) ++ if (user->pwd_ctime_min && shadow && shadow->sp_min > 0) + xasprintf(&user->pwd_ctime_min, "%ld", shadow->sp_min); + break; + case COL_PWD_CTIME_MAX: +- if (shadow && shadow->sp_max > 0) ++ if (!user->pwd_ctime_max && shadow && shadow->sp_max > 0) + xasprintf(&user->pwd_ctime_max, "%ld", shadow->sp_max); + break; + case COL_SELINUX: +@@ -1006,8 +1017,8 @@ static struct lslogins_user *get_user_info(struct lslogins_control *ctl, const c + break; + case COL_NPROCS: + #ifdef __linux__ +- +- xasprintf(&user->nprocs, "%d", get_nprocs(pwd->pw_uid)); ++ if (!user->nprocs) ++ xasprintf(&user->nprocs, "%d", get_nprocs(pwd->pw_uid)); + #endif + break; + default: diff --git a/mkfs.bfs-fix-memory-leaks-and-weak-code.patch b/backport-mkfs.bfs-fix-memory-leaks-and-weak-code.patch similarity index 98% rename from mkfs.bfs-fix-memory-leaks-and-weak-code.patch rename to backport-mkfs.bfs-fix-memory-leaks-and-weak-code.patch index 86d36243c5c8f473c0cffa4dae00b91ff3bd54fb..73f17247653f1feb3ba2ef0e46b6e761833fc8e6 100644 --- a/mkfs.bfs-fix-memory-leaks-and-weak-code.patch +++ b/backport-mkfs.bfs-fix-memory-leaks-and-weak-code.patch @@ -17,7 +17,7 @@ Signed-off-by: Karel Zak 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/disk-utils/mkfs.bfs.c b/disk-utils/mkfs.bfs.c -index 895a1f27b..d18589ab2 100644 +index 895a1f27b7a..d18589ab288 100644 --- a/disk-utils/mkfs.bfs.c +++ b/disk-utils/mkfs.bfs.c @@ -103,7 +103,7 @@ static void __attribute__((__noreturn__)) usage(void) @@ -103,6 +103,3 @@ index 895a1f27b..d18589ab2 100644 fprintf(stderr, _("BlockSize: %d\n"), BFS_BLOCKSIZE); if (ino_blocks == 1) fprintf(stderr, _("Inodes: %ld (in 1 block)\n"), --- -2.20.1 - diff --git a/backport-swapoff-clean-up-tag-resolution.patch b/backport-swapoff-clean-up-tag-resolution.patch new file mode 100644 index 0000000000000000000000000000000000000000..24d47c0342d367d399ecc740ddd30f47251c33f5 --- /dev/null +++ b/backport-swapoff-clean-up-tag-resolution.patch @@ -0,0 +1,98 @@ +From 702f6f0178fa74cf66a13813bd40e5c7839cfe6a Mon Sep 17 00:00:00 2001 +From: Karel Zak +Date: Wed, 9 Apr 2025 10:51:59 +0200 +Subject: [PATCH] swapoff: clean up tag resolution + +- Rename swapoff_resolve_tag() to resolve_swapfile_tag() and retain + only code relevant to swapfiles. + +- Always call mnt_resolve_*() before resolve_swapfile_tag() to resolve + tags/paths on standard block devices. + +- Call free() for resolve_swapfile_tag() to avoid memory leaks. + +Signed-off-by: Karel Zak +--- + sys-utils/swapoff.c | 34 +++++++++++++++++++++------------- + 1 file changed, 21 insertions(+), 13 deletions(-) + +diff --git a/sys-utils/swapoff.c b/sys-utils/swapoff.c +index 5677d87a152..ab7e4ca11e1 100644 +--- a/sys-utils/swapoff.c ++++ b/sys-utils/swapoff.c +@@ -54,20 +54,13 @@ static int all; + * mnt_resolve_tag() and mnt_resolve_spec() works with system visible block + * devices only. + */ +-static char *swapoff_resolve_tag(const char *name, const char *value, +- struct libmnt_cache *cache) ++static char *resolve_swapfile_tag(const char *name, const char *value) + { + char *path; + struct libmnt_table *tb; + struct libmnt_iter *itr; + struct libmnt_fs *fs; + +- /* this is usual case for block devices (and it's really fast as it uses +- * udev /dev/disk/by-* symlinks by default */ +- path = mnt_resolve_tag(name, value, cache); +- if (path) +- return path; +- + /* try regular files from /proc/swaps */ + tb = get_swaps(); + if (!tb) +@@ -103,6 +96,7 @@ static char *swapoff_resolve_tag(const char *name, const char *value, + static int do_swapoff(const char *orig_special, int quiet, int canonic) + { + const char *special = orig_special; ++ char *buf = NULL; + int rc = SWAPOFF_EX_OK; + + if (verbose) +@@ -113,12 +107,14 @@ static int do_swapoff(const char *orig_special, int quiet, int canonic) + + special = mnt_resolve_spec(orig_special, mntcache); + if (!special && blkid_parse_tag_string(orig_special, &n, &v) == 0) { +- special = swapoff_resolve_tag(n, v, mntcache); ++ special = buf = resolve_swapfile_tag(n, v); + free(n); + free(v); + } +- if (!special) +- return cannot_find(orig_special); ++ if (!special) { ++ rc = cannot_find(orig_special); ++ goto done; ++ } + } + + if (swapoff(special) == 0) +@@ -140,13 +136,25 @@ static int do_swapoff(const char *orig_special, int quiet, int canonic) + } + } + ++done: ++ free(buf); + return rc; + } + + static int swapoff_by(const char *name, const char *value, int quiet) + { +- const char *special = swapoff_resolve_tag(name, value, mntcache); +- return special ? do_swapoff(special, quiet, CANONIC) : cannot_find(value); ++ const char *special; ++ char *buf = NULL; ++ int rc; ++ ++ special = mnt_resolve_tag(name, value, mntcache); ++ if (!special) ++ special = buf = resolve_swapfile_tag(name, value); ++ ++ rc = special ? do_swapoff(special, quiet, CANONIC) : cannot_find(value); ++ free(buf); ++ ++ return rc; + } + + static void __attribute__((__noreturn__)) usage(void) diff --git a/util-linux.spec b/util-linux.spec index 24bdfd4948321385c5537a7779cc5fd8991dd981..c8b140212432030e9041d3be4b3db76f27a8c968 100644 --- a/util-linux.spec +++ b/util-linux.spec @@ -3,7 +3,7 @@ Name: util-linux Version: 2.39.1 -Release: 22 +Release: 23 Summary: A random collection of Linux utilities License: GPLv2 and GPLv2+ and LGPLv2+ and BSD with advertising and Public Domain URL: https://git.kernel.org/pub/scm/utils/util-linux/util-linux.git @@ -100,13 +100,17 @@ Patch6078: backport-sulogin-fix-POSIX-locale-use.patch Patch6079: backport-setpriv.c-fix-memory-leak-in-parse_groups-function.patch Patch6080: backport-whereis-avoid-accessing-uninitialized-memory.patch Patch6081: backport-dmesg-fix-notime-use.patch +Patch6082: backport-lslogins-remove-possible-memory-leaks-coverity-scan.patch +Patch6083: backport-mkfs.bfs-fix-memory-leaks-and-weak-code.patch +Patch6084: backport-cfdisk-fix-memory-leak-and-possible-NULL-dereference.patch +Patch6085: backport-swapoff-clean-up-tag-resolution.patch +Patch6086: backport-libblkid-befs-fix-underflow.patch Patch9000: SKIPPED-no-root-permissions-test.patch Patch9001: util-linux-Add-sw64-architecture.patch Patch9002: sfdisk-fix-crash-casued-by-out-of-bounds-access.patch Patch9003: add-new-gmo-file.patch Patch9004: mount-fix-use-option-owner-mount-failed.patch -Patch9005: mkfs.bfs-fix-memory-leaks-and-weak-code.patch BuildRequires: audit-libs-devel >= 1.0.6 gettext-devel libselinux-devel ncurses-devel pam-devel zlib-devel popt-devel BuildRequires: libutempter-devel systemd-devel systemd libuser-devel libcap-ng-devel python3-devel gcc autoconf automake @@ -465,6 +469,17 @@ fi %endif %changelog +* Mon Jun 16 2025 markeryang - 2.39.1-23 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC:backport community patches + [add] backport-lslogins-remove-possible-memory-leaks-coverity-scan.patch + backport-mkfs.bfs-fix-memory-leaks-and-weak-code.patch + backport-cfdisk-fix-memory-leak-and-possible-NULL-dereference.patch + backport-swapoff-clean-up-tag-resolution.patch + backport-libblkid-befs-fix-underflow.patch + * Mon May 26 2025 hugel - 2.39.1-22 - Type:bugfix - CVE:NA