summaryrefslogtreecommitdiffstats
path: root/kernel/sys.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sys.c')
-rw-r--r--kernel/sys.c95
1 files changed, 45 insertions, 50 deletions
diff --git a/kernel/sys.c b/kernel/sys.c
index 38509dc1f77b..69b9a37ecf0d 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