diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-13 18:58:36 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-13 18:58:36 -0800 |
| commit | a66b4cd1e7163adb327838a3c81faaf6a9330d5a (patch) | |
| tree | 2b123a010bb0f1566ff6f34e529f01ddf10ee308 /ipc | |
| parent | b16528466786a540cb00148acb124e0149d62710 (diff) | |
| parent | 5f336e722cc961be94d264d96b90c92888fffae1 (diff) | |
| download | linux-stable-a66b4cd1e7163adb327838a3c81faaf6a9330d5a.tar.gz linux-stable-a66b4cd1e7163adb327838a3c81faaf6a9330d5a.tar.bz2 linux-stable-a66b4cd1e7163adb327838a3c81faaf6a9330d5a.tar.xz linux-stable-a66b4cd1e7163adb327838a3c81faaf6a9330d5a.zip | |
Merge branch 'work.open3' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs open-related updates from Al Viro:
- "do we need fput() or put_filp()" rules are gone - it's always fput()
now. We keep track of that state where it belongs - in ->f_mode.
- int *opened mess killed - in finish_open(), in ->atomic_open()
instances and in fs/namei.c code around do_last()/lookup_open()/atomic_open().
- alloc_file() wrappers with saner calling conventions are introduced
(alloc_file_clone() and alloc_file_pseudo()); callers converted, with
much simplification.
- while we are at it, saner calling conventions for path_init() and
link_path_walk(), simplifying things inside fs/namei.c (both on
open-related paths and elsewhere).
* 'work.open3' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (40 commits)
few more cleanups of link_path_walk() callers
allow link_path_walk() to take ERR_PTR()
make path_init() unconditionally paired with terminate_walk()
document alloc_file() changes
make alloc_file() static
do_shmat(): grab shp->shm_file earlier, switch to alloc_file_clone()
new helper: alloc_file_clone()
create_pipe_files(): switch the first allocation to alloc_file_pseudo()
anon_inode_getfile(): switch to alloc_file_pseudo()
hugetlb_file_setup(): switch to alloc_file_pseudo()
ocxlflash_getfile(): switch to alloc_file_pseudo()
cxl_getfile(): switch to alloc_file_pseudo()
... and switch shmem_file_setup() to alloc_file_pseudo()
__shmem_file_setup(): reorder allocations
new wrapper: alloc_file_pseudo()
kill FILE_{CREATED,OPENED}
switch atomic_open() and lookup_open() to returning 0 in all success cases
document ->atomic_open() changes
->atomic_open(): return 0 in all success cases
get rid of 'opened' in path_openat() and the helpers downstream
...
Diffstat (limited to 'ipc')
| -rw-r--r-- | ipc/shm.c | 45 |
1 files changed, 21 insertions, 24 deletions
| @@ -1366,15 +1366,14 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, | |||
| 1366 | struct shmid_kernel *shp; | 1366 | struct shmid_kernel *shp; |
| 1367 | unsigned long addr = (unsigned long)shmaddr; | 1367 | unsigned long addr = (unsigned long)shmaddr; |
| 1368 | unsigned long size; | 1368 | unsigned long size; |
| 1369 | struct file *file; | 1369 | struct file *file, *base; |
| 1370 | int err; | 1370 | int err; |
| 1371 | unsigned long flags = MAP_SHARED; | 1371 | unsigned long flags = MAP_SHARED; |
| 1372 | unsigned long prot; | 1372 | unsigned long prot; |
| 1373 | int acc_mode; | 1373 | int acc_mode; |
| 1374 | struct ipc_namespace *ns; | 1374 | struct ipc_namespace *ns; |
| 1375 | struct shm_file_data *sfd; | 1375 | struct shm_file_data *sfd; |
| 1376 | struct path path; | 1376 | int f_flags; |
| 1377 | fmode_t f_mode; | ||
| 1378 | unsigned long populate = 0; | 1377 | unsigned long populate = 0; |
| 1379 | 1378 | ||
| 1380 | err = -EINVAL; | 1379 | err = -EINVAL; |
| @@ -1407,11 +1406,11 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, | |||
| 1407 | if (shmflg & SHM_RDONLY) { | 1406 | if (shmflg & SHM_RDONLY) { |
| 1408 | prot = PROT_READ; | 1407 | prot = PROT_READ; |
| 1409 | acc_mode = S_IRUGO; | 1408 | acc_mode = S_IRUGO; |
| 1410 | f_mode = FMODE_READ; | 1409 | f_flags = O_RDONLY; |
| 1411 | } else { | 1410 | } else { |
| 1412 | prot = PROT_READ | PROT_WRITE; | 1411 | prot = PROT_READ | PROT_WRITE; |
| 1413 | acc_mode = S_IRUGO | S_IWUGO; | 1412 | acc_mode = S_IRUGO | S_IWUGO; |
| 1414 | f_mode = FMODE_READ | FMODE_WRITE; | 1413 | f_flags = O_RDWR; |
| 1415 | } | 1414 | } |
| 1416 | if (shmflg & SHM_EXEC) { | 1415 | if (shmflg & SHM_EXEC) { |
| 1417 | prot |= PROT_EXEC; | 1416 | prot |= PROT_EXEC; |
| @@ -1447,46 +1446,44 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, | |||
| 1447 | goto out_unlock; | 1446 | goto out_unlock; |
| 1448 | } | 1447 | } |
| 1449 | 1448 | ||
| 1450 | path = shp->shm_file->f_path; | 1449 | /* |
| 1451 | path_get(&path); | 1450 | * We need to take a reference to the real shm file to prevent the |
| 1451 | * pointer from becoming stale in cases where the lifetime of the outer | ||
| 1452 | * file extends beyond that of the shm segment. It's not usually | ||
| 1453 | * possible, but it can happen during remap_file_pages() emulation as | ||
| 1454 | * that unmaps the memory, then does ->mmap() via file reference only. | ||
| 1455 | * We'll deny the ->mmap() if the shm segment was since removed, but to | ||
| 1456 | * detect shm ID reuse we need to compare the file pointers. | ||
| 1457 | */ | ||
| 1458 | base = get_file(shp->shm_file); | ||
| 1452 | shp->shm_nattch++; | 1459 | shp->shm_nattch++; |
| 1453 | size = i_size_read(d_inode(path.dentry)); | 1460 | size = i_size_read(file_inode(base)); |
| 1454 | ipc_unlock_object(&shp->shm_perm); | 1461 | ipc_unlock_object(&shp->shm_perm); |
| 1455 | rcu_read_unlock(); | 1462 | rcu_read_unlock(); |
| 1456 | 1463 | ||
| 1457 | err = -ENOMEM; | 1464 | err = -ENOMEM; |
| 1458 | sfd = kzalloc(sizeof(*sfd), GFP_KERNEL); | 1465 | sfd = kzalloc(sizeof(*sfd), GFP_KERNEL); |
| 1459 | if (!sfd) { | 1466 | if (!sfd) { |
| 1460 | path_put(&path); | 1467 | fput(base); |
| 1461 | goto out_nattch; | 1468 | goto out_nattch; |
| 1462 | } | 1469 | } |
| 1463 | 1470 | ||
| 1464 | file = alloc_file(&path, f_mode, | 1471 | file = alloc_file_clone(base, f_flags, |
| 1465 | is_file_hugepages(shp->shm_file) ? | 1472 | is_file_hugepages(base) ? |
| 1466 | &shm_file_operations_huge : | 1473 | &shm_file_operations_huge : |
| 1467 | &shm_file_operations); | 1474 | &shm_file_operations); |
| 1468 | err = PTR_ERR(file); | 1475 | err = PTR_ERR(file); |
| 1469 | if (IS_ERR(file)) { | 1476 | if (IS_ERR(file)) { |
| 1470 | kfree(sfd); | 1477 | kfree(sfd); |
| 1471 | path_put(&path); | 1478 | fput(base); |
| 1472 | goto out_nattch; | 1479 | goto out_nattch; |
| 1473 | } | 1480 | } |
| 1474 | 1481 | ||
| 1475 | file->private_data = sfd; | ||
| 1476 | file->f_mapping = shp->shm_file->f_mapping; | ||
| 1477 | sfd->id = shp->shm_perm.id; | 1482 | sfd->id = shp->shm_perm.id; |
| 1478 | sfd->ns = get_ipc_ns(ns); | 1483 | sfd->ns = get_ipc_ns(ns); |
| 1479 | /* | 1484 | sfd->file = base; |
| 1480 | * We need to take a reference to the real shm file to prevent the | ||
| 1481 | * pointer from becoming stale in cases where the lifetime of the outer | ||
| 1482 | * file extends beyond that of the shm segment. It's not usually | ||
| 1483 | * possible, but it can happen during remap_file_pages() emulation as | ||
| 1484 | * that unmaps the memory, then does ->mmap() via file reference only. | ||
| 1485 | * We'll deny the ->mmap() if the shm segment was since removed, but to | ||
| 1486 | * detect shm ID reuse we need to compare the file pointers. | ||
| 1487 | */ | ||
| 1488 | sfd->file = get_file(shp->shm_file); | ||
| 1489 | sfd->vm_ops = NULL; | 1485 | sfd->vm_ops = NULL; |
| 1486 | file->private_data = sfd; | ||
| 1490 | 1487 | ||
| 1491 | err = security_mmap_file(file, prot, flags); | 1488 | err = security_mmap_file(file, prot, flags); |
| 1492 | if (err) | 1489 | if (err) |
