diff options
author | Leo Famulari <[email protected]> | 2022-01-26 00:19:34 -0500 |
---|---|---|
committer | Leo Famulari <[email protected]> | 2022-01-26 13:02:09 -0500 |
commit | 16ce73d87f664b2a539c2264671fddc2077f6ecc (patch) | |
tree | 762879bbba71c24a67f4b600d0dba60a90d667d7 /gnu/packages/patches/util-linux-CVE-2021-3995.patch | |
parent | 7afed75764348e60bca90be3cc13e8deeadc6947 (diff) |
gnu: util-linux: Fix CVE-2021-3995 and CVE-2021-3996.
* gnu/packages/patches/util-linux-CVE-2021-3995.patch,
gnu/packages/patches/util-linux-CVE-2021-3996.patch: New files.
* gnu/local.mk (dist_patch_DATA): Add them.
* gnu/packages/linux.scm (util-linux)[replacement]: New field.
(util-linux/fixed): New variable.
Diffstat (limited to 'gnu/packages/patches/util-linux-CVE-2021-3995.patch')
-rw-r--r-- | gnu/packages/patches/util-linux-CVE-2021-3995.patch | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/gnu/packages/patches/util-linux-CVE-2021-3995.patch b/gnu/packages/patches/util-linux-CVE-2021-3995.patch new file mode 100644 index 0000000000..7faea83801 --- /dev/null +++ b/gnu/packages/patches/util-linux-CVE-2021-3995.patch @@ -0,0 +1,146 @@ +Fix CVE-2021-3995: + +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-3995 +https://seclists.org/oss-sec/2022/q1/66 + +Patch copied from upstream source repository: + +https://github.com/util-linux/util-linux/commit/f3db9bd609494099f0c1b95231c5dfe383346929 + +From f3db9bd609494099f0c1b95231c5dfe383346929 Mon Sep 17 00:00:00 2001 +From: Karel Zak <[email protected]> +Date: Wed, 24 Nov 2021 13:53:25 +0100 +Subject: [PATCH] libmount: fix UID check for FUSE umount [CVE-2021-3995] + +Improper UID check allows an unprivileged user to unmount FUSE +filesystems of users with similar UID. + +Signed-off-by: Karel Zak <[email protected]> +--- + include/strutils.h | 2 +- + libmount/src/context_umount.c | 14 +++--------- + libmount/src/mountP.h | 1 + + libmount/src/optstr.c | 42 +++++++++++++++++++++++++++++++++++ + 4 files changed, 47 insertions(+), 12 deletions(-) + +diff --git a/include/strutils.h b/include/strutils.h +index 6e95707ea..a84d29594 100644 +--- a/include/strutils.h ++++ b/include/strutils.h +@@ -106,8 +106,8 @@ static inline char *mem2strcpy(char *dest, const void *src, size_t n, size_t nma + if (n + 1 > nmax) + n = nmax - 1; + ++ memset(dest, '\0', nmax); + memcpy(dest, src, n); +- dest[nmax-1] = '\0'; + return dest; + } + +diff --git a/libmount/src/context_umount.c b/libmount/src/context_umount.c +index 173637a15..8773c65ff 100644 +--- a/libmount/src/context_umount.c ++++ b/libmount/src/context_umount.c +@@ -453,10 +453,7 @@ static int is_fuse_usermount(struct libmnt_context *cxt, int *errsv) + struct libmnt_ns *ns_old; + const char *type = mnt_fs_get_fstype(cxt->fs); + const char *optstr; +- char *user_id = NULL; +- size_t sz; +- uid_t uid; +- char uidstr[sizeof(stringify_value(ULONG_MAX))]; ++ uid_t uid, entry_uid; + + *errsv = 0; + +@@ -473,11 +470,7 @@ static int is_fuse_usermount(struct libmnt_context *cxt, int *errsv) + optstr = mnt_fs_get_fs_options(cxt->fs); + if (!optstr) + return 0; +- +- if (mnt_optstr_get_option(optstr, "user_id", &user_id, &sz) != 0) +- return 0; +- +- if (sz == 0 || user_id == NULL) ++ if (mnt_optstr_get_uid(optstr, "user_id", &entry_uid) != 0) + return 0; + + /* get current user */ +@@ -494,8 +487,7 @@ static int is_fuse_usermount(struct libmnt_context *cxt, int *errsv) + return 0; + } + +- snprintf(uidstr, sizeof(uidstr), "%lu", (unsigned long) uid); +- return strncmp(user_id, uidstr, sz) == 0; ++ return uid == entry_uid; + } + + /* +diff --git a/libmount/src/mountP.h b/libmount/src/mountP.h +index d43a83541..22442ec55 100644 +--- a/libmount/src/mountP.h ++++ b/libmount/src/mountP.h +@@ -399,6 +399,7 @@ extern const struct libmnt_optmap *mnt_optmap_get_entry( + const struct libmnt_optmap **mapent); + + /* optstr.c */ ++extern int mnt_optstr_get_uid(const char *optstr, const char *name, uid_t *uid); + extern int mnt_optstr_remove_option_at(char **optstr, char *begin, char *end); + extern int mnt_optstr_fix_gid(char **optstr, char *value, size_t valsz, char **next); + extern int mnt_optstr_fix_uid(char **optstr, char *value, size_t valsz, char **next); +diff --git a/libmount/src/optstr.c b/libmount/src/optstr.c +index 921b9318e..16800f571 100644 +--- a/libmount/src/optstr.c ++++ b/libmount/src/optstr.c +@@ -1076,6 +1076,48 @@ int mnt_optstr_fix_user(char **optstr) + return rc; + } + ++/* ++ * Converts value from @optstr addressed by @name to uid. ++ * ++ * Returns: 0 on success, 1 if not found, <0 on error ++ */ ++int mnt_optstr_get_uid(const char *optstr, const char *name, uid_t *uid) ++{ ++ char *value = NULL; ++ size_t valsz = 0; ++ char buf[sizeof(stringify_value(UINT64_MAX))]; ++ int rc; ++ uint64_t num; ++ ++ assert(optstr); ++ assert(name); ++ assert(uid); ++ ++ rc = mnt_optstr_get_option(optstr, name, &value, &valsz); ++ if (rc != 0) ++ goto fail; ++ ++ if (valsz > sizeof(buf) - 1) { ++ rc = -ERANGE; ++ goto fail; ++ } ++ mem2strcpy(buf, value, valsz, sizeof(buf)); ++ ++ rc = ul_strtou64(buf, &num, 10); ++ if (rc != 0) ++ goto fail; ++ if (num > ULONG_MAX || (uid_t) num != num) { ++ rc = -ERANGE; ++ goto fail; ++ } ++ *uid = (uid_t) num; ++ ++ return 0; ++fail: ++ DBG(UTILS, ul_debug("failed to convert '%s'= to number [rc=%d]", name, rc)); ++ return rc; ++} ++ + /** + * mnt_match_options: + * @optstr: options string +-- +2.34.0 + |