1 |
commit: 9c4a376d0b08f77d0755b5812b7772bd18519dea |
2 |
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org> |
3 |
AuthorDate: Thu Feb 28 17:43:23 2013 +0000 |
4 |
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org> |
5 |
CommitDate: Thu Feb 28 17:43:23 2013 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/hardened-patchset.git;a=commit;h=9c4a376d |
7 |
|
8 |
Grsec/PaX: 2.9.1-{2.6.32.60,3.2.39,3.8.0}-201302271810 |
9 |
|
10 |
--- |
11 |
..._grsecurity-2.9.1-2.6.32.60-201302271816.patch} | 246 ++++++++++- |
12 |
3.2.39/0000_README | 2 +- |
13 |
...420_grsecurity-2.9.1-3.2.39-201302271819.patch} | 212 +++++++++- |
14 |
3.8.0/0000_README | 2 +- |
15 |
...4420_grsecurity-2.9.1-3.8.0-201302271810.patch} | 473 +++++++++++++++++++- |
16 |
5 files changed, 901 insertions(+), 34 deletions(-) |
17 |
|
18 |
diff --git a/2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201302222044.patch b/2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201302271816.patch |
19 |
similarity index 99% |
20 |
rename from 2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201302222044.patch |
21 |
rename to 2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201302271816.patch |
22 |
index f5ba675..ee04841 100644 |
23 |
--- a/2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201302222044.patch |
24 |
+++ b/2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201302271816.patch |
25 |
@@ -42821,7 +42821,7 @@ index 87c67b4..230527a 100644 |
26 |
.part_num = MBCS_PART_NUM, |
27 |
.mfg_num = MBCS_MFG_NUM, |
28 |
diff --git a/drivers/char/mem.c b/drivers/char/mem.c |
29 |
-index 1270f64..3b87405 100644 |
30 |
+index 1270f64..3f4b1fa 100644 |
31 |
--- a/drivers/char/mem.c |
32 |
+++ b/drivers/char/mem.c |
33 |
@@ -18,6 +18,7 @@ |
34 |
@@ -42955,7 +42955,19 @@ index 1270f64..3b87405 100644 |
35 |
return -EFAULT; |
36 |
buf += sz; |
37 |
p += sz; |
38 |
-@@ -889,6 +941,9 @@ static const struct memdev { |
39 |
+@@ -848,6 +900,11 @@ static ssize_t kmsg_write(struct file * file, const char __user * buf, |
40 |
+ char *tmp; |
41 |
+ ssize_t ret; |
42 |
+ |
43 |
++#ifdef CONFIG_GRKERNSEC_DMESG |
44 |
++ if (!capable(CAP_SYS_ADMIN)) |
45 |
++ return -EPERM; |
46 |
++#endif |
47 |
++ |
48 |
+ tmp = kmalloc(count + 1, GFP_KERNEL); |
49 |
+ if (tmp == NULL) |
50 |
+ return -ENOMEM; |
51 |
+@@ -889,6 +946,9 @@ static const struct memdev { |
52 |
#ifdef CONFIG_CRASH_DUMP |
53 |
[12] = { "oldmem", 0, &oldmem_fops, NULL }, |
54 |
#endif |
55 |
@@ -77258,10 +77270,24 @@ index d84e705..d8c364c 100644 |
56 |
|
57 |
return ioctl_preallocate(file, p); |
58 |
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c |
59 |
-index 8e48b52..f01ed91 100644 |
60 |
+index 8e48b52..2c592f8 100644 |
61 |
--- a/fs/configfs/dir.c |
62 |
+++ b/fs/configfs/dir.c |
63 |
-@@ -1572,7 +1572,8 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir |
64 |
+@@ -1044,10 +1044,11 @@ static int configfs_dump(struct configfs_dirent *sd, int level) |
65 |
+ static int configfs_depend_prep(struct dentry *origin, |
66 |
+ struct config_item *target) |
67 |
+ { |
68 |
+- struct configfs_dirent *child_sd, *sd = origin->d_fsdata; |
69 |
++ struct configfs_dirent *child_sd, *sd; |
70 |
+ int ret = 0; |
71 |
+ |
72 |
+- BUG_ON(!origin || !sd); |
73 |
++ BUG_ON(!origin || !origin->d_fsdata); |
74 |
++ sd = origin->d_fsdata; |
75 |
+ |
76 |
+ if (sd->s_element == target) /* Boo-yah */ |
77 |
+ goto out; |
78 |
+@@ -1572,7 +1573,8 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir |
79 |
} |
80 |
for (p=q->next; p!= &parent_sd->s_children; p=p->next) { |
81 |
struct configfs_dirent *next; |
82 |
@@ -77271,7 +77297,7 @@ index 8e48b52..f01ed91 100644 |
83 |
int len; |
84 |
|
85 |
next = list_entry(p, struct configfs_dirent, |
86 |
-@@ -1581,7 +1582,12 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir |
87 |
+@@ -1581,7 +1583,12 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir |
88 |
continue; |
89 |
|
90 |
name = configfs_get_name(next); |
91 |
@@ -78561,6 +78587,54 @@ index f1e7077..edd86b2 100644 |
92 |
.show = ext4_attr_show, |
93 |
.store = ext4_attr_store, |
94 |
}; |
95 |
+diff --git a/fs/fat/inode.c b/fs/fat/inode.c |
96 |
+index 76b7961..c187e92 100644 |
97 |
+--- a/fs/fat/inode.c |
98 |
++++ b/fs/fat/inode.c |
99 |
+@@ -558,7 +558,7 @@ static int fat_statfs(struct dentry *dentry, struct kstatfs *buf) |
100 |
+ buf->f_bavail = sbi->free_clusters; |
101 |
+ buf->f_fsid.val[0] = (u32)id; |
102 |
+ buf->f_fsid.val[1] = (u32)(id >> 32); |
103 |
+- buf->f_namelen = sbi->options.isvfat ? 260 : 12; |
104 |
++ buf->f_namelen = sbi->options.isvfat ? FAT_LFN_LEN : 12; |
105 |
+ |
106 |
+ return 0; |
107 |
+ } |
108 |
+diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c |
109 |
+index 72646e2..4251f35 100644 |
110 |
+--- a/fs/fat/namei_vfat.c |
111 |
++++ b/fs/fat/namei_vfat.c |
112 |
+@@ -499,17 +499,18 @@ xlate_to_uni(const unsigned char *name, int len, unsigned char *outname, |
113 |
+ int charlen; |
114 |
+ |
115 |
+ if (utf8) { |
116 |
+- *outlen = utf8s_to_utf16s(name, len, (wchar_t *)outname); |
117 |
++ *outlen = utf8s_to_utf16s(name, len, UTF16_HOST_ENDIAN, |
118 |
++ (wchar_t *) outname, FAT_LFN_LEN + 2); |
119 |
+ if (*outlen < 0) |
120 |
+ return *outlen; |
121 |
+- else if (*outlen > 255) |
122 |
++ else if (*outlen > FAT_LFN_LEN) |
123 |
+ return -ENAMETOOLONG; |
124 |
+ |
125 |
+ op = &outname[*outlen * sizeof(wchar_t)]; |
126 |
+ } else { |
127 |
+ if (nls) { |
128 |
+ for (i = 0, ip = name, op = outname, *outlen = 0; |
129 |
+- i < len && *outlen <= 255; |
130 |
++ i < len && *outlen <= FAT_LFN_LEN; |
131 |
+ *outlen += 1) |
132 |
+ { |
133 |
+ if (escape && (*ip == ':')) { |
134 |
+@@ -549,7 +550,7 @@ xlate_to_uni(const unsigned char *name, int len, unsigned char *outname, |
135 |
+ return -ENAMETOOLONG; |
136 |
+ } else { |
137 |
+ for (i = 0, ip = name, op = outname, *outlen = 0; |
138 |
+- i < len && *outlen <= 255; |
139 |
++ i < len && *outlen <= FAT_LFN_LEN; |
140 |
+ i++, *outlen += 1) |
141 |
+ { |
142 |
+ *op++ = *ip++; |
143 |
diff --git a/fs/fcntl.c b/fs/fcntl.c |
144 |
index 97e01dc..e9aab2d 100644 |
145 |
--- a/fs/fcntl.c |
146 |
@@ -81507,6 +81581,78 @@ index f6af760..d0adf34 100644 |
147 |
len = argv[n].v_size * argv[n].v_nmembs; |
148 |
base = (void __user *)(unsigned long)argv[n].v_base; |
149 |
if (len == 0) { |
150 |
+diff --git a/fs/nls/nls_base.c b/fs/nls/nls_base.c |
151 |
+index 44a88a9..0eb059e 100644 |
152 |
+--- a/fs/nls/nls_base.c |
153 |
++++ b/fs/nls/nls_base.c |
154 |
+@@ -114,34 +114,57 @@ int utf32_to_utf8(unicode_t u, u8 *s, int maxlen) |
155 |
+ } |
156 |
+ EXPORT_SYMBOL(utf32_to_utf8); |
157 |
+ |
158 |
+-int utf8s_to_utf16s(const u8 *s, int len, wchar_t *pwcs) |
159 |
++static inline void put_utf16(wchar_t *s, unsigned c, enum utf16_endian endian) |
160 |
++{ |
161 |
++ switch (endian) { |
162 |
++ default: |
163 |
++ *s = (wchar_t) c; |
164 |
++ break; |
165 |
++ case UTF16_LITTLE_ENDIAN: |
166 |
++ *s = __cpu_to_le16(c); |
167 |
++ break; |
168 |
++ case UTF16_BIG_ENDIAN: |
169 |
++ *s = __cpu_to_be16(c); |
170 |
++ break; |
171 |
++ } |
172 |
++} |
173 |
++ |
174 |
++int utf8s_to_utf16s(const u8 *s, int len, enum utf16_endian endian, |
175 |
++ wchar_t *pwcs, int maxlen) |
176 |
+ { |
177 |
+ u16 *op; |
178 |
+ int size; |
179 |
+ unicode_t u; |
180 |
+ |
181 |
+ op = pwcs; |
182 |
+- while (*s && len > 0) { |
183 |
++ while (len > 0 && maxlen > 0 && *s) { |
184 |
+ if (*s & 0x80) { |
185 |
+ size = utf8_to_utf32(s, len, &u); |
186 |
+ if (size < 0) |
187 |
+ return -EINVAL; |
188 |
++ s += size; |
189 |
++ len -= size; |
190 |
+ |
191 |
+ if (u >= PLANE_SIZE) { |
192 |
++ if (maxlen < 2) |
193 |
++ break; |
194 |
+ u -= PLANE_SIZE; |
195 |
+- *op++ = (wchar_t) (SURROGATE_PAIR | |
196 |
+- ((u >> 10) & SURROGATE_BITS)); |
197 |
+- *op++ = (wchar_t) (SURROGATE_PAIR | |
198 |
++ put_utf16(op++, SURROGATE_PAIR | |
199 |
++ ((u >> 10) & SURROGATE_BITS), |
200 |
++ endian); |
201 |
++ put_utf16(op++, SURROGATE_PAIR | |
202 |
+ SURROGATE_LOW | |
203 |
+- (u & SURROGATE_BITS)); |
204 |
++ (u & SURROGATE_BITS), |
205 |
++ endian); |
206 |
++ maxlen -= 2; |
207 |
+ } else { |
208 |
+- *op++ = (wchar_t) u; |
209 |
++ put_utf16(op++, u, endian); |
210 |
++ maxlen--; |
211 |
+ } |
212 |
+- s += size; |
213 |
+- len -= size; |
214 |
+ } else { |
215 |
+- *op++ = *s++; |
216 |
++ put_utf16(op++, *s++, endian); |
217 |
+ len--; |
218 |
++ maxlen--; |
219 |
+ } |
220 |
+ } |
221 |
+ return op - pwcs; |
222 |
diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c |
223 |
index 7e54e52..9337248 100644 |
224 |
--- a/fs/notify/dnotify/dnotify.c |
225 |
@@ -98947,6 +99093,28 @@ index 82a9124..8a5f622 100644 |
226 |
= { ARRAY_SIZE(array), nump, param_set_##type, param_get_##type,\ |
227 |
sizeof(array[0]), array }; \ |
228 |
__module_param_call(MODULE_PARAM_PREFIX, name, \ |
229 |
+diff --git a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h |
230 |
+index ce38f1c..34066e6 100644 |
231 |
+--- a/include/linux/msdos_fs.h |
232 |
++++ b/include/linux/msdos_fs.h |
233 |
+@@ -15,6 +15,7 @@ |
234 |
+ #define MSDOS_DPB_BITS 4 /* log2(MSDOS_DPB) */ |
235 |
+ #define MSDOS_DPS (SECTOR_SIZE / sizeof(struct msdos_dir_entry)) |
236 |
+ #define MSDOS_DPS_BITS 4 /* log2(MSDOS_DPS) */ |
237 |
++#define MSDOS_LONGNAME 256 /* maximum name length */ |
238 |
+ #define CF_LE_W(v) le16_to_cpu(v) |
239 |
+ #define CF_LE_L(v) le32_to_cpu(v) |
240 |
+ #define CT_LE_W(v) cpu_to_le16(v) |
241 |
+@@ -47,8 +48,8 @@ |
242 |
+ #define DELETED_FLAG 0xe5 /* marks file as deleted when in name[0] */ |
243 |
+ #define IS_FREE(n) (!*(n) || *(n) == DELETED_FLAG) |
244 |
+ |
245 |
++#define FAT_LFN_LEN 255 /* maximum long name length */ |
246 |
+ #define MSDOS_NAME 11 /* maximum name length */ |
247 |
+-#define MSDOS_LONGNAME 256 /* maximum name length */ |
248 |
+ #define MSDOS_SLOTS 21 /* max # of slots for short and long names */ |
249 |
+ #define MSDOS_DOT ". " /* ".", padded to MSDOS_NAME chars */ |
250 |
+ #define MSDOS_DOTDOT ".. " /* "..", padded to MSDOS_NAME chars */ |
251 |
diff --git a/include/linux/mutex.h b/include/linux/mutex.h |
252 |
index 878cab4..c92cb3e 100644 |
253 |
--- a/include/linux/mutex.h |
254 |
@@ -99037,6 +99205,29 @@ index 0000000..33f4af8 |
255 |
+}; |
256 |
+ |
257 |
+#endif |
258 |
+diff --git a/include/linux/nls.h b/include/linux/nls.h |
259 |
+index d47beef..5dc635f 100644 |
260 |
+--- a/include/linux/nls.h |
261 |
++++ b/include/linux/nls.h |
262 |
+@@ -43,7 +43,7 @@ enum utf16_endian { |
263 |
+ UTF16_BIG_ENDIAN |
264 |
+ }; |
265 |
+ |
266 |
+-/* nls.c */ |
267 |
++/* nls_base.c */ |
268 |
+ extern int register_nls(struct nls_table *); |
269 |
+ extern int unregister_nls(struct nls_table *); |
270 |
+ extern struct nls_table *load_nls(char *); |
271 |
+@@ -52,7 +52,8 @@ extern struct nls_table *load_nls_default(void); |
272 |
+ |
273 |
+ extern int utf8_to_utf32(const u8 *s, int len, unicode_t *pu); |
274 |
+ extern int utf32_to_utf8(unicode_t u, u8 *s, int maxlen); |
275 |
+-extern int utf8s_to_utf16s(const u8 *s, int len, wchar_t *pwcs); |
276 |
++extern int utf8s_to_utf16s(const u8 *s, int len, |
277 |
++ enum utf16_endian endian, wchar_t *pwcs, int maxlen); |
278 |
+ extern int utf16s_to_utf8s(const wchar_t *pwcs, int len, |
279 |
+ enum utf16_endian endian, u8 *s, int maxlen); |
280 |
+ |
281 |
diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h |
282 |
index b359c4a..c08b334 100644 |
283 |
--- a/include/linux/nodemask.h |
284 |
@@ -111909,7 +112100,7 @@ index dd43373..d848cd7 100644 |
285 |
list_add_tail(&vma->anon_vma_node, &anon_vma->head); |
286 |
allocated = NULL; |
287 |
diff --git a/mm/shmem.c b/mm/shmem.c |
288 |
-index 3e0005b..1d659a8 100644 |
289 |
+index 3e0005b..eac2525 100644 |
290 |
--- a/mm/shmem.c |
291 |
+++ b/mm/shmem.c |
292 |
@@ -31,7 +31,7 @@ |
293 |
@@ -111948,7 +112139,31 @@ index 3e0005b..1d659a8 100644 |
294 |
/* do it inline */ |
295 |
memcpy(info, symname, len); |
296 |
inode->i_op = &shmem_symlink_inline_operations; |
297 |
-@@ -2310,8 +2314,7 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent) |
298 |
+@@ -2242,6 +2246,7 @@ static int shmem_remount_fs(struct super_block *sb, int *flags, char *data) |
299 |
+ unsigned long inodes; |
300 |
+ int error = -EINVAL; |
301 |
+ |
302 |
++ config.mpol = NULL; |
303 |
+ if (shmem_parse_options(data, &config, true)) |
304 |
+ return error; |
305 |
+ |
306 |
+@@ -2269,8 +2274,13 @@ static int shmem_remount_fs(struct super_block *sb, int *flags, char *data) |
307 |
+ sbinfo->max_inodes = config.max_inodes; |
308 |
+ sbinfo->free_inodes = config.max_inodes - inodes; |
309 |
+ |
310 |
+- mpol_put(sbinfo->mpol); |
311 |
+- sbinfo->mpol = config.mpol; /* transfers initial ref */ |
312 |
++ /* |
313 |
++ * Preserve previous mempolicy unless mpol remount option was specified. |
314 |
++ */ |
315 |
++ if (config.mpol) { |
316 |
++ mpol_put(sbinfo->mpol); |
317 |
++ sbinfo->mpol = config.mpol; /* transfers initial ref */ |
318 |
++ } |
319 |
+ out: |
320 |
+ spin_unlock(&sbinfo->stat_lock); |
321 |
+ return error; |
322 |
+@@ -2310,8 +2320,7 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent) |
323 |
int err = -ENOMEM; |
324 |
|
325 |
/* Round up to L1_CACHE_BYTES to resist false sharing */ |
326 |
@@ -113416,6 +113631,23 @@ index 75302a9..09e36d3 100644 |
327 |
uf.type_mask = f->type_mask; |
328 |
uf.opcode = f->opcode; |
329 |
uf.event_mask[0] = *((u32 *) f->event_mask + 0); |
330 |
+diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c |
331 |
+index 49d8495..6b0a111 100644 |
332 |
+--- a/net/bluetooth/hidp/core.c |
333 |
++++ b/net/bluetooth/hidp/core.c |
334 |
+@@ -778,9 +778,9 @@ static int hidp_setup_hid(struct hidp_session *session, |
335 |
+ hid->version = req->version; |
336 |
+ hid->country = req->country; |
337 |
+ |
338 |
+- strncpy(hid->name, req->name, 128); |
339 |
+- strncpy(hid->phys, batostr(&src), 64); |
340 |
+- strncpy(hid->uniq, batostr(&dst), 64); |
341 |
++ strncpy(hid->name, req->name, sizeof(hid->name) - 1); |
342 |
++ strncpy(hid->phys, batostr(&src), sizeof(hid->phys) - 1); |
343 |
++ strncpy(hid->uniq, batostr(&dst), sizeof(hid->uniq) - 1); |
344 |
+ |
345 |
+ hid->dev.parent = hidp_get_device(session); |
346 |
+ hid->ll_driver = &hidp_hid_driver; |
347 |
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c |
348 |
index 1ae3f80..c5d763b 100644 |
349 |
--- a/net/bluetooth/rfcomm/sock.c |
350 |
|
351 |
diff --git a/3.2.39/0000_README b/3.2.39/0000_README |
352 |
index 4b7b629..b8fcdf1 100644 |
353 |
--- a/3.2.39/0000_README |
354 |
+++ b/3.2.39/0000_README |
355 |
@@ -74,7 +74,7 @@ Patch: 1039_linux-3.2.39.patch |
356 |
From: http://www.kernel.org |
357 |
Desc: Linux 3.2.39 |
358 |
|
359 |
-Patch: 4420_grsecurity-2.9.1-3.2.39-201302222046.patch |
360 |
+Patch: 4420_grsecurity-2.9.1-3.2.39-201302271819.patch |
361 |
From: http://www.grsecurity.net |
362 |
Desc: hardened-sources base patch from upstream grsecurity |
363 |
|
364 |
|
365 |
diff --git a/3.2.39/4420_grsecurity-2.9.1-3.2.39-201302222046.patch b/3.2.39/4420_grsecurity-2.9.1-3.2.39-201302271819.patch |
366 |
similarity index 99% |
367 |
rename from 3.2.39/4420_grsecurity-2.9.1-3.2.39-201302222046.patch |
368 |
rename to 3.2.39/4420_grsecurity-2.9.1-3.2.39-201302271819.patch |
369 |
index ed3c4f5..b220f78 100644 |
370 |
--- a/3.2.39/4420_grsecurity-2.9.1-3.2.39-201302222046.patch |
371 |
+++ b/3.2.39/4420_grsecurity-2.9.1-3.2.39-201302271819.patch |
372 |
@@ -31455,7 +31455,7 @@ index 1aeaaba..e018570 100644 |
373 |
.part_num = MBCS_PART_NUM, |
374 |
.mfg_num = MBCS_MFG_NUM, |
375 |
diff --git a/drivers/char/mem.c b/drivers/char/mem.c |
376 |
-index 1451790..3c7dfbb 100644 |
377 |
+index 1451790..d42d89d 100644 |
378 |
--- a/drivers/char/mem.c |
379 |
+++ b/drivers/char/mem.c |
380 |
@@ -18,6 +18,7 @@ |
381 |
@@ -31580,7 +31580,19 @@ index 1451790..3c7dfbb 100644 |
382 |
return -EFAULT; |
383 |
buf += sz; |
384 |
p += sz; |
385 |
-@@ -867,6 +914,9 @@ static const struct memdev { |
386 |
+@@ -815,6 +862,11 @@ static ssize_t kmsg_writev(struct kiocb *iocb, const struct iovec *iv, |
387 |
+ ssize_t ret = -EFAULT; |
388 |
+ size_t len = iov_length(iv, count); |
389 |
+ |
390 |
++#ifdef CONFIG_GRKERNSEC_DMESG |
391 |
++ if (!capable(CAP_SYSLOG)) |
392 |
++ return -EPERM; |
393 |
++#endif |
394 |
++ |
395 |
+ line = kmalloc(len + 1, GFP_KERNEL); |
396 |
+ if (line == NULL) |
397 |
+ return -ENOMEM; |
398 |
+@@ -867,6 +919,9 @@ static const struct memdev { |
399 |
#ifdef CONFIG_CRASH_DUMP |
400 |
[12] = { "oldmem", 0, &oldmem_fops, NULL }, |
401 |
#endif |
402 |
@@ -33807,6 +33819,28 @@ index 0fb100e..baf87e5 100644 |
403 |
|
404 |
__asm__ __volatile__ ("call *%8" : "=d"(hv_status_hi), |
405 |
"=a"(hv_status_lo) : "d" (control_hi), |
406 |
+diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c |
407 |
+index 89f5244..0e8343f 100644 |
408 |
+--- a/drivers/hv/hv_kvp.c |
409 |
++++ b/drivers/hv/hv_kvp.c |
410 |
+@@ -212,11 +212,13 @@ kvp_respond_to_host(char *key, char *value, int error) |
411 |
+ * The windows host expects the key/value pair to be encoded |
412 |
+ * in utf16. |
413 |
+ */ |
414 |
+- keylen = utf8s_to_utf16s(key_name, strlen(key_name), |
415 |
+- (wchar_t *)kvp_data->data.key); |
416 |
++ keylen = utf8s_to_utf16s(key_name, strlen(key_name), UTF16_HOST_ENDIAN, |
417 |
++ (wchar_t *) kvp_data->data.key, |
418 |
++ HV_KVP_EXCHANGE_MAX_KEY_SIZE / 2); |
419 |
+ kvp_data->data.key_size = 2*(keylen + 1); /* utf16 encoding */ |
420 |
+- valuelen = utf8s_to_utf16s(value, strlen(value), |
421 |
+- (wchar_t *)kvp_data->data.value); |
422 |
++ valuelen = utf8s_to_utf16s(value, strlen(value), UTF16_HOST_ENDIAN, |
423 |
++ (wchar_t *) kvp_data->data.value, |
424 |
++ HV_KVP_EXCHANGE_MAX_VALUE_SIZE / 2); |
425 |
+ kvp_data->data.value_size = 2*(valuelen + 1); /* utf16 encoding */ |
426 |
+ |
427 |
+ kvp_data->data.value_type = REG_SZ; /* all our values are strings */ |
428 |
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h |
429 |
index 0aee112..b72d21f 100644 |
430 |
--- a/drivers/hv/hyperv_vmbus.h |
431 |
@@ -46826,10 +46860,24 @@ index f854cf9..93292ff 100644 |
432 |
return 1; |
433 |
if (a < b) |
434 |
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c |
435 |
-index 9a37a9b..35792b6 100644 |
436 |
+index 9a37a9b..80968f3 100644 |
437 |
--- a/fs/configfs/dir.c |
438 |
+++ b/fs/configfs/dir.c |
439 |
-@@ -1575,7 +1575,8 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir |
440 |
+@@ -1047,10 +1047,11 @@ static int configfs_dump(struct configfs_dirent *sd, int level) |
441 |
+ static int configfs_depend_prep(struct dentry *origin, |
442 |
+ struct config_item *target) |
443 |
+ { |
444 |
+- struct configfs_dirent *child_sd, *sd = origin->d_fsdata; |
445 |
++ struct configfs_dirent *child_sd, *sd; |
446 |
+ int ret = 0; |
447 |
+ |
448 |
+- BUG_ON(!origin || !sd); |
449 |
++ BUG_ON(!origin || !origin->d_fsdata); |
450 |
++ sd = origin->d_fsdata; |
451 |
+ |
452 |
+ if (sd->s_element == target) /* Boo-yah */ |
453 |
+ goto out; |
454 |
+@@ -1575,7 +1576,8 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir |
455 |
} |
456 |
for (p=q->next; p!= &parent_sd->s_children; p=p->next) { |
457 |
struct configfs_dirent *next; |
458 |
@@ -46839,7 +46887,7 @@ index 9a37a9b..35792b6 100644 |
459 |
int len; |
460 |
struct inode *inode = NULL; |
461 |
|
462 |
-@@ -1585,7 +1586,12 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir |
463 |
+@@ -1585,7 +1587,12 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir |
464 |
continue; |
465 |
|
466 |
name = configfs_get_name(next); |
467 |
@@ -48134,6 +48182,20 @@ index 24ac7a2..c596196 100644 |
468 |
if (!buf) |
469 |
return -ENOMEM; |
470 |
|
471 |
+diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c |
472 |
+index a87a656..c25cf15 100644 |
473 |
+--- a/fs/fat/namei_vfat.c |
474 |
++++ b/fs/fat/namei_vfat.c |
475 |
+@@ -512,7 +512,8 @@ xlate_to_uni(const unsigned char *name, int len, unsigned char *outname, |
476 |
+ int charlen; |
477 |
+ |
478 |
+ if (utf8) { |
479 |
+- *outlen = utf8s_to_utf16s(name, len, (wchar_t *)outname); |
480 |
++ *outlen = utf8s_to_utf16s(name, len, UTF16_HOST_ENDIAN, |
481 |
++ (wchar_t *) outname, FAT_LFN_LEN + 2); |
482 |
+ if (*outlen < 0) |
483 |
+ return *outlen; |
484 |
+ else if (*outlen > FAT_LFN_LEN) |
485 |
diff --git a/fs/fcntl.c b/fs/fcntl.c |
486 |
index 22764c7..86372c9 100644 |
487 |
--- a/fs/fcntl.c |
488 |
@@ -50769,6 +50831,78 @@ index 1c98f53..41e6a04 100644 |
489 |
nilfs_set_nsegments(nilfs, le64_to_cpu(sbp->s_nsegments)); |
490 |
nilfs->ns_crc_seed = le32_to_cpu(sbp->s_crc_seed); |
491 |
return 0; |
492 |
+diff --git a/fs/nls/nls_base.c b/fs/nls/nls_base.c |
493 |
+index 44a88a9..0eb059e 100644 |
494 |
+--- a/fs/nls/nls_base.c |
495 |
++++ b/fs/nls/nls_base.c |
496 |
+@@ -114,34 +114,57 @@ int utf32_to_utf8(unicode_t u, u8 *s, int maxlen) |
497 |
+ } |
498 |
+ EXPORT_SYMBOL(utf32_to_utf8); |
499 |
+ |
500 |
+-int utf8s_to_utf16s(const u8 *s, int len, wchar_t *pwcs) |
501 |
++static inline void put_utf16(wchar_t *s, unsigned c, enum utf16_endian endian) |
502 |
++{ |
503 |
++ switch (endian) { |
504 |
++ default: |
505 |
++ *s = (wchar_t) c; |
506 |
++ break; |
507 |
++ case UTF16_LITTLE_ENDIAN: |
508 |
++ *s = __cpu_to_le16(c); |
509 |
++ break; |
510 |
++ case UTF16_BIG_ENDIAN: |
511 |
++ *s = __cpu_to_be16(c); |
512 |
++ break; |
513 |
++ } |
514 |
++} |
515 |
++ |
516 |
++int utf8s_to_utf16s(const u8 *s, int len, enum utf16_endian endian, |
517 |
++ wchar_t *pwcs, int maxlen) |
518 |
+ { |
519 |
+ u16 *op; |
520 |
+ int size; |
521 |
+ unicode_t u; |
522 |
+ |
523 |
+ op = pwcs; |
524 |
+- while (*s && len > 0) { |
525 |
++ while (len > 0 && maxlen > 0 && *s) { |
526 |
+ if (*s & 0x80) { |
527 |
+ size = utf8_to_utf32(s, len, &u); |
528 |
+ if (size < 0) |
529 |
+ return -EINVAL; |
530 |
++ s += size; |
531 |
++ len -= size; |
532 |
+ |
533 |
+ if (u >= PLANE_SIZE) { |
534 |
++ if (maxlen < 2) |
535 |
++ break; |
536 |
+ u -= PLANE_SIZE; |
537 |
+- *op++ = (wchar_t) (SURROGATE_PAIR | |
538 |
+- ((u >> 10) & SURROGATE_BITS)); |
539 |
+- *op++ = (wchar_t) (SURROGATE_PAIR | |
540 |
++ put_utf16(op++, SURROGATE_PAIR | |
541 |
++ ((u >> 10) & SURROGATE_BITS), |
542 |
++ endian); |
543 |
++ put_utf16(op++, SURROGATE_PAIR | |
544 |
+ SURROGATE_LOW | |
545 |
+- (u & SURROGATE_BITS)); |
546 |
++ (u & SURROGATE_BITS), |
547 |
++ endian); |
548 |
++ maxlen -= 2; |
549 |
+ } else { |
550 |
+- *op++ = (wchar_t) u; |
551 |
++ put_utf16(op++, u, endian); |
552 |
++ maxlen--; |
553 |
+ } |
554 |
+- s += size; |
555 |
+- len -= size; |
556 |
+ } else { |
557 |
+- *op++ = *s++; |
558 |
++ put_utf16(op++, *s++, endian); |
559 |
+ len--; |
560 |
++ maxlen--; |
561 |
+ } |
562 |
+ } |
563 |
+ return op - pwcs; |
564 |
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c |
565 |
index 9fde1c0..14e8827 100644 |
566 |
--- a/fs/notify/fanotify/fanotify_user.c |
567 |
@@ -66831,6 +66965,29 @@ index 0000000..33f4af8 |
568 |
+}; |
569 |
+ |
570 |
+#endif |
571 |
+diff --git a/include/linux/nls.h b/include/linux/nls.h |
572 |
+index d47beef..5dc635f 100644 |
573 |
+--- a/include/linux/nls.h |
574 |
++++ b/include/linux/nls.h |
575 |
+@@ -43,7 +43,7 @@ enum utf16_endian { |
576 |
+ UTF16_BIG_ENDIAN |
577 |
+ }; |
578 |
+ |
579 |
+-/* nls.c */ |
580 |
++/* nls_base.c */ |
581 |
+ extern int register_nls(struct nls_table *); |
582 |
+ extern int unregister_nls(struct nls_table *); |
583 |
+ extern struct nls_table *load_nls(char *); |
584 |
+@@ -52,7 +52,8 @@ extern struct nls_table *load_nls_default(void); |
585 |
+ |
586 |
+ extern int utf8_to_utf32(const u8 *s, int len, unicode_t *pu); |
587 |
+ extern int utf32_to_utf8(unicode_t u, u8 *s, int maxlen); |
588 |
+-extern int utf8s_to_utf16s(const u8 *s, int len, wchar_t *pwcs); |
589 |
++extern int utf8s_to_utf16s(const u8 *s, int len, |
590 |
++ enum utf16_endian endian, wchar_t *pwcs, int maxlen); |
591 |
+ extern int utf16s_to_utf8s(const wchar_t *pwcs, int len, |
592 |
+ enum utf16_endian endian, u8 *s, int maxlen); |
593 |
+ |
594 |
diff --git a/include/linux/notifier.h b/include/linux/notifier.h |
595 |
index d65746e..62e72c2 100644 |
596 |
--- a/include/linux/notifier.h |
597 |
@@ -78890,7 +79047,7 @@ index 8685697..b490361 100644 |
598 |
struct anon_vma_chain *avc; |
599 |
struct anon_vma *anon_vma; |
600 |
diff --git a/mm/shmem.c b/mm/shmem.c |
601 |
-index 12b9e80..5118865 100644 |
602 |
+index 12b9e80..a31df98 100644 |
603 |
--- a/mm/shmem.c |
604 |
+++ b/mm/shmem.c |
605 |
@@ -31,7 +31,7 @@ |
606 |
@@ -78939,7 +79096,31 @@ index 12b9e80..5118865 100644 |
607 |
if (size == 0) |
608 |
value = ""; /* empty EA, do not remove */ |
609 |
|
610 |
-@@ -2189,8 +2203,7 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent) |
611 |
+@@ -2121,6 +2135,7 @@ static int shmem_remount_fs(struct super_block *sb, int *flags, char *data) |
612 |
+ unsigned long inodes; |
613 |
+ int error = -EINVAL; |
614 |
+ |
615 |
++ config.mpol = NULL; |
616 |
+ if (shmem_parse_options(data, &config, true)) |
617 |
+ return error; |
618 |
+ |
619 |
+@@ -2145,8 +2160,13 @@ static int shmem_remount_fs(struct super_block *sb, int *flags, char *data) |
620 |
+ sbinfo->max_inodes = config.max_inodes; |
621 |
+ sbinfo->free_inodes = config.max_inodes - inodes; |
622 |
+ |
623 |
+- mpol_put(sbinfo->mpol); |
624 |
+- sbinfo->mpol = config.mpol; /* transfers initial ref */ |
625 |
++ /* |
626 |
++ * Preserve previous mempolicy unless mpol remount option was specified. |
627 |
++ */ |
628 |
++ if (config.mpol) { |
629 |
++ mpol_put(sbinfo->mpol); |
630 |
++ sbinfo->mpol = config.mpol; /* transfers initial ref */ |
631 |
++ } |
632 |
+ out: |
633 |
+ spin_unlock(&sbinfo->stat_lock); |
634 |
+ return error; |
635 |
+@@ -2189,8 +2209,7 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent) |
636 |
int err = -ENOMEM; |
637 |
|
638 |
/* Round up to L1_CACHE_BYTES to resist false sharing */ |
639 |
@@ -80487,6 +80668,23 @@ index 8361ee4..a4f0f18 100644 |
640 |
if (copy_from_user(&uf, optval, len)) { |
641 |
err = -EFAULT; |
642 |
break; |
643 |
+diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c |
644 |
+index 0274157..f8afbf3c7 100644 |
645 |
+--- a/net/bluetooth/hidp/core.c |
646 |
++++ b/net/bluetooth/hidp/core.c |
647 |
+@@ -945,9 +945,9 @@ static int hidp_setup_hid(struct hidp_session *session, |
648 |
+ hid->version = req->version; |
649 |
+ hid->country = req->country; |
650 |
+ |
651 |
+- strncpy(hid->name, req->name, sizeof(req->name) - 1); |
652 |
+- strncpy(hid->phys, batostr(&bt_sk(session->ctrl_sock->sk)->src), 64); |
653 |
+- strncpy(hid->uniq, batostr(&bt_sk(session->ctrl_sock->sk)->dst), 64); |
654 |
++ strncpy(hid->name, req->name, sizeof(hid->name) - 1); |
655 |
++ strncpy(hid->phys, batostr(&bt_sk(session->ctrl_sock->sk)->src), sizeof(hid->phys) - 1); |
656 |
++ strncpy(hid->uniq, batostr(&bt_sk(session->ctrl_sock->sk)->dst), sizeof(hid->uniq) - 1); |
657 |
+ |
658 |
+ hid->dev.parent = hidp_get_device(session); |
659 |
+ hid->ll_driver = &hidp_hid_driver; |
660 |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c |
661 |
index 04175d9..26291c1 100644 |
662 |
--- a/net/bluetooth/l2cap_core.c |
663 |
|
664 |
diff --git a/3.8.0/0000_README b/3.8.0/0000_README |
665 |
index 8d7fe2e..a9cab40 100644 |
666 |
--- a/3.8.0/0000_README |
667 |
+++ b/3.8.0/0000_README |
668 |
@@ -2,7 +2,7 @@ README |
669 |
----------------------------------------------------------------------------- |
670 |
Individual Patch Descriptions: |
671 |
----------------------------------------------------------------------------- |
672 |
-Patch: 4420_grsecurity-2.9.1-3.8.0-201302231124.patch |
673 |
+Patch: 4420_grsecurity-2.9.1-3.8.0-201302271810.patch |
674 |
From: http://www.grsecurity.net |
675 |
Desc: hardened-sources base patch from upstream grsecurity |
676 |
|
677 |
|
678 |
diff --git a/3.8.0/4420_grsecurity-2.9.1-3.8.0-201302231124.patch b/3.8.0/4420_grsecurity-2.9.1-3.8.0-201302271810.patch |
679 |
similarity index 99% |
680 |
rename from 3.8.0/4420_grsecurity-2.9.1-3.8.0-201302231124.patch |
681 |
rename to 3.8.0/4420_grsecurity-2.9.1-3.8.0-201302271810.patch |
682 |
index c065fb8..24c501f 100644 |
683 |
--- a/3.8.0/4420_grsecurity-2.9.1-3.8.0-201302231124.patch |
684 |
+++ b/3.8.0/4420_grsecurity-2.9.1-3.8.0-201302271810.patch |
685 |
@@ -41521,6 +41521,19 @@ index 681765b..d3ccdf2 100644 |
686 |
if (!perm) { |
687 |
ret = -EPERM; |
688 |
goto reterr; |
689 |
+diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c |
690 |
+index 8fd8968..3614c9c 100644 |
691 |
+--- a/drivers/tty/vt/vt.c |
692 |
++++ b/drivers/tty/vt/vt.c |
693 |
+@@ -539,7 +539,7 @@ static void insert_char(struct vc_data *vc, unsigned int nr) |
694 |
+ { |
695 |
+ unsigned short *p = (unsigned short *) vc->vc_pos; |
696 |
+ |
697 |
+- scr_memmovew(p + nr, p, (vc->vc_cols - vc->vc_x) * 2); |
698 |
++ scr_memmovew(p + nr, p, (vc->vc_cols - vc->vc_x - nr) * 2); |
699 |
+ scr_memsetw(p, vc->vc_video_erase_char, nr * 2); |
700 |
+ vc->vc_need_wrap = 0; |
701 |
+ if (DO_UPDATE(vc)) |
702 |
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c |
703 |
index 5110f36..8dc0a74 100644 |
704 |
--- a/drivers/uio/uio.c |
705 |
@@ -47182,10 +47195,24 @@ index e2f57a0..3c78771 100644 |
706 |
return 1; |
707 |
if (a < b) |
708 |
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c |
709 |
-index 712b10f..6b54d7b 100644 |
710 |
+index 712b10f..c33c4ca 100644 |
711 |
--- a/fs/configfs/dir.c |
712 |
+++ b/fs/configfs/dir.c |
713 |
-@@ -1564,7 +1564,8 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir |
714 |
+@@ -1037,10 +1037,11 @@ static int configfs_dump(struct configfs_dirent *sd, int level) |
715 |
+ static int configfs_depend_prep(struct dentry *origin, |
716 |
+ struct config_item *target) |
717 |
+ { |
718 |
+- struct configfs_dirent *child_sd, *sd = origin->d_fsdata; |
719 |
++ struct configfs_dirent *child_sd, *sd; |
720 |
+ int ret = 0; |
721 |
+ |
722 |
+- BUG_ON(!origin || !sd); |
723 |
++ BUG_ON(!origin || !origin->d_fsdata); |
724 |
++ sd = origin->d_fsdata; |
725 |
+ |
726 |
+ if (sd->s_element == target) /* Boo-yah */ |
727 |
+ goto out; |
728 |
+@@ -1564,7 +1565,8 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir |
729 |
} |
730 |
for (p=q->next; p!= &parent_sd->s_children; p=p->next) { |
731 |
struct configfs_dirent *next; |
732 |
@@ -47195,7 +47222,7 @@ index 712b10f..6b54d7b 100644 |
733 |
int len; |
734 |
struct inode *inode = NULL; |
735 |
|
736 |
-@@ -1574,7 +1575,12 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir |
737 |
+@@ -1574,7 +1576,12 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir |
738 |
continue; |
739 |
|
740 |
name = configfs_get_name(next); |
741 |
@@ -50208,7 +50235,7 @@ index a94e331..060bce3 100644 |
742 |
|
743 |
lock_flocks(); |
744 |
diff --git a/fs/namei.c b/fs/namei.c |
745 |
-index 43a97ee..ff3f601 100644 |
746 |
+index 43a97ee..117e7e4 100644 |
747 |
--- a/fs/namei.c |
748 |
+++ b/fs/namei.c |
749 |
@@ -319,16 +319,32 @@ int generic_permission(struct inode *inode, int mask) |
750 |
@@ -50574,13 +50601,13 @@ index 43a97ee..ff3f601 100644 |
751 |
} |
752 |
EXPORT_SYMBOL(user_path_create); |
753 |
|
754 |
-+static struct dentry *user_path_create_with_name(int dfd, const char __user *pathname, struct path *path, struct filename **to, int is_dir) |
755 |
++static struct dentry *user_path_create_with_name(int dfd, const char __user *pathname, struct path *path, struct filename **to, unsigned int lookup_flags) |
756 |
+{ |
757 |
+ struct filename *tmp = getname(pathname); |
758 |
+ struct dentry *res; |
759 |
+ if (IS_ERR(tmp)) |
760 |
+ return ERR_CAST(tmp); |
761 |
-+ res = kern_path_create(dfd, tmp->name, path, is_dir); |
762 |
++ res = kern_path_create(dfd, tmp->name, path, lookup_flags); |
763 |
+ if (IS_ERR(res)) |
764 |
+ putname(tmp); |
765 |
+ else |
766 |
@@ -50810,7 +50837,7 @@ index 43a97ee..ff3f601 100644 |
767 |
out: |
768 |
return len; |
769 |
diff --git a/fs/namespace.c b/fs/namespace.c |
770 |
-index 55605c5..22e9a03 100644 |
771 |
+index 55605c5..f2908c8 100644 |
772 |
--- a/fs/namespace.c |
773 |
+++ b/fs/namespace.c |
774 |
@@ -1215,6 +1215,9 @@ static int do_umount(struct mount *mnt, int flags) |
775 |
@@ -50823,7 +50850,7 @@ index 55605c5..22e9a03 100644 |
776 |
return retval; |
777 |
} |
778 |
|
779 |
-@@ -1234,6 +1237,9 @@ static int do_umount(struct mount *mnt, int flags) |
780 |
+@@ -1234,9 +1237,20 @@ static int do_umount(struct mount *mnt, int flags) |
781 |
br_write_unlock(&vfsmount_lock); |
782 |
up_write(&namespace_sem); |
783 |
release_mounts(&umount_list); |
784 |
@@ -50833,7 +50860,85 @@ index 55605c5..22e9a03 100644 |
785 |
return retval; |
786 |
} |
787 |
|
788 |
-@@ -2282,6 +2288,16 @@ long do_mount(const char *dev_name, const char *dir_name, |
789 |
++/* |
790 |
++ * Is the caller allowed to modify his namespace? |
791 |
++ */ |
792 |
++static inline bool may_mount(void) |
793 |
++{ |
794 |
++ return ns_capable(current->nsproxy->mnt_ns->user_ns, CAP_SYS_ADMIN); |
795 |
++} |
796 |
++ |
797 |
+ /* |
798 |
+ * Now umount can handle mount points as well as block devices. |
799 |
+ * This is important for filesystems which use unnamed block devices. |
800 |
+@@ -1255,6 +1269,9 @@ SYSCALL_DEFINE2(umount, char __user *, name, int, flags) |
801 |
+ if (flags & ~(MNT_FORCE | MNT_DETACH | MNT_EXPIRE | UMOUNT_NOFOLLOW)) |
802 |
+ return -EINVAL; |
803 |
+ |
804 |
++ if (!may_mount()) |
805 |
++ return -EPERM; |
806 |
++ |
807 |
+ if (!(flags & UMOUNT_NOFOLLOW)) |
808 |
+ lookup_flags |= LOOKUP_FOLLOW; |
809 |
+ |
810 |
+@@ -1268,10 +1285,6 @@ SYSCALL_DEFINE2(umount, char __user *, name, int, flags) |
811 |
+ if (!check_mnt(mnt)) |
812 |
+ goto dput_and_out; |
813 |
+ |
814 |
+- retval = -EPERM; |
815 |
+- if (!ns_capable(mnt->mnt_ns->user_ns, CAP_SYS_ADMIN)) |
816 |
+- goto dput_and_out; |
817 |
+- |
818 |
+ retval = do_umount(mnt, flags); |
819 |
+ dput_and_out: |
820 |
+ /* we mustn't call path_put() as that would clear mnt_expiry_mark */ |
821 |
+@@ -1295,7 +1308,7 @@ SYSCALL_DEFINE1(oldumount, char __user *, name) |
822 |
+ |
823 |
+ static int mount_is_safe(struct path *path) |
824 |
+ { |
825 |
+- if (ns_capable(real_mount(path->mnt)->mnt_ns->user_ns, CAP_SYS_ADMIN)) |
826 |
++ if (may_mount()) |
827 |
+ return 0; |
828 |
+ return -EPERM; |
829 |
+ #ifdef notyet |
830 |
+@@ -1633,7 +1646,7 @@ static int do_change_type(struct path *path, int flag) |
831 |
+ int type; |
832 |
+ int err = 0; |
833 |
+ |
834 |
+- if (!ns_capable(mnt->mnt_ns->user_ns, CAP_SYS_ADMIN)) |
835 |
++ if (!may_mount()) |
836 |
+ return -EPERM; |
837 |
+ |
838 |
+ if (path->dentry != path->mnt->mnt_root) |
839 |
+@@ -1797,7 +1810,7 @@ static int do_move_mount(struct path *path, const char *old_name) |
840 |
+ struct mount *p; |
841 |
+ struct mount *old; |
842 |
+ int err = 0; |
843 |
+- if (!ns_capable(real_mount(path->mnt)->mnt_ns->user_ns, CAP_SYS_ADMIN)) |
844 |
++ if (!may_mount()) |
845 |
+ return -EPERM; |
846 |
+ if (!old_name || !*old_name) |
847 |
+ return -EINVAL; |
848 |
+@@ -1933,16 +1946,14 @@ static int do_new_mount(struct path *path, const char *fstype, int flags, |
849 |
+ int mnt_flags, const char *name, void *data) |
850 |
+ { |
851 |
+ struct file_system_type *type; |
852 |
+- struct user_namespace *user_ns; |
853 |
++ struct user_namespace *user_ns = current->nsproxy->mnt_ns->user_ns; |
854 |
+ struct vfsmount *mnt; |
855 |
+ int err; |
856 |
+ |
857 |
+ if (!fstype) |
858 |
+ return -EINVAL; |
859 |
+ |
860 |
+- /* we need capabilities... */ |
861 |
+- user_ns = real_mount(path->mnt)->mnt_ns->user_ns; |
862 |
+- if (!ns_capable(user_ns, CAP_SYS_ADMIN)) |
863 |
++ if (!may_mount()) |
864 |
+ return -EPERM; |
865 |
+ |
866 |
+ type = get_fs_type(fstype); |
867 |
+@@ -2282,6 +2293,16 @@ long do_mount(const char *dev_name, const char *dir_name, |
868 |
MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT | |
869 |
MS_STRICTATIME); |
870 |
|
871 |
@@ -50850,7 +50955,7 @@ index 55605c5..22e9a03 100644 |
872 |
if (flags & MS_REMOUNT) |
873 |
retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags, |
874 |
data_page); |
875 |
-@@ -2296,6 +2312,9 @@ long do_mount(const char *dev_name, const char *dir_name, |
876 |
+@@ -2296,6 +2317,9 @@ long do_mount(const char *dev_name, const char *dir_name, |
877 |
dev_name, data_page); |
878 |
dput_out: |
879 |
path_put(&path); |
880 |
@@ -50860,7 +50965,16 @@ index 55605c5..22e9a03 100644 |
881 |
return retval; |
882 |
} |
883 |
|
884 |
-@@ -2582,6 +2601,11 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root, |
885 |
+@@ -2567,7 +2591,7 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root, |
886 |
+ struct mount *new_mnt, *root_mnt; |
887 |
+ int error; |
888 |
+ |
889 |
+- if (!ns_capable(current->nsproxy->mnt_ns->user_ns, CAP_SYS_ADMIN)) |
890 |
++ if (!may_mount()) |
891 |
+ return -EPERM; |
892 |
+ |
893 |
+ error = user_path_dir(new_root, &new); |
894 |
+@@ -2582,6 +2606,11 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root, |
895 |
if (error) |
896 |
goto out2; |
897 |
|
898 |
@@ -50872,7 +50986,7 @@ index 55605c5..22e9a03 100644 |
899 |
get_fs_root(current->fs, &root); |
900 |
error = lock_mount(&old); |
901 |
if (error) |
902 |
-@@ -2785,7 +2809,7 @@ static int mntns_install(struct nsproxy *nsproxy, void *ns) |
903 |
+@@ -2785,7 +2814,7 @@ static int mntns_install(struct nsproxy *nsproxy, void *ns) |
904 |
!nsown_capable(CAP_SYS_ADMIN)) |
905 |
return -EPERM; |
906 |
|
907 |
@@ -67595,6 +67709,42 @@ index c5d36c6..108f4f9 100644 |
908 |
|
909 |
/* |
910 |
* callback functions for platform |
911 |
+diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h |
912 |
+index b9bd2e6..4ce0093 100644 |
913 |
+--- a/include/linux/user_namespace.h |
914 |
++++ b/include/linux/user_namespace.h |
915 |
+@@ -21,7 +21,7 @@ struct user_namespace { |
916 |
+ struct uid_gid_map uid_map; |
917 |
+ struct uid_gid_map gid_map; |
918 |
+ struct uid_gid_map projid_map; |
919 |
+- struct kref kref; |
920 |
++ atomic_t count; |
921 |
+ struct user_namespace *parent; |
922 |
+ kuid_t owner; |
923 |
+ kgid_t group; |
924 |
+@@ -35,18 +35,18 @@ extern struct user_namespace init_user_ns; |
925 |
+ static inline struct user_namespace *get_user_ns(struct user_namespace *ns) |
926 |
+ { |
927 |
+ if (ns) |
928 |
+- kref_get(&ns->kref); |
929 |
++ atomic_inc(&ns->count); |
930 |
+ return ns; |
931 |
+ } |
932 |
+ |
933 |
+ extern int create_user_ns(struct cred *new); |
934 |
+ extern int unshare_userns(unsigned long unshare_flags, struct cred **new_cred); |
935 |
+-extern void free_user_ns(struct kref *kref); |
936 |
++extern void free_user_ns(struct user_namespace *ns); |
937 |
+ |
938 |
+ static inline void put_user_ns(struct user_namespace *ns) |
939 |
+ { |
940 |
+- if (ns) |
941 |
+- kref_put(&ns->kref, free_user_ns); |
942 |
++ if (ns && atomic_dec_and_test(&ns->count)) |
943 |
++ free_user_ns(ns); |
944 |
+ } |
945 |
+ |
946 |
+ struct seq_operations; |
947 |
diff --git a/include/linux/vermagic.h b/include/linux/vermagic.h |
948 |
index 6f8fbcf..8259001 100644 |
949 |
--- a/include/linux/vermagic.h |
950 |
@@ -72066,10 +72216,37 @@ index d5a258b..4271191 100644 |
951 |
|
952 |
if (pm_wakeup_pending()) { |
953 |
diff --git a/kernel/printk.c b/kernel/printk.c |
954 |
-index 267ce78..952f8a8 100644 |
955 |
+index 267ce78..2487112 100644 |
956 |
--- a/kernel/printk.c |
957 |
+++ b/kernel/printk.c |
958 |
-@@ -834,6 +834,11 @@ static int check_syslog_permissions(int type, bool from_file) |
959 |
+@@ -609,11 +609,17 @@ static unsigned int devkmsg_poll(struct file *file, poll_table *wait) |
960 |
+ return ret; |
961 |
+ } |
962 |
+ |
963 |
++static int check_syslog_permissions(int type, bool from_file); |
964 |
++ |
965 |
+ static int devkmsg_open(struct inode *inode, struct file *file) |
966 |
+ { |
967 |
+ struct devkmsg_user *user; |
968 |
+ int err; |
969 |
+ |
970 |
++ err = check_syslog_permissions(SYSLOG_ACTION_OPEN, SYSLOG_FROM_FILE); |
971 |
++ if (err) |
972 |
++ return err; |
973 |
++ |
974 |
+ /* write-only does not need any file context */ |
975 |
+ if ((file->f_flags & O_ACCMODE) == O_WRONLY) |
976 |
+ return 0; |
977 |
+@@ -822,7 +828,7 @@ static int syslog_action_restricted(int type) |
978 |
+ if (dmesg_restrict) |
979 |
+ return 1; |
980 |
+ /* Unless restricted, we allow "read all" and "get buffer size" for everybody */ |
981 |
+- return type != SYSLOG_ACTION_READ_ALL && type != SYSLOG_ACTION_SIZE_BUFFER; |
982 |
++ return type != SYSLOG_ACTION_OPEN && type != SYSLOG_ACTION_READ_ALL && type != SYSLOG_ACTION_SIZE_BUFFER; |
983 |
+ } |
984 |
+ |
985 |
+ static int check_syslog_permissions(int type, bool from_file) |
986 |
+@@ -834,6 +840,11 @@ static int check_syslog_permissions(int type, bool from_file) |
987 |
if (from_file && type != SYSLOG_ACTION_OPEN) |
988 |
return 0; |
989 |
|
990 |
@@ -73028,7 +73205,7 @@ index 26058d0..06f15dd 100644 |
991 |
.priority = CPU_PRI_MIGRATION, |
992 |
}; |
993 |
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c |
994 |
-index 81fa536..80fa821 100644 |
995 |
+index 81fa536..6ccf96a 100644 |
996 |
--- a/kernel/sched/fair.c |
997 |
+++ b/kernel/sched/fair.c |
998 |
@@ -830,7 +830,7 @@ void task_numa_fault(int node, int pages, bool migrated) |
999 |
@@ -73040,7 +73217,48 @@ index 81fa536..80fa821 100644 |
1000 |
p->mm->numa_scan_offset = 0; |
1001 |
} |
1002 |
|
1003 |
-@@ -5663,7 +5663,7 @@ static void nohz_idle_balance(int this_cpu, enum cpu_idle_type idle) { } |
1004 |
+@@ -3254,25 +3254,18 @@ find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu) |
1005 |
+ */ |
1006 |
+ static int select_idle_sibling(struct task_struct *p, int target) |
1007 |
+ { |
1008 |
+- int cpu = smp_processor_id(); |
1009 |
+- int prev_cpu = task_cpu(p); |
1010 |
+ struct sched_domain *sd; |
1011 |
+ struct sched_group *sg; |
1012 |
+- int i; |
1013 |
++ int i = task_cpu(p); |
1014 |
+ |
1015 |
+- /* |
1016 |
+- * If the task is going to be woken-up on this cpu and if it is |
1017 |
+- * already idle, then it is the right target. |
1018 |
+- */ |
1019 |
+- if (target == cpu && idle_cpu(cpu)) |
1020 |
+- return cpu; |
1021 |
++ if (idle_cpu(target)) |
1022 |
++ return target; |
1023 |
+ |
1024 |
+ /* |
1025 |
+- * If the task is going to be woken-up on the cpu where it previously |
1026 |
+- * ran and if it is currently idle, then it the right target. |
1027 |
++ * If the prevous cpu is cache affine and idle, don't be stupid. |
1028 |
+ */ |
1029 |
+- if (target == prev_cpu && idle_cpu(prev_cpu)) |
1030 |
+- return prev_cpu; |
1031 |
++ if (i != target && cpus_share_cache(i, target) && idle_cpu(i)) |
1032 |
++ return i; |
1033 |
+ |
1034 |
+ /* |
1035 |
+ * Otherwise, iterate the domains and find an elegible idle cpu. |
1036 |
+@@ -3286,7 +3279,7 @@ static int select_idle_sibling(struct task_struct *p, int target) |
1037 |
+ goto next; |
1038 |
+ |
1039 |
+ for_each_cpu(i, sched_group_cpus(sg)) { |
1040 |
+- if (!idle_cpu(i)) |
1041 |
++ if (i == target || !idle_cpu(i)) |
1042 |
+ goto next; |
1043 |
+ } |
1044 |
+ |
1045 |
+@@ -5663,7 +5656,7 @@ static void nohz_idle_balance(int this_cpu, enum cpu_idle_type idle) { } |
1046 |
* run_rebalance_domains is triggered when needed from the scheduler tick. |
1047 |
* Also triggered for nohz idle balancing (with nohz_balancing_kick set). |
1048 |
*/ |
1049 |
@@ -74508,6 +74726,58 @@ index 42ca822..cdcacc6 100644 |
1050 |
return; |
1051 |
|
1052 |
local_irq_save(flags); |
1053 |
+diff --git a/kernel/user.c b/kernel/user.c |
1054 |
+index 33acb5e..57ebfd4 100644 |
1055 |
+--- a/kernel/user.c |
1056 |
++++ b/kernel/user.c |
1057 |
+@@ -47,9 +47,7 @@ struct user_namespace init_user_ns = { |
1058 |
+ .count = 4294967295U, |
1059 |
+ }, |
1060 |
+ }, |
1061 |
+- .kref = { |
1062 |
+- .refcount = ATOMIC_INIT(3), |
1063 |
+- }, |
1064 |
++ .count = ATOMIC_INIT(3), |
1065 |
+ .owner = GLOBAL_ROOT_UID, |
1066 |
+ .group = GLOBAL_ROOT_GID, |
1067 |
+ .proc_inum = PROC_USER_INIT_INO, |
1068 |
+diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c |
1069 |
+index 2b042c4..24f8ec3 100644 |
1070 |
+--- a/kernel/user_namespace.c |
1071 |
++++ b/kernel/user_namespace.c |
1072 |
+@@ -78,7 +78,7 @@ int create_user_ns(struct cred *new) |
1073 |
+ return ret; |
1074 |
+ } |
1075 |
+ |
1076 |
+- kref_init(&ns->kref); |
1077 |
++ atomic_set(&ns->count, 1); |
1078 |
+ /* Leave the new->user_ns reference with the new user namespace. */ |
1079 |
+ ns->parent = parent_ns; |
1080 |
+ ns->owner = owner; |
1081 |
+@@ -104,15 +104,16 @@ int unshare_userns(unsigned long unshare_flags, struct cred **new_cred) |
1082 |
+ return create_user_ns(cred); |
1083 |
+ } |
1084 |
+ |
1085 |
+-void free_user_ns(struct kref *kref) |
1086 |
++void free_user_ns(struct user_namespace *ns) |
1087 |
+ { |
1088 |
+- struct user_namespace *parent, *ns = |
1089 |
+- container_of(kref, struct user_namespace, kref); |
1090 |
++ struct user_namespace *parent; |
1091 |
+ |
1092 |
+- parent = ns->parent; |
1093 |
+- proc_free_inum(ns->proc_inum); |
1094 |
+- kmem_cache_free(user_ns_cachep, ns); |
1095 |
+- put_user_ns(parent); |
1096 |
++ do { |
1097 |
++ parent = ns->parent; |
1098 |
++ proc_free_inum(ns->proc_inum); |
1099 |
++ kmem_cache_free(user_ns_cachep, ns); |
1100 |
++ ns = parent; |
1101 |
++ } while (atomic_dec_and_test(&parent->count)); |
1102 |
+ } |
1103 |
+ EXPORT_SYMBOL(free_user_ns); |
1104 |
+ |
1105 |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug |
1106 |
index 67604e5..3ebb003 100644 |
1107 |
--- a/lib/Kconfig.debug |
1108 |
@@ -77437,6 +77707,136 @@ index d1e4124..32a6988 100644 |
1109 |
vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND; |
1110 |
vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); |
1111 |
|
1112 |
+diff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c |
1113 |
+index 8a5ac8c..f5c3d96 100644 |
1114 |
+--- a/mm/mmu_notifier.c |
1115 |
++++ b/mm/mmu_notifier.c |
1116 |
+@@ -37,49 +37,51 @@ static struct srcu_struct srcu; |
1117 |
+ void __mmu_notifier_release(struct mm_struct *mm) |
1118 |
+ { |
1119 |
+ struct mmu_notifier *mn; |
1120 |
+- struct hlist_node *n; |
1121 |
+ int id; |
1122 |
+ |
1123 |
+ /* |
1124 |
+- * SRCU here will block mmu_notifier_unregister until |
1125 |
+- * ->release returns. |
1126 |
++ * srcu_read_lock() here will block synchronize_srcu() in |
1127 |
++ * mmu_notifier_unregister() until all registered |
1128 |
++ * ->release() callouts this function makes have |
1129 |
++ * returned. |
1130 |
+ */ |
1131 |
+ id = srcu_read_lock(&srcu); |
1132 |
+- hlist_for_each_entry_rcu(mn, n, &mm->mmu_notifier_mm->list, hlist) |
1133 |
+- /* |
1134 |
+- * if ->release runs before mmu_notifier_unregister it |
1135 |
+- * must be handled as it's the only way for the driver |
1136 |
+- * to flush all existing sptes and stop the driver |
1137 |
+- * from establishing any more sptes before all the |
1138 |
+- * pages in the mm are freed. |
1139 |
+- */ |
1140 |
+- if (mn->ops->release) |
1141 |
+- mn->ops->release(mn, mm); |
1142 |
+- srcu_read_unlock(&srcu, id); |
1143 |
+- |
1144 |
+ spin_lock(&mm->mmu_notifier_mm->lock); |
1145 |
+ while (unlikely(!hlist_empty(&mm->mmu_notifier_mm->list))) { |
1146 |
+ mn = hlist_entry(mm->mmu_notifier_mm->list.first, |
1147 |
+ struct mmu_notifier, |
1148 |
+ hlist); |
1149 |
++ |
1150 |
+ /* |
1151 |
+- * We arrived before mmu_notifier_unregister so |
1152 |
+- * mmu_notifier_unregister will do nothing other than |
1153 |
+- * to wait ->release to finish and |
1154 |
+- * mmu_notifier_unregister to return. |
1155 |
++ * Unlink. This will prevent mmu_notifier_unregister() |
1156 |
++ * from also making the ->release() callout. |
1157 |
+ */ |
1158 |
+ hlist_del_init_rcu(&mn->hlist); |
1159 |
++ spin_unlock(&mm->mmu_notifier_mm->lock); |
1160 |
++ |
1161 |
++ /* |
1162 |
++ * Clear sptes. (see 'release' description in mmu_notifier.h) |
1163 |
++ */ |
1164 |
++ if (mn->ops->release) |
1165 |
++ mn->ops->release(mn, mm); |
1166 |
++ |
1167 |
++ spin_lock(&mm->mmu_notifier_mm->lock); |
1168 |
+ } |
1169 |
+ spin_unlock(&mm->mmu_notifier_mm->lock); |
1170 |
+ |
1171 |
+ /* |
1172 |
+- * synchronize_srcu here prevents mmu_notifier_release to |
1173 |
+- * return to exit_mmap (which would proceed freeing all pages |
1174 |
+- * in the mm) until the ->release method returns, if it was |
1175 |
+- * invoked by mmu_notifier_unregister. |
1176 |
+- * |
1177 |
+- * The mmu_notifier_mm can't go away from under us because one |
1178 |
+- * mm_count is hold by exit_mmap. |
1179 |
++ * All callouts to ->release() which we have done are complete. |
1180 |
++ * Allow synchronize_srcu() in mmu_notifier_unregister() to complete |
1181 |
++ */ |
1182 |
++ srcu_read_unlock(&srcu, id); |
1183 |
++ |
1184 |
++ /* |
1185 |
++ * mmu_notifier_unregister() may have unlinked a notifier and may |
1186 |
++ * still be calling out to it. Additionally, other notifiers |
1187 |
++ * may have been active via vmtruncate() et. al. Block here |
1188 |
++ * to ensure that all notifier callouts for this mm have been |
1189 |
++ * completed and the sptes are really cleaned up before returning |
1190 |
++ * to exit_mmap(). |
1191 |
+ */ |
1192 |
+ synchronize_srcu(&srcu); |
1193 |
+ } |
1194 |
+@@ -294,31 +296,31 @@ void mmu_notifier_unregister(struct mmu_notifier *mn, struct mm_struct *mm) |
1195 |
+ { |
1196 |
+ BUG_ON(atomic_read(&mm->mm_count) <= 0); |
1197 |
+ |
1198 |
++ spin_lock(&mm->mmu_notifier_mm->lock); |
1199 |
+ if (!hlist_unhashed(&mn->hlist)) { |
1200 |
+- /* |
1201 |
+- * SRCU here will force exit_mmap to wait ->release to finish |
1202 |
+- * before freeing the pages. |
1203 |
+- */ |
1204 |
+ int id; |
1205 |
+ |
1206 |
++ /* |
1207 |
++ * Ensure we synchronize up with __mmu_notifier_release(). |
1208 |
++ */ |
1209 |
+ id = srcu_read_lock(&srcu); |
1210 |
+- /* |
1211 |
+- * exit_mmap will block in mmu_notifier_release to |
1212 |
+- * guarantee ->release is called before freeing the |
1213 |
+- * pages. |
1214 |
+- */ |
1215 |
+- if (mn->ops->release) |
1216 |
+- mn->ops->release(mn, mm); |
1217 |
+- srcu_read_unlock(&srcu, id); |
1218 |
+ |
1219 |
+- spin_lock(&mm->mmu_notifier_mm->lock); |
1220 |
+ hlist_del_rcu(&mn->hlist); |
1221 |
+ spin_unlock(&mm->mmu_notifier_mm->lock); |
1222 |
+- } |
1223 |
++ |
1224 |
++ if (mn->ops->release) |
1225 |
++ mn->ops->release(mn, mm); |
1226 |
++ |
1227 |
++ /* |
1228 |
++ * Allow __mmu_notifier_release() to complete. |
1229 |
++ */ |
1230 |
++ srcu_read_unlock(&srcu, id); |
1231 |
++ } else |
1232 |
++ spin_unlock(&mm->mmu_notifier_mm->lock); |
1233 |
+ |
1234 |
+ /* |
1235 |
+- * Wait any running method to finish, of course including |
1236 |
+- * ->release if it was run by mmu_notifier_relase instead of us. |
1237 |
++ * Wait for any running method to finish, including ->release() if it |
1238 |
++ * was run by __mmu_notifier_release() instead of us. |
1239 |
+ */ |
1240 |
+ synchronize_srcu(&srcu); |
1241 |
+ |
1242 |
diff --git a/mm/mprotect.c b/mm/mprotect.c |
1243 |
index 94722a4..9837984 100644 |
1244 |
--- a/mm/mprotect.c |
1245 |
@@ -78041,7 +78441,7 @@ index 2c78f8c..9e9c624 100644 |
1246 |
struct anon_vma_chain *avc; |
1247 |
struct anon_vma *anon_vma; |
1248 |
diff --git a/mm/shmem.c b/mm/shmem.c |
1249 |
-index 5dd56f6..7c51725 100644 |
1250 |
+index 5dd56f6..994b702 100644 |
1251 |
--- a/mm/shmem.c |
1252 |
+++ b/mm/shmem.c |
1253 |
@@ -31,7 +31,7 @@ |
1254 |
@@ -78090,7 +78490,31 @@ index 5dd56f6..7c51725 100644 |
1255 |
return simple_xattr_set(&info->xattrs, name, value, size, flags); |
1256 |
} |
1257 |
|
1258 |
-@@ -2556,8 +2570,7 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent) |
1259 |
+@@ -2487,6 +2501,7 @@ static int shmem_remount_fs(struct super_block *sb, int *flags, char *data) |
1260 |
+ unsigned long inodes; |
1261 |
+ int error = -EINVAL; |
1262 |
+ |
1263 |
++ config.mpol = NULL; |
1264 |
+ if (shmem_parse_options(data, &config, true)) |
1265 |
+ return error; |
1266 |
+ |
1267 |
+@@ -2511,8 +2526,13 @@ static int shmem_remount_fs(struct super_block *sb, int *flags, char *data) |
1268 |
+ sbinfo->max_inodes = config.max_inodes; |
1269 |
+ sbinfo->free_inodes = config.max_inodes - inodes; |
1270 |
+ |
1271 |
+- mpol_put(sbinfo->mpol); |
1272 |
+- sbinfo->mpol = config.mpol; /* transfers initial ref */ |
1273 |
++ /* |
1274 |
++ * Preserve previous mempolicy unless mpol remount option was specified. |
1275 |
++ */ |
1276 |
++ if (config.mpol) { |
1277 |
++ mpol_put(sbinfo->mpol); |
1278 |
++ sbinfo->mpol = config.mpol; /* transfers initial ref */ |
1279 |
++ } |
1280 |
+ out: |
1281 |
+ spin_unlock(&sbinfo->stat_lock); |
1282 |
+ return error; |
1283 |
+@@ -2556,8 +2576,7 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent) |
1284 |
int err = -ENOMEM; |
1285 |
|
1286 |
/* Round up to L1_CACHE_BYTES to resist false sharing */ |
1287 |
@@ -84936,6 +85360,19 @@ index 6ece7f2..ecdb55c 100644 |
1288 |
goto error; |
1289 |
|
1290 |
buflen -= tmp; |
1291 |
+diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c |
1292 |
+index 20e4bf5..58dfe08 100644 |
1293 |
+--- a/security/keys/process_keys.c |
1294 |
++++ b/security/keys/process_keys.c |
1295 |
+@@ -367,6 +367,8 @@ key_ref_t search_my_process_keyrings(struct key_type *type, |
1296 |
+ |
1297 |
+ switch (PTR_ERR(key_ref)) { |
1298 |
+ case -EAGAIN: /* no key */ |
1299 |
++ if (ret) |
1300 |
++ break; |
1301 |
+ case -ENOKEY: /* negative key */ |
1302 |
+ ret = key_ref; |
1303 |
+ break; |
1304 |
diff --git a/security/min_addr.c b/security/min_addr.c |
1305 |
index f728728..6457a0c 100644 |
1306 |
--- a/security/min_addr.c |