diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-14 21:13:32 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-14 21:13:32 -0400 |
| commit | 581bfce969cbfc7ce43ee92273be9cb7c3fdfa61 (patch) | |
| tree | 0a693778ce39c49b9b7d93d0d6795c576896f5cf | |
| parent | cc73fee0bae2d66594d1fa2df92bbd783aa98e04 (diff) | |
| parent | 9725d4cef62229b4ec4c912e0db0761e7d400650 (diff) | |
Merge branch 'work.set_fs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull more set_fs removal from Al Viro:
"Christoph's 'use kernel_read and friends rather than open-coding
set_fs()' series"
* 'work.set_fs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
fs: unexport vfs_readv and vfs_writev
fs: unexport vfs_read and vfs_write
fs: unexport __vfs_read/__vfs_write
lustre: switch to kernel_write
gadget/f_mass_storage: stop messing with the address limit
mconsole: switch to kernel_read
btrfs: switch write_buf to kernel_write
net/9p: switch p9_fd_read to kernel_write
mm/nommu: switch do_mmap_private to kernel_read
serial2002: switch serial2002_tty_write to kernel_{read/write}
fs: make the buf argument to __kernel_write a void pointer
fs: fix kernel_write prototype
fs: fix kernel_read prototype
fs: move kernel_read to fs/read_write.c
fs: move kernel_write to fs/read_write.c
autofs4: switch autofs4_write to __kernel_write
ashmem: switch to ->read_iter
31 files changed, 147 insertions, 236 deletions
diff --git a/arch/mips/kernel/elf.c b/arch/mips/kernel/elf.c index 5c429d70e17f..0828d6d963b7 100644 --- a/arch/mips/kernel/elf.c +++ b/arch/mips/kernel/elf.c | |||
| @@ -87,6 +87,7 @@ int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf, | |||
| 87 | bool elf32; | 87 | bool elf32; |
| 88 | u32 flags; | 88 | u32 flags; |
| 89 | int ret; | 89 | int ret; |
| 90 | loff_t pos; | ||
| 90 | 91 | ||
| 91 | elf32 = ehdr->e32.e_ident[EI_CLASS] == ELFCLASS32; | 92 | elf32 = ehdr->e32.e_ident[EI_CLASS] == ELFCLASS32; |
| 92 | flags = elf32 ? ehdr->e32.e_flags : ehdr->e64.e_flags; | 93 | flags = elf32 ? ehdr->e32.e_flags : ehdr->e64.e_flags; |
| @@ -108,21 +109,16 @@ int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf, | |||
| 108 | 109 | ||
| 109 | if (phdr32->p_filesz < sizeof(abiflags)) | 110 | if (phdr32->p_filesz < sizeof(abiflags)) |
| 110 | return -EINVAL; | 111 | return -EINVAL; |
| 111 | 112 | pos = phdr32->p_offset; | |
| 112 | ret = kernel_read(elf, phdr32->p_offset, | ||
| 113 | (char *)&abiflags, | ||
| 114 | sizeof(abiflags)); | ||
| 115 | } else { | 113 | } else { |
| 116 | if (phdr64->p_type != PT_MIPS_ABIFLAGS) | 114 | if (phdr64->p_type != PT_MIPS_ABIFLAGS) |
| 117 | return 0; | 115 | return 0; |
| 118 | if (phdr64->p_filesz < sizeof(abiflags)) | 116 | if (phdr64->p_filesz < sizeof(abiflags)) |
| 119 | return -EINVAL; | 117 | return -EINVAL; |
| 120 | 118 | pos = phdr64->p_offset; | |
| 121 | ret = kernel_read(elf, phdr64->p_offset, | ||
| 122 | (char *)&abiflags, | ||
| 123 | sizeof(abiflags)); | ||
| 124 | } | 119 | } |
| 125 | 120 | ||
| 121 | ret = kernel_read(elf, &abiflags, sizeof(abiflags), &pos); | ||
| 126 | if (ret < 0) | 122 | if (ret < 0) |
| 127 | return ret; | 123 | return ret; |
| 128 | if (ret != sizeof(abiflags)) | 124 | if (ret != sizeof(abiflags)) |
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index af326fb6510d..c4d162a94be9 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c | |||
| @@ -148,12 +148,7 @@ void mconsole_proc(struct mc_request *req) | |||
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | do { | 150 | do { |
| 151 | loff_t pos = file->f_pos; | 151 | len = kernel_read(file, buf, PAGE_SIZE - 1, &file->f_pos); |
| 152 | mm_segment_t old_fs = get_fs(); | ||
| 153 | set_fs(KERNEL_DS); | ||
| 154 | len = vfs_read(file, buf, PAGE_SIZE - 1, &pos); | ||
| 155 | set_fs(old_fs); | ||
| 156 | file->f_pos = pos; | ||
| 157 | if (len < 0) { | 152 | if (len < 0) { |
| 158 | mconsole_reply(req, "Read of file failed", 1, 0); | 153 | mconsole_reply(req, "Read of file failed", 1, 0); |
| 159 | goto out_free; | 154 | goto out_free; |
diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c index 8d0879f1d42c..8e02b30cf08e 100644 --- a/arch/x86/ia32/ia32_aout.c +++ b/arch/x86/ia32/ia32_aout.c | |||
| @@ -407,10 +407,10 @@ static int load_aout_library(struct file *file) | |||
| 407 | unsigned long bss, start_addr, len, error; | 407 | unsigned long bss, start_addr, len, error; |
| 408 | int retval; | 408 | int retval; |
| 409 | struct exec ex; | 409 | struct exec ex; |
| 410 | 410 | loff_t pos = 0; | |
| 411 | 411 | ||
| 412 | retval = -ENOEXEC; | 412 | retval = -ENOEXEC; |
| 413 | error = kernel_read(file, 0, (char *) &ex, sizeof(ex)); | 413 | error = kernel_read(file, &ex, sizeof(ex), &pos); |
| 414 | if (error != sizeof(ex)) | 414 | if (error != sizeof(ex)) |
| 415 | goto out; | 415 | goto out; |
| 416 | 416 | ||
diff --git a/drivers/media/pci/cx25821/cx25821-audio-upstream.c b/drivers/media/pci/cx25821/cx25821-audio-upstream.c index b94eb1c0023d..ada26d4acfb4 100644 --- a/drivers/media/pci/cx25821/cx25821-audio-upstream.c +++ b/drivers/media/pci/cx25821/cx25821-audio-upstream.c | |||
| @@ -277,7 +277,7 @@ static int cx25821_get_audio_data(struct cx25821_dev *dev, | |||
| 277 | p = (char *)dev->_audiodata_buf_virt_addr + frame_offset; | 277 | p = (char *)dev->_audiodata_buf_virt_addr + frame_offset; |
| 278 | 278 | ||
| 279 | for (i = 0; i < dev->_audio_lines_count; i++) { | 279 | for (i = 0; i < dev->_audio_lines_count; i++) { |
| 280 | int n = kernel_read(file, file_offset, mybuf, AUDIO_LINE_SIZE); | 280 | int n = kernel_read(file, mybuf, AUDIO_LINE_SIZE, &file_offset); |
| 281 | if (n < AUDIO_LINE_SIZE) { | 281 | if (n < AUDIO_LINE_SIZE) { |
| 282 | pr_info("Done: exit %s() since no more bytes to read from Audio file\n", | 282 | pr_info("Done: exit %s() since no more bytes to read from Audio file\n", |
| 283 | __func__); | 283 | __func__); |
| @@ -290,7 +290,6 @@ static int cx25821_get_audio_data(struct cx25821_dev *dev, | |||
| 290 | memcpy(p, mybuf, n); | 290 | memcpy(p, mybuf, n); |
| 291 | p += n; | 291 | p += n; |
| 292 | } | 292 | } |
| 293 | file_offset += n; | ||
| 294 | } | 293 | } |
| 295 | dev->_audioframe_count++; | 294 | dev->_audioframe_count++; |
| 296 | fput(file); | 295 | fput(file); |
| @@ -318,7 +317,7 @@ static int cx25821_openfile_audio(struct cx25821_dev *dev, | |||
| 318 | { | 317 | { |
| 319 | char *p = (void *)dev->_audiodata_buf_virt_addr; | 318 | char *p = (void *)dev->_audiodata_buf_virt_addr; |
| 320 | struct file *file; | 319 | struct file *file; |
| 321 | loff_t offset; | 320 | loff_t file_offset = 0; |
| 322 | int i, j; | 321 | int i, j; |
| 323 | 322 | ||
| 324 | file = filp_open(dev->_audiofilename, O_RDONLY | O_LARGEFILE, 0); | 323 | file = filp_open(dev->_audiofilename, O_RDONLY | O_LARGEFILE, 0); |
| @@ -328,11 +327,11 @@ static int cx25821_openfile_audio(struct cx25821_dev *dev, | |||
| 328 | return PTR_ERR(file); | 327 | return PTR_ERR(file); |
| 329 | } | 328 | } |
| 330 | 329 | ||
| 331 | for (j = 0, offset = 0; j < NUM_AUDIO_FRAMES; j++) { | 330 | for (j = 0; j < NUM_AUDIO_FRAMES; j++) { |
| 332 | for (i = 0; i < dev->_audio_lines_count; i++) { | 331 | for (i = 0; i < dev->_audio_lines_count; i++) { |
| 333 | char buf[AUDIO_LINE_SIZE]; | 332 | char buf[AUDIO_LINE_SIZE]; |
| 334 | int n = kernel_read(file, offset, buf, | 333 | loff_t offset = file_offset; |
| 335 | AUDIO_LINE_SIZE); | 334 | int n = kernel_read(file, buf, AUDIO_LINE_SIZE, &file_offset); |
| 336 | 335 | ||
| 337 | if (n < AUDIO_LINE_SIZE) { | 336 | if (n < AUDIO_LINE_SIZE) { |
| 338 | pr_info("Done: exit %s() since no more bytes to read from Audio file\n", | 337 | pr_info("Done: exit %s() since no more bytes to read from Audio file\n", |
| @@ -344,8 +343,6 @@ static int cx25821_openfile_audio(struct cx25821_dev *dev, | |||
| 344 | 343 | ||
| 345 | if (p) | 344 | if (p) |
| 346 | memcpy(p + offset, buf, n); | 345 | memcpy(p + offset, buf, n); |
| 347 | |||
| 348 | offset += n; | ||
| 349 | } | 346 | } |
| 350 | dev->_audioframe_count++; | 347 | dev->_audioframe_count++; |
| 351 | } | 348 | } |
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index fec613221958..246b4393118e 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c | |||
| @@ -1356,7 +1356,7 @@ static ssize_t read_file(struct nandsim *ns, struct file *file, void *buf, size_ | |||
| 1356 | if (err) | 1356 | if (err) |
| 1357 | return err; | 1357 | return err; |
| 1358 | noreclaim_flag = memalloc_noreclaim_save(); | 1358 | noreclaim_flag = memalloc_noreclaim_save(); |
| 1359 | tx = kernel_read(file, pos, buf, count); | 1359 | tx = kernel_read(file, buf, count, &pos); |
| 1360 | memalloc_noreclaim_restore(noreclaim_flag); | 1360 | memalloc_noreclaim_restore(noreclaim_flag); |
| 1361 | put_pages(ns); | 1361 | put_pages(ns); |
| 1362 | return tx; | 1362 | return tx; |
| @@ -1372,7 +1372,7 @@ static ssize_t write_file(struct nandsim *ns, struct file *file, void *buf, size | |||
| 1372 | if (err) | 1372 | if (err) |
| 1373 | return err; | 1373 | return err; |
| 1374 | noreclaim_flag = memalloc_noreclaim_save(); | 1374 | noreclaim_flag = memalloc_noreclaim_save(); |
| 1375 | tx = kernel_write(file, buf, count, pos); | 1375 | tx = kernel_write(file, buf, count, &pos); |
| 1376 | memalloc_noreclaim_restore(noreclaim_flag); | 1376 | memalloc_noreclaim_restore(noreclaim_flag); |
| 1377 | put_pages(ns); | 1377 | put_pages(ns); |
| 1378 | return tx; | 1378 | return tx; |
diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c index 6ba270e0494d..0f695df14c9d 100644 --- a/drivers/staging/android/ashmem.c +++ b/drivers/staging/android/ashmem.c | |||
| @@ -294,19 +294,9 @@ static int ashmem_release(struct inode *ignored, struct file *file) | |||
| 294 | return 0; | 294 | return 0; |
| 295 | } | 295 | } |
| 296 | 296 | ||
| 297 | /** | 297 | static ssize_t ashmem_read_iter(struct kiocb *iocb, struct iov_iter *iter) |
| 298 | * ashmem_read() - Reads a set of bytes from an Ashmem-enabled file | ||
| 299 | * @file: The associated backing file. | ||
| 300 | * @buf: The buffer of data being written to | ||
| 301 | * @len: The number of bytes being read | ||
| 302 | * @pos: The position of the first byte to read. | ||
| 303 | * | ||
| 304 | * Return: 0 if successful, or another return code if not. | ||
| 305 | */ | ||
| 306 | static ssize_t ashmem_read(struct file *file, char __user *buf, | ||
| 307 | size_t len, loff_t *pos) | ||
| 308 | { | 298 | { |
| 309 | struct ashmem_area *asma = file->private_data; | 299 | struct ashmem_area *asma = iocb->ki_filp->private_data; |
| 310 | int ret = 0; | 300 | int ret = 0; |
| 311 | 301 | ||
| 312 | mutex_lock(&ashmem_mutex); | 302 | mutex_lock(&ashmem_mutex); |
| @@ -320,20 +310,17 @@ static ssize_t ashmem_read(struct file *file, char __user *buf, | |||
| 320 | goto out_unlock; | 310 | goto out_unlock; |
| 321 | } | 311 | } |
| 322 | 312 | ||
| 323 | mutex_unlock(&ashmem_mutex); | ||
| 324 | |||
| 325 | /* | 313 | /* |
| 326 | * asma and asma->file are used outside the lock here. We assume | 314 | * asma and asma->file are used outside the lock here. We assume |
| 327 | * once asma->file is set it will never be changed, and will not | 315 | * once asma->file is set it will never be changed, and will not |
| 328 | * be destroyed until all references to the file are dropped and | 316 | * be destroyed until all references to the file are dropped and |
| 329 | * ashmem_release is called. | 317 | * ashmem_release is called. |
| 330 | */ | 318 | */ |
| 331 | ret = __vfs_read(asma->file, buf, len, pos); | 319 | mutex_unlock(&ashmem_mutex); |
| 332 | if (ret >= 0) | 320 | ret = vfs_iter_read(asma->file, iter, &iocb->ki_pos, 0); |
| 333 | /** Update backing file pos, since f_ops->read() doesn't */ | 321 | mutex_lock(&ashmem_mutex); |
| 334 | asma->file->f_pos = *pos; | 322 | if (ret > 0) |
| 335 | return ret; | 323 | asma->file->f_pos = iocb->ki_pos; |
| 336 | |||
| 337 | out_unlock: | 324 | out_unlock: |
| 338 | mutex_unlock(&ashmem_mutex); | 325 | mutex_unlock(&ashmem_mutex); |
| 339 | return ret; | 326 | return ret; |
| @@ -834,7 +821,7 @@ static const struct file_operations ashmem_fops = { | |||
| 834 | .owner = THIS_MODULE, | 821 | .owner = THIS_MODULE, |
| 835 | .open = ashmem_open, | 822 | .open = ashmem_open, |
| 836 | .release = ashmem_release, | 823 | .release = ashmem_release, |
| 837 | .read = ashmem_read, | 824 | .read_iter = ashmem_read_iter, |
| 838 | .llseek = ashmem_llseek, | 825 | .llseek = ashmem_llseek, |
| 839 | .mmap = ashmem_mmap, | 826 | .mmap = ashmem_mmap, |
| 840 | .unlocked_ioctl = ashmem_ioctl, | 827 | .unlocked_ioctl = ashmem_ioctl, |
diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c index 0d33e520f635..cc18e25103ca 100644 --- a/drivers/staging/comedi/drivers/serial2002.c +++ b/drivers/staging/comedi/drivers/serial2002.c | |||
| @@ -106,16 +106,8 @@ static long serial2002_tty_ioctl(struct file *f, unsigned int op, | |||
| 106 | 106 | ||
| 107 | static int serial2002_tty_write(struct file *f, unsigned char *buf, int count) | 107 | static int serial2002_tty_write(struct file *f, unsigned char *buf, int count) |
| 108 | { | 108 | { |
| 109 | const char __user *p = (__force const char __user *)buf; | 109 | loff_t pos = 0; |
| 110 | int result; | 110 | return kernel_write(f, buf, count, &pos); |
| 111 | loff_t offset = 0; | ||
| 112 | mm_segment_t oldfs; | ||
| 113 | |||
| 114 | oldfs = get_fs(); | ||
| 115 | set_fs(KERNEL_DS); | ||
| 116 | result = __vfs_write(f, p, count, &offset); | ||
| 117 | set_fs(oldfs); | ||
| 118 | return result; | ||
| 119 | } | 111 | } |
| 120 | 112 | ||
| 121 | static void serial2002_tty_read_poll_wait(struct file *f, int timeout) | 113 | static void serial2002_tty_read_poll_wait(struct file *f, int timeout) |
| @@ -148,19 +140,14 @@ static int serial2002_tty_read(struct file *f, int timeout) | |||
| 148 | { | 140 | { |
| 149 | unsigned char ch; | 141 | unsigned char ch; |
| 150 | int result; | 142 | int result; |
| 143 | loff_t pos = 0; | ||
| 151 | 144 | ||
| 152 | result = -1; | 145 | result = -1; |
| 153 | if (!IS_ERR(f)) { | 146 | if (!IS_ERR(f)) { |
| 154 | mm_segment_t oldfs; | ||
| 155 | char __user *p = (__force char __user *)&ch; | ||
| 156 | loff_t offset = 0; | ||
| 157 | |||
| 158 | oldfs = get_fs(); | ||
| 159 | set_fs(KERNEL_DS); | ||
| 160 | if (f->f_op->poll) { | 147 | if (f->f_op->poll) { |
| 161 | serial2002_tty_read_poll_wait(f, timeout); | 148 | serial2002_tty_read_poll_wait(f, timeout); |
| 162 | 149 | ||
| 163 | if (__vfs_read(f, p, 1, &offset) == 1) | 150 | if (kernel_read(f, &ch, 1, &pos) == 1) |
| 164 | result = ch; | 151 | result = ch; |
| 165 | } else { | 152 | } else { |
| 166 | /* Device does not support poll, busy wait */ | 153 | /* Device does not support poll, busy wait */ |
| @@ -171,14 +158,13 @@ static int serial2002_tty_read(struct file *f, int timeout) | |||
| 171 | if (retries >= timeout) | 158 | if (retries >= timeout) |
| 172 | break; | 159 | break; |
| 173 | 160 | ||
| 174 | if (__vfs_read(f, p, 1, &offset) == 1) { | 161 | if (kernel_read(f, &ch, 1, &pos) == 1) { |
| 175 | result = ch; | 162 | result = ch; |
| 176 | break; | 163 | break; |
| 177 | } | 164 | } |
| 178 | usleep_range(100, 1000); | 165 | usleep_range(100, 1000); |
| 179 | } | 166 | } |
| 180 | } | 167 | } |
| 181 | set_fs(oldfs); | ||
| 182 | } | 168 | } |
| 183 | return result; | 169 | return result; |
| 184 | } | 170 | } |
diff --git a/drivers/staging/lustre/lnet/libcfs/tracefile.c b/drivers/staging/lustre/lnet/libcfs/tracefile.c index 68f283a2744c..f916b475e767 100644 --- a/drivers/staging/lustre/lnet/libcfs/tracefile.c +++ b/drivers/staging/lustre/lnet/libcfs/tracefile.c | |||
| @@ -731,8 +731,7 @@ int cfs_tracefile_dump_all_pages(char *filename) | |||
| 731 | __LASSERT_TAGE_INVARIANT(tage); | 731 | __LASSERT_TAGE_INVARIANT(tage); |
| 732 | 732 | ||
| 733 | buf = kmap(tage->page); | 733 | buf = kmap(tage->page); |
| 734 | rc = vfs_write(filp, (__force const char __user *)buf, | 734 | rc = kernel_write(filp, buf, tage->used, &filp->f_pos); |
| 735 | tage->used, &filp->f_pos); | ||
| 736 | kunmap(tage->page); | 735 | kunmap(tage->page); |
| 737 | 736 | ||
| 738 | if (rc != (int)tage->used) { | 737 | if (rc != (int)tage->used) { |
| @@ -976,7 +975,6 @@ static int tracefiled(void *arg) | |||
| 976 | struct tracefiled_ctl *tctl = arg; | 975 | struct tracefiled_ctl *tctl = arg; |
| 977 | struct cfs_trace_page *tage; | 976 | struct cfs_trace_page *tage; |
| 978 | struct cfs_trace_page *tmp; | 977 | struct cfs_trace_page *tmp; |
| 979 | mm_segment_t __oldfs; | ||
| 980 | struct file *filp; | 978 | struct file *filp; |
| 981 | char *buf; | 979 | char *buf; |
| 982 | int last_loop = 0; | 980 | int last_loop = 0; |
| @@ -1014,8 +1012,6 @@ static int tracefiled(void *arg) | |||
| 1014 | __LASSERT(list_empty(&pc.pc_pages)); | 1012 | __LASSERT(list_empty(&pc.pc_pages)); |
| 1015 | goto end_loop; | 1013 | goto end_loop; |
| 1016 | } | 1014 | } |
| 1017 | __oldfs = get_fs(); | ||
| 1018 | set_fs(get_ds()); | ||
| 1019 | 1015 | ||
| 1020 | list_for_each_entry_safe(tage, tmp, &pc.pc_pages, linkage) { | 1016 | list_for_each_entry_safe(tage, tmp, &pc.pc_pages, linkage) { |
| 1021 | static loff_t f_pos; | 1017 | static loff_t f_pos; |
| @@ -1028,8 +1024,7 @@ static int tracefiled(void *arg) | |||
| 1028 | f_pos = i_size_read(file_inode(filp)); | 1024 | f_pos = i_size_read(file_inode(filp)); |
| 1029 | 1025 | ||
| 1030 | buf = kmap(tage->page); | 1026 | buf = kmap(tage->page); |
| 1031 | rc = vfs_write(filp, (__force const char __user *)buf, | 1027 | rc = kernel_write(filp, buf, tage->used, &f_pos); |
| 1032 | tage->used, &f_pos); | ||
| 1033 | kunmap(tage->page); | 1028 | kunmap(tage->page); |
| 1034 | 1029 | ||
| 1035 | if (rc != (int)tage->used) { | 1030 | if (rc != (int)tage->used) { |
| @@ -1040,7 +1035,6 @@ static int tracefiled(void *arg) | |||
| 1040 | break; | 1035 | break; |
| 1041 | } | 1036 | } |
| 1042 | } | 1037 | } |
| 1043 | set_fs(__oldfs); | ||
| 1044 | 1038 | ||
| 1045 | filp_close(filp, NULL); | 1039 | filp_close(filp, NULL); |
| 1046 | put_pages_on_daemon_list(&pc); | 1040 | put_pages_on_daemon_list(&pc); |
diff --git a/drivers/staging/lustre/lustre/obdclass/kernelcomm.c b/drivers/staging/lustre/lustre/obdclass/kernelcomm.c index 8f0707a27a83..4f0a42633d5a 100644 --- a/drivers/staging/lustre/lustre/obdclass/kernelcomm.c +++ b/drivers/staging/lustre/lustre/obdclass/kernelcomm.c | |||
| @@ -52,7 +52,6 @@ int libcfs_kkuc_msg_put(struct file *filp, void *payload) | |||
| 52 | struct kuc_hdr *kuch = (struct kuc_hdr *)payload; | 52 | struct kuc_hdr *kuch = (struct kuc_hdr *)payload; |
| 53 | ssize_t count = kuch->kuc_msglen; | 53 | ssize_t count = kuch->kuc_msglen; |
| 54 | loff_t offset = 0; | 54 | loff_t offset = 0; |
| 55 | mm_segment_t fs; | ||
| 56 | int rc = -ENXIO; | 55 | int rc = -ENXIO; |
| 57 | 56 | ||
| 58 | if (IS_ERR_OR_NULL(filp)) | 57 | if (IS_ERR_OR_NULL(filp)) |
| @@ -63,18 +62,14 @@ int libcfs_kkuc_msg_put(struct file *filp, void *payload) | |||
| 63 | return rc; | 62 | return rc; |
| 64 | } | 63 | } |
| 65 | 64 | ||
| 66 | fs = get_fs(); | ||
| 67 | set_fs(KERNEL_DS); | ||
| 68 | while (count > 0) { | 65 | while (count > 0) { |
| 69 | rc = vfs_write(filp, (void __force __user *)payload, | 66 | rc = kernel_write(filp, payload, count, &offset); |
| 70 | count, &offset); | ||
| 71 | if (rc < 0) | 67 | if (rc < 0) |
| 72 | break; | 68 | break; |
| 73 | count -= rc; | 69 | count -= rc; |
| 74 | payload += rc; | 70 | payload += rc; |
| 75 | rc = 0; | 71 | rc = 0; |
| 76 | } | 72 | } |
| 77 | set_fs(fs); | ||
| 78 | 73 | ||
| 79 | if (rc < 0) | 74 | if (rc < 0) |
| 80 | CWARN("message send failed (%d)\n", rc); | 75 | CWARN("message send failed (%d)\n", rc); |
diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index a91b7c25ffd4..928127642574 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c | |||
| @@ -896,13 +896,14 @@ static int core_alua_write_tpg_metadata( | |||
| 896 | u32 md_buf_len) | 896 | u32 md_buf_len) |
| 897 | { | 897 | { |
| 898 | struct file *file = filp_open(path, O_RDWR | O_CREAT | O_TRUNC, 0600); | 898 | struct file *file = filp_open(path, O_RDWR | O_CREAT | O_TRUNC, 0600); |
| 899 | loff_t pos = 0; | ||
| 899 | int ret; | 900 | int ret; |
| 900 | 901 | ||
| 901 | if (IS_ERR(file)) { | 902 | if (IS_ERR(file)) { |
| 902 | pr_err("filp_open(%s) for ALUA metadata failed\n", path); | 903 | pr_err("filp_open(%s) for ALUA metadata failed\n", path); |
| 903 | return -ENODEV; | 904 | return -ENODEV; |
| 904 | } | 905 | } |
| 905 | ret = kernel_write(file, md_buf, md_buf_len, 0); | 906 | ret = kernel_write(file, md_buf, md_buf_len, &pos); |
| 906 | if (ret < 0) | 907 | if (ret < 0) |
| 907 | pr_err("Error writing ALUA metadata file: %s\n", path); | 908 | pr_err("Error writing ALUA metadata file: %s\n", path); |
| 908 | fput(file); | 909 | fput(file); |
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index 24cf11d9e50a..c629817a8854 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c | |||
| @@ -443,7 +443,7 @@ fd_do_prot_fill(struct se_device *se_dev, sector_t lba, sector_t nolb, | |||
| 443 | 443 | ||
| 444 | for (prot = 0; prot < prot_length;) { | 444 | for (prot = 0; prot < prot_length;) { |
| 445 | sector_t len = min_t(sector_t, bufsize, prot_length - prot); | 445 | sector_t len = min_t(sector_t, bufsize, prot_length - prot); |
| 446 | ssize_t ret = kernel_write(prot_fd, buf, len, pos + prot); | 446 | ssize_t ret = kernel_write(prot_fd, buf, len, &pos); |
| 447 | 447 | ||
| 448 | if (ret != len) { | 448 | if (ret != len) { |
| 449 | pr_err("vfs_write to prot file failed: %zd\n", ret); | 449 | pr_err("vfs_write to prot file failed: %zd\n", ret); |
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 6d5def64db61..dd2cd8048582 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c | |||
| @@ -1974,6 +1974,7 @@ static int __core_scsi3_write_aptpl_to_file( | |||
| 1974 | char path[512]; | 1974 | char path[512]; |
| 1975 | u32 pr_aptpl_buf_len; | 1975 | u32 pr_aptpl_buf_len; |
| 1976 | int ret; | 1976 | int ret; |
| 1977 | loff_t pos = 0; | ||
| 1977 | 1978 | ||
| 1978 | memset(path, 0, 512); | 1979 | memset(path, 0, 512); |
| 1979 | 1980 | ||
| @@ -1993,7 +1994,7 @@ static int __core_scsi3_write_aptpl_to_file( | |||
| 1993 | 1994 | ||
| 1994 | pr_aptpl_buf_len = (strlen(buf) + 1); /* Add extra for NULL */ | 1995 | pr_aptpl_buf_len = (strlen(buf) + 1); /* Add extra for NULL */ |
| 1995 | 1996 | ||
| 1996 | ret = kernel_write(file, buf, pr_aptpl_buf_len, 0); | 1997 | ret = kernel_write(file, buf, pr_aptpl_buf_len, &pos); |
| 1997 | 1998 | ||
| 1998 | if (ret < 0) | 1999 | if (ret < 0) |
| 1999 | pr_debug("Error writing APTPL metadata file: %s\n", path); | 2000 | pr_debug("Error writing APTPL metadata file: %s\n", path); |
diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c index f95bddd6513f..d6bd0244b008 100644 --- a/drivers/usb/gadget/function/f_mass_storage.c +++ b/drivers/usb/gadget/function/f_mass_storage.c | |||
| @@ -686,9 +686,8 @@ static int do_read(struct fsg_common *common) | |||
| 686 | 686 | ||
| 687 | /* Perform the read */ | 687 | /* Perform the read */ |
| 688 | file_offset_tmp = file_offset; | 688 | file_offset_tmp = file_offset; |
| 689 | nread = vfs_read(curlun->filp, | 689 | nread = kernel_read(curlun->filp, bh->buf, amount, |
| 690 | (char __user *)bh->buf, | 690 | &file_offset_tmp); |
| 691 | amount, &file_offset_tmp); | ||
| 692 | VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, | 691 | VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, |
| 693 | (unsigned long long)file_offset, (int)nread); | 692 | (unsigned long long)file_offset, (int)nread); |
| 694 | if (signal_pending(current)) | 693 | if (signal_pending(current)) |
| @@ -883,8 +882,8 @@ static int do_write(struct fsg_common *common) | |||
| 883 | 882 | ||
| 884 | /* Perform the write */ | 883 | /* Perform the write */ |
| 885 | file_offset_tmp = file_offset; | 884 | file_offset_tmp = file_offset; |
| 886 | nwritten = vfs_write(curlun->filp, (char __user *)bh->buf, | 885 | nwritten = kernel_write(curlun->filp, bh->buf, amount, |
| 887 | amount, &file_offset_tmp); | 886 | &file_offset_tmp); |
| 888 | VLDBG(curlun, "file write %u @ %llu -> %d\n", amount, | 887 | VLDBG(curlun, "file write %u @ %llu -> %d\n", amount, |
| 889 | (unsigned long long)file_offset, (int)nwritten); | 888 | (unsigned long long)file_offset, (int)nwritten); |
| 890 | if (signal_pending(current)) | 889 | if (signal_pending(current)) |
| @@ -1021,9 +1020,8 @@ static int do_verify(struct fsg_common *common) | |||
| 1021 | 1020 | ||
| 1022 | /* Perform the read */ | 1021 | /* Perform the read */ |
| 1023 | file_offset_tmp = file_offset; | 1022 | file_offset_tmp = file_offset; |
| 1024 | nread = vfs_read(curlun->filp, | 1023 | nread = kernel_read(curlun->filp, bh->buf, amount, |
| 1025 | (char __user *) bh->buf, | 1024 | &file_offset_tmp); |
| 1026 | amount, &file_offset_tmp); | ||
| 1027 | VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, | 1025 | VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, |
| 1028 | (unsigned long long) file_offset, | 1026 | (unsigned long long) file_offset, |
| 1029 | (int) nread); | 1027 | (int) nread); |
| @@ -2453,13 +2451,6 @@ static int fsg_main_thread(void *common_) | |||
| 2453 | /* Allow the thread to be frozen */ | 2451 | /* Allow the thread to be frozen */ |
| 2454 | set_freezable(); | 2452 | set_freezable(); |
| 2455 | 2453 | ||
| 2456 | /* | ||
| 2457 | * Arrange for userspace references to be interpreted as kernel | ||
| 2458 | * pointers. That way we can pass a kernel pointer to a routine | ||
| 2459 | * that expects a __user pointer and it will work okay. | ||
| 2460 | */ | ||
| 2461 | set_fs(get_ds()); | ||
| 2462 | |||
| 2463 | /* The main loop */ | 2454 | /* The main loop */ |
| 2464 | while (common->state != FSG_STATE_TERMINATED) { | 2455 | while (common->state != FSG_STATE_TERMINATED) { |
| 2465 | if (exception_in_progress(common) || signal_pending(current)) { | 2456 | if (exception_in_progress(common) || signal_pending(current)) { |
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c index 24a58bf9ca72..4ac49d038bf3 100644 --- a/fs/autofs4/waitq.c +++ b/fs/autofs4/waitq.c | |||
| @@ -56,19 +56,14 @@ static int autofs4_write(struct autofs_sb_info *sbi, | |||
| 56 | struct file *file, const void *addr, int bytes) | 56 | struct file *file, const void *addr, int bytes) |
| 57 | { | 57 | { |
| 58 | unsigned long sigpipe, flags; | 58 | unsigned long sigpipe, flags; |
| 59 | mm_segment_t fs; | ||
| 60 | const char *data = (const char *)addr; | 59 | const char *data = (const char *)addr; |
| 61 | ssize_t wr = 0; | 60 | ssize_t wr = 0; |
| 62 | 61 | ||
| 63 | sigpipe = sigismember(¤t->pending.signal, SIGPIPE); | 62 | sigpipe = sigismember(¤t->pending.signal, SIGPIPE); |
| 64 | 63 | ||
| 65 | /* Save pointer to user space and point back to kernel space */ | ||
| 66 | fs = get_fs(); | ||
| 67 | set_fs(KERNEL_DS); | ||
| 68 | |||
| 69 | mutex_lock(&sbi->pipe_mutex); | 64 | mutex_lock(&sbi->pipe_mutex); |
| 70 | while (bytes) { | 65 | while (bytes) { |
| 71 | wr = __vfs_write(file, data, bytes, &file->f_pos); | 66 | wr = __kernel_write(file, data, bytes, &file->f_pos); |
| 72 | if (wr <= 0) | 67 | if (wr <= 0) |
| 73 | break; | 68 | break; |
| 74 | data += wr; | 69 | data += wr; |
| @@ -76,8 +71,6 @@ static int autofs4_write(struct autofs_sb_info *sbi, | |||
| 76 | } | 71 | } |
| 77 | mutex_unlock(&sbi->pipe_mutex); | 72 | mutex_unlock(&sbi->pipe_mutex); |
| 78 | 73 | ||
| 79 | set_fs(fs); | ||
| 80 | |||
| 81 | /* Keep the currently executing process from receiving a | 74 | /* Keep the currently executing process from receiving a |
| 82 | * SIGPIPE unless it was already supposed to get one | 75 | * SIGPIPE unless it was already supposed to get one |
| 83 | */ | 76 | */ |
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index 9be82c4e14a4..ce1824f47ba6 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c | |||
| @@ -341,11 +341,12 @@ static int load_aout_library(struct file *file) | |||
| 341 | unsigned long error; | 341 | unsigned long error; |
| 342 | int retval; | 342 | int retval; |
| 343 | struct exec ex; | 343 | struct exec ex; |
| 344 | loff_t pos = 0; | ||
| 344 | 345 | ||
| 345 | inode = file_inode(file); | 346 | inode = file_inode(file); |
| 346 | 347 | ||
| 347 | retval = -ENOEXEC; | 348 | retval = -ENOEXEC; |
| 348 | error = kernel_read(file, 0, (char *) &ex, sizeof(ex)); | 349 | error = kernel_read(file, &ex, sizeof(ex), &pos); |
| 349 | if (error != sizeof(ex)) | 350 | if (error != sizeof(ex)) |
| 350 | goto out; | 351 | goto out; |
| 351 | 352 | ||
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index ec45d24875b1..73b01e474fdc 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
| @@ -409,6 +409,7 @@ static struct elf_phdr *load_elf_phdrs(struct elfhdr *elf_ex, | |||
| 409 | { | 409 | { |
| 410 | struct elf_phdr *elf_phdata = NULL; | 410 | struct elf_phdr *elf_phdata = NULL; |
| 411 | int retval, size, err = -1; | 411 | int retval, size, err = -1; |
| 412 | loff_t pos = elf_ex->e_phoff; | ||
| 412 | 413 | ||
| 413 | /* | 414 | /* |
| 414 | * If the size of this structure has changed, then punt, since | 415 | * If the size of this structure has changed, then punt, since |
| @@ -432,8 +433,7 @@ static struct elf_phdr *load_elf_phdrs(struct elfhdr *elf_ex, | |||
| 432 | goto out; | 433 | goto out; |
| 433 | 434 | ||
| 434 | /* Read in the program headers */ | 435 | /* Read in the program headers */ |
| 435 | retval = kernel_read(elf_file, elf_ex->e_phoff, | 436 | retval = kernel_read(elf_file, elf_phdata, size, &pos); |
| 436 | (char *)elf_phdata, size); | ||
| 437 | if (retval != size) { | 437 | if (retval != size) { |
| 438 | err = (retval < 0) ? retval : -EIO; | 438 | err = (retval < 0) ? retval : -EIO; |
| 439 | goto out; | 439 | goto out; |
| @@ -698,6 +698,7 @@ static int load_elf_binary(struct linux_binprm *bprm) | |||
| 698 | struct elfhdr interp_elf_ex; | 698 | struct elfhdr interp_elf_ex; |
| 699 | } *loc; | 699 | } *loc; |
| 700 | struct arch_elf_state arch_state = INIT_ARCH_ELF_STATE; | 700 | struct arch_elf_state arch_state = INIT_ARCH_ELF_STATE; |
| 701 | loff_t pos; | ||
| 701 | 702 | ||
| 702 | loc = kmalloc(sizeof(*loc), GFP_KERNEL); | 703 | loc = kmalloc(sizeof(*loc), GFP_KERNEL); |
| 703 | if (!loc) { | 704 | if (!loc) { |
| @@ -750,9 +751,9 @@ static int load_elf_binary(struct linux_binprm *bprm) | |||
| 750 | if (!elf_interpreter) | 751 | if (!elf_interpreter) |
| 751 | goto out_free_ph; | 752 | goto out_free_ph; |
| 752 | 753 | ||
| 753 | retval = kernel_read(bprm->file, elf_ppnt->p_offset, | 754 | pos = elf_ppnt->p_offset; |
| 754 | elf_interpreter, | 755 | retval = kernel_read(bprm->file, elf_interpreter, |
| 755 | elf_ppnt->p_filesz); | 756 | elf_ppnt->p_filesz, &pos); |
| 756 | if (retval != elf_ppnt->p_filesz) { | 757 | if (retval != elf_ppnt->p_filesz) { |
| 757 | if (retval >= 0) | 758 | if (retval >= 0) |
| 758 | retval = -EIO; | 759 | retval = -EIO; |
| @@ -776,9 +777,9 @@ static int load_elf_binary(struct linux_binprm *bprm) | |||
| 776 | would_dump(bprm, interpreter); | 777 | would_dump(bprm, interpreter); |
| 777 | 778 | ||
| 778 | /* Get the exec headers */ | 779 | /* Get the exec headers */ |
| 779 | retval = kernel_read(interpreter, 0, | 780 | pos = 0; |
| 780 | (void *)&loc->interp_elf_ex, | 781 | retval = kernel_read(interpreter, &loc->interp_elf_ex, |
| 781 | sizeof(loc->interp_elf_ex)); | 782 | sizeof(loc->interp_elf_ex), &pos); |
| 782 | if (retval != sizeof(loc->interp_elf_ex)) { | 783 | if (retval != sizeof(loc->interp_elf_ex)) { |
| 783 | if (retval >= 0) | 784 | if (retval >= 0) |
| 784 | retval = -EIO; | 785 | retval = -EIO; |
| @@ -1175,9 +1176,10 @@ static int load_elf_library(struct file *file) | |||
| 1175 | unsigned long elf_bss, bss, len; | 1176 | unsigned long elf_bss, bss, len; |
| 1176 | int retval, error, i, j; | 1177 | int retval, error, i, j; |
| 1177 | struct elfhdr elf_ex; | 1178 | struct elfhdr elf_ex; |
| 1179 | loff_t pos = 0; | ||
| 1178 | 1180 | ||
| 1179 | error = -ENOEXEC; | 1181 | error = -ENOEXEC; |
| 1180 | retval = kernel_read(file, 0, (char *)&elf_ex, sizeof(elf_ex)); | 1182 | retval = kernel_read(file, &elf_ex, sizeof(elf_ex), &pos); |
| 1181 | if (retval != sizeof(elf_ex)) | 1183 | if (retval != sizeof(elf_ex)) |
| 1182 | goto out; | 1184 | goto out; |
| 1183 | 1185 | ||
| @@ -1201,7 +1203,8 @@ static int load_elf_library(struct file *file) | |||
| 1201 | 1203 | ||
| 1202 | eppnt = elf_phdata; | 1204 | eppnt = elf_phdata; |
| 1203 | error = -ENOEXEC; | 1205 | error = -ENOEXEC; |
| 1204 | retval = kernel_read(file, elf_ex.e_phoff, (char *)eppnt, j); | 1206 | pos = elf_ex.e_phoff; |
| 1207 | retval = kernel_read(file, eppnt, j, &pos); | ||
| 1205 | if (retval != j) | 1208 | if (retval != j) |
| 1206 | goto out_free_ph; | 1209 | goto out_free_ph; |
| 1207 | 1210 | ||
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 5aa9199dfb13..e70c039ac190 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c | |||
| @@ -145,6 +145,7 @@ static int elf_fdpic_fetch_phdrs(struct elf_fdpic_params *params, | |||
| 145 | struct elf32_phdr *phdr; | 145 | struct elf32_phdr *phdr; |
| 146 | unsigned long size; | 146 | unsigned long size; |
| 147 | int retval, loop; | 147 | int retval, loop; |
| 148 | loff_t pos = params->hdr.e_phoff; | ||
| 148 | 149 | ||
| 149 | if (params->hdr.e_phentsize != sizeof(struct elf_phdr)) | 150 | if (params->hdr.e_phentsize != sizeof(struct elf_phdr)) |
| 150 | return -ENOMEM; | 151 | return -ENOMEM; |
| @@ -156,8 +157,7 @@ static int elf_fdpic_fetch_phdrs(struct elf_fdpic_params *params, | |||
| 156 | if (!params->phdrs) | 157 | if (!params->phdrs) |
| 157 | return -ENOMEM; | 158 | return -ENOMEM; |
| 158 | 159 | ||
| 159 | retval = kernel_read(file, params->hdr.e_phoff, | 160 | retval = kernel_read(file, params->phdrs, size, &pos); |
| 160 | (char *) params->phdrs, size); | ||
| 161 | if (unlikely(retval != size)) | 161 | if (unlikely(retval != size)) |
| 162 | return retval < 0 ? retval : -ENOEXEC; | 162 | return retval < 0 ? retval : -ENOEXEC; |
| 163 | 163 | ||
| @@ -199,6 +199,7 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm) | |||
| 199 | char *interpreter_name = NULL; | 199 | char *interpreter_name = NULL; |
| 200 | int executable_stack; | 200 | int executable_stack; |
| 201 | int retval, i; | 201 | int retval, i; |
| 202 | loff_t pos; | ||
| 202 | 203 | ||
| 203 | kdebug("____ LOAD %d ____", current->pid); | 204 | kdebug("____ LOAD %d ____", current->pid); |
| 204 | 205 | ||
| @@ -246,10 +247,9 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm) | |||
| 246 | if (!interpreter_name) | 247 | if (!interpreter_name) |
| 247 | goto error; | 248 | goto error; |
| 248 | 249 | ||
| 249 | retval = kernel_read(bprm->file, | 250 | pos = phdr->p_offset; |
| 250 | phdr->p_offset, | 251 | retval = kernel_read(bprm->file, interpreter_name, |
| 251 | interpreter_name, | 252 | phdr->p_filesz, &pos); |
| 252 | phdr->p_filesz); | ||
| 253 | if (unlikely(retval != phdr->p_filesz)) { | 253 | if (unlikely(retval != phdr->p_filesz)) { |
| 254 | if (retval >= 0) | 254 | if (retval >= 0) |
| 255 | retval = -ENOEXEC; | 255 | retval = -ENOEXEC; |
| @@ -277,8 +277,9 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm) | |||
| 277 | */ | 277 | */ |
| 278 | would_dump(bprm, interpreter); | 278 | would_dump(bprm, interpreter); |
| 279 | 279 | ||
| 280 | retval = kernel_read(interpreter, 0, bprm->buf, | 280 | pos = 0; |
| 281 | BINPRM_BUF_SIZE); | 281 | retval = kernel_read(interpreter, bprm->buf, |
| 282 | BINPRM_BUF_SIZE, &pos); | ||
| 282 | if (unlikely(retval != BINPRM_BUF_SIZE)) { | 283 | if (unlikely(retval != BINPRM_BUF_SIZE)) { |
| 283 | if (retval >= 0) | 284 | if (retval >= 0) |
| 284 | retval = -ENOEXEC; | 285 | retval = -ENOEXEC; |
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index ce6537c50ec1..475d083f8088 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c | |||
| @@ -176,19 +176,14 @@ static int create_flat_tables(struct linux_binprm *bprm, unsigned long arg_start | |||
| 176 | #define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ | 176 | #define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ |
| 177 | #define RESERVED 0xC0 /* bit 6,7: reserved */ | 177 | #define RESERVED 0xC0 /* bit 6,7: reserved */ |
| 178 | 178 | ||
| 179 | static int decompress_exec( | 179 | static int decompress_exec(struct linux_binprm *bprm, loff_t fpos, char *dst, |
| 180 | struct linux_binprm *bprm, | 180 | long len, int fd) |
| 181 | unsigned long offset, | ||
| 182 | char *dst, | ||
| 183 | long len, | ||
| 184 | int fd) | ||
| 185 | { | 181 | { |
| 186 | unsigned char *buf; | 182 | unsigned char *buf; |
| 187 | z_stream strm; | 183 | z_stream strm; |
| 188 | loff_t fpos; | ||
| 189 | int ret, retval; | 184 | int ret, retval; |
| 190 | 185 | ||
| 191 | pr_debug("decompress_exec(offset=%lx,buf=%p,len=%lx)\n", offset, dst, len); | 186 | pr_debug("decompress_exec(offset=%llx,buf=%p,len=%lx)\n", fpos, dst, len); |
| 192 | 187 | ||
| 193 | memset(&strm, 0, sizeof(strm)); | 188 | memset(&strm, 0, sizeof(strm)); |
| 194 | strm.workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL); | 189 | strm.workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL); |
| @@ -202,13 +197,11 @@ static int decompress_exec( | |||
| 202 | } | 197 | } |
| 203 | 198 | ||
| 204 | /* Read in first chunk of data and parse gzip header. */ | 199 | /* Read in first chunk of data and parse gzip header. */ |
| 205 | fpos = offset; | 200 | ret = kernel_read(bprm->file, buf, LBUFSIZE, &fpos); |
| 206 | ret = kernel_read(bprm->file, offset, buf, LBUFSIZE); | ||
| 207 | 201 | ||
| 208 | strm.next_in = buf; | 202 | strm.next_in = buf; |
| 209 | strm.avail_in = ret; | 203 | strm.avail_in = ret; |
| 210 | strm.total_in = 0; | 204 | strm.total_in = 0; |
| 211 | fpos += ret; | ||
| 212 | 205 | ||
| 213 | retval = -ENOEXEC; | 206 | retval = -ENOEXEC; |
| 214 | 207 | ||
| @@ -274,7 +267,7 @@ static int decompress_exec( | |||
| 274 | } | 267 | } |
| 275 | 268 | ||
| 276 | while ((ret = zlib_inflate(&strm, Z_NO_FLUSH)) == Z_OK) { | 269 | while ((ret = zlib_inflate(&strm, Z_NO_FLUSH)) == Z_OK) { |
| 277 | ret = kernel_read(bprm->file, fpos, buf, LBUFSIZE); | 270 | ret = kernel_read(bprm->file, buf, LBUFSIZE, &fpos); |
| 278 | if (ret <= 0) | 271 | if (ret <= 0) |
| 279 | break; | 272 | break; |
| 280 | len -= ret; | 273 | len -= ret; |
| @@ -282,7 +275,6 @@ static int decompress_exec( | |||
| 282 | strm.next_in = buf; | 275 | strm.next_in = buf; |
| 283 | strm.avail_in = ret; | 276 | strm.avail_in = ret; |
| 284 | strm.total_in = 0; | 277 | strm.total_in = 0; |
| 285 | fpos += ret; | ||
| 286 | } | 278 | } |
| 287 | 279 | ||
| 288 | if (ret < 0) { | 280 | if (ret < 0) { |
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index f4718098ac31..ce7181ea60fa 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c | |||
| @@ -218,12 +218,15 @@ static int load_misc_binary(struct linux_binprm *bprm) | |||
| 218 | 218 | ||
| 219 | bprm->file = interp_file; | 219 | bprm->file = interp_file; |
| 220 | if (fmt->flags & MISC_FMT_CREDENTIALS) { | 220 | if (fmt->flags & MISC_FMT_CREDENTIALS) { |
| 221 | loff_t pos = 0; | ||
| 222 | |||
| 221 | /* | 223 | /* |
| 222 | * No need to call prepare_binprm(), it's already been | 224 | * No need to call prepare_binprm(), it's already been |
| 223 | * done. bprm->buf is stale, update from interp_file. | 225 | * done. bprm->buf is stale, update from interp_file. |
| 224 | */ | 226 | */ |
| 225 | memset(bprm->buf, 0, BINPRM_BUF_SIZE); | 227 | memset(bprm->buf, 0, BINPRM_BUF_SIZE); |
| 226 | retval = kernel_read(bprm->file, 0, bprm->buf, BINPRM_BUF_SIZE); | 228 | retval = kernel_read(bprm->file, bprm->buf, BINPRM_BUF_SIZE, |
| 229 | &pos); | ||
| 227 | } else | 230 | } else |
| 228 | retval = prepare_binprm(bprm); | 231 | retval = prepare_binprm(bprm); |
| 229 | 232 | ||
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index 8f1d3d6e7087..32b043ef8ac9 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c | |||
| @@ -539,33 +539,23 @@ static struct btrfs_path *alloc_path_for_send(void) | |||
| 539 | static int write_buf(struct file *filp, const void *buf, u32 len, loff_t *off) | 539 | static int write_buf(struct file *filp, const void *buf, u32 len, loff_t *off) |
| 540 | { | 540 | { |
| 541 | int ret; | 541 | int ret; |
| 542 | mm_segment_t old_fs; | ||
| 543 | u32 pos = 0; | 542 | u32 pos = 0; |
| 544 | 543 | ||
| 545 | old_fs = get_fs(); | ||
| 546 | set_fs(KERNEL_DS); | ||
| 547 | |||
| 548 | while (pos < len) { | 544 | while (pos < len) { |
| 549 | ret = vfs_write(filp, (__force const char __user *)buf + pos, | 545 | ret = kernel_write(filp, buf + pos, len - pos, off); |
| 550 | len - pos, off); | ||
| 551 | /* TODO handle that correctly */ | 546 | /* TODO handle that correctly */ |
| 552 | /*if (ret == -ERESTARTSYS) { | 547 | /*if (ret == -ERESTARTSYS) { |
| 553 | continue; | 548 | continue; |
| 554 | }*/ | 549 | }*/ |
| 555 | if (ret < 0) | 550 | if (ret < 0) |
| 556 | goto out; | 551 | return ret; |
| 557 | if (ret == 0) { | 552 | if (ret == 0) { |
| 558 | ret = -EIO; | 553 | return -EIO; |
| 559 | goto out; | ||
| 560 | } | 554 | } |
| 561 | pos += ret; | 555 | pos += ret; |
| 562 | } | 556 | } |
| 563 | 557 | ||
| 564 | ret = 0; | 558 | return 0; |
| 565 | |||
| 566 | out: | ||
| 567 | set_fs(old_fs); | ||
| 568 | return ret; | ||
| 569 | } | 559 | } |
| 570 | 560 | ||
| 571 | static int tlv_put(struct send_ctx *sctx, u16 attr, const void *data, int len) | 561 | static int tlv_put(struct send_ctx *sctx, u16 attr, const void *data, int len) |
diff --git a/fs/coda/dir.c b/fs/coda/dir.c index c0474ac6cbf2..274ab5586dd0 100644 --- a/fs/coda/dir.c +++ b/fs/coda/dir.c | |||
| @@ -368,9 +368,10 @@ static int coda_venus_readdir(struct file *coda_file, struct dir_context *ctx) | |||
| 368 | goto out; | 368 | goto out; |
| 369 | 369 | ||
| 370 | while (1) { | 370 | while (1) { |
| 371 | loff_t pos = ctx->pos - 2; | ||
| 372 | |||
| 371 | /* read entries from the directory file */ | 373 | /* read entries from the directory file */ |
| 372 | ret = kernel_read(host_file, ctx->pos - 2, (char *)vdir, | 374 | ret = kernel_read(host_file, vdir, sizeof(*vdir), &pos); |
| 373 | sizeof(*vdir)); | ||
| 374 | if (ret < 0) { | 375 | if (ret < 0) { |
| 375 | pr_err("%s: read dir %s failed %d\n", | 376 | pr_err("%s: read dir %s failed %d\n", |
| 376 | __func__, coda_f2s(&cii->c_fid), ret); | 377 | __func__, coda_f2s(&cii->c_fid), ret); |
diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c index 039e627194a9..c596e7c03424 100644 --- a/fs/ecryptfs/read_write.c +++ b/fs/ecryptfs/read_write.c | |||
| @@ -47,7 +47,7 @@ int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data, | |||
| 47 | lower_file = ecryptfs_inode_to_private(ecryptfs_inode)->lower_file; | 47 | lower_file = ecryptfs_inode_to_private(ecryptfs_inode)->lower_file; |
| 48 | if (!lower_file) | 48 | if (!lower_file) |
| 49 | return -EIO; | 49 | return -EIO; |
| 50 | rc = kernel_write(lower_file, data, size, offset); | 50 | rc = kernel_write(lower_file, data, size, &offset); |
| 51 | mark_inode_dirty_sync(ecryptfs_inode); | 51 | mark_inode_dirty_sync(ecryptfs_inode); |
| 52 | return rc; | 52 | return rc; |
| 53 | } | 53 | } |
| @@ -237,7 +237,7 @@ int ecryptfs_read_lower(char *data, loff_t offset, size_t size, | |||
| 237 | lower_file = ecryptfs_inode_to_private(ecryptfs_inode)->lower_file; | 237 | lower_file = ecryptfs_inode_to_private(ecryptfs_inode)->lower_file; |
| 238 | if (!lower_file) | 238 | if (!lower_file) |
| 239 | return -EIO; | 239 | return -EIO; |
| 240 | return kernel_read(lower_file, offset, data, size); | 240 | return kernel_read(lower_file, data, size, &offset); |
| 241 | } | 241 | } |
| 242 | 242 | ||
| 243 | /** | 243 | /** |
| @@ -885,23 +885,6 @@ struct file *open_exec(const char *name) | |||
| 885 | } | 885 | } |
| 886 | EXPORT_SYMBOL(open_exec); | 886 | EXPORT_SYMBOL(open_exec); |
| 887 | 887 | ||
| 888 | int kernel_read(struct file *file, loff_t offset, | ||
| 889 | char *addr, unsigned long count) | ||
| 890 | { | ||
| 891 | mm_segment_t old_fs; | ||
| 892 | loff_t pos = offset; | ||
| 893 | int result; | ||
| 894 | |||
| 895 | old_fs = get_fs(); | ||
| 896 | set_fs(get_ds()); | ||
| 897 | /* The cast to a user pointer is valid due to the set_fs() */ | ||
| 898 | result = vfs_read(file, (void __user *)addr, count, &pos); | ||
| 899 | set_fs(old_fs); | ||
| 900 | return result; | ||
| 901 | } | ||
| 902 | |||
| 903 | EXPORT_SYMBOL(kernel_read); | ||
| 904 | |||
| 905 | int kernel_read_file(struct file *file, void **buf, loff_t *size, | 888 | int kernel_read_file(struct file *file, void **buf, loff_t *size, |
| 906 | loff_t max_size, enum kernel_read_file_id id) | 889 | loff_t max_size, enum kernel_read_file_id id) |
| 907 | { | 890 | { |
| @@ -939,8 +922,7 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size, | |||
| 939 | 922 | ||
| 940 | pos = 0; | 923 | pos = 0; |
| 941 | while (pos < i_size) { | 924 | while (pos < i_size) { |
| 942 | bytes = kernel_read(file, pos, (char *)(*buf) + pos, | 925 | bytes = kernel_read(file, *buf + pos, i_size - pos, &pos); |
| 943 | i_size - pos); | ||
| 944 | if (bytes < 0) { | 926 | if (bytes < 0) { |
| 945 | ret = bytes; | 927 | ret = bytes; |
| 946 | goto out; | 928 | goto out; |
| @@ -948,7 +930,6 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size, | |||
| 948 | 930 | ||
| 949 | if (bytes == 0) | 931 | if (bytes == 0) |
| 950 | break; | 932 | break; |
| 951 | pos += bytes; | ||
| 952 | } | 933 | } |
| 953 | 934 | ||
| 954 | if (pos != i_size) { | 935 | if (pos != i_size) { |
| @@ -1567,6 +1548,7 @@ static void bprm_fill_uid(struct linux_binprm *bprm) | |||
| 1567 | int prepare_binprm(struct linux_binprm *bprm) | 1548 | int prepare_binprm(struct linux_binprm *bprm) |
| 1568 | { | 1549 | { |
| 1569 | int retval; | 1550 | int retval; |
| 1551 | loff_t pos = 0; | ||
| 1570 | 1552 | ||
| 1571 | bprm_fill_uid(bprm); | 1553 | bprm_fill_uid(bprm); |
| 1572 | 1554 | ||
| @@ -1577,7 +1559,7 @@ int prepare_binprm(struct linux_binprm *bprm) | |||
| 1577 | bprm->called_set_creds = 1; | 1559 | bprm->called_set_creds = 1; |
| 1578 | 1560 | ||
| 1579 | memset(bprm->buf, 0, BINPRM_BUF_SIZE); | 1561 | memset(bprm->buf, 0, BINPRM_BUF_SIZE); |
| 1580 | return kernel_read(bprm->file, 0, bprm->buf, BINPRM_BUF_SIZE); | 1562 | return kernel_read(bprm->file, bprm->buf, BINPRM_BUF_SIZE, &pos); |
| 1581 | } | 1563 | } |
| 1582 | 1564 | ||
| 1583 | EXPORT_SYMBOL(prepare_binprm); | 1565 | EXPORT_SYMBOL(prepare_binprm); |
diff --git a/fs/read_write.c b/fs/read_write.c index 61b58c7b6531..a2b9a47235c5 100644 --- a/fs/read_write.c +++ b/fs/read_write.c | |||
| @@ -413,7 +413,20 @@ ssize_t __vfs_read(struct file *file, char __user *buf, size_t count, | |||
| 413 | else | 413 | else |
| 414 | return -EINVAL; | 414 | return -EINVAL; |
| 415 | } | 415 | } |
| 416 | EXPORT_SYMBOL(__vfs_read); | 416 | |
| 417 | ssize_t kernel_read(struct file *file, void *buf, size_t count, loff_t *pos) | ||
| 418 | { | ||
| 419 | mm_segment_t old_fs; | ||
| 420 | ssize_t result; | ||
| 421 | |||
| 422 | old_fs = get_fs(); | ||
| 423 | set_fs(get_ds()); | ||
| 424 | /* The cast to a user pointer is valid due to the set_fs() */ | ||
| 425 | result = vfs_read(file, (void __user *)buf, count, pos); | ||
| 426 | set_fs(old_fs); | ||
| 427 | return result; | ||
| 428 | } | ||
| 429 | EXPORT_SYMBOL(kernel_read); | ||
| 417 | 430 | ||
| 418 | ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) | 431 | ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) |
| 419 | { | 432 | { |
| @@ -441,8 +454,6 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) | |||
| 441 | return ret; | 454 | return ret; |
| 442 | } | 455 | } |
| 443 | 456 | ||
| 444 | EXPORT_SYMBOL(vfs_read); | ||
| 445 | |||
| 446 | static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) | 457 | static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) |
| 447 | { | 458 | { |
| 448 | struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len }; | 459 | struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len }; |
| @@ -471,9 +482,8 @@ ssize_t __vfs_write(struct file *file, const char __user *p, size_t count, | |||
| 471 | else | 482 | else |
| 472 | return -EINVAL; | 483 | return -EINVAL; |
| 473 | } | 484 | } |
| 474 | EXPORT_SYMBOL(__vfs_write); | ||
| 475 | 485 | ||
| 476 | ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t *pos) | 486 | ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos) |
| 477 | { | 487 | { |
| 478 | mm_segment_t old_fs; | 488 | mm_segment_t old_fs; |
| 479 | const char __user *p; | 489 | const char __user *p; |
| @@ -496,9 +506,24 @@ ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t | |||
| 496 | inc_syscw(current); | 506 | inc_syscw(current); |
| 497 | return ret; | 507 | return ret; |
| 498 | } | 508 | } |
| 499 | |||
| 500 | EXPORT_SYMBOL(__kernel_write); | 509 | EXPORT_SYMBOL(__kernel_write); |
| 501 | 510 | ||
| 511 | ssize_t kernel_write(struct file *file, const void *buf, size_t count, | ||
| 512 | loff_t *pos) | ||
| 513 | { | ||
| 514 | mm_segment_t old_fs; | ||
| 515 | ssize_t res; | ||
| 516 | |||
| 517 | old_fs = get_fs(); | ||
| 518 | set_fs(get_ds()); | ||
| 519 | /* The cast to a user pointer is valid due to the set_fs() */ | ||
| 520 | res = vfs_write(file, (__force const char __user *)buf, count, pos); | ||
| 521 | set_fs(old_fs); | ||
| 522 | |||
| 523 | return res; | ||
| 524 | } | ||
| 525 | EXPORT_SYMBOL(kernel_write); | ||
| 526 | |||
| 502 | ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) | 527 | ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) |
| 503 | { | 528 | { |
| 504 | ssize_t ret; | 529 | ssize_t ret; |
| @@ -527,8 +552,6 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_ | |||
| 527 | return ret; | 552 | return ret; |
| 528 | } | 553 | } |
| 529 | 554 | ||
| 530 | EXPORT_SYMBOL(vfs_write); | ||
| 531 | |||
| 532 | static inline loff_t file_pos_read(struct file *file) | 555 | static inline loff_t file_pos_read(struct file *file) |
| 533 | { | 556 | { |
| 534 | return file->f_pos; | 557 | return file->f_pos; |
| @@ -959,9 +982,8 @@ ssize_t vfs_readv(struct file *file, const struct iovec __user *vec, | |||
| 959 | 982 | ||
| 960 | return ret; | 983 | return ret; |
| 961 | } | 984 | } |
| 962 | EXPORT_SYMBOL(vfs_readv); | ||
| 963 | 985 | ||
| 964 | ssize_t vfs_writev(struct file *file, const struct iovec __user *vec, | 986 | static ssize_t vfs_writev(struct file *file, const struct iovec __user *vec, |
| 965 | unsigned long vlen, loff_t *pos, rwf_t flags) | 987 | unsigned long vlen, loff_t *pos, rwf_t flags) |
| 966 | { | 988 | { |
| 967 | struct iovec iovstack[UIO_FASTIOV]; | 989 | struct iovec iovstack[UIO_FASTIOV]; |
| @@ -978,7 +1000,6 @@ ssize_t vfs_writev(struct file *file, const struct iovec __user *vec, | |||
| 978 | } | 1000 | } |
| 979 | return ret; | 1001 | return ret; |
| 980 | } | 1002 | } |
| 981 | EXPORT_SYMBOL(vfs_writev); | ||
| 982 | 1003 | ||
| 983 | static ssize_t do_readv(unsigned long fd, const struct iovec __user *vec, | 1004 | static ssize_t do_readv(unsigned long fd, const struct iovec __user *vec, |
| 984 | unsigned long vlen, rwf_t flags) | 1005 | unsigned long vlen, rwf_t flags) |
diff --git a/fs/splice.c b/fs/splice.c index ae41201d0325..f3084cce0ea6 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
| @@ -364,22 +364,6 @@ static ssize_t kernel_readv(struct file *file, const struct kvec *vec, | |||
| 364 | return res; | 364 | return res; |
| 365 | } | 365 | } |
| 366 | 366 | ||
| 367 | ssize_t kernel_write(struct file *file, const char *buf, size_t count, | ||
| 368 | loff_t pos) | ||
| 369 | { | ||
| 370 | mm_segment_t old_fs; | ||
| 371 | ssize_t res; | ||
| 372 | |||
| 373 | old_fs = get_fs(); | ||
| 374 | set_fs(get_ds()); | ||
| 375 | /* The cast to a user pointer is valid due to the set_fs() */ | ||
| 376 | res = vfs_write(file, (__force const char __user *)buf, count, &pos); | ||
| 377 | set_fs(old_fs); | ||
| 378 | |||
| 379 | return res; | ||
| 380 | } | ||
| 381 | EXPORT_SYMBOL(kernel_write); | ||
| 382 | |||
| 383 | static ssize_t default_file_splice_read(struct file *in, loff_t *ppos, | 367 | static ssize_t default_file_splice_read(struct file *in, loff_t *ppos, |
| 384 | struct pipe_inode_info *pipe, size_t len, | 368 | struct pipe_inode_info *pipe, size_t len, |
| 385 | unsigned int flags) | 369 | unsigned int flags) |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 33d8e45cd874..6e187cba94c3 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
| @@ -1754,13 +1754,10 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, | |||
| 1754 | struct iovec **ret_pointer); | 1754 | struct iovec **ret_pointer); |
| 1755 | 1755 | ||
| 1756 | extern ssize_t __vfs_read(struct file *, char __user *, size_t, loff_t *); | 1756 | extern ssize_t __vfs_read(struct file *, char __user *, size_t, loff_t *); |
| 1757 | extern ssize_t __vfs_write(struct file *, const char __user *, size_t, loff_t *); | ||
| 1758 | extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *); | 1757 | extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *); |
| 1759 | extern ssize_t vfs_write(struct file *, const char __user *, size_t, loff_t *); | 1758 | extern ssize_t vfs_write(struct file *, const char __user *, size_t, loff_t *); |
| 1760 | extern ssize_t vfs_readv(struct file *, const struct iovec __user *, | 1759 | extern ssize_t vfs_readv(struct file *, const struct iovec __user *, |
| 1761 | unsigned long, loff_t *, rwf_t); | 1760 | unsigned long, loff_t *, rwf_t); |
| 1762 | extern ssize_t vfs_writev(struct file *, const struct iovec __user *, | ||
| 1763 | unsigned long, loff_t *, rwf_t); | ||
| 1764 | extern ssize_t vfs_copy_file_range(struct file *, loff_t , struct file *, | 1761 | extern ssize_t vfs_copy_file_range(struct file *, loff_t , struct file *, |
| 1765 | loff_t, size_t, unsigned int); | 1762 | loff_t, size_t, unsigned int); |
| 1766 | extern int vfs_clone_file_prep_inodes(struct inode *inode_in, loff_t pos_in, | 1763 | extern int vfs_clone_file_prep_inodes(struct inode *inode_in, loff_t pos_in, |
| @@ -2788,15 +2785,15 @@ static inline const char *kernel_read_file_id_str(enum kernel_read_file_id id) | |||
| 2788 | return kernel_read_file_str[id]; | 2785 | return kernel_read_file_str[id]; |
| 2789 | } | 2786 | } |
| 2790 | 2787 | ||
| 2791 | extern int kernel_read(struct file *, loff_t, char *, unsigned long); | ||
| 2792 | extern int kernel_read_file(struct file *, void **, loff_t *, loff_t, | 2788 | extern int kernel_read_file(struct file *, void **, loff_t *, loff_t, |
| 2793 | enum kernel_read_file_id); | 2789 | enum kernel_read_file_id); |
| 2794 | extern int kernel_read_file_from_path(char *, void **, loff_t *, loff_t, | 2790 | extern int kernel_read_file_from_path(char *, void **, loff_t *, loff_t, |
| 2795 | enum kernel_read_file_id); | 2791 | enum kernel_read_file_id); |
| 2796 | extern int kernel_read_file_from_fd(int, void **, loff_t *, loff_t, | 2792 | extern int kernel_read_file_from_fd(int, void **, loff_t *, loff_t, |
| 2797 | enum kernel_read_file_id); | 2793 | enum kernel_read_file_id); |
| 2798 | extern ssize_t kernel_write(struct file *, const char *, size_t, loff_t); | 2794 | extern ssize_t kernel_read(struct file *, void *, size_t, loff_t *); |
| 2799 | extern ssize_t __kernel_write(struct file *, const char *, size_t, loff_t *); | 2795 | extern ssize_t kernel_write(struct file *, const void *, size_t, loff_t *); |
| 2796 | extern ssize_t __kernel_write(struct file *, const void *, size_t, loff_t *); | ||
| 2800 | extern struct file * open_exec(const char *); | 2797 | extern struct file * open_exec(const char *); |
| 2801 | 2798 | ||
| 2802 | /* fs/dcache.c -- generic fs support functions */ | 2799 | /* fs/dcache.c -- generic fs support functions */ |
diff --git a/kernel/acct.c b/kernel/acct.c index 5b1284370367..5e72af29ab73 100644 --- a/kernel/acct.c +++ b/kernel/acct.c | |||
| @@ -516,7 +516,7 @@ static void do_acct_process(struct bsd_acct_struct *acct) | |||
| 516 | if (file_start_write_trylock(file)) { | 516 | if (file_start_write_trylock(file)) { |
| 517 | /* it's been opened O_APPEND, so position is irrelevant */ | 517 | /* it's been opened O_APPEND, so position is irrelevant */ |
| 518 | loff_t pos = 0; | 518 | loff_t pos = 0; |
| 519 | __kernel_write(file, (char *)&ac, sizeof(acct_t), &pos); | 519 | __kernel_write(file, &ac, sizeof(acct_t), &pos); |
| 520 | file_end_write(file); | 520 | file_end_write(file); |
| 521 | } | 521 | } |
| 522 | out: | 522 | out: |
diff --git a/kernel/sysctl_binary.c b/kernel/sysctl_binary.c index 02e1859f2ca8..58ea8c03662e 100644 --- a/kernel/sysctl_binary.c +++ b/kernel/sysctl_binary.c | |||
| @@ -986,8 +986,9 @@ static ssize_t bin_intvec(struct file *file, | |||
| 986 | size_t length = oldlen / sizeof(*vec); | 986 | size_t length = oldlen / sizeof(*vec); |
| 987 | char *str, *end; | 987 | char *str, *end; |
| 988 | int i; | 988 | int i; |
| 989 | loff_t pos = 0; | ||
| 989 | 990 | ||
| 990 | result = kernel_read(file, 0, buffer, BUFSZ - 1); | 991 | result = kernel_read(file, buffer, BUFSZ - 1, &pos); |
| 991 | if (result < 0) | 992 | if (result < 0) |
| 992 | goto out_kfree; | 993 | goto out_kfree; |
| 993 | 994 | ||
| @@ -1016,6 +1017,7 @@ static ssize_t bin_intvec(struct file *file, | |||
| 1016 | size_t length = newlen / sizeof(*vec); | 1017 | size_t length = newlen / sizeof(*vec); |
| 1017 | char *str, *end; | 1018 | char *str, *end; |
| 1018 | int i; | 1019 | int i; |
| 1020 | loff_t pos = 0; | ||
| 1019 | 1021 | ||
| 1020 | str = buffer; | 1022 | str = buffer; |
| 1021 | end = str + BUFSZ; | 1023 | end = str + BUFSZ; |
| @@ -1029,7 +1031,7 @@ static ssize_t bin_intvec(struct file *file, | |||
| 1029 | str += scnprintf(str, end - str, "%lu\t", value); | 1031 | str += scnprintf(str, end - str, "%lu\t", value); |
| 1030 | } | 1032 | } |
| 1031 | 1033 | ||
| 1032 | result = kernel_write(file, buffer, str - buffer, 0); | 1034 | result = kernel_write(file, buffer, str - buffer, &pos); |
| 1033 | if (result < 0) | 1035 | if (result < 0) |
| 1034 | goto out_kfree; | 1036 | goto out_kfree; |
| 1035 | } | 1037 | } |
| @@ -1057,8 +1059,9 @@ static ssize_t bin_ulongvec(struct file *file, | |||
| 1057 | size_t length = oldlen / sizeof(*vec); | 1059 | size_t length = oldlen / sizeof(*vec); |
| 1058 | char *str, *end; | 1060 | char *str, *end; |
| 1059 | int i; | 1061 | int i; |
| 1062 | loff_t pos = 0; | ||
| 1060 | 1063 | ||
| 1061 | result = kernel_read(file, 0, buffer, BUFSZ - 1); | 1064 | result = kernel_read(file, buffer, BUFSZ - 1, &pos); |
| 1062 | if (result < 0) | 1065 | if (result < 0) |
| 1063 | goto out_kfree; | 1066 | goto out_kfree; |
| 1064 | 1067 | ||
| @@ -1087,6 +1090,7 @@ static ssize_t bin_ulongvec(struct file *file, | |||
| 1087 | size_t length = newlen / sizeof(*vec); | 1090 | size_t length = newlen / sizeof(*vec); |
| 1088 | char *str, *end; | 1091 | char *str, *end; |
| 1089 | int i; | 1092 | int i; |
| 1093 | loff_t pos = 0; | ||
| 1090 | 1094 | ||
| 1091 | str = buffer; | 1095 | str = buffer; |
| 1092 | end = str + BUFSZ; | 1096 | end = str + BUFSZ; |
| @@ -1100,7 +1104,7 @@ static ssize_t bin_ulongvec(struct file *file, | |||
| 1100 | str += scnprintf(str, end - str, "%lu\t", value); | 1104 | str += scnprintf(str, end - str, "%lu\t", value); |
| 1101 | } | 1105 | } |
| 1102 | 1106 | ||
| 1103 | result = kernel_write(file, buffer, str - buffer, 0); | 1107 | result = kernel_write(file, buffer, str - buffer, &pos); |
| 1104 | if (result < 0) | 1108 | if (result < 0) |
| 1105 | goto out_kfree; | 1109 | goto out_kfree; |
| 1106 | } | 1110 | } |
| @@ -1120,8 +1124,9 @@ static ssize_t bin_uuid(struct file *file, | |||
| 1120 | if (oldval && oldlen) { | 1124 | if (oldval && oldlen) { |
| 1121 | char buf[UUID_STRING_LEN + 1]; | 1125 | char buf[UUID_STRING_LEN + 1]; |
| 1122 | uuid_t uuid; | 1126 | uuid_t uuid; |
| 1127 | loff_t pos = 0; | ||
| 1123 | 1128 | ||
| 1124 | result = kernel_read(file, 0, buf, sizeof(buf) - 1); | 1129 | result = kernel_read(file, buf, sizeof(buf) - 1, &pos); |
| 1125 | if (result < 0) | 1130 | if (result < 0) |
| 1126 | goto out; | 1131 | goto out; |
| 1127 | 1132 | ||
| @@ -1154,8 +1159,9 @@ static ssize_t bin_dn_node_address(struct file *file, | |||
| 1154 | char buf[15], *nodep; | 1159 | char buf[15], *nodep; |
| 1155 | unsigned long area, node; | 1160 | unsigned long area, node; |
| 1156 | __le16 dnaddr; | 1161 | __le16 dnaddr; |
| 1162 | loff_t pos = 0; | ||
| 1157 | 1163 | ||
| 1158 | result = kernel_read(file, 0, buf, sizeof(buf) - 1); | 1164 | result = kernel_read(file, buf, sizeof(buf) - 1, &pos); |
| 1159 | if (result < 0) | 1165 | if (result < 0) |
| 1160 | goto out; | 1166 | goto out; |
| 1161 | 1167 | ||
| @@ -1188,6 +1194,7 @@ static ssize_t bin_dn_node_address(struct file *file, | |||
| 1188 | __le16 dnaddr; | 1194 | __le16 dnaddr; |
| 1189 | char buf[15]; | 1195 | char buf[15]; |
| 1190 | int len; | 1196 | int len; |
| 1197 | loff_t pos = 0; | ||
| 1191 | 1198 | ||
| 1192 | result = -EINVAL; | 1199 | result = -EINVAL; |
| 1193 | if (newlen != sizeof(dnaddr)) | 1200 | if (newlen != sizeof(dnaddr)) |
| @@ -1201,7 +1208,7 @@ static ssize_t bin_dn_node_address(struct file *file, | |||
| 1201 | le16_to_cpu(dnaddr) >> 10, | 1208 | le16_to_cpu(dnaddr) >> 10, |
| 1202 | le16_to_cpu(dnaddr) & 0x3ff); | 1209 | le16_to_cpu(dnaddr) & 0x3ff); |
| 1203 | 1210 | ||
| 1204 | result = kernel_write(file, buf, len, 0); | 1211 | result = kernel_write(file, buf, len, &pos); |
| 1205 | if (result < 0) | 1212 | if (result < 0) |
| 1206 | goto out; | 1213 | goto out; |
| 1207 | } | 1214 | } |
diff --git a/mm/nommu.c b/mm/nommu.c index 53d5175a5c14..17c00d93de2e 100644 --- a/mm/nommu.c +++ b/mm/nommu.c | |||
| @@ -1164,17 +1164,12 @@ static int do_mmap_private(struct vm_area_struct *vma, | |||
| 1164 | 1164 | ||
| 1165 | if (vma->vm_file) { | 1165 | if (vma->vm_file) { |
| 1166 | /* read the contents of a file into the copy */ | 1166 | /* read the contents of a file into the copy */ |
| 1167 | mm_segment_t old_fs; | ||
| 1168 | loff_t fpos; | 1167 | loff_t fpos; |
| 1169 | 1168 | ||
| 1170 | fpos = vma->vm_pgoff; | 1169 | fpos = vma->vm_pgoff; |
| 1171 | fpos <<= PAGE_SHIFT; | 1170 | fpos <<= PAGE_SHIFT; |
| 1172 | 1171 | ||
| 1173 | old_fs = get_fs(); | 1172 | ret = kernel_read(vma->vm_file, base, len, &fpos); |
| 1174 | set_fs(KERNEL_DS); | ||
| 1175 | ret = __vfs_read(vma->vm_file, base, len, &fpos); | ||
| 1176 | set_fs(old_fs); | ||
| 1177 | |||
| 1178 | if (ret < 0) | 1173 | if (ret < 0) |
| 1179 | goto error_free; | 1174 | goto error_free; |
| 1180 | 1175 | ||
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index ddfa86648f95..903a190319b9 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c | |||
| @@ -272,6 +272,7 @@ static int p9_fd_read(struct p9_client *client, void *v, int len) | |||
| 272 | { | 272 | { |
| 273 | int ret; | 273 | int ret; |
| 274 | struct p9_trans_fd *ts = NULL; | 274 | struct p9_trans_fd *ts = NULL; |
| 275 | loff_t pos; | ||
| 275 | 276 | ||
| 276 | if (client && client->status != Disconnected) | 277 | if (client && client->status != Disconnected) |
| 277 | ts = client->trans; | 278 | ts = client->trans; |
| @@ -282,7 +283,8 @@ static int p9_fd_read(struct p9_client *client, void *v, int len) | |||
| 282 | if (!(ts->rd->f_flags & O_NONBLOCK)) | 283 | if (!(ts->rd->f_flags & O_NONBLOCK)) |
| 283 | p9_debug(P9_DEBUG_ERROR, "blocking read ...\n"); | 284 | p9_debug(P9_DEBUG_ERROR, "blocking read ...\n"); |
| 284 | 285 | ||
| 285 | ret = kernel_read(ts->rd, ts->rd->f_pos, v, len); | 286 | pos = ts->rd->f_pos; |
| 287 | ret = kernel_read(ts->rd, v, len, &pos); | ||
| 286 | if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN) | 288 | if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN) |
| 287 | client->status = Disconnected; | 289 | client->status = Disconnected; |
| 288 | return ret; | 290 | return ret; |
| @@ -420,8 +422,7 @@ error: | |||
| 420 | 422 | ||
| 421 | static int p9_fd_write(struct p9_client *client, void *v, int len) | 423 | static int p9_fd_write(struct p9_client *client, void *v, int len) |
| 422 | { | 424 | { |
| 423 | int ret; | 425 | ssize_t ret; |
| 424 | mm_segment_t oldfs; | ||
| 425 | struct p9_trans_fd *ts = NULL; | 426 | struct p9_trans_fd *ts = NULL; |
| 426 | 427 | ||
| 427 | if (client && client->status != Disconnected) | 428 | if (client && client->status != Disconnected) |
| @@ -433,12 +434,7 @@ static int p9_fd_write(struct p9_client *client, void *v, int len) | |||
| 433 | if (!(ts->wr->f_flags & O_NONBLOCK)) | 434 | if (!(ts->wr->f_flags & O_NONBLOCK)) |
| 434 | p9_debug(P9_DEBUG_ERROR, "blocking write ...\n"); | 435 | p9_debug(P9_DEBUG_ERROR, "blocking write ...\n"); |
| 435 | 436 | ||
| 436 | oldfs = get_fs(); | 437 | ret = kernel_write(ts->wr, v, len, &ts->wr->f_pos); |
| 437 | set_fs(get_ds()); | ||
| 438 | /* The cast to a user pointer is valid due to the set_fs() */ | ||
| 439 | ret = vfs_write(ts->wr, (__force void __user *)v, len, &ts->wr->f_pos); | ||
| 440 | set_fs(oldfs); | ||
| 441 | |||
| 442 | if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN) | 438 | if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN) |
| 443 | client->status = Disconnected; | 439 | client->status = Disconnected; |
| 444 | return ret; | 440 | return ret; |
diff --git a/security/keys/big_key.c b/security/keys/big_key.c index 835c1ab30d01..6acb00f6f22c 100644 --- a/security/keys/big_key.c +++ b/security/keys/big_key.c | |||
| @@ -147,6 +147,7 @@ int big_key_preparse(struct key_preparsed_payload *prep) | |||
| 147 | * File content is stored encrypted with randomly generated key. | 147 | * File content is stored encrypted with randomly generated key. |
| 148 | */ | 148 | */ |
| 149 | size_t enclen = ALIGN(datalen, crypto_skcipher_blocksize(big_key_skcipher)); | 149 | size_t enclen = ALIGN(datalen, crypto_skcipher_blocksize(big_key_skcipher)); |
| 150 | loff_t pos = 0; | ||
| 150 | 151 | ||
| 151 | /* prepare aligned data to encrypt */ | 152 | /* prepare aligned data to encrypt */ |
| 152 | data = kmalloc(enclen, GFP_KERNEL); | 153 | data = kmalloc(enclen, GFP_KERNEL); |
| @@ -179,7 +180,7 @@ int big_key_preparse(struct key_preparsed_payload *prep) | |||
| 179 | goto err_enckey; | 180 | goto err_enckey; |
| 180 | } | 181 | } |
| 181 | 182 | ||
| 182 | written = kernel_write(file, data, enclen, 0); | 183 | written = kernel_write(file, data, enclen, &pos); |
| 183 | if (written != enclen) { | 184 | if (written != enclen) { |
| 184 | ret = written; | 185 | ret = written; |
| 185 | if (written >= 0) | 186 | if (written >= 0) |
| @@ -295,6 +296,7 @@ long big_key_read(const struct key *key, char __user *buffer, size_t buflen) | |||
| 295 | u8 *data; | 296 | u8 *data; |
| 296 | u8 *enckey = (u8 *)key->payload.data[big_key_data]; | 297 | u8 *enckey = (u8 *)key->payload.data[big_key_data]; |
| 297 | size_t enclen = ALIGN(datalen, crypto_skcipher_blocksize(big_key_skcipher)); | 298 | size_t enclen = ALIGN(datalen, crypto_skcipher_blocksize(big_key_skcipher)); |
| 299 | loff_t pos = 0; | ||
| 298 | 300 | ||
| 299 | data = kmalloc(enclen, GFP_KERNEL); | 301 | data = kmalloc(enclen, GFP_KERNEL); |
| 300 | if (!data) | 302 | if (!data) |
| @@ -307,7 +309,7 @@ long big_key_read(const struct key *key, char __user *buffer, size_t buflen) | |||
| 307 | } | 309 | } |
| 308 | 310 | ||
| 309 | /* read file to kernel and decrypt */ | 311 | /* read file to kernel and decrypt */ |
| 310 | ret = kernel_read(file, 0, data, enclen); | 312 | ret = kernel_read(file, data, enclen, &pos); |
| 311 | if (ret >= 0 && ret != enclen) { | 313 | if (ret >= 0 && ret != enclen) { |
| 312 | ret = -EIO; | 314 | ret = -EIO; |
| 313 | goto err_fput; | 315 | goto err_fput; |
