Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'work.compat' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull compat updates from Al Viro:
"Some biarch patches - getting rid of assorted (mis)uses of
compat_alloc_user_space().

Not much in that area this cycle..."

* 'work.compat' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
orangefs: simplify compat ioctl handling
signalfd: lift sigmask copyin and size checks to callers of do_signalfd4()
vmsplice(): lift importing iovec into vmsplice(2) and compat counterpart

+112 -136
+12 -42
fs/orangefs/devorangefs-req.c
··· 719 719 __s32 count; 720 720 }; 721 721 722 - static unsigned long translate_dev_map26(unsigned long args, long *error) 723 - { 724 - struct ORANGEFS_dev_map_desc32 __user *p32 = (void __user *)args; 725 - /* 726 - * Depending on the architecture, allocate some space on the 727 - * user-call-stack based on our expected layout. 728 - */ 729 - struct ORANGEFS_dev_map_desc __user *p = 730 - compat_alloc_user_space(sizeof(*p)); 731 - compat_uptr_t addr; 732 - 733 - *error = 0; 734 - /* get the ptr from the 32 bit user-space */ 735 - if (get_user(addr, &p32->ptr)) 736 - goto err; 737 - /* try to put that into a 64-bit layout */ 738 - if (put_user(compat_ptr(addr), &p->ptr)) 739 - goto err; 740 - /* copy the remaining fields */ 741 - if (copy_in_user(&p->total_size, &p32->total_size, sizeof(__s32))) 742 - goto err; 743 - if (copy_in_user(&p->size, &p32->size, sizeof(__s32))) 744 - goto err; 745 - if (copy_in_user(&p->count, &p32->count, sizeof(__s32))) 746 - goto err; 747 - return (unsigned long)p; 748 - err: 749 - *error = -EFAULT; 750 - return 0; 751 - } 752 - 753 722 /* 754 723 * 32 bit user-space apps' ioctl handlers when kernel modules 755 724 * is compiled as a 64 bit one ··· 727 758 unsigned long args) 728 759 { 729 760 long ret; 730 - unsigned long arg = args; 731 761 732 762 /* Check for properly constructed commands */ 733 763 ret = check_ioctl_command(cmd); 734 764 if (ret < 0) 735 765 return ret; 736 766 if (cmd == ORANGEFS_DEV_MAP) { 737 - /* 738 - * convert the arguments to what we expect internally 739 - * in kernel space 740 - */ 741 - arg = translate_dev_map26(args, &ret); 742 - if (ret < 0) { 743 - gossip_err("Could not translate dev map\n"); 744 - return ret; 745 - } 767 + struct ORANGEFS_dev_map_desc desc; 768 + struct ORANGEFS_dev_map_desc32 d32; 769 + 770 + if (copy_from_user(&d32, (void __user *)args, sizeof(d32))) 771 + return -EFAULT; 772 + 773 + desc.ptr = compat_ptr(d32.ptr); 774 + desc.total_size = d32.total_size; 775 + desc.size = d32.size; 776 + desc.count = d32.count; 777 + return orangefs_bufmap_initialize(&desc); 746 778 } 747 779 /* no other ioctl requires translation */ 748 - return dispatch_ioctl_command(cmd, arg); 780 + return dispatch_ioctl_command(cmd, args); 749 781 } 750 782 751 783 #endif /* CONFIG_COMPAT is in .config */
+25 -25
fs/signalfd.c
··· 259 259 .llseek = noop_llseek, 260 260 }; 261 261 262 - static int do_signalfd4(int ufd, sigset_t __user *user_mask, size_t sizemask, 263 - int flags) 262 + static int do_signalfd4(int ufd, sigset_t *mask, int flags) 264 263 { 265 - sigset_t sigmask; 266 264 struct signalfd_ctx *ctx; 267 265 268 266 /* Check the SFD_* constants for consistency. */ ··· 270 272 if (flags & ~(SFD_CLOEXEC | SFD_NONBLOCK)) 271 273 return -EINVAL; 272 274 273 - if (sizemask != sizeof(sigset_t) || 274 - copy_from_user(&sigmask, user_mask, sizeof(sigmask))) 275 - return -EINVAL; 276 - sigdelsetmask(&sigmask, sigmask(SIGKILL) | sigmask(SIGSTOP)); 277 - signotset(&sigmask); 275 + sigdelsetmask(mask, sigmask(SIGKILL) | sigmask(SIGSTOP)); 276 + signotset(mask); 278 277 279 278 if (ufd == -1) { 280 279 ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); 281 280 if (!ctx) 282 281 return -ENOMEM; 283 282 284 - ctx->sigmask = sigmask; 283 + ctx->sigmask = *mask; 285 284 286 285 /* 287 286 * When we call this, the initialization must be complete, since ··· 298 303 return -EINVAL; 299 304 } 300 305 spin_lock_irq(&current->sighand->siglock); 301 - ctx->sigmask = sigmask; 306 + ctx->sigmask = *mask; 302 307 spin_unlock_irq(&current->sighand->siglock); 303 308 304 309 wake_up(&current->sighand->signalfd_wqh); ··· 311 316 SYSCALL_DEFINE4(signalfd4, int, ufd, sigset_t __user *, user_mask, 312 317 size_t, sizemask, int, flags) 313 318 { 314 - return do_signalfd4(ufd, user_mask, sizemask, flags); 319 + sigset_t mask; 320 + 321 + if (sizemask != sizeof(sigset_t) || 322 + copy_from_user(&mask, user_mask, sizeof(mask))) 323 + return -EINVAL; 324 + return do_signalfd4(ufd, &mask, flags); 315 325 } 316 326 317 327 SYSCALL_DEFINE3(signalfd, int, ufd, sigset_t __user *, user_mask, 318 328 size_t, sizemask) 319 329 { 320 - return do_signalfd4(ufd, user_mask, sizemask, 0); 330 + sigset_t mask; 331 + 332 + if (sizemask != sizeof(sigset_t) || 333 + copy_from_user(&mask, user_mask, sizeof(mask))) 334 + return -EINVAL; 335 + return do_signalfd4(ufd, &mask, 0); 321 336 } 322 337 323 338 #ifdef CONFIG_COMPAT 324 339 static long do_compat_signalfd4(int ufd, 325 - const compat_sigset_t __user *sigmask, 340 + const compat_sigset_t __user *user_mask, 326 341 compat_size_t sigsetsize, int flags) 327 342 { 328 - sigset_t tmp; 329 - sigset_t __user *ksigmask; 343 + sigset_t mask; 330 344 331 345 if (sigsetsize != sizeof(compat_sigset_t)) 332 346 return -EINVAL; 333 - if (get_compat_sigset(&tmp, sigmask)) 347 + if (get_compat_sigset(&mask, user_mask)) 334 348 return -EFAULT; 335 - ksigmask = compat_alloc_user_space(sizeof(sigset_t)); 336 - if (copy_to_user(ksigmask, &tmp, sizeof(sigset_t))) 337 - return -EFAULT; 338 - 339 - return do_signalfd4(ufd, ksigmask, sizeof(sigset_t), flags); 349 + return do_signalfd4(ufd, &mask, flags); 340 350 } 341 351 342 352 COMPAT_SYSCALL_DEFINE4(signalfd4, int, ufd, 343 - const compat_sigset_t __user *, sigmask, 353 + const compat_sigset_t __user *, user_mask, 344 354 compat_size_t, sigsetsize, 345 355 int, flags) 346 356 { 347 - return do_compat_signalfd4(ufd, sigmask, sigsetsize, flags); 357 + return do_compat_signalfd4(ufd, user_mask, sigsetsize, flags); 348 358 } 349 359 350 360 COMPAT_SYSCALL_DEFINE3(signalfd, int, ufd, 351 - const compat_sigset_t __user *,sigmask, 361 + const compat_sigset_t __user *, user_mask, 352 362 compat_size_t, sigsetsize) 353 363 { 354 - return do_compat_signalfd4(ufd, sigmask, sigsetsize, 0); 364 + return do_compat_signalfd4(ufd, user_mask, sigsetsize, 0); 355 365 } 356 366 #endif
+75 -69
fs/splice.c
··· 1243 1243 * For lack of a better implementation, implement vmsplice() to userspace 1244 1244 * as a simple copy of the pipes pages to the user iov. 1245 1245 */ 1246 - static long vmsplice_to_user(struct file *file, const struct iovec __user *uiov, 1247 - unsigned long nr_segs, unsigned int flags) 1246 + static long vmsplice_to_user(struct file *file, struct iov_iter *iter, 1247 + unsigned int flags) 1248 1248 { 1249 - struct pipe_inode_info *pipe; 1250 - struct splice_desc sd; 1251 - long ret; 1252 - struct iovec iovstack[UIO_FASTIOV]; 1253 - struct iovec *iov = iovstack; 1254 - struct iov_iter iter; 1249 + struct pipe_inode_info *pipe = get_pipe_info(file); 1250 + struct splice_desc sd = { 1251 + .total_len = iov_iter_count(iter), 1252 + .flags = flags, 1253 + .u.data = iter 1254 + }; 1255 + long ret = 0; 1255 1256 1256 - pipe = get_pipe_info(file); 1257 1257 if (!pipe) 1258 1258 return -EBADF; 1259 - 1260 - ret = import_iovec(READ, uiov, nr_segs, 1261 - ARRAY_SIZE(iovstack), &iov, &iter); 1262 - if (ret < 0) 1263 - return ret; 1264 - 1265 - sd.total_len = iov_iter_count(&iter); 1266 - sd.len = 0; 1267 - sd.flags = flags; 1268 - sd.u.data = &iter; 1269 - sd.pos = 0; 1270 1259 1271 1260 if (sd.total_len) { 1272 1261 pipe_lock(pipe); ··· 1263 1274 pipe_unlock(pipe); 1264 1275 } 1265 1276 1266 - kfree(iov); 1267 1277 return ret; 1268 1278 } 1269 1279 ··· 1271 1283 * as splice-from-memory, where the regular splice is splice-from-file (or 1272 1284 * to file). In both cases the output is a pipe, naturally. 1273 1285 */ 1274 - static long vmsplice_to_pipe(struct file *file, const struct iovec __user *uiov, 1275 - unsigned long nr_segs, unsigned int flags) 1286 + static long vmsplice_to_pipe(struct file *file, struct iov_iter *iter, 1287 + unsigned int flags) 1276 1288 { 1277 1289 struct pipe_inode_info *pipe; 1278 - struct iovec iovstack[UIO_FASTIOV]; 1279 - struct iovec *iov = iovstack; 1280 - struct iov_iter from; 1281 - long ret; 1290 + long ret = 0; 1282 1291 unsigned buf_flag = 0; 1283 1292 1284 1293 if (flags & SPLICE_F_GIFT) ··· 1285 1300 if (!pipe) 1286 1301 return -EBADF; 1287 1302 1288 - ret = import_iovec(WRITE, uiov, nr_segs, 1289 - ARRAY_SIZE(iovstack), &iov, &from); 1290 - if (ret < 0) 1291 - return ret; 1292 - 1293 1303 pipe_lock(pipe); 1294 1304 ret = wait_for_space(pipe, flags); 1295 1305 if (!ret) 1296 - ret = iter_to_pipe(&from, pipe, buf_flag); 1306 + ret = iter_to_pipe(iter, pipe, buf_flag); 1297 1307 pipe_unlock(pipe); 1298 1308 if (ret > 0) 1299 1309 wakeup_pipe_readers(pipe); 1300 - kfree(iov); 1301 1310 return ret; 1311 + } 1312 + 1313 + static int vmsplice_type(struct fd f, int *type) 1314 + { 1315 + if (!f.file) 1316 + return -EBADF; 1317 + if (f.file->f_mode & FMODE_WRITE) { 1318 + *type = WRITE; 1319 + } else if (f.file->f_mode & FMODE_READ) { 1320 + *type = READ; 1321 + } else { 1322 + fdput(f); 1323 + return -EBADF; 1324 + } 1325 + return 0; 1302 1326 } 1303 1327 1304 1328 /* ··· 1326 1332 * Currently we punt and implement it as a normal copy, see pipe_to_user(). 1327 1333 * 1328 1334 */ 1329 - static long do_vmsplice(int fd, const struct iovec __user *iov, 1330 - unsigned long nr_segs, unsigned int flags) 1335 + static long do_vmsplice(struct file *f, struct iov_iter *iter, unsigned int flags) 1331 1336 { 1332 - struct fd f; 1333 - long error; 1334 - 1335 1337 if (unlikely(flags & ~SPLICE_F_ALL)) 1336 1338 return -EINVAL; 1337 - if (unlikely(nr_segs > UIO_MAXIOV)) 1338 - return -EINVAL; 1339 - else if (unlikely(!nr_segs)) 1339 + 1340 + if (!iov_iter_count(iter)) 1340 1341 return 0; 1341 1342 1342 - error = -EBADF; 1343 - f = fdget(fd); 1344 - if (f.file) { 1345 - if (f.file->f_mode & FMODE_WRITE) 1346 - error = vmsplice_to_pipe(f.file, iov, nr_segs, flags); 1347 - else if (f.file->f_mode & FMODE_READ) 1348 - error = vmsplice_to_user(f.file, iov, nr_segs, flags); 1349 - 1350 - fdput(f); 1351 - } 1352 - 1353 - return error; 1343 + if (iov_iter_rw(iter) == WRITE) 1344 + return vmsplice_to_pipe(f, iter, flags); 1345 + else 1346 + return vmsplice_to_user(f, iter, flags); 1354 1347 } 1355 1348 1356 - SYSCALL_DEFINE4(vmsplice, int, fd, const struct iovec __user *, iov, 1349 + SYSCALL_DEFINE4(vmsplice, int, fd, const struct iovec __user *, uiov, 1357 1350 unsigned long, nr_segs, unsigned int, flags) 1358 1351 { 1359 - return do_vmsplice(fd, iov, nr_segs, flags); 1352 + struct iovec iovstack[UIO_FASTIOV]; 1353 + struct iovec *iov = iovstack; 1354 + struct iov_iter iter; 1355 + long error; 1356 + struct fd f; 1357 + int type; 1358 + 1359 + f = fdget(fd); 1360 + error = vmsplice_type(f, &type); 1361 + if (error) 1362 + return error; 1363 + 1364 + error = import_iovec(type, uiov, nr_segs, 1365 + ARRAY_SIZE(iovstack), &iov, &iter); 1366 + if (!error) { 1367 + error = do_vmsplice(f.file, &iter, flags); 1368 + kfree(iov); 1369 + } 1370 + fdput(f); 1371 + return error; 1360 1372 } 1361 1373 1362 1374 #ifdef CONFIG_COMPAT 1363 1375 COMPAT_SYSCALL_DEFINE4(vmsplice, int, fd, const struct compat_iovec __user *, iov32, 1364 1376 unsigned int, nr_segs, unsigned int, flags) 1365 1377 { 1366 - unsigned i; 1367 - struct iovec __user *iov; 1368 - if (nr_segs > UIO_MAXIOV) 1369 - return -EINVAL; 1370 - iov = compat_alloc_user_space(nr_segs * sizeof(struct iovec)); 1371 - for (i = 0; i < nr_segs; i++) { 1372 - struct compat_iovec v; 1373 - if (get_user(v.iov_base, &iov32[i].iov_base) || 1374 - get_user(v.iov_len, &iov32[i].iov_len) || 1375 - put_user(compat_ptr(v.iov_base), &iov[i].iov_base) || 1376 - put_user(v.iov_len, &iov[i].iov_len)) 1377 - return -EFAULT; 1378 + struct iovec iovstack[UIO_FASTIOV]; 1379 + struct iovec *iov = iovstack; 1380 + struct iov_iter iter; 1381 + long error; 1382 + struct fd f; 1383 + int type; 1384 + 1385 + f = fdget(fd); 1386 + error = vmsplice_type(f, &type); 1387 + if (error) 1388 + return error; 1389 + 1390 + error = compat_import_iovec(type, iov32, nr_segs, 1391 + ARRAY_SIZE(iovstack), &iov, &iter); 1392 + if (!error) { 1393 + error = do_vmsplice(f.file, &iter, flags); 1394 + kfree(iov); 1378 1395 } 1379 - return do_vmsplice(fd, iov, nr_segs, flags); 1396 + fdput(f); 1397 + return error; 1380 1398 } 1381 1399 #endif 1382 1400