diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-17 14:54:55 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-17 14:54:55 -0500 |
commit | 93f30c73ecd0281cf3685ef0e4e384980a176176 (patch) | |
tree | bd272334a0dbd258c08b5b2237e8bf5e17ce7255 /fs | |
parent | 06ede5f6086757f746b7be860ae76137f4e95032 (diff) | |
parent | 96271654f55c74ff7325fbdfc535466c9deb0ce6 (diff) |
Merge branch 'misc.compat' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull compat and uaccess updates from Al Viro:
- {get,put}_compat_sigset() series
- assorted compat ioctl stuff
- more set_fs() elimination
- a few more timespec64 conversions
- several removals of pointless access_ok() in places where it was
followed only by non-__ variants of primitives
* 'misc.compat' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (24 commits)
coredump: call do_unlinkat directly instead of sys_unlink
fs: expose do_unlinkat for built-in callers
ext4: take handling of EXT4_IOC_GROUP_ADD into a helper, get rid of set_fs()
ipmi: get rid of pointless access_ok()
pi433: sanitize ioctl
cxlflash: get rid of pointless access_ok()
mtdchar: get rid of pointless access_ok()
r128: switch compat ioctls to drm_ioctl_kernel()
selection: get rid of field-by-field copyin
VT_RESIZEX: get rid of field-by-field copyin
i2c compat ioctls: move to ->compat_ioctl()
sched_rr_get_interval(): move compat to native, get rid of set_fs()
mips: switch to {get,put}_compat_sigset()
sparc: switch to {get,put}_compat_sigset()
s390: switch to {get,put}_compat_sigset()
ppc: switch to {get,put}_compat_sigset()
parisc: switch to {get,put}_compat_sigset()
get_compat_sigset()
get rid of {get,put}_compat_itimerspec()
io_getevents: Use timespec64 to represent timeouts
...
Diffstat (limited to 'fs')
-rw-r--r-- | fs/aio.c | 55 | ||||
-rw-r--r-- | fs/compat_ioctl.c | 122 | ||||
-rw-r--r-- | fs/coredump.c | 7 | ||||
-rw-r--r-- | fs/eventpoll.c | 4 | ||||
-rw-r--r-- | fs/ext4/ioctl.c | 86 | ||||
-rw-r--r-- | fs/internal.h | 1 | ||||
-rw-r--r-- | fs/namei.c | 12 | ||||
-rw-r--r-- | fs/select.c | 68 | ||||
-rw-r--r-- | fs/signalfd.c | 4 |
9 files changed, 108 insertions, 251 deletions
@@ -1297,20 +1297,10 @@ static bool aio_read_events(struct kioctx *ctx, long min_nr, long nr, | |||
1297 | 1297 | ||
1298 | static long read_events(struct kioctx *ctx, long min_nr, long nr, | 1298 | static long read_events(struct kioctx *ctx, long min_nr, long nr, |
1299 | struct io_event __user *event, | 1299 | struct io_event __user *event, |
1300 | struct timespec __user *timeout) | 1300 | ktime_t until) |
1301 | { | 1301 | { |
1302 | ktime_t until = KTIME_MAX; | ||
1303 | long ret = 0; | 1302 | long ret = 0; |
1304 | 1303 | ||
1305 | if (timeout) { | ||
1306 | struct timespec ts; | ||
1307 | |||
1308 | if (unlikely(copy_from_user(&ts, timeout, sizeof(ts)))) | ||
1309 | return -EFAULT; | ||
1310 | |||
1311 | until = timespec_to_ktime(ts); | ||
1312 | } | ||
1313 | |||
1314 | /* | 1304 | /* |
1315 | * Note that aio_read_events() is being called as the conditional - i.e. | 1305 | * Note that aio_read_events() is being called as the conditional - i.e. |
1316 | * we're calling it after prepare_to_wait() has set task state to | 1306 | * we're calling it after prepare_to_wait() has set task state to |
@@ -1826,6 +1816,25 @@ SYSCALL_DEFINE3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb, | |||
1826 | return ret; | 1816 | return ret; |
1827 | } | 1817 | } |
1828 | 1818 | ||
1819 | static long do_io_getevents(aio_context_t ctx_id, | ||
1820 | long min_nr, | ||
1821 | long nr, | ||
1822 | struct io_event __user *events, | ||
1823 | struct timespec64 *ts) | ||
1824 | { | ||
1825 | ktime_t until = ts ? timespec64_to_ktime(*ts) : KTIME_MAX; | ||
1826 | struct kioctx *ioctx = lookup_ioctx(ctx_id); | ||
1827 | long ret = -EINVAL; | ||
1828 | |||
1829 | if (likely(ioctx)) { | ||
1830 | if (likely(min_nr <= nr && min_nr >= 0)) | ||
1831 | ret = read_events(ioctx, min_nr, nr, events, until); | ||
1832 | percpu_ref_put(&ioctx->users); | ||
1833 | } | ||
1834 | |||
1835 | return ret; | ||
1836 | } | ||
1837 | |||
1829 | /* io_getevents: | 1838 | /* io_getevents: |
1830 | * Attempts to read at least min_nr events and up to nr events from | 1839 | * Attempts to read at least min_nr events and up to nr events from |
1831 | * the completion queue for the aio_context specified by ctx_id. If | 1840 | * the completion queue for the aio_context specified by ctx_id. If |
@@ -1844,15 +1853,14 @@ SYSCALL_DEFINE5(io_getevents, aio_context_t, ctx_id, | |||
1844 | struct io_event __user *, events, | 1853 | struct io_event __user *, events, |
1845 | struct timespec __user *, timeout) | 1854 | struct timespec __user *, timeout) |
1846 | { | 1855 | { |
1847 | struct kioctx *ioctx = lookup_ioctx(ctx_id); | 1856 | struct timespec64 ts; |
1848 | long ret = -EINVAL; | ||
1849 | 1857 | ||
1850 | if (likely(ioctx)) { | 1858 | if (timeout) { |
1851 | if (likely(min_nr <= nr && min_nr >= 0)) | 1859 | if (unlikely(get_timespec64(&ts, timeout))) |
1852 | ret = read_events(ioctx, min_nr, nr, events, timeout); | 1860 | return -EFAULT; |
1853 | percpu_ref_put(&ioctx->users); | ||
1854 | } | 1861 | } |
1855 | return ret; | 1862 | |
1863 | return do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &ts : NULL); | ||
1856 | } | 1864 | } |
1857 | 1865 | ||
1858 | #ifdef CONFIG_COMPAT | 1866 | #ifdef CONFIG_COMPAT |
@@ -1862,17 +1870,14 @@ COMPAT_SYSCALL_DEFINE5(io_getevents, compat_aio_context_t, ctx_id, | |||
1862 | struct io_event __user *, events, | 1870 | struct io_event __user *, events, |
1863 | struct compat_timespec __user *, timeout) | 1871 | struct compat_timespec __user *, timeout) |
1864 | { | 1872 | { |
1865 | struct timespec t; | 1873 | struct timespec64 t; |
1866 | struct timespec __user *ut = NULL; | ||
1867 | 1874 | ||
1868 | if (timeout) { | 1875 | if (timeout) { |
1869 | if (compat_get_timespec(&t, timeout)) | 1876 | if (compat_get_timespec64(&t, timeout)) |
1870 | return -EFAULT; | 1877 | return -EFAULT; |
1871 | 1878 | ||
1872 | ut = compat_alloc_user_space(sizeof(*ut)); | ||
1873 | if (copy_to_user(ut, &t, sizeof(t))) | ||
1874 | return -EFAULT; | ||
1875 | } | 1879 | } |
1876 | return sys_io_getevents(ctx_id, min_nr, nr, events, ut); | 1880 | |
1881 | return do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &t : NULL); | ||
1877 | } | 1882 | } |
1878 | #endif | 1883 | #endif |
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index bd5d91e119ca..f95aa0b2e9c0 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c | |||
@@ -54,8 +54,6 @@ | |||
54 | #include <linux/if_tun.h> | 54 | #include <linux/if_tun.h> |
55 | #include <linux/ctype.h> | 55 | #include <linux/ctype.h> |
56 | #include <linux/syscalls.h> | 56 | #include <linux/syscalls.h> |
57 | #include <linux/i2c.h> | ||
58 | #include <linux/i2c-dev.h> | ||
59 | #include <linux/atalk.h> | 57 | #include <linux/atalk.h> |
60 | #include <linux/gfp.h> | 58 | #include <linux/gfp.h> |
61 | #include <linux/cec.h> | 59 | #include <linux/cec.h> |
@@ -137,22 +135,6 @@ static int do_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
137 | return vfs_ioctl(file, cmd, arg); | 135 | return vfs_ioctl(file, cmd, arg); |
138 | } | 136 | } |
139 | 137 | ||
140 | static int w_long(struct file *file, | ||
141 | unsigned int cmd, compat_ulong_t __user *argp) | ||
142 | { | ||
143 | int err; | ||
144 | unsigned long __user *valp = compat_alloc_user_space(sizeof(*valp)); | ||
145 | |||
146 | if (valp == NULL) | ||
147 | return -EFAULT; | ||
148 | err = do_ioctl(file, cmd, (unsigned long)valp); | ||
149 | if (err) | ||
150 | return err; | ||
151 | if (convert_in_user(valp, argp)) | ||
152 | return -EFAULT; | ||
153 | return 0; | ||
154 | } | ||
155 | |||
156 | struct compat_video_event { | 138 | struct compat_video_event { |
157 | int32_t type; | 139 | int32_t type; |
158 | compat_time_t timestamp; | 140 | compat_time_t timestamp; |
@@ -671,96 +653,6 @@ static int serial_struct_ioctl(struct file *file, | |||
671 | return err; | 653 | return err; |
672 | } | 654 | } |
673 | 655 | ||
674 | /* | ||
675 | * I2C layer ioctls | ||
676 | */ | ||
677 | |||
678 | struct i2c_msg32 { | ||
679 | u16 addr; | ||
680 | u16 flags; | ||
681 | u16 len; | ||
682 | compat_caddr_t buf; | ||
683 | }; | ||
684 | |||
685 | struct i2c_rdwr_ioctl_data32 { | ||
686 | compat_caddr_t msgs; /* struct i2c_msg __user *msgs */ | ||
687 | u32 nmsgs; | ||
688 | }; | ||
689 | |||
690 | struct i2c_smbus_ioctl_data32 { | ||
691 | u8 read_write; | ||
692 | u8 command; | ||
693 | u32 size; | ||
694 | compat_caddr_t data; /* union i2c_smbus_data *data */ | ||
695 | }; | ||
696 | |||
697 | struct i2c_rdwr_aligned { | ||
698 | struct i2c_rdwr_ioctl_data cmd; | ||
699 | struct i2c_msg msgs[0]; | ||
700 | }; | ||
701 | |||
702 | static int do_i2c_rdwr_ioctl(struct file *file, | ||
703 | unsigned int cmd, struct i2c_rdwr_ioctl_data32 __user *udata) | ||
704 | { | ||
705 | struct i2c_rdwr_aligned __user *tdata; | ||
706 | struct i2c_msg __user *tmsgs; | ||
707 | struct i2c_msg32 __user *umsgs; | ||
708 | compat_caddr_t datap; | ||
709 | u32 nmsgs; | ||
710 | int i; | ||
711 | |||
712 | if (get_user(nmsgs, &udata->nmsgs)) | ||
713 | return -EFAULT; | ||
714 | if (nmsgs > I2C_RDWR_IOCTL_MAX_MSGS) | ||
715 | return -EINVAL; | ||
716 | |||
717 | if (get_user(datap, &udata->msgs)) | ||
718 | return -EFAULT; | ||
719 | umsgs = compat_ptr(datap); | ||
720 | |||
721 | tdata = compat_alloc_user_space(sizeof(*tdata) + | ||
722 | nmsgs * sizeof(struct i2c_msg)); | ||
723 | tmsgs = &tdata->msgs[0]; | ||
724 | |||
725 | if (put_user(nmsgs, &tdata->cmd.nmsgs) || | ||
726 | put_user(tmsgs, &tdata->cmd.msgs)) | ||
727 | return -EFAULT; | ||
728 | |||
729 | for (i = 0; i < nmsgs; i++) { | ||
730 | if (copy_in_user(&tmsgs[i].addr, &umsgs[i].addr, 3*sizeof(u16))) | ||
731 | return -EFAULT; | ||
732 | if (get_user(datap, &umsgs[i].buf) || | ||
733 | put_user(compat_ptr(datap), &tmsgs[i].buf)) | ||
734 | return -EFAULT; | ||
735 | } | ||
736 | return do_ioctl(file, cmd, (unsigned long)tdata); | ||
737 | } | ||
738 | |||
739 | static int do_i2c_smbus_ioctl(struct file *file, | ||
740 | unsigned int cmd, struct i2c_smbus_ioctl_data32 __user *udata) | ||
741 | { | ||
742 | struct i2c_smbus_ioctl_data __user *tdata; | ||
743 | union { | ||
744 | /* beginnings of those have identical layouts */ | ||
745 | struct i2c_smbus_ioctl_data32 data32; | ||
746 | struct i2c_smbus_ioctl_data data; | ||
747 | } v; | ||
748 | |||
749 | tdata = compat_alloc_user_space(sizeof(*tdata)); | ||
750 | if (tdata == NULL) | ||
751 | return -ENOMEM; | ||
752 | |||
753 | memset(&v, 0, sizeof(v)); | ||
754 | if (copy_from_user(&v.data32, udata, sizeof(v.data32))) | ||
755 | return -EFAULT; | ||
756 | v.data.data = compat_ptr(v.data32.data); | ||
757 | |||
758 | if (copy_to_user(tdata, &v.data, sizeof(v.data))) | ||
759 | return -EFAULT; | ||
760 | |||
761 | return do_ioctl(file, cmd, (unsigned long)tdata); | ||
762 | } | ||
763 | |||
764 | #define RTC_IRQP_READ32 _IOR('p', 0x0b, compat_ulong_t) | 656 | #define RTC_IRQP_READ32 _IOR('p', 0x0b, compat_ulong_t) |
765 | #define RTC_IRQP_SET32 _IOW('p', 0x0c, compat_ulong_t) | 657 | #define RTC_IRQP_SET32 _IOW('p', 0x0c, compat_ulong_t) |
766 | #define RTC_EPOCH_READ32 _IOR('p', 0x0d, compat_ulong_t) | 658 | #define RTC_EPOCH_READ32 _IOR('p', 0x0d, compat_ulong_t) |
@@ -1283,13 +1175,6 @@ COMPATIBLE_IOCTL(PCIIOC_CONTROLLER) | |||
1283 | COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_IO) | 1175 | COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_IO) |
1284 | COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_MEM) | 1176 | COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_MEM) |
1285 | COMPATIBLE_IOCTL(PCIIOC_WRITE_COMBINE) | 1177 | COMPATIBLE_IOCTL(PCIIOC_WRITE_COMBINE) |
1286 | /* i2c */ | ||
1287 | COMPATIBLE_IOCTL(I2C_SLAVE) | ||
1288 | COMPATIBLE_IOCTL(I2C_SLAVE_FORCE) | ||
1289 | COMPATIBLE_IOCTL(I2C_TENBIT) | ||
1290 | COMPATIBLE_IOCTL(I2C_PEC) | ||
1291 | COMPATIBLE_IOCTL(I2C_RETRIES) | ||
1292 | COMPATIBLE_IOCTL(I2C_TIMEOUT) | ||
1293 | /* hiddev */ | 1178 | /* hiddev */ |
1294 | COMPATIBLE_IOCTL(HIDIOCGVERSION) | 1179 | COMPATIBLE_IOCTL(HIDIOCGVERSION) |
1295 | COMPATIBLE_IOCTL(HIDIOCAPPLICATION) | 1180 | COMPATIBLE_IOCTL(HIDIOCAPPLICATION) |
@@ -1464,13 +1349,6 @@ static long do_ioctl_trans(unsigned int cmd, | |||
1464 | case TIOCGSERIAL: | 1349 | case TIOCGSERIAL: |
1465 | case TIOCSSERIAL: | 1350 | case TIOCSSERIAL: |
1466 | return serial_struct_ioctl(file, cmd, argp); | 1351 | return serial_struct_ioctl(file, cmd, argp); |
1467 | /* i2c */ | ||
1468 | case I2C_FUNCS: | ||
1469 | return w_long(file, cmd, argp); | ||
1470 | case I2C_RDWR: | ||
1471 | return do_i2c_rdwr_ioctl(file, cmd, argp); | ||
1472 | case I2C_SMBUS: | ||
1473 | return do_i2c_smbus_ioctl(file, cmd, argp); | ||
1474 | /* Not implemented in the native kernel */ | 1352 | /* Not implemented in the native kernel */ |
1475 | case RTC_IRQP_READ32: | 1353 | case RTC_IRQP_READ32: |
1476 | case RTC_IRQP_SET32: | 1354 | case RTC_IRQP_SET32: |
diff --git a/fs/coredump.c b/fs/coredump.c index 52c63d6c9143..1e2c87acac9b 100644 --- a/fs/coredump.c +++ b/fs/coredump.c | |||
@@ -680,16 +680,11 @@ void do_coredump(const siginfo_t *siginfo) | |||
680 | * privs and don't want to unlink another user's coredump. | 680 | * privs and don't want to unlink another user's coredump. |
681 | */ | 681 | */ |
682 | if (!need_suid_safe) { | 682 | if (!need_suid_safe) { |
683 | mm_segment_t old_fs; | ||
684 | |||
685 | old_fs = get_fs(); | ||
686 | set_fs(KERNEL_DS); | ||
687 | /* | 683 | /* |
688 | * If it doesn't exist, that's fine. If there's some | 684 | * If it doesn't exist, that's fine. If there's some |
689 | * other problem, we'll catch it at the filp_open(). | 685 | * other problem, we'll catch it at the filp_open(). |
690 | */ | 686 | */ |
691 | (void) sys_unlink((const char __user *)cn.corename); | 687 | do_unlinkat(AT_FDCWD, getname_kernel(cn.corename)); |
692 | set_fs(old_fs); | ||
693 | } | 688 | } |
694 | 689 | ||
695 | /* | 690 | /* |
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 2fabd19cdeea..396a3c075fd4 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c | |||
@@ -2259,7 +2259,6 @@ COMPAT_SYSCALL_DEFINE6(epoll_pwait, int, epfd, | |||
2259 | compat_size_t, sigsetsize) | 2259 | compat_size_t, sigsetsize) |
2260 | { | 2260 | { |
2261 | long err; | 2261 | long err; |
2262 | compat_sigset_t csigmask; | ||
2263 | sigset_t ksigmask, sigsaved; | 2262 | sigset_t ksigmask, sigsaved; |
2264 | 2263 | ||
2265 | /* | 2264 | /* |
@@ -2269,9 +2268,8 @@ COMPAT_SYSCALL_DEFINE6(epoll_pwait, int, epfd, | |||
2269 | if (sigmask) { | 2268 | if (sigmask) { |
2270 | if (sigsetsize != sizeof(compat_sigset_t)) | 2269 | if (sigsetsize != sizeof(compat_sigset_t)) |
2271 | return -EINVAL; | 2270 | return -EINVAL; |
2272 | if (copy_from_user(&csigmask, sigmask, sizeof(csigmask))) | 2271 | if (get_compat_sigset(&ksigmask, sigmask)) |
2273 | return -EFAULT; | 2272 | return -EFAULT; |
2274 | sigset_from_compat(&ksigmask, &csigmask); | ||
2275 | sigsaved = current->blocked; | 2273 | sigsaved = current->blocked; |
2276 | set_current_blocked(&ksigmask); | 2274 | set_current_blocked(&ksigmask); |
2277 | } | 2275 | } |
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index b7558f292420..1eec25014f62 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c | |||
@@ -592,6 +592,44 @@ static int ext4_ioc_getfsmap(struct super_block *sb, | |||
592 | return 0; | 592 | return 0; |
593 | } | 593 | } |
594 | 594 | ||
595 | static long ext4_ioctl_group_add(struct file *file, | ||
596 | struct ext4_new_group_data *input) | ||
597 | { | ||
598 | struct super_block *sb = file_inode(file)->i_sb; | ||
599 | int err, err2=0; | ||
600 | |||
601 | err = ext4_resize_begin(sb); | ||
602 | if (err) | ||
603 | return err; | ||
604 | |||
605 | if (ext4_has_feature_bigalloc(sb)) { | ||
606 | ext4_msg(sb, KERN_ERR, | ||
607 | "Online resizing not supported with bigalloc"); | ||
608 | err = -EOPNOTSUPP; | ||
609 | goto group_add_out; | ||
610 | } | ||
611 | |||
612 | err = mnt_want_write_file(file); | ||
613 | if (err) | ||
614 | goto group_add_out; | ||
615 | |||
616 | err = ext4_group_add(sb, input); | ||
617 | if (EXT4_SB(sb)->s_journal) { | ||
618 | jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); | ||
619 | err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal); | ||
620 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); | ||
621 | } | ||
622 | if (err == 0) | ||
623 | err = err2; | ||
624 | mnt_drop_write_file(file); | ||
625 | if (!err && ext4_has_group_desc_csum(sb) && | ||
626 | test_opt(sb, INIT_INODE_TABLE)) | ||
627 | err = ext4_register_li_request(sb, input->group); | ||
628 | group_add_out: | ||
629 | ext4_resize_end(sb); | ||
630 | return err; | ||
631 | } | ||
632 | |||
595 | long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | 633 | long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
596 | { | 634 | { |
597 | struct inode *inode = file_inode(filp); | 635 | struct inode *inode = file_inode(filp); |
@@ -776,44 +814,12 @@ mext_out: | |||
776 | 814 | ||
777 | case EXT4_IOC_GROUP_ADD: { | 815 | case EXT4_IOC_GROUP_ADD: { |
778 | struct ext4_new_group_data input; | 816 | struct ext4_new_group_data input; |
779 | int err, err2=0; | ||
780 | |||
781 | err = ext4_resize_begin(sb); | ||
782 | if (err) | ||
783 | return err; | ||
784 | 817 | ||
785 | if (copy_from_user(&input, (struct ext4_new_group_input __user *)arg, | 818 | if (copy_from_user(&input, (struct ext4_new_group_input __user *)arg, |
786 | sizeof(input))) { | 819 | sizeof(input))) |
787 | err = -EFAULT; | 820 | return -EFAULT; |
788 | goto group_add_out; | ||
789 | } | ||
790 | |||
791 | if (ext4_has_feature_bigalloc(sb)) { | ||
792 | ext4_msg(sb, KERN_ERR, | ||
793 | "Online resizing not supported with bigalloc"); | ||
794 | err = -EOPNOTSUPP; | ||
795 | goto group_add_out; | ||
796 | } | ||
797 | |||
798 | err = mnt_want_write_file(filp); | ||
799 | if (err) | ||
800 | goto group_add_out; | ||
801 | 821 | ||
802 | err = ext4_group_add(sb, &input); | 822 | return ext4_ioctl_group_add(filp, &input); |
803 | if (EXT4_SB(sb)->s_journal) { | ||
804 | jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); | ||
805 | err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal); | ||
806 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); | ||
807 | } | ||
808 | if (err == 0) | ||
809 | err = err2; | ||
810 | mnt_drop_write_file(filp); | ||
811 | if (!err && ext4_has_group_desc_csum(sb) && | ||
812 | test_opt(sb, INIT_INODE_TABLE)) | ||
813 | err = ext4_register_li_request(sb, input.group); | ||
814 | group_add_out: | ||
815 | ext4_resize_end(sb); | ||
816 | return err; | ||
817 | } | 823 | } |
818 | 824 | ||
819 | case EXT4_IOC_MIGRATE: | 825 | case EXT4_IOC_MIGRATE: |
@@ -1078,8 +1084,7 @@ long ext4_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
1078 | break; | 1084 | break; |
1079 | case EXT4_IOC32_GROUP_ADD: { | 1085 | case EXT4_IOC32_GROUP_ADD: { |
1080 | struct compat_ext4_new_group_input __user *uinput; | 1086 | struct compat_ext4_new_group_input __user *uinput; |
1081 | struct ext4_new_group_input input; | 1087 | struct ext4_new_group_data input; |
1082 | mm_segment_t old_fs; | ||
1083 | int err; | 1088 | int err; |
1084 | 1089 | ||
1085 | uinput = compat_ptr(arg); | 1090 | uinput = compat_ptr(arg); |
@@ -1092,12 +1097,7 @@ long ext4_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
1092 | &uinput->reserved_blocks); | 1097 | &uinput->reserved_blocks); |
1093 | if (err) | 1098 | if (err) |
1094 | return -EFAULT; | 1099 | return -EFAULT; |
1095 | old_fs = get_fs(); | 1100 | return ext4_ioctl_group_add(file, &input); |
1096 | set_fs(KERNEL_DS); | ||
1097 | err = ext4_ioctl(file, EXT4_IOC_GROUP_ADD, | ||
1098 | (unsigned long) &input); | ||
1099 | set_fs(old_fs); | ||
1100 | return err; | ||
1101 | } | 1101 | } |
1102 | case EXT4_IOC_MOVE_EXT: | 1102 | case EXT4_IOC_MOVE_EXT: |
1103 | case EXT4_IOC_RESIZE_FS: | 1103 | case EXT4_IOC_RESIZE_FS: |
diff --git a/fs/internal.h b/fs/internal.h index 48cee21b4f14..df262f41a0ef 100644 --- a/fs/internal.h +++ b/fs/internal.h | |||
@@ -55,6 +55,7 @@ extern void __init chrdev_init(void); | |||
55 | extern int user_path_mountpoint_at(int, const char __user *, unsigned int, struct path *); | 55 | extern int user_path_mountpoint_at(int, const char __user *, unsigned int, struct path *); |
56 | extern int vfs_path_lookup(struct dentry *, struct vfsmount *, | 56 | extern int vfs_path_lookup(struct dentry *, struct vfsmount *, |
57 | const char *, unsigned int, struct path *); | 57 | const char *, unsigned int, struct path *); |
58 | long do_unlinkat(int dfd, struct filename *name); | ||
58 | 59 | ||
59 | /* | 60 | /* |
60 | * namespace.c | 61 | * namespace.c |
diff --git a/fs/namei.c b/fs/namei.c index 5424b10cfdc4..287781363763 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -4010,10 +4010,9 @@ EXPORT_SYMBOL(vfs_unlink); | |||
4010 | * writeout happening, and we don't want to prevent access to the directory | 4010 | * writeout happening, and we don't want to prevent access to the directory |
4011 | * while waiting on the I/O. | 4011 | * while waiting on the I/O. |
4012 | */ | 4012 | */ |
4013 | static long do_unlinkat(int dfd, const char __user *pathname) | 4013 | long do_unlinkat(int dfd, struct filename *name) |
4014 | { | 4014 | { |
4015 | int error; | 4015 | int error; |
4016 | struct filename *name; | ||
4017 | struct dentry *dentry; | 4016 | struct dentry *dentry; |
4018 | struct path path; | 4017 | struct path path; |
4019 | struct qstr last; | 4018 | struct qstr last; |
@@ -4022,8 +4021,7 @@ static long do_unlinkat(int dfd, const char __user *pathname) | |||
4022 | struct inode *delegated_inode = NULL; | 4021 | struct inode *delegated_inode = NULL; |
4023 | unsigned int lookup_flags = 0; | 4022 | unsigned int lookup_flags = 0; |
4024 | retry: | 4023 | retry: |
4025 | name = filename_parentat(dfd, getname(pathname), lookup_flags, | 4024 | name = filename_parentat(dfd, name, lookup_flags, &path, &last, &type); |
4026 | &path, &last, &type); | ||
4027 | if (IS_ERR(name)) | 4025 | if (IS_ERR(name)) |
4028 | return PTR_ERR(name); | 4026 | return PTR_ERR(name); |
4029 | 4027 | ||
@@ -4065,12 +4063,12 @@ exit2: | |||
4065 | mnt_drop_write(path.mnt); | 4063 | mnt_drop_write(path.mnt); |
4066 | exit1: | 4064 | exit1: |
4067 | path_put(&path); | 4065 | path_put(&path); |
4068 | putname(name); | ||
4069 | if (retry_estale(error, lookup_flags)) { | 4066 | if (retry_estale(error, lookup_flags)) { |
4070 | lookup_flags |= LOOKUP_REVAL; | 4067 | lookup_flags |= LOOKUP_REVAL; |
4071 | inode = NULL; | 4068 | inode = NULL; |
4072 | goto retry; | 4069 | goto retry; |
4073 | } | 4070 | } |
4071 | putname(name); | ||
4074 | return error; | 4072 | return error; |
4075 | 4073 | ||
4076 | slashes: | 4074 | slashes: |
@@ -4091,12 +4089,12 @@ SYSCALL_DEFINE3(unlinkat, int, dfd, const char __user *, pathname, int, flag) | |||
4091 | if (flag & AT_REMOVEDIR) | 4089 | if (flag & AT_REMOVEDIR) |
4092 | return do_rmdir(dfd, pathname); | 4090 | return do_rmdir(dfd, pathname); |
4093 | 4091 | ||
4094 | return do_unlinkat(dfd, pathname); | 4092 | return do_unlinkat(dfd, getname(pathname)); |
4095 | } | 4093 | } |
4096 | 4094 | ||
4097 | SYSCALL_DEFINE1(unlink, const char __user *, pathname) | 4095 | SYSCALL_DEFINE1(unlink, const char __user *, pathname) |
4098 | { | 4096 | { |
4099 | return do_unlinkat(AT_FDCWD, pathname); | 4097 | return do_unlinkat(AT_FDCWD, getname(pathname)); |
4100 | } | 4098 | } |
4101 | 4099 | ||
4102 | int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname) | 4100 | int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname) |
diff --git a/fs/select.c b/fs/select.c index 063067e606ca..6de493bb42a4 100644 --- a/fs/select.c +++ b/fs/select.c | |||
@@ -292,8 +292,7 @@ static int poll_select_copy_remaining(struct timespec64 *end_time, | |||
292 | void __user *p, | 292 | void __user *p, |
293 | int timeval, int ret) | 293 | int timeval, int ret) |
294 | { | 294 | { |
295 | struct timespec64 rts64; | 295 | struct timespec64 rts; |
296 | struct timespec rts; | ||
297 | struct timeval rtv; | 296 | struct timeval rtv; |
298 | 297 | ||
299 | if (!p) | 298 | if (!p) |
@@ -306,23 +305,22 @@ static int poll_select_copy_remaining(struct timespec64 *end_time, | |||
306 | if (!end_time->tv_sec && !end_time->tv_nsec) | 305 | if (!end_time->tv_sec && !end_time->tv_nsec) |
307 | return ret; | 306 | return ret; |
308 | 307 | ||
309 | ktime_get_ts64(&rts64); | 308 | ktime_get_ts64(&rts); |
310 | rts64 = timespec64_sub(*end_time, rts64); | 309 | rts = timespec64_sub(*end_time, rts); |
311 | if (rts64.tv_sec < 0) | 310 | if (rts.tv_sec < 0) |
312 | rts64.tv_sec = rts64.tv_nsec = 0; | 311 | rts.tv_sec = rts.tv_nsec = 0; |
313 | 312 | ||
314 | rts = timespec64_to_timespec(rts64); | ||
315 | 313 | ||
316 | if (timeval) { | 314 | if (timeval) { |
317 | if (sizeof(rtv) > sizeof(rtv.tv_sec) + sizeof(rtv.tv_usec)) | 315 | if (sizeof(rtv) > sizeof(rtv.tv_sec) + sizeof(rtv.tv_usec)) |
318 | memset(&rtv, 0, sizeof(rtv)); | 316 | memset(&rtv, 0, sizeof(rtv)); |
319 | rtv.tv_sec = rts64.tv_sec; | 317 | rtv.tv_sec = rts.tv_sec; |
320 | rtv.tv_usec = rts64.tv_nsec / NSEC_PER_USEC; | 318 | rtv.tv_usec = rts.tv_nsec / NSEC_PER_USEC; |
321 | 319 | ||
322 | if (!copy_to_user(p, &rtv, sizeof(rtv))) | 320 | if (!copy_to_user(p, &rtv, sizeof(rtv))) |
323 | return ret; | 321 | return ret; |
324 | 322 | ||
325 | } else if (!copy_to_user(p, &rts, sizeof(rts))) | 323 | } else if (!put_timespec64(&rts, p)) |
326 | return ret; | 324 | return ret; |
327 | 325 | ||
328 | /* | 326 | /* |
@@ -705,17 +703,15 @@ static long do_pselect(int n, fd_set __user *inp, fd_set __user *outp, | |||
705 | const sigset_t __user *sigmask, size_t sigsetsize) | 703 | const sigset_t __user *sigmask, size_t sigsetsize) |
706 | { | 704 | { |
707 | sigset_t ksigmask, sigsaved; | 705 | sigset_t ksigmask, sigsaved; |
708 | struct timespec ts; | 706 | struct timespec64 ts, end_time, *to = NULL; |
709 | struct timespec64 ts64, end_time, *to = NULL; | ||
710 | int ret; | 707 | int ret; |
711 | 708 | ||
712 | if (tsp) { | 709 | if (tsp) { |
713 | if (copy_from_user(&ts, tsp, sizeof(ts))) | 710 | if (get_timespec64(&ts, tsp)) |
714 | return -EFAULT; | 711 | return -EFAULT; |
715 | ts64 = timespec_to_timespec64(ts); | ||
716 | 712 | ||
717 | to = &end_time; | 713 | to = &end_time; |
718 | if (poll_select_set_timeout(to, ts64.tv_sec, ts64.tv_nsec)) | 714 | if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec)) |
719 | return -EINVAL; | 715 | return -EINVAL; |
720 | } | 716 | } |
721 | 717 | ||
@@ -1052,12 +1048,11 @@ SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds, | |||
1052 | size_t, sigsetsize) | 1048 | size_t, sigsetsize) |
1053 | { | 1049 | { |
1054 | sigset_t ksigmask, sigsaved; | 1050 | sigset_t ksigmask, sigsaved; |
1055 | struct timespec ts; | 1051 | struct timespec64 ts, end_time, *to = NULL; |
1056 | struct timespec64 end_time, *to = NULL; | ||
1057 | int ret; | 1052 | int ret; |
1058 | 1053 | ||
1059 | if (tsp) { | 1054 | if (tsp) { |
1060 | if (copy_from_user(&ts, tsp, sizeof(ts))) | 1055 | if (get_timespec64(&ts, tsp)) |
1061 | return -EFAULT; | 1056 | return -EFAULT; |
1062 | 1057 | ||
1063 | to = &end_time; | 1058 | to = &end_time; |
@@ -1103,10 +1098,10 @@ SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds, | |||
1103 | #define __COMPAT_NFDBITS (8 * sizeof(compat_ulong_t)) | 1098 | #define __COMPAT_NFDBITS (8 * sizeof(compat_ulong_t)) |
1104 | 1099 | ||
1105 | static | 1100 | static |
1106 | int compat_poll_select_copy_remaining(struct timespec *end_time, void __user *p, | 1101 | int compat_poll_select_copy_remaining(struct timespec64 *end_time, void __user *p, |
1107 | int timeval, int ret) | 1102 | int timeval, int ret) |
1108 | { | 1103 | { |
1109 | struct timespec ts; | 1104 | struct timespec64 ts; |
1110 | 1105 | ||
1111 | if (!p) | 1106 | if (!p) |
1112 | return ret; | 1107 | return ret; |
@@ -1118,8 +1113,8 @@ int compat_poll_select_copy_remaining(struct timespec *end_time, void __user *p, | |||
1118 | if (!end_time->tv_sec && !end_time->tv_nsec) | 1113 | if (!end_time->tv_sec && !end_time->tv_nsec) |
1119 | return ret; | 1114 | return ret; |
1120 | 1115 | ||
1121 | ktime_get_ts(&ts); | 1116 | ktime_get_ts64(&ts); |
1122 | ts = timespec_sub(*end_time, ts); | 1117 | ts = timespec64_sub(*end_time, ts); |
1123 | if (ts.tv_sec < 0) | 1118 | if (ts.tv_sec < 0) |
1124 | ts.tv_sec = ts.tv_nsec = 0; | 1119 | ts.tv_sec = ts.tv_nsec = 0; |
1125 | 1120 | ||
@@ -1132,12 +1127,7 @@ int compat_poll_select_copy_remaining(struct timespec *end_time, void __user *p, | |||
1132 | if (!copy_to_user(p, &rtv, sizeof(rtv))) | 1127 | if (!copy_to_user(p, &rtv, sizeof(rtv))) |
1133 | return ret; | 1128 | return ret; |
1134 | } else { | 1129 | } else { |
1135 | struct compat_timespec rts; | 1130 | if (!compat_put_timespec64(&ts, p)) |
1136 | |||
1137 | rts.tv_sec = ts.tv_sec; | ||
1138 | rts.tv_nsec = ts.tv_nsec; | ||
1139 | |||
1140 | if (!copy_to_user(p, &rts, sizeof(rts))) | ||
1141 | return ret; | 1131 | return ret; |
1142 | } | 1132 | } |
1143 | /* | 1133 | /* |
@@ -1195,7 +1185,7 @@ int compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, | |||
1195 | */ | 1185 | */ |
1196 | static int compat_core_sys_select(int n, compat_ulong_t __user *inp, | 1186 | static int compat_core_sys_select(int n, compat_ulong_t __user *inp, |
1197 | compat_ulong_t __user *outp, compat_ulong_t __user *exp, | 1187 | compat_ulong_t __user *outp, compat_ulong_t __user *exp, |
1198 | struct timespec *end_time) | 1188 | struct timespec64 *end_time) |
1199 | { | 1189 | { |
1200 | fd_set_bits fds; | 1190 | fd_set_bits fds; |
1201 | void *bits; | 1191 | void *bits; |
@@ -1268,7 +1258,7 @@ COMPAT_SYSCALL_DEFINE5(select, int, n, compat_ulong_t __user *, inp, | |||
1268 | compat_ulong_t __user *, outp, compat_ulong_t __user *, exp, | 1258 | compat_ulong_t __user *, outp, compat_ulong_t __user *, exp, |
1269 | struct compat_timeval __user *, tvp) | 1259 | struct compat_timeval __user *, tvp) |
1270 | { | 1260 | { |
1271 | struct timespec end_time, *to = NULL; | 1261 | struct timespec64 end_time, *to = NULL; |
1272 | struct compat_timeval tv; | 1262 | struct compat_timeval tv; |
1273 | int ret; | 1263 | int ret; |
1274 | 1264 | ||
@@ -1312,14 +1302,12 @@ static long do_compat_pselect(int n, compat_ulong_t __user *inp, | |||
1312 | struct compat_timespec __user *tsp, compat_sigset_t __user *sigmask, | 1302 | struct compat_timespec __user *tsp, compat_sigset_t __user *sigmask, |
1313 | compat_size_t sigsetsize) | 1303 | compat_size_t sigsetsize) |
1314 | { | 1304 | { |
1315 | compat_sigset_t ss32; | ||
1316 | sigset_t ksigmask, sigsaved; | 1305 | sigset_t ksigmask, sigsaved; |
1317 | struct compat_timespec ts; | 1306 | struct timespec64 ts, end_time, *to = NULL; |
1318 | struct timespec end_time, *to = NULL; | ||
1319 | int ret; | 1307 | int ret; |
1320 | 1308 | ||
1321 | if (tsp) { | 1309 | if (tsp) { |
1322 | if (copy_from_user(&ts, tsp, sizeof(ts))) | 1310 | if (compat_get_timespec64(&ts, tsp)) |
1323 | return -EFAULT; | 1311 | return -EFAULT; |
1324 | 1312 | ||
1325 | to = &end_time; | 1313 | to = &end_time; |
@@ -1330,9 +1318,8 @@ static long do_compat_pselect(int n, compat_ulong_t __user *inp, | |||
1330 | if (sigmask) { | 1318 | if (sigmask) { |
1331 | if (sigsetsize != sizeof(compat_sigset_t)) | 1319 | if (sigsetsize != sizeof(compat_sigset_t)) |
1332 | return -EINVAL; | 1320 | return -EINVAL; |
1333 | if (copy_from_user(&ss32, sigmask, sizeof(ss32))) | 1321 | if (get_compat_sigset(&ksigmask, sigmask)) |
1334 | return -EFAULT; | 1322 | return -EFAULT; |
1335 | sigset_from_compat(&ksigmask, &ss32); | ||
1336 | 1323 | ||
1337 | sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP)); | 1324 | sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP)); |
1338 | sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved); | 1325 | sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved); |
@@ -1381,14 +1368,12 @@ COMPAT_SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, | |||
1381 | unsigned int, nfds, struct compat_timespec __user *, tsp, | 1368 | unsigned int, nfds, struct compat_timespec __user *, tsp, |
1382 | const compat_sigset_t __user *, sigmask, compat_size_t, sigsetsize) | 1369 | const compat_sigset_t __user *, sigmask, compat_size_t, sigsetsize) |
1383 | { | 1370 | { |
1384 | compat_sigset_t ss32; | ||
1385 | sigset_t ksigmask, sigsaved; | 1371 | sigset_t ksigmask, sigsaved; |
1386 | struct compat_timespec ts; | 1372 | struct timespec64 ts, end_time, *to = NULL; |
1387 | struct timespec end_time, *to = NULL; | ||
1388 | int ret; | 1373 | int ret; |
1389 | 1374 | ||
1390 | if (tsp) { | 1375 | if (tsp) { |
1391 | if (copy_from_user(&ts, tsp, sizeof(ts))) | 1376 | if (compat_get_timespec64(&ts, tsp)) |
1392 | return -EFAULT; | 1377 | return -EFAULT; |
1393 | 1378 | ||
1394 | to = &end_time; | 1379 | to = &end_time; |
@@ -1399,9 +1384,8 @@ COMPAT_SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, | |||
1399 | if (sigmask) { | 1384 | if (sigmask) { |
1400 | if (sigsetsize != sizeof(compat_sigset_t)) | 1385 | if (sigsetsize != sizeof(compat_sigset_t)) |
1401 | return -EINVAL; | 1386 | return -EINVAL; |
1402 | if (copy_from_user(&ss32, sigmask, sizeof(ss32))) | 1387 | if (get_compat_sigset(&ksigmask, sigmask)) |
1403 | return -EFAULT; | 1388 | return -EFAULT; |
1404 | sigset_from_compat(&ksigmask, &ss32); | ||
1405 | 1389 | ||
1406 | sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP)); | 1390 | sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP)); |
1407 | sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved); | 1391 | sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved); |
diff --git a/fs/signalfd.c b/fs/signalfd.c index 1c667af86da5..5f1ff8756595 100644 --- a/fs/signalfd.c +++ b/fs/signalfd.c | |||
@@ -313,15 +313,13 @@ COMPAT_SYSCALL_DEFINE4(signalfd4, int, ufd, | |||
313 | compat_size_t, sigsetsize, | 313 | compat_size_t, sigsetsize, |
314 | int, flags) | 314 | int, flags) |
315 | { | 315 | { |
316 | compat_sigset_t ss32; | ||
317 | sigset_t tmp; | 316 | sigset_t tmp; |
318 | sigset_t __user *ksigmask; | 317 | sigset_t __user *ksigmask; |
319 | 318 | ||
320 | if (sigsetsize != sizeof(compat_sigset_t)) | 319 | if (sigsetsize != sizeof(compat_sigset_t)) |
321 | return -EINVAL; | 320 | return -EINVAL; |
322 | if (copy_from_user(&ss32, sigmask, sizeof(ss32))) | 321 | if (get_compat_sigset(&tmp, sigmask)) |
323 | return -EFAULT; | 322 | return -EFAULT; |
324 | sigset_from_compat(&tmp, &ss32); | ||
325 | ksigmask = compat_alloc_user_space(sizeof(sigset_t)); | 323 | ksigmask = compat_alloc_user_space(sizeof(sigset_t)); |
326 | if (copy_to_user(ksigmask, &tmp, sizeof(sigset_t))) | 324 | if (copy_to_user(ksigmask, &tmp, sizeof(sigset_t))) |
327 | return -EFAULT; | 325 | return -EFAULT; |