diff options
Diffstat (limited to 'kernel/sys.c')
-rw-r--r-- | kernel/sys.c | 95 |
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 | ||
1238 | SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name) | 1238 | SYSCALL_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 | */ |
1258 | SYSCALL_DEFINE1(uname, struct old_utsname __user *, name) | 1259 | SYSCALL_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 | ||
1277 | SYSCALL_DEFINE1(olduname, struct oldold_utsname __user *, name) | 1279 | SYSCALL_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 | ||
1338 | SYSCALL_DEFINE2(gethostname, char __user *, name, int, len) | 1331 | SYSCALL_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 | ||