diff options
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.patch | 139 |
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 @@ | |||
1 | From f3db9bd609494099f0c1b95231c5dfe383346929 Mon Sep 17 00:00:00 2001 | ||
2 | From: Karel Zak <kzak@redhat.com> | ||
3 | Date: Wed, 24 Nov 2021 13:53:25 +0100 | ||
4 | Subject: [PATCH] libmount: fix UID check for FUSE umount [CVE-2021-3995] | ||
5 | |||
6 | Improper UID check allows an unprivileged user to unmount FUSE | ||
7 | filesystems of users with similar UID. | ||
8 | |||
9 | Signed-off-by: Karel Zak <kzak@redhat.com> | ||
10 | |||
11 | CVE: CVE-2021-3995 | ||
12 | Upstream-Status: Backport [https://github.com/util-linux/util-linux/commit/f3db9bd609494099f0c1b95231c5dfe383346929] | ||
13 | Signed-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 | |||
22 | diff --git a/include/strutils.h b/include/strutils.h | ||
23 | index 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 | |||
36 | diff --git a/libmount/src/context_umount.c b/libmount/src/context_umount.c | ||
37 | index 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 | /* | ||
75 | diff --git a/libmount/src/mountP.h b/libmount/src/mountP.h | ||
76 | index 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); | ||
87 | diff --git a/libmount/src/optstr.c b/libmount/src/optstr.c | ||
88 | index 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 | ||