summaryrefslogtreecommitdiffstats
path: root/meta/recipes-core/util-linux/util-linux/CVE-2021-3995.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-core/util-linux/util-linux/CVE-2021-3995.patch')
-rw-r--r--meta/recipes-core/util-linux/util-linux/CVE-2021-3995.patch139
1 files changed, 139 insertions, 0 deletions
diff --git a/meta/recipes-core/util-linux/util-linux/CVE-2021-3995.patch b/meta/recipes-core/util-linux/util-linux/CVE-2021-3995.patch
new file mode 100644
index 0000000000..1dcb66ad1d
--- /dev/null
+++ b/meta/recipes-core/util-linux/util-linux/CVE-2021-3995.patch
@@ -0,0 +1,139 @@
1From f3db9bd609494099f0c1b95231c5dfe383346929 Mon Sep 17 00:00:00 2001
2From: Karel Zak <kzak@redhat.com>
3Date: Wed, 24 Nov 2021 13:53:25 +0100
4Subject: [PATCH] libmount: fix UID check for FUSE umount [CVE-2021-3995]
5
6Improper UID check allows an unprivileged user to unmount FUSE
7filesystems of users with similar UID.
8
9Signed-off-by: Karel Zak <kzak@redhat.com>
10
11CVE: CVE-2021-3995
12Upstream-Status: Backport [https://github.com/util-linux/util-linux/commit/f3db9bd609494099f0c1b95231c5dfe383346929]
13Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
14
15---
16 include/strutils.h | 2 +-
17 libmount/src/context_umount.c | 14 +++---------
18 libmount/src/mountP.h | 1 +
19 libmount/src/optstr.c | 42 +++++++++++++++++++++++++++++++++++
20 4 files changed, 47 insertions(+), 12 deletions(-)
21
22diff --git a/include/strutils.h b/include/strutils.h
23index 6e95707ea9..a84d29594d 100644
24--- a/include/strutils.h
25+++ b/include/strutils.h
26@@ -91,8 +91,8 @@ static inline char *mem2strcpy(char *dest, const void *src, size_t n, size_t nma
27 if (n + 1 > nmax)
28 n = nmax - 1;
29
30+ memset(dest, '\0', nmax);
31 memcpy(dest, src, n);
32- dest[nmax-1] = '\0';
33 return dest;
34 }
35
36diff --git a/libmount/src/context_umount.c b/libmount/src/context_umount.c
37index 173637a15a..8773c65ffa 100644
38--- a/libmount/src/context_umount.c
39+++ b/libmount/src/context_umount.c
40@@ -393,10 +393,7 @@ static int is_fuse_usermount(struct libmnt_context *cxt, int *errsv)
41 struct libmnt_ns *ns_old;
42 const char *type = mnt_fs_get_fstype(cxt->fs);
43 const char *optstr;
44- char *user_id = NULL;
45- size_t sz;
46- uid_t uid;
47- char uidstr[sizeof(stringify_value(ULONG_MAX))];
48+ uid_t uid, entry_uid;
49
50 *errsv = 0;
51
52@@ -413,11 +410,7 @@ static int is_fuse_usermount(struct libmnt_context *cxt, int *errsv)
53 optstr = mnt_fs_get_fs_options(cxt->fs);
54 if (!optstr)
55 return 0;
56-
57- if (mnt_optstr_get_option(optstr, "user_id", &user_id, &sz) != 0)
58- return 0;
59-
60- if (sz == 0 || user_id == NULL)
61+ if (mnt_optstr_get_uid(optstr, "user_id", &entry_uid) != 0)
62 return 0;
63
64 /* get current user */
65@@ -434,8 +427,7 @@ static int is_fuse_usermount(struct libmnt_context *cxt, int *errsv)
66 return 0;
67 }
68
69- snprintf(uidstr, sizeof(uidstr), "%lu", (unsigned long) uid);
70- return strncmp(user_id, uidstr, sz) == 0;
71+ return uid == entry_uid;
72 }
73
74 /*
75diff --git a/libmount/src/mountP.h b/libmount/src/mountP.h
76index d43a835418..22442ec55e 100644
77--- a/libmount/src/mountP.h
78+++ b/libmount/src/mountP.h
79@@ -400,6 +400,7 @@ extern const struct libmnt_optmap *mnt_optmap_get_entry(
80 const struct libmnt_optmap **mapent);
81
82 /* optstr.c */
83+extern int mnt_optstr_get_uid(const char *optstr, const char *name, uid_t *uid);
84 extern int mnt_optstr_remove_option_at(char **optstr, char *begin, char *end);
85 extern int mnt_optstr_fix_gid(char **optstr, char *value, size_t valsz, char **next);
86 extern int mnt_optstr_fix_uid(char **optstr, char *value, size_t valsz, char **next);
87diff --git a/libmount/src/optstr.c b/libmount/src/optstr.c
88index 921b9318e7..16800f571c 100644
89--- a/libmount/src/optstr.c
90+++ b/libmount/src/optstr.c
91@@ -1090,6 +1090,48 @@ int mnt_optstr_fix_user(char **optstr)
92 return rc;
93 }
94
95+/*
96+ * Converts value from @optstr addressed by @name to uid.
97+ *
98+ * Returns: 0 on success, 1 if not found, <0 on error
99+ */
100+int mnt_optstr_get_uid(const char *optstr, const char *name, uid_t *uid)
101+{
102+ char *value = NULL;
103+ size_t valsz = 0;
104+ char buf[sizeof(stringify_value(UINT64_MAX))];
105+ int rc;
106+ uint64_t num;
107+
108+ assert(optstr);
109+ assert(name);
110+ assert(uid);
111+
112+ rc = mnt_optstr_get_option(optstr, name, &value, &valsz);
113+ if (rc != 0)
114+ goto fail;
115+
116+ if (valsz > sizeof(buf) - 1) {
117+ rc = -ERANGE;
118+ goto fail;
119+ }
120+ mem2strcpy(buf, value, valsz, sizeof(buf));
121+
122+ rc = ul_strtou64(buf, &num, 10);
123+ if (rc != 0)
124+ goto fail;
125+ if (num > ULONG_MAX || (uid_t) num != num) {
126+ rc = -ERANGE;
127+ goto fail;
128+ }
129+ *uid = (uid_t) num;
130+
131+ return 0;
132+fail:
133+ DBG(UTILS, ul_debug("failed to convert '%s'= to number [rc=%d]", name, rc));
134+ return rc;
135+}
136+
137 /**
138 * mnt_match_options:
139 * @optstr: options string