Skip to content

Commit a307d0a

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull final vfs updates from Al Viro: "Assorted cleanups and fixes all over the place" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: sg_write()/bsg_write() is not fit to be called under KERNEL_DS ufs: fix function declaration for ufs_truncate_blocks fs: exec: apply CLOEXEC before changing dumpable task flags seq_file: reset iterator to first record for zero offset vfs: fix isize/pos/len checks for reflink & dedupe [iov_iter] fix iterate_all_kinds() on empty iterators move aio compat to fs/aio.c reorganize do_make_slave() clone_private_mount() doesn't need to touch namespace_sem remove a bogus claim about namespace_sem being held by callers of mnt_alloc_id()
2 parents fc26901 + faf0dce commit a307d0a

File tree

15 files changed

+197
-167
lines changed

15 files changed

+197
-167
lines changed

block/bsg.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,9 @@ bsg_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
655655

656656
dprintk("%s: write %Zd bytes\n", bd->name, count);
657657

658+
if (unlikely(segment_eq(get_fs(), KERNEL_DS)))
659+
return -EINVAL;
660+
658661
bsg_set_block(bd, file);
659662

660663
bytes_written = 0;

drivers/scsi/sg.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,9 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
581581
sg_io_hdr_t *hp;
582582
unsigned char cmnd[SG_MAX_CDB_SIZE];
583583

584+
if (unlikely(segment_eq(get_fs(), KERNEL_DS)))
585+
return -EINVAL;
586+
584587
if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
585588
return -ENXIO;
586589
SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sdp,

fs/aio.c

Lines changed: 95 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1367,6 +1367,39 @@ SYSCALL_DEFINE2(io_setup, unsigned, nr_events, aio_context_t __user *, ctxp)
13671367
return ret;
13681368
}
13691369

1370+
#ifdef CONFIG_COMPAT
1371+
COMPAT_SYSCALL_DEFINE2(io_setup, unsigned, nr_events, u32 __user *, ctx32p)
1372+
{
1373+
struct kioctx *ioctx = NULL;
1374+
unsigned long ctx;
1375+
long ret;
1376+
1377+
ret = get_user(ctx, ctx32p);
1378+
if (unlikely(ret))
1379+
goto out;
1380+
1381+
ret = -EINVAL;
1382+
if (unlikely(ctx || nr_events == 0)) {
1383+
pr_debug("EINVAL: ctx %lu nr_events %u\n",
1384+
ctx, nr_events);
1385+
goto out;
1386+
}
1387+
1388+
ioctx = ioctx_alloc(nr_events);
1389+
ret = PTR_ERR(ioctx);
1390+
if (!IS_ERR(ioctx)) {
1391+
/* truncating is ok because it's a user address */
1392+
ret = put_user((u32)ioctx->user_id, ctx32p);
1393+
if (ret)
1394+
kill_ioctx(current->mm, ioctx, NULL);
1395+
percpu_ref_put(&ioctx->users);
1396+
}
1397+
1398+
out:
1399+
return ret;
1400+
}
1401+
#endif
1402+
13701403
/* sys_io_destroy:
13711404
* Destroy the aio_context specified. May cancel any outstanding
13721405
* AIOs and block on completion. Will fail with -ENOSYS if not
@@ -1591,8 +1624,8 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
15911624
return ret;
15921625
}
15931626

1594-
long do_io_submit(aio_context_t ctx_id, long nr,
1595-
struct iocb __user *__user *iocbpp, bool compat)
1627+
static long do_io_submit(aio_context_t ctx_id, long nr,
1628+
struct iocb __user *__user *iocbpp, bool compat)
15961629
{
15971630
struct kioctx *ctx;
15981631
long ret = 0;
@@ -1662,6 +1695,44 @@ SYSCALL_DEFINE3(io_submit, aio_context_t, ctx_id, long, nr,
16621695
return do_io_submit(ctx_id, nr, iocbpp, 0);
16631696
}
16641697

1698+
#ifdef CONFIG_COMPAT
1699+
static inline long
1700+
copy_iocb(long nr, u32 __user *ptr32, struct iocb __user * __user *ptr64)
1701+
{
1702+
compat_uptr_t uptr;
1703+
int i;
1704+
1705+
for (i = 0; i < nr; ++i) {
1706+
if (get_user(uptr, ptr32 + i))
1707+
return -EFAULT;
1708+
if (put_user(compat_ptr(uptr), ptr64 + i))
1709+
return -EFAULT;
1710+
}
1711+
return 0;
1712+
}
1713+
1714+
#define MAX_AIO_SUBMITS (PAGE_SIZE/sizeof(struct iocb *))
1715+
1716+
COMPAT_SYSCALL_DEFINE3(io_submit, compat_aio_context_t, ctx_id,
1717+
int, nr, u32 __user *, iocb)
1718+
{
1719+
struct iocb __user * __user *iocb64;
1720+
long ret;
1721+
1722+
if (unlikely(nr < 0))
1723+
return -EINVAL;
1724+
1725+
if (nr > MAX_AIO_SUBMITS)
1726+
nr = MAX_AIO_SUBMITS;
1727+
1728+
iocb64 = compat_alloc_user_space(nr * sizeof(*iocb64));
1729+
ret = copy_iocb(nr, iocb, iocb64);
1730+
if (!ret)
1731+
ret = do_io_submit(ctx_id, nr, iocb64, 1);
1732+
return ret;
1733+
}
1734+
#endif
1735+
16651736
/* lookup_kiocb
16661737
* Finds a given iocb for cancellation.
16671738
*/
@@ -1761,3 +1832,25 @@ SYSCALL_DEFINE5(io_getevents, aio_context_t, ctx_id,
17611832
}
17621833
return ret;
17631834
}
1835+
1836+
#ifdef CONFIG_COMPAT
1837+
COMPAT_SYSCALL_DEFINE5(io_getevents, compat_aio_context_t, ctx_id,
1838+
compat_long_t, min_nr,
1839+
compat_long_t, nr,
1840+
struct io_event __user *, events,
1841+
struct compat_timespec __user *, timeout)
1842+
{
1843+
struct timespec t;
1844+
struct timespec __user *ut = NULL;
1845+
1846+
if (timeout) {
1847+
if (compat_get_timespec(&t, timeout))
1848+
return -EFAULT;
1849+
1850+
ut = compat_alloc_user_space(sizeof(*ut));
1851+
if (copy_to_user(ut, &t, sizeof(t)))
1852+
return -EFAULT;
1853+
}
1854+
return sys_io_getevents(ctx_id, min_nr, nr, events, ut);
1855+
}
1856+
#endif

fs/compat.c

Lines changed: 0 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -487,45 +487,6 @@ COMPAT_SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd,
487487
return compat_sys_fcntl64(fd, cmd, arg);
488488
}
489489

490-
COMPAT_SYSCALL_DEFINE2(io_setup, unsigned, nr_reqs, u32 __user *, ctx32p)
491-
{
492-
long ret;
493-
aio_context_t ctx64;
494-
495-
mm_segment_t oldfs = get_fs();
496-
if (unlikely(get_user(ctx64, ctx32p)))
497-
return -EFAULT;
498-
499-
set_fs(KERNEL_DS);
500-
/* The __user pointer cast is valid because of the set_fs() */
501-
ret = sys_io_setup(nr_reqs, (aio_context_t __user *) &ctx64);
502-
set_fs(oldfs);
503-
/* truncating is ok because it's a user address */
504-
if (!ret)
505-
ret = put_user((u32) ctx64, ctx32p);
506-
return ret;
507-
}
508-
509-
COMPAT_SYSCALL_DEFINE5(io_getevents, compat_aio_context_t, ctx_id,
510-
compat_long_t, min_nr,
511-
compat_long_t, nr,
512-
struct io_event __user *, events,
513-
struct compat_timespec __user *, timeout)
514-
{
515-
struct timespec t;
516-
struct timespec __user *ut = NULL;
517-
518-
if (timeout) {
519-
if (compat_get_timespec(&t, timeout))
520-
return -EFAULT;
521-
522-
ut = compat_alloc_user_space(sizeof(*ut));
523-
if (copy_to_user(ut, &t, sizeof(t)) )
524-
return -EFAULT;
525-
}
526-
return sys_io_getevents(ctx_id, min_nr, nr, events, ut);
527-
}
528-
529490
/* A write operation does a read from user space and vice versa */
530491
#define vrfy_dir(type) ((type) == READ ? VERIFY_WRITE : VERIFY_READ)
531492

@@ -602,42 +563,6 @@ ssize_t compat_rw_copy_check_uvector(int type,
602563
return ret;
603564
}
604565

605-
static inline long
606-
copy_iocb(long nr, u32 __user *ptr32, struct iocb __user * __user *ptr64)
607-
{
608-
compat_uptr_t uptr;
609-
int i;
610-
611-
for (i = 0; i < nr; ++i) {
612-
if (get_user(uptr, ptr32 + i))
613-
return -EFAULT;
614-
if (put_user(compat_ptr(uptr), ptr64 + i))
615-
return -EFAULT;
616-
}
617-
return 0;
618-
}
619-
620-
#define MAX_AIO_SUBMITS (PAGE_SIZE/sizeof(struct iocb *))
621-
622-
COMPAT_SYSCALL_DEFINE3(io_submit, compat_aio_context_t, ctx_id,
623-
int, nr, u32 __user *, iocb)
624-
{
625-
struct iocb __user * __user *iocb64;
626-
long ret;
627-
628-
if (unlikely(nr < 0))
629-
return -EINVAL;
630-
631-
if (nr > MAX_AIO_SUBMITS)
632-
nr = MAX_AIO_SUBMITS;
633-
634-
iocb64 = compat_alloc_user_space(nr * sizeof(*iocb64));
635-
ret = copy_iocb(nr, iocb, iocb64);
636-
if (!ret)
637-
ret = do_io_submit(ctx_id, nr, iocb64, 1);
638-
return ret;
639-
}
640-
641566
struct compat_ncp_mount_data {
642567
compat_int_t version;
643568
compat_uint_t ncp_fd;

fs/exec.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
* current->executable is only used by the procfs. This allows a dispatch
2020
* table to check for several different types of binary formats. We keep
2121
* trying until we recognize the file or we run out of supported binary
22-
* formats.
22+
* formats.
2323
*/
2424

2525
#include <linux/slab.h>
@@ -1268,6 +1268,13 @@ int flush_old_exec(struct linux_binprm * bprm)
12681268
flush_thread();
12691269
current->personality &= ~bprm->per_clear;
12701270

1271+
/*
1272+
* We have to apply CLOEXEC before we change whether the process is
1273+
* dumpable (in setup_new_exec) to avoid a race with a process in userspace
1274+
* trying to access the should-be-closed file descriptors of a process
1275+
* undergoing exec(2).
1276+
*/
1277+
do_close_on_exec(current->files);
12711278
return 0;
12721279

12731280
out:
@@ -1330,7 +1337,6 @@ void setup_new_exec(struct linux_binprm * bprm)
13301337
group */
13311338
current->self_exec_id++;
13321339
flush_signal_handlers(current, 0);
1333-
do_close_on_exec(current->files);
13341340
}
13351341
EXPORT_SYMBOL(setup_new_exec);
13361342

fs/namespace.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,6 @@ static inline struct hlist_head *mp_hash(struct dentry *dentry)
9696
return &mountpoint_hashtable[tmp & mp_hash_mask];
9797
}
9898

99-
/*
100-
* allocation is serialized by namespace_sem, but we need the spinlock to
101-
* serialize with freeing.
102-
*/
10399
static int mnt_alloc_id(struct mount *mnt)
104100
{
105101
int res;
@@ -1034,6 +1030,8 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root,
10341030
if (IS_MNT_SLAVE(old))
10351031
list_add(&mnt->mnt_slave, &old->mnt_slave);
10361032
mnt->mnt_master = old->mnt_master;
1033+
} else {
1034+
CLEAR_MNT_SHARED(mnt);
10371035
}
10381036
if (flag & CL_MAKE_SHARED)
10391037
set_mnt_shared(mnt);
@@ -1828,9 +1826,7 @@ struct vfsmount *clone_private_mount(const struct path *path)
18281826
if (IS_MNT_UNBINDABLE(old_mnt))
18291827
return ERR_PTR(-EINVAL);
18301828

1831-
down_read(&namespace_sem);
18321829
new_mnt = clone_mnt(old_mnt, path->dentry, CL_PRIVATE);
1833-
up_read(&namespace_sem);
18341830
if (IS_ERR(new_mnt))
18351831
return ERR_CAST(new_mnt);
18361832

fs/ocfs2/refcounttree.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4834,7 +4834,7 @@ int ocfs2_reflink_remap_range(struct file *file_in,
48344834

48354835
ret = vfs_clone_file_prep_inodes(inode_in, pos_in, inode_out, pos_out,
48364836
&len, is_dedupe);
4837-
if (ret || len == 0)
4837+
if (ret <= 0)
48384838
goto out_unlock;
48394839

48404840
/* Lock out changes to the allocation maps and remap. */

fs/pnode.c

Lines changed: 36 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -67,49 +67,47 @@ int get_dominating_id(struct mount *mnt, const struct path *root)
6767

6868
static int do_make_slave(struct mount *mnt)
6969
{
70-
struct mount *peer_mnt = mnt, *master = mnt->mnt_master;
71-
struct mount *slave_mnt;
70+
struct mount *master, *slave_mnt;
7271

73-
/*
74-
* slave 'mnt' to a peer mount that has the
75-
* same root dentry. If none is available then
76-
* slave it to anything that is available.
77-
*/
78-
while ((peer_mnt = next_peer(peer_mnt)) != mnt &&
79-
peer_mnt->mnt.mnt_root != mnt->mnt.mnt_root) ;
80-
81-
if (peer_mnt == mnt) {
82-
peer_mnt = next_peer(mnt);
83-
if (peer_mnt == mnt)
84-
peer_mnt = NULL;
85-
}
86-
if (mnt->mnt_group_id && IS_MNT_SHARED(mnt) &&
87-
list_empty(&mnt->mnt_share))
88-
mnt_release_group_id(mnt);
89-
90-
list_del_init(&mnt->mnt_share);
91-
mnt->mnt_group_id = 0;
92-
93-
if (peer_mnt)
94-
master = peer_mnt;
95-
96-
if (master) {
97-
list_for_each_entry(slave_mnt, &mnt->mnt_slave_list, mnt_slave)
98-
slave_mnt->mnt_master = master;
99-
list_move(&mnt->mnt_slave, &master->mnt_slave_list);
100-
list_splice(&mnt->mnt_slave_list, master->mnt_slave_list.prev);
101-
INIT_LIST_HEAD(&mnt->mnt_slave_list);
72+
if (list_empty(&mnt->mnt_share)) {
73+
if (IS_MNT_SHARED(mnt)) {
74+
mnt_release_group_id(mnt);
75+
CLEAR_MNT_SHARED(mnt);
76+
}
77+
master = mnt->mnt_master;
78+
if (!master) {
79+
struct list_head *p = &mnt->mnt_slave_list;
80+
while (!list_empty(p)) {
81+
slave_mnt = list_first_entry(p,
82+
struct mount, mnt_slave);
83+
list_del_init(&slave_mnt->mnt_slave);
84+
slave_mnt->mnt_master = NULL;
85+
}
86+
return 0;
87+
}
10288
} else {
103-
struct list_head *p = &mnt->mnt_slave_list;
104-
while (!list_empty(p)) {
105-
slave_mnt = list_first_entry(p,
106-
struct mount, mnt_slave);
107-
list_del_init(&slave_mnt->mnt_slave);
108-
slave_mnt->mnt_master = NULL;
89+
struct mount *m;
90+
/*
91+
* slave 'mnt' to a peer mount that has the
92+
* same root dentry. If none is available then
93+
* slave it to anything that is available.
94+
*/
95+
for (m = master = next_peer(mnt); m != mnt; m = next_peer(m)) {
96+
if (m->mnt.mnt_root == mnt->mnt.mnt_root) {
97+
master = m;
98+
break;
99+
}
109100
}
101+
list_del_init(&mnt->mnt_share);
102+
mnt->mnt_group_id = 0;
103+
CLEAR_MNT_SHARED(mnt);
110104
}
105+
list_for_each_entry(slave_mnt, &mnt->mnt_slave_list, mnt_slave)
106+
slave_mnt->mnt_master = master;
107+
list_move(&mnt->mnt_slave, &master->mnt_slave_list);
108+
list_splice(&mnt->mnt_slave_list, master->mnt_slave_list.prev);
109+
INIT_LIST_HEAD(&mnt->mnt_slave_list);
111110
mnt->mnt_master = master;
112-
CLEAR_MNT_SHARED(mnt);
113111
return 0;
114112
}
115113

0 commit comments

Comments
 (0)