aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-08-24 12:25:39 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-08-24 12:25:39 -0400
commit4def1963608ed2b61aca5b52fdedb4ca2798820c (patch)
tree83b36e8ff3c5eabe0d235f863adcf54f838f838a /kernel
parent5e8704ac1cfa9fceef94fcc457e18613b1589b34 (diff)
parent82c9a927bc5df6e06b72d206d24a9d10cced4eb5 (diff)
Merge branch 'userns-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace
Pull namespace fixes from Eric Biederman: "This is a set of four fairly obvious bug fixes: - a switch from d_find_alias to d_find_any_alias because the xattr code perversely takes a dentry - two mutex vs copy_to_user fixes from Jann Horn - a fix to use a sanitized size not the size userspace passed in from Christian Brauner" * 'userns-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace: getxattr: use correct xattr length sys: don't hold uts_sem while accessing userspace memory userns: move user access out of the mutex cap_inode_getsecurity: use d_find_any_alias() instead of d_find_alias()
Diffstat (limited to 'kernel')
-rw-r--r--kernel/sys.c95
-rw-r--r--kernel/user_namespace.c24
-rw-r--r--kernel/utsname_sysctl.c41
3 files changed, 80 insertions, 80 deletions
diff --git a/kernel/sys.c b/kernel/sys.c
index e27b51d3facd..cf5c67533ff1 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1237,18 +1237,19 @@ static int override_release(char __user *release, size_t len)
1237 1237
1238SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name) 1238SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name)
1239{ 1239{
1240 int errno = 0; 1240 struct new_utsname tmp;
1241 1241
1242 down_read(&uts_sem); 1242 down_read(&uts_sem);
1243 if (copy_to_user(name, utsname(), sizeof *name)) 1243 memcpy(&tmp, utsname(), sizeof(tmp));
1244 errno = -EFAULT;
1245 up_read(&uts_sem); 1244 up_read(&uts_sem);
1245 if (copy_to_user(name, &tmp, sizeof(tmp)))
1246 return -EFAULT;
1246 1247
1247 if (!errno && override_release(name->release, sizeof(name->release))) 1248 if (override_release(name->release, sizeof(name->release)))
1248 errno = -EFAULT; 1249 return -EFAULT;
1249 if (!errno && override_architecture(name)) 1250 if (override_architecture(name))
1250 errno = -EFAULT; 1251 return -EFAULT;
1251 return errno; 1252 return 0;
1252} 1253}
1253 1254
1254#ifdef __ARCH_WANT_SYS_OLD_UNAME 1255#ifdef __ARCH_WANT_SYS_OLD_UNAME
@@ -1257,55 +1258,46 @@ SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name)
1257 */ 1258 */
1258SYSCALL_DEFINE1(uname, struct old_utsname __user *, name) 1259SYSCALL_DEFINE1(uname, struct old_utsname __user *, name)
1259{ 1260{
1260 int error = 0; 1261 struct old_utsname tmp;
1261 1262
1262 if (!name) 1263 if (!name)
1263 return -EFAULT; 1264 return -EFAULT;
1264 1265
1265 down_read(&uts_sem); 1266 down_read(&uts_sem);
1266 if (copy_to_user(name, utsname(), sizeof(*name))) 1267 memcpy(&tmp, utsname(), sizeof(tmp));
1267 error = -EFAULT;
1268 up_read(&uts_sem); 1268 up_read(&uts_sem);
1269 if (copy_to_user(name, &tmp, sizeof(tmp)))
1270 return -EFAULT;
1269 1271
1270 if (!error && override_release(name->release, sizeof(name->release))) 1272 if (override_release(name->release, sizeof(name->release)))
1271 error = -EFAULT; 1273 return -EFAULT;
1272 if (!error && override_architecture(name)) 1274 if (override_architecture(name))
1273 error = -EFAULT; 1275 return -EFAULT;
1274 return error; 1276 return 0;
1275} 1277}
1276 1278
1277SYSCALL_DEFINE1(olduname, struct oldold_utsname __user *, name) 1279SYSCALL_DEFINE1(olduname, struct oldold_utsname __user *, name)
1278{ 1280{
1279 int error; 1281 struct oldold_utsname tmp = {};
1280 1282
1281 if (!name) 1283 if (!name)
1282 return -EFAULT; 1284 return -EFAULT;
1283 if (!access_ok(VERIFY_WRITE, name, sizeof(struct oldold_utsname)))
1284 return -EFAULT;
1285 1285
1286 down_read(&uts_sem); 1286 down_read(&uts_sem);
1287 error = __copy_to_user(&name->sysname, &utsname()->sysname, 1287 memcpy(&tmp.sysname, &utsname()->sysname, __OLD_UTS_LEN);
1288 __OLD_UTS_LEN); 1288 memcpy(&tmp.nodename, &utsname()->nodename, __OLD_UTS_LEN);
1289 error |= __put_user(0, name->sysname + __OLD_UTS_LEN); 1289 memcpy(&tmp.release, &utsname()->release, __OLD_UTS_LEN);
1290 error |= __copy_to_user(&name->nodename, &utsname()->nodename, 1290 memcpy(&tmp.version, &utsname()->version, __OLD_UTS_LEN);
1291 __OLD_UTS_LEN); 1291 memcpy(&tmp.machine, &utsname()->machine, __OLD_UTS_LEN);
1292 error |= __put_user(0, name->nodename + __OLD_UTS_LEN);
1293 error |= __copy_to_user(&name->release, &utsname()->release,
1294 __OLD_UTS_LEN);
1295 error |= __put_user(0, name->release + __OLD_UTS_LEN);
1296 error |= __copy_to_user(&name->version, &utsname()->version,
1297 __OLD_UTS_LEN);
1298 error |= __put_user(0, name->version + __OLD_UTS_LEN);
1299 error |= __copy_to_user(&name->machine, &utsname()->machine,
1300 __OLD_UTS_LEN);
1301 error |= __put_user(0, name->machine + __OLD_UTS_LEN);
1302 up_read(&uts_sem); 1292 up_read(&uts_sem);
1293 if (copy_to_user(name, &tmp, sizeof(tmp)))
1294 return -EFAULT;
1303 1295
1304 if (!error && override_architecture(name)) 1296 if (override_architecture(name))
1305 error = -EFAULT; 1297 return -EFAULT;
1306 if (!error && override_release(name->release, sizeof(name->release))) 1298 if (override_release(name->release, sizeof(name->release)))
1307 error = -EFAULT; 1299 return -EFAULT;
1308 return error ? -EFAULT : 0; 1300 return 0;
1309} 1301}
1310#endif 1302#endif
1311 1303
@@ -1319,17 +1311,18 @@ SYSCALL_DEFINE2(sethostname, char __user *, name, int, len)
1319 1311
1320 if (len < 0 || len > __NEW_UTS_LEN) 1312 if (len < 0 || len > __NEW_UTS_LEN)
1321 return -EINVAL; 1313 return -EINVAL;
1322 down_write(&uts_sem);
1323 errno = -EFAULT; 1314 errno = -EFAULT;
1324 if (!copy_from_user(tmp, name, len)) { 1315 if (!copy_from_user(tmp, name, len)) {
1325 struct new_utsname *u = utsname(); 1316 struct new_utsname *u;
1326 1317
1318 down_write(&uts_sem);
1319 u = utsname();
1327 memcpy(u->nodename, tmp, len); 1320 memcpy(u->nodename, tmp, len);
1328 memset(u->nodename + len, 0, sizeof(u->nodename) - len); 1321 memset(u->nodename + len, 0, sizeof(u->nodename) - len);
1329 errno = 0; 1322 errno = 0;
1330 uts_proc_notify(UTS_PROC_HOSTNAME); 1323 uts_proc_notify(UTS_PROC_HOSTNAME);
1324 up_write(&uts_sem);
1331 } 1325 }
1332 up_write(&uts_sem);
1333 return errno; 1326 return errno;
1334} 1327}
1335 1328
@@ -1337,8 +1330,9 @@ SYSCALL_DEFINE2(sethostname, char __user *, name, int, len)
1337 1330
1338SYSCALL_DEFINE2(gethostname, char __user *, name, int, len) 1331SYSCALL_DEFINE2(gethostname, char __user *, name, int, len)
1339{ 1332{
1340 int i, errno; 1333 int i;
1341 struct new_utsname *u; 1334 struct new_utsname *u;
1335 char tmp[__NEW_UTS_LEN + 1];
1342 1336
1343 if (len < 0) 1337 if (len < 0)
1344 return -EINVAL; 1338 return -EINVAL;
@@ -1347,11 +1341,11 @@ SYSCALL_DEFINE2(gethostname, char __user *, name, int, len)
1347 i = 1 + strlen(u->nodename); 1341 i = 1 + strlen(u->nodename);
1348 if (i > len) 1342 if (i > len)
1349 i = len; 1343 i = len;
1350 errno = 0; 1344 memcpy(tmp, u->nodename, i);
1351 if (copy_to_user(name, u->nodename, i))
1352 errno = -EFAULT;
1353 up_read(&uts_sem); 1345 up_read(&uts_sem);
1354 return errno; 1346 if (copy_to_user(name, tmp, i))
1347 return -EFAULT;
1348 return 0;
1355} 1349}
1356 1350
1357#endif 1351#endif
@@ -1370,17 +1364,18 @@ SYSCALL_DEFINE2(setdomainname, char __user *, name, int, len)
1370 if (len < 0 || len > __NEW_UTS_LEN) 1364 if (len < 0 || len > __NEW_UTS_LEN)
1371 return -EINVAL; 1365 return -EINVAL;
1372 1366
1373 down_write(&uts_sem);
1374 errno = -EFAULT; 1367 errno = -EFAULT;
1375 if (!copy_from_user(tmp, name, len)) { 1368 if (!copy_from_user(tmp, name, len)) {
1376 struct new_utsname *u = utsname(); 1369 struct new_utsname *u;
1377 1370
1371 down_write(&uts_sem);
1372 u = utsname();
1378 memcpy(u->domainname, tmp, len); 1373 memcpy(u->domainname, tmp, len);
1379 memset(u->domainname + len, 0, sizeof(u->domainname) - len); 1374 memset(u->domainname + len, 0, sizeof(u->domainname) - len);
1380 errno = 0; 1375 errno = 0;
1381 uts_proc_notify(UTS_PROC_DOMAINNAME); 1376 uts_proc_notify(UTS_PROC_DOMAINNAME);
1377 up_write(&uts_sem);
1382 } 1378 }
1383 up_write(&uts_sem);
1384 return errno; 1379 return errno;
1385} 1380}
1386 1381
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index c3d7583fcd21..e5222b5fb4fe 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -859,7 +859,16 @@ static ssize_t map_write(struct file *file, const char __user *buf,
859 unsigned idx; 859 unsigned idx;
860 struct uid_gid_extent extent; 860 struct uid_gid_extent extent;
861 char *kbuf = NULL, *pos, *next_line; 861 char *kbuf = NULL, *pos, *next_line;
862 ssize_t ret = -EINVAL; 862 ssize_t ret;
863
864 /* Only allow < page size writes at the beginning of the file */
865 if ((*ppos != 0) || (count >= PAGE_SIZE))
866 return -EINVAL;
867
868 /* Slurp in the user data */
869 kbuf = memdup_user_nul(buf, count);
870 if (IS_ERR(kbuf))
871 return PTR_ERR(kbuf);
863 872
864 /* 873 /*
865 * The userns_state_mutex serializes all writes to any given map. 874 * The userns_state_mutex serializes all writes to any given map.
@@ -895,19 +904,6 @@ static ssize_t map_write(struct file *file, const char __user *buf,
895 if (cap_valid(cap_setid) && !file_ns_capable(file, ns, CAP_SYS_ADMIN)) 904 if (cap_valid(cap_setid) && !file_ns_capable(file, ns, CAP_SYS_ADMIN))
896 goto out; 905 goto out;
897 906
898 /* Only allow < page size writes at the beginning of the file */
899 ret = -EINVAL;
900 if ((*ppos != 0) || (count >= PAGE_SIZE))
901 goto out;
902
903 /* Slurp in the user data */
904 kbuf = memdup_user_nul(buf, count);
905 if (IS_ERR(kbuf)) {
906 ret = PTR_ERR(kbuf);
907 kbuf = NULL;
908 goto out;
909 }
910
911 /* Parse the user data */ 907 /* Parse the user data */
912 ret = -EINVAL; 908 ret = -EINVAL;
913 pos = kbuf; 909 pos = kbuf;
diff --git a/kernel/utsname_sysctl.c b/kernel/utsname_sysctl.c
index 233cd8fc6910..258033d62cb3 100644
--- a/kernel/utsname_sysctl.c
+++ b/kernel/utsname_sysctl.c
@@ -18,7 +18,7 @@
18 18
19#ifdef CONFIG_PROC_SYSCTL 19#ifdef CONFIG_PROC_SYSCTL
20 20
21static void *get_uts(struct ctl_table *table, int write) 21static void *get_uts(struct ctl_table *table)
22{ 22{
23 char *which = table->data; 23 char *which = table->data;
24 struct uts_namespace *uts_ns; 24 struct uts_namespace *uts_ns;
@@ -26,21 +26,9 @@ static void *get_uts(struct ctl_table *table, int write)
26 uts_ns = current->nsproxy->uts_ns; 26 uts_ns = current->nsproxy->uts_ns;
27 which = (which - (char *)&init_uts_ns) + (char *)uts_ns; 27 which = (which - (char *)&init_uts_ns) + (char *)uts_ns;
28 28
29 if (!write)
30 down_read(&uts_sem);
31 else
32 down_write(&uts_sem);
33 return which; 29 return which;
34} 30}
35 31
36static void put_uts(struct ctl_table *table, int write, void *which)
37{
38 if (!write)
39 up_read(&uts_sem);
40 else
41 up_write(&uts_sem);
42}
43
44/* 32/*
45 * Special case of dostring for the UTS structure. This has locks 33 * Special case of dostring for the UTS structure. This has locks
46 * to observe. Should this be in kernel/sys.c ???? 34 * to observe. Should this be in kernel/sys.c ????
@@ -50,13 +38,34 @@ static int proc_do_uts_string(struct ctl_table *table, int write,
50{ 38{
51 struct ctl_table uts_table; 39 struct ctl_table uts_table;
52 int r; 40 int r;
41 char tmp_data[__NEW_UTS_LEN + 1];
42
53 memcpy(&uts_table, table, sizeof(uts_table)); 43 memcpy(&uts_table, table, sizeof(uts_table));
54 uts_table.data = get_uts(table, write); 44 uts_table.data = tmp_data;
45
46 /*
47 * Buffer the value in tmp_data so that proc_dostring() can be called
48 * without holding any locks.
49 * We also need to read the original value in the write==1 case to
50 * support partial writes.
51 */
52 down_read(&uts_sem);
53 memcpy(tmp_data, get_uts(table), sizeof(tmp_data));
54 up_read(&uts_sem);
55 r = proc_dostring(&uts_table, write, buffer, lenp, ppos); 55 r = proc_dostring(&uts_table, write, buffer, lenp, ppos);
56 put_uts(table, write, uts_table.data);
57 56
58 if (write) 57 if (write) {
58 /*
59 * Write back the new value.
60 * Note that, since we dropped uts_sem, the result can
61 * theoretically be incorrect if there are two parallel writes
62 * at non-zero offsets to the same sysctl.
63 */
64 down_write(&uts_sem);
65 memcpy(get_uts(table), tmp_data, sizeof(tmp_data));
66 up_write(&uts_sem);
59 proc_sys_poll_notify(table->poll); 67 proc_sys_poll_notify(table->poll);
68 }
60 69
61 return r; 70 return r;
62} 71}