diff options
Diffstat (limited to 'drivers')
31 files changed, 166 insertions, 514 deletions
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 0422c47261c3..b38bd06d564c 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -514,14 +514,9 @@ cciss_proc_write(struct file *file, const char __user *buf, if (!buf || length > PAGE_SIZE - 1) return -EINVAL; - buffer = (char *)__get_free_page(GFP_KERNEL); - if (!buffer) - return -ENOMEM; - - err = -EFAULT; - if (copy_from_user(buffer, buf, length)) - goto out; - buffer[length] = '\0'; + buffer = memdup_user_nul(buf, length); + if (IS_ERR(buffer)) + return PTR_ERR(buffer); #ifdef CONFIG_CISS_SCSI_TAPE if (strncmp(ENGAGE_SCSI, buffer, sizeof ENGAGE_SCSI - 1) == 0) { @@ -537,8 +532,7 @@ cciss_proc_write(struct file *file, const char __user *buf, /* might be nice to have "disengage" too, but it's not safely possible. (only 1 module use count, lock issues.) */ -out: - free_page((unsigned long)buffer); + kfree(buffer); return err; } diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 3457ac8c03e2..34997d8ecd64 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -2029,13 +2029,10 @@ static int exec_drive_taskfile(struct driver_data *dd, } if (taskout) { - outbuf = kzalloc(taskout, GFP_KERNEL); - if (outbuf == NULL) { - err = -ENOMEM; - goto abort; - } - if (copy_from_user(outbuf, buf + outtotal, taskout)) { - err = -EFAULT; + outbuf = memdup_user(buf + outtotal, taskout); + if (IS_ERR(outbuf)) { + err = PTR_ERR(outbuf); + outbuf = NULL; goto abort; } outbuf_dma = pci_map_single(dd->pdev, @@ -2050,14 +2047,10 @@ static int exec_drive_taskfile(struct driver_data *dd, } if (taskin) { - inbuf = kzalloc(taskin, GFP_KERNEL); - if (inbuf == NULL) { - err = -ENOMEM; - goto abort; - } - - if (copy_from_user(inbuf, buf + intotal, taskin)) { - err = -EFAULT; + inbuf = memdup_user(buf + intotal, taskin); + if (IS_ERR(inbuf)) { + err = PTR_ERR(inbuf); + inbuf = NULL; goto abort; } inbuf_dma = pci_map_single(dd->pdev, diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 93b3f99b6865..e4c5cc107934 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -827,6 +827,7 @@ static const struct block_device_operations nbd_fops = { .owner = THIS_MODULE, .ioctl = nbd_ioctl, + .compat_ioctl = nbd_ioctl, }; #if IS_ENABLED(CONFIG_DEBUG_FS) diff --git a/drivers/block/rsxx/core.c b/drivers/block/rsxx/core.c index d8b2488aaade..34997df132e2 100644 --- a/drivers/block/rsxx/core.c +++ b/drivers/block/rsxx/core.c @@ -203,14 +203,11 @@ static ssize_t rsxx_cram_write(struct file *fp, const char __user *ubuf, char *buf; ssize_t st; - buf = kzalloc(cnt, GFP_KERNEL); - if (!buf) - return -ENOMEM; + buf = memdup_user(ubuf, cnt); + if (IS_ERR(buf)) + return PTR_ERR(buf); - st = copy_from_user(buf, ubuf, cnt); - if (!st) - st = rsxx_creg_write(card, CREG_ADD_CRAM + (u32)*ppos, cnt, - buf, 1); + st = rsxx_creg_write(card, CREG_ADD_CRAM + (u32)*ppos, cnt, buf, 1); kfree(buf); if (st) return st; diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index c206ccda899b..1b257ea9776a 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c @@ -3186,15 +3186,11 @@ static noinline int mmc_ioctl_dvd_read_struct(struct cdrom_device_info *cdi, if (!CDROM_CAN(CDC_DVD)) return -ENOSYS; - s = kmalloc(size, GFP_KERNEL); - if (!s) - return -ENOMEM; + s = memdup_user(arg, size); + if (IS_ERR(s)) + return PTR_ERR(s); cd_dbg(CD_DO_IOCTL, "entering DVD_READ_STRUCT\n"); - if (copy_from_user(s, arg, size)) { - kfree(s); - return -EFAULT; - } ret = dvd_read_struct(cdi, s, cgc); if (ret) diff --git a/drivers/char/generic_nvram.c b/drivers/char/generic_nvram.c index 6c4f4b5a9dd3..073db9558379 100644 --- a/drivers/char/generic_nvram.c +++ b/drivers/char/generic_nvram.c @@ -20,6 +20,7 @@ #include <linux/fcntl.h> #include <linux/init.h> #include <linux/mutex.h> +#include <linux/pagemap.h> #include <asm/uaccess.h> #include <asm/nvram.h> #ifdef CONFIG_PPC_PMAC @@ -33,24 +34,8 @@ static ssize_t nvram_len; static loff_t nvram_llseek(struct file *file, loff_t offset, int origin) { - switch (origin) { - case 0: - break; - case 1: - offset += file->f_pos; - break; - case 2: - offset += nvram_len; - break; - default: - offset = -1; - } - if (offset < 0) - return -EINVAL; - - file->f_pos = offset; - - return file->f_pos; + return generic_file_llseek_size(file, offset, origin, + MAX_LFS_FILESIZE, nvram_len); } static ssize_t read_nvram(struct file *file, char __user *buf, diff --git a/drivers/char/mbcs.c b/drivers/char/mbcs.c index e5d3e3f7a49b..67d426470e53 100644 --- a/drivers/char/mbcs.c +++ b/drivers/char/mbcs.c @@ -26,6 +26,7 @@ #include <linux/uio.h> #include <linux/mutex.h> #include <linux/slab.h> +#include <linux/pagemap.h> #include <asm/io.h> #include <asm/uaccess.h> #include <asm/pgtable.h> @@ -451,31 +452,8 @@ mbcs_sram_write(struct file * fp, const char __user *buf, size_t len, loff_t * o static loff_t mbcs_sram_llseek(struct file * filp, loff_t off, int whence) { - loff_t newpos; - - switch (whence) { - case SEEK_SET: - newpos = off; - break; - - case SEEK_CUR: - newpos = filp->f_pos + off; - break; - - case SEEK_END: - newpos = MBCS_SRAM_SIZE + off; - break; - - default: /* can't happen */ - return -EINVAL; - } - - if (newpos < 0) - return -EINVAL; - - filp->f_pos = newpos; - - return newpos; + return generic_file_llseek_size(filp, off, whence, MAX_LFS_FILESIZE, + MBCS_SRAM_SIZE); } static uint64_t mbcs_pioaddr(struct mbcs_soft *soft, uint64_t offset) diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c index 97c2d8d433d6..01292328a456 100644 --- a/drivers/char/nvram.c +++ b/drivers/char/nvram.c @@ -110,6 +110,7 @@ #include <linux/io.h> #include <linux/uaccess.h> #include <linux/mutex.h> +#include <linux/pagemap.h> static DEFINE_MUTEX(nvram_mutex); @@ -213,21 +214,8 @@ void nvram_set_checksum(void) static loff_t nvram_llseek(struct file *file, loff_t offset, int origin) { - switch (origin) { - case 0: - /* nothing to do */ - break; - case 1: - offset += file->f_pos; - break; - case 2: - offset += NVRAM_BYTES; - break; - default: - return -EINVAL; - } - - return (offset >= 0) ? (file->f_pos = offset) : -EINVAL; + return generic_file_llseek_size(file, offset, origin, MAX_LFS_FILESIZE, + NVRAM_BYTES); } static ssize_t nvram_read(struct file *file, char __user *buf, diff --git a/drivers/char/nwflash.c b/drivers/char/nwflash.c index e371480d3639..dbe598de9b74 100644 --- a/drivers/char/nwflash.c +++ b/drivers/char/nwflash.c @@ -277,36 +277,7 @@ static loff_t flash_llseek(struct file *file, loff_t offset, int orig) printk(KERN_DEBUG "flash_llseek: offset=0x%X, orig=0x%X.\n", (unsigned int) offset, orig); - switch (orig) { - case 0: - if (offset < 0) { - ret = -EINVAL; - break; - } - - if ((unsigned int) offset > gbFlashSize) { - ret = -EINVAL; - break; - } - - file->f_pos = (unsigned int) offset; - ret = file->f_pos; - break; - case 1: - if ((file->f_pos + offset) > gbFlashSize) { - ret = -EINVAL; - break; - } - if ((file->f_pos + offset) < 0) { - ret = -EINVAL; - break; - } - file->f_pos += offset; - ret = file->f_pos; - break; - default: - ret = -EINVAL; - } + ret = no_seek_end_llseek_size(file, offset, orig, gbFlashSize); mutex_unlock(&flash_mutex); return ret; } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index c6a1b4cc6458..d321222fd92e 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -559,19 +559,10 @@ static int kfd_ioctl_dbg_address_watch(struct file *filep, /* this is the actual buffer to work with */ - args_buff = kmalloc(args->buf_size_in_bytes - - sizeof(*args), GFP_KERNEL); - if (args_buff == NULL) - return -ENOMEM; - - status = copy_from_user(args_buff, cmd_from_user, + args_buff = memdup_user(args_buff, args->buf_size_in_bytes - sizeof(*args)); - - if (status != 0) { - pr_debug("Failed to copy address watch user data\n"); - kfree(args_buff); - return -EINVAL; - } + if (IS_ERR(args_buff)) + return PTR_ERR(args_buff); aw_info.process = p; @@ -677,22 +668,12 @@ static int kfd_ioctl_dbg_wave_control(struct file *filep, if (cmd_from_user == NULL) return -EINVAL; - /* this is the actual buffer to work with */ + /* copy the entire buffer from user */ - args_buff = kmalloc(args->buf_size_in_bytes - sizeof(*args), - GFP_KERNEL); - - if (args_buff == NULL) - return -ENOMEM; - - /* Now copy the entire buffer from user */ - status = copy_from_user(args_buff, cmd_from_user, + args_buff = memdup_user(cmd_from_user, args->buf_size_in_bytes - sizeof(*args)); - if (status != 0) { - pr_debug("Failed to copy wave control user data\n"); - kfree(args_buff); - return -EINVAL; - } + if (IS_ERR(args_buff)) + return PTR_ERR(args_buff); /* move ptr to the start of the "pay-load" area */ wac_info.process = p; diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c index 9abcaa53bd25..f17cb0431833 100644 --- a/drivers/gpu/vga/vgaarb.c +++ b/drivers/gpu/vga/vgaarb.c @@ -1163,12 +1163,8 @@ done: static unsigned int vga_arb_fpoll(struct file *file, poll_table *wait) { - struct vga_arb_private *priv = file->private_data; - pr_debug("%s\n", __func__); - if (priv == NULL) - return -ENODEV; poll_wait(file, &vga_wait_queue, wait); return POLLIN; } @@ -1209,9 +1205,6 @@ static int vga_arb_release(struct inode *inode, struct file *file) pr_debug("%s\n", __func__); - if (priv == NULL) - return -ENODEV; - spin_lock_irqsave(&vga_user_lock, flags); list_del(&priv->list); for (i = 0; i < MAX_USER_CARDS; i++) { diff --git a/drivers/md/bcache/util.c b/drivers/md/bcache/util.c index db3ae4c2b223..dde6172f3f10 100644 --- a/drivers/md/bcache/util.c +++ b/drivers/md/bcache/util.c @@ -230,7 +230,7 @@ void bch_bio_map(struct bio *bio, void *base) BUG_ON(!bio->bi_iter.bi_size); BUG_ON(bio->bi_vcnt); - bv->bv_offset = base ? ((unsigned long) base) % PAGE_SIZE : 0; + bv->bv_offset = base ? offset_in_page(base) : 0; goto start; for (; size; bio->bi_vcnt++, bv++) { diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c index 6b832e06580d..cd77216beff1 100644 --- a/drivers/md/dm-bufio.c +++ b/drivers/md/dm-bufio.c @@ -650,7 +650,7 @@ static void use_inline_bio(struct dm_buffer *b, int rw, sector_t block, do { if (!bio_add_page(&b->bio, virt_to_page(ptr), len < PAGE_SIZE ? len : PAGE_SIZE, - virt_to_phys(ptr) & (PAGE_SIZE - 1))) { + offset_in_page(ptr))) { BUG_ON(b->c->block_size <= PAGE_SIZE); use_dmio(b, rw, block, end_io); return; diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c index 81c5e1a1f363..06d426eb5a30 100644 --- a/drivers/md/dm-io.c +++ b/drivers/md/dm-io.c @@ -246,7 +246,7 @@ static void vm_dp_init(struct dpages *dp, void *data) { dp->get_page = vm_get_page; dp->next_page = vm_next_page; - dp->context_u = ((unsigned long) data) & (PAGE_SIZE - 1); + dp->context_u = offset_in_page(data); dp->context_ptr = data; } @@ -271,7 +271,7 @@ static void km_dp_init(struct dpages *dp, void *data) { dp->get_page = km_get_page; dp->next_page = km_next_page; - dp->context_u = ((unsigned long) data) & (PAGE_SIZE - 1); + dp->context_u = offset_in_page(data); dp->context_ptr = data; } diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c index 3dad2111b7e3..70bb403f69f7 100644 --- a/drivers/mtd/maps/pcmciamtd.c +++ b/drivers/mtd/maps/pcmciamtd.c @@ -30,7 +30,7 @@ struct pcmciamtd_dev { struct pcmcia_device *p_dev; - caddr_t win_base; /* ioremapped address of PCMCIA window */ + void __iomem *win_base; /* ioremapped address of PCMCIA window */ unsigned int win_size; /* size of window */ unsigned int offset; /* offset into card the window currently points at */ struct map_info pcmcia_map; @@ -80,7 +80,7 @@ MODULE_PARM_DESC(mem_type, "Set Memory type (0=Flash, 1=RAM, 2=ROM, default=0)") /* read/write{8,16} copy_{from,to} routines with window remapping * to access whole card */ -static caddr_t remap_window(struct map_info *map, unsigned long to) +static void __iomem *remap_window(struct map_info *map, unsigned long to) { struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1; struct resource *win = (struct resource *) map->map_priv_2; @@ -107,7 +107,7 @@ static caddr_t remap_window(struct map_info *map, unsigned long to) static map_word pcmcia_read8_remap(struct map_info *map, unsigned long ofs) { - caddr_t addr; + void __iomem *addr; map_word d = {{0}}; addr = remap_window(map, ofs); @@ -122,7 +122,7 @@ static map_word pcmcia_read8_remap(struct map_info *map, unsigned long ofs) static map_word pcmcia_read16_remap(struct map_info *map, unsigned long ofs) { - caddr_t addr; + void __iomem *addr; map_word d = {{0}}; addr = remap_window(map, ofs); @@ -143,7 +143,7 @@ static void pcmcia_copy_from_remap(struct map_info *map, void *to, unsigned long pr_debug("to = %p from = %lu len = %zd\n", to, from, len); while(len) { int toread = win_size - (from & (win_size-1)); - caddr_t addr; + void __iomem *addr; if(toread > len) toread = len; @@ -163,7 +163,7 @@ static void pcmcia_copy_from_remap(struct map_info *map, void *to, unsigned long static void pcmcia_write8_remap(struct map_info *map, map_word d, unsigned long adr) { - caddr_t addr = remap_window(map, adr); + void __iomem *addr = remap_window(map, adr); if(!addr) return; @@ -175,7 +175,7 @@ static void pcmcia_write8_remap(struct map_info *map, map_word d, unsigned long static void pcmcia_write16_remap(struct map_info *map, map_word d, unsigned long adr) { - caddr_t addr = remap_window(map, adr); + void __iomem *addr = remap_window(map, adr); if(!addr) return; @@ -192,7 +192,7 @@ static void pcmcia_copy_to_remap(struct map_info *map, unsigned long to, const v pr_debug("to = %lu from = %p len = %zd\n", to, from, len); while(len) { int towrite = win_size - (to & (win_size-1)); - caddr_t addr; + void __iomem *addr; if(towrite > len) towrite = len; @@ -216,7 +216,7 @@ static void pcmcia_copy_to_remap(struct map_info *map, unsigned long to, const v static map_word pcmcia_read8(struct map_info *map, unsigned long ofs) { - caddr_t win_base = (caddr_t)map->map_priv_2; + void __iomem *win_base = (void __iomem *)map->map_priv_2; map_word d = {{0}}; if(DEV_REMOVED(map)) @@ -231,7 +231,7 @@ static map_word pcmcia_read8(struct map_info *map, unsigned long ofs) static map_word pcmcia_read16(struct map_info *map, unsigned long ofs) { - caddr_t win_base = (caddr_t)map->map_priv_2; + void __iomem *win_base = (void __iomem *)map->map_priv_2; map_word d = {{0}}; if(DEV_REMOVED(map)) @@ -246,7 +246,7 @@ static map_word pcmcia_read16(struct map_info *map, unsigned long ofs) static void pcmcia_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) { - caddr_t win_base = (caddr_t)map->map_priv_2; + void __iomem *win_base = (void __iomem *)map->map_priv_2; if(DEV_REMOVED(map)) return; @@ -258,7 +258,7 @@ static void pcmcia_copy_from(struct map_info *map, void *to, unsigned long from, static void pcmcia_write8(struct map_info *map, map_word d, unsigned long adr) { - caddr_t win_base = (caddr_t)map->map_priv_2; + void __iomem *win_base = (void __iomem *)map->map_priv_2; if(DEV_REMOVED(map)) return; @@ -271,7 +271,7 @@ static void pcmcia_write8(struct map_info *map, map_word d, unsigned long adr) static void pcmcia_write16(struct map_info *map, map_word d, unsigned long adr) { - caddr_t win_base = (caddr_t)map->map_priv_2; + void __iomem *win_base = (void __iomem *)map->map_priv_2; if(DEV_REMOVED(map)) return; @@ -284,7 +284,7 @@ static void pcmcia_write16(struct map_info *map, map_word d, unsigned long adr) static void pcmcia_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) { - caddr_t win_base = (caddr_t)map->map_priv_2; + void __iomem *win_base = (void __iomem *)map->map_priv_2; if(DEV_REMOVED(map)) return; diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c index 97bc186f9728..a1d10b85989f 100644 --- a/drivers/net/wireless/ath/wil6210/debugfs.c +++ b/drivers/net/wireless/ath/wil6210/debugfs.c @@ -580,16 +580,10 @@ static ssize_t wil_write_file_rxon(struct file *file, const char __user *buf, long channel; bool on; - char *kbuf = kmalloc(len + 1, GFP_KERNEL); - - if (!kbuf) - return -ENOMEM; - if (copy_from_user(kbuf, buf, len)) { - kfree(kbuf); - return -EIO; - } + char *kbuf = memdup_user_nul(buf, len); - kbuf[len] = '\0'; + if (IS_ERR(kbuf)) + return PTR_ERR(kbuf); rc = kstrtol(kbuf, 0, &channel); kfree(kbuf); if (rc) diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c index 26cbf1dcc662..faed1823c58e 100644 --- a/drivers/net/wireless/libertas/debugfs.c +++ b/drivers/net/wireless/libertas/debugfs.c @@ -56,19 +56,15 @@ static ssize_t lbs_sleepparams_write(struct file *file, loff_t *ppos) { struct lbs_private *priv = file->private_data; - ssize_t buf_size, ret; + ssize_t ret; struct sleep_params sp; int p1, p2, p3, p4, p5, p6; - unsigned long addr = get_zeroed_page(GFP_KERNEL); - char *buf = (char *)addr; - if (!buf) - return -ENOMEM; + char *buf; + + buf = memdup_user_nul(user_buf, min(count, len - 1)); + if (IS_ERR(buf)) + return PTR_ERR(buf); - buf_size = min(count, len - 1); - if (copy_from_user(buf, user_buf, buf_size)) { - ret = -EFAULT; - goto out_unlock; - } ret = sscanf(buf, "%d %d %d %d %d %d", &p1, &p2, &p3, &p4, &p5, &p6); if (ret != 6) { ret = -EINVAL; @@ -88,7 +84,7 @@ static ssize_t lbs_sleepparams_write(struct file *file, ret = -EINVAL; out_unlock: - free_page(addr); + kfree(buf); return ret; } @@ -125,18 +121,14 @@ static ssize_t lbs_host_sleep_write(struct file *file, loff_t *ppos) { struct lbs_private *priv = file->private_data; - ssize_t buf_size, ret; + ssize_t ret; int host_sleep; - unsigned long addr = get_zeroed_page(GFP_KERNEL); - char *buf = (char *)addr; - if (!buf) - return -ENOMEM; + char *buf; + + buf = memdup_user_nul(user_buf, min(count, len - 1)); + if (IS_ERR(buf)) + return PTR_ERR(buf); - buf_size = min(count, len - 1); - if (copy_from_user(buf, user_buf, buf_size)) { - ret = -EFAULT; - goto out_unlock; - } ret = sscanf(buf, "%d", &host_sleep); if (ret != 1) { ret = -EINVAL; @@ -162,7 +154,7 @@ static ssize_t lbs_host_sleep_write(struct file *file, ret = count; out_unlock: - free_page(addr); + kfree(buf); return ret; } @@ -281,21 +273,15 @@ static ssize_t lbs_threshold_write(uint16_t tlv_type, uint16_t event_mask, struct cmd_ds_802_11_subscribe_event *events; struct mrvl_ie_thresholds *tlv; struct lbs_private *priv = file->private_data; - ssize_t buf_size; int value, freq, new_mask; uint16_t curr_mask; char *buf; int ret; - buf = (char *)get_zeroed_page(GFP_KERNEL); - if (!buf) - return -ENOMEM; + buf = memdup_user_nul(userbuf, min(count, len - 1)); + if (IS_ERR(buf)) + return PTR_ERR(buf); - buf_size = min(count, len - 1); - if (copy_from_user(buf, userbuf, buf_size)) { - ret = -EFAULT; - goto out_page; - } ret = sscanf(buf, "%d %d %d", &value, &freq, &new_mask); if (ret != 3) { ret = -EINVAL; @@ -343,7 +329,7 @@ static ssize_t lbs_threshold_write(uint16_t tlv_type, uint16_t event_mask, out_events: kfree(events); out_page: - free_page((unsigned long)buf); + kfree(buf); return ret; } @@ -472,22 +458,15 @@ static ssize_t lbs_rdmac_write(struct file *file, size_t count, loff_t *ppos) { struct lbs_private *priv = file->private_data; - ssize_t res, buf_size; - unsigned long addr = get_zeroed_page(GFP_KERNEL); - char *buf = (char *)addr; - if (!buf) - return -ENOMEM; + char *buf; + + buf = memdup_user_nul(userbuf, min(count, len - 1)); + if (IS_ERR(buf)) + return PTR_ERR(buf); - buf_size = min(count, len - 1); - if (copy_from_user(buf, userbuf, buf_size)) { - res = -EFAULT; - goto out_unlock; - } priv->mac_offset = simple_strtoul(buf, NULL, 16); - res = count; -out_unlock: - free_page(addr); - return res; + kfree(buf); + return count; } static ssize_t lbs_wrmac_write(struct file *file, @@ -496,18 +475,14 @@ static ssize_t lbs_wrmac_write(struct file *file, { struct lbs_private *priv = file->private_data; - ssize_t res, buf_size; + ssize_t res; u32 offset, value; - unsigned long addr = get_zeroed_page(GFP_KERNEL); - char *buf = (char *)addr; - if (!buf) - return -ENOMEM; + char *buf; + + buf = memdup_user_nul(userbuf, min(count, len - 1)); + if (IS_ERR(buf)) + return PTR_ERR(buf); - buf_size = min(count, len - 1); - if (copy_from_user(buf, userbuf, buf_size)) { - res = -EFAULT; - goto out_unlock; - } res = sscanf(buf, "%x %x", &offset, &value); if (res != 2) { res = -EFAULT; @@ -520,7 +495,7 @@ static ssize_t lbs_wrmac_write(struct file *file, if (!res) res = count; out_unlock: - free_page(addr); + kfree(buf); return res; } @@ -554,22 +529,16 @@ static ssize_t lbs_rdbbp_write(struct file *file, size_t count, loff_t *ppos) { struct lbs_private *priv = file->private_data; - ssize_t res, buf_size; - unsigned long addr = get_zeroed_page(GFP_KERNEL); - char *buf = (char *)addr; - if (!buf) - return -ENOMEM; + char *buf; + + buf = memdup_user_nul(userbuf, min(count, len - 1)); + if (IS_ERR(buf)) + return PTR_ERR(buf); - buf_size = min(count, len - 1); - if (copy_from_user(buf, userbuf, buf_size)) { - res = -EFAULT; - goto out_unlock; - } priv->bbp_offset = simple_strtoul(buf, NULL, 16); - res = count; -out_unlock: - free_page(addr); - return res; + kfree(buf); + + return count; } static ssize_t lbs_wrbbp_write(struct file *file, @@ -578,18 +547,14 @@ static ssize_t lbs_wrbbp_write(struct file *file, { struct lbs_private *priv = file->private_data; - ssize_t res, buf_size; + ssize_t res; u32 offset, value; - unsigned long addr = get_zeroed_page(GFP_KERNEL); - char *buf = (char *)addr; - if (!buf) - return -ENOMEM; + char *buf; + + buf = memdup_user_nul(userbuf, min(count, len - 1)); + if (IS_ERR(buf)) + return PTR_ERR(buf); - buf_size = min(count, len - 1); - if (copy_from_user(buf, userbuf, buf_size)) { - res = -EFAULT; - goto out_unlock; - } res = sscanf(buf, "%x %x", &offset, &value); if (res != 2) { res = -EFAULT; @@ -602,7 +567,7 @@ static ssize_t lbs_wrbbp_write(struct file *file, if (!res) res = count; out_unlock: - free_page(addr); + kfree(buf); return res; } @@ -636,22 +601,15 @@ static ssize_t lbs_rdrf_write(struct file *file, size_t count, loff_t *ppos) { struct lbs_private *priv = file->private_data; - ssize_t res, buf_size; - unsigned long addr = get_zeroed_page(GFP_KERNEL); - char *buf = (char *)addr; - if (!buf) - return -ENOMEM; + char *buf; + + buf = memdup_user_nul(userbuf, min(count, len - 1)); + if (IS_ERR(buf)) + return PTR_ERR(buf); - buf_size = min(count, len - 1); - if (copy_from_user(buf, userbuf, buf_size)) { - res = -EFAULT; - goto out_unlock; - } priv->rf_offset = simple_strtoul(buf, NULL, 16); - res = count; -out_unlock: - free_page(addr); - return res; + kfree(buf); + return count; } static ssize_t lbs_wrrf_write(struct file *file, @@ -660,18 +618,14 @@ static ssize_t lbs_wrrf_write(struct file *file, { struct lbs_private *priv = file->private_data; - ssize_t res, buf_size; + ssize_t res; u32 offset, value; - unsigned long addr = get_zeroed_page(GFP_KERNEL); - char *buf = (char *)addr; - if (!buf) - return -ENOMEM; + char *buf; + + buf = memdup_user_nul(userbuf, min(count, len - 1)); + if (IS_ERR(buf)) + return PTR_ERR(buf); - buf_size = min(count, len - 1); - if (copy_from_user(buf, userbuf, buf_size)) { - res = -EFAULT; - goto out_unlock; - } res = sscanf(buf, "%x %x", &offset, &value); if (res != 2) { res = -EFAULT; @@ -684,7 +638,7 @@ static ssize_t lbs_wrrf_write(struct file *file, if (!res) res = count; out_unlock: - free_page(addr); + kfree(buf); return res; } @@ -915,16 +869,9 @@ static ssize_t lbs_debugfs_write(struct file *f, const char __user *buf, if (cnt == 0) return 0; - pdata = kmalloc(cnt + 1, GFP_KERNEL); - if (pdata == NULL) - return 0; - - if (copy_from_user(pdata, buf, cnt)) { - lbs_deb_debugfs("Copy from user failed\n"); - kfree(pdata); - return 0; - } - pdata[cnt] = '\0'; + pdata = memdup_user_nul(buf, cnt); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); p0 = pdata; for (i = 0; i < num_of_items; i++) { diff --git a/drivers/net/wireless/mwifiex/debugfs.c b/drivers/net/wireless/mwifiex/debugfs.c index 9824d8dd2b44..241e1c3fbf08 100644 --- a/drivers/net/wireless/mwifiex/debugfs.c +++ b/drivers/net/wireless/mwifiex/debugfs.c @@ -447,20 +447,13 @@ static ssize_t mwifiex_regrdwr_write(struct file *file, const char __user *ubuf, size_t count, loff_t *ppos) { - unsigned long addr = get_zeroed_page(GFP_KERNEL); - char *buf = (char *) addr; - size_t buf_size = min_t(size_t, count, PAGE_SIZE - 1); + char *buf; int ret; u32 reg_type = 0, reg_offset = 0, reg_value = UINT_MAX; - if (!buf) - return -ENOMEM; - - - if (copy_from_user(buf, ubuf, buf_size)) { - ret = -EFAULT; - goto done; - } + buf = memdup_user_nul(ubuf, min(count, (size_t)(PAGE_SIZE - 1))); + if (IS_ERR(buf)) + return PTR_ERR(buf); sscanf(buf, "%u %x %x", ®_type, ®_offset, ®_value); @@ -474,7 +467,7 @@ mwifiex_regrdwr_write(struct file *file, ret = count; } done: - free_page(addr); + kfree(buf); return ret; } @@ -572,17 +565,11 @@ mwifiex_debug_mask_write(struct file *file, const char __user *ubuf, int ret; unsigned long debug_mask; struct mwifiex_private *priv = (void *)file->private_data; - unsigned long addr = get_zeroed_page(GFP_KERNEL); - char *buf = (void *)addr; - size_t buf_size = min(count, (size_t)(PAGE_SIZE - 1)); + char *buf; - if (!buf) - return -ENOMEM; - - if (copy_from_user(buf, ubuf, buf_size)) { - ret = -EFAULT; - goto done; - } + buf = memdup_user_nul(ubuf, min(count, (size_t)(PAGE_SIZE - 1))); + if (IS_ERR(buf)) + return PTR_ERR(buf); if (kstrtoul(buf, 0, &debug_mask)) { ret = -EINVAL; @@ -592,7 +579,7 @@ mwifiex_debug_mask_write(struct file *file, const char __user *ubuf, priv->adapter->debug_mask = debug_mask; ret = count; done: - free_page(addr); + kfree(buf); return ret; } @@ -609,17 +596,11 @@ mwifiex_memrw_write(struct file *file, const char __user *ubuf, size_t count, struct mwifiex_ds_mem_rw mem_rw; u16 cmd_action; struct mwifiex_private *priv = (void *)file->private_data; - unsigned long addr = get_zeroed_page(GFP_KERNEL); - char *buf = (void *)addr; - size_t buf_size = min(count, (size_t)(PAGE_SIZE - 1)); - - if (!buf) - return -ENOMEM; + char *buf; - if (copy_from_user(buf, ubuf, buf_size)) { - ret = -EFAULT; - goto done; - } + buf = memdup_user_nul(ubuf, min(count, (size_t)(PAGE_SIZE - 1))); + if (IS_ERR(buf)) + return PTR_ERR(buf); ret = sscanf(buf, "%c %x %x", &cmd, &mem_rw.addr, &mem_rw.value); if (ret != 3) { @@ -645,7 +626,7 @@ mwifiex_memrw_write(struct file *file, const char __user *ubuf, size_t count, ret = count; done: - free_page(addr); + kfree(buf); return ret; } @@ -686,20 +667,13 @@ static ssize_t mwifiex_rdeeprom_write(struct file *file, const char __user *ubuf, size_t count, loff_t *ppos) { - unsigned long addr = get_zeroed_page(GFP_KERNEL); - char *buf = (char *) addr; - size_t buf_size = min_t(size_t, count, PAGE_SIZE - 1); + char *buf; int ret = 0; int offset = -1, bytes = -1; - if (!buf) - return -ENOMEM; - - - if (copy_from_user(buf, ubuf, buf_size)) { - ret = -EFAULT; - goto done; - } + buf = memdup_user_nul(ubuf, min(count, (size_t)(PAGE_SIZE - 1))); + if (IS_ERR(buf)) + return PTR_ERR(buf); sscanf(buf, "%d %d", &offset, &bytes); @@ -712,7 +686,7 @@ mwifiex_rdeeprom_write(struct file *file, ret = count; } done: - free_page(addr); + kfree(buf); return ret; } @@ -771,21 +745,15 @@ mwifiex_hscfg_write(struct file *file, const char __user *ubuf, size_t count, loff_t *ppos) { struct mwifiex_private *priv = (void *)file->private_data; - unsigned long addr = get_zeroed_page(GFP_KERNEL); - char *buf = (char *)addr; - size_t buf_size = min_t(size_t, count, PAGE_SIZE - 1); + char *buf; int ret, arg_num; struct mwifiex_ds_hs_cfg hscfg; int conditions = HS_CFG_COND_DEF; u32 gpio = HS_CFG_GPIO_DEF, gap = HS_CFG_GAP_DEF; - if (!buf) - return -ENOMEM; - - if (copy_from_user(buf, ubuf, buf_size)) { - ret = -EFAULT; - goto done; - } + buf = memdup_user_nul(ubuf, min(count, (size_t)(PAGE_SIZE - 1))); + if (IS_ERR(buf)) + return PTR_ERR(buf); arg_num = sscanf(buf, "%d %x %x", &conditions, &gpio, &gap); @@ -823,7 +791,7 @@ mwifiex_hscfg_write(struct file *file, const char __user *ubuf, priv->adapter->hs_enabling = false; ret = count; done: - free_page(addr); + kfree(buf); return ret; } diff --git a/drivers/net/wireless/ti/wlcore/debugfs.c b/drivers/net/wireless/ti/wlcore/debugfs.c index eb43f94a1597..be72306f8c69 100644 --- a/drivers/net/wireless/ti/wlcore/debugfs.c +++ b/drivers/net/wireless/ti/wlcore/debugfs.c @@ -1205,26 +1205,11 @@ err_out: static loff_t dev_mem_seek(struct file *file, loff_t offset, int orig) { - loff_t ret; - /* only requests of dword-aligned size and offset are supported */ if (offset % 4) return -EINVAL; - switch (orig) { - case SEEK_SET: - file->f_pos = offset; - ret = file->f_pos; - break; - case SEEK_CUR: - file->f_pos += offset; - ret = file->f_pos; - break; - default: - ret = -EINVAL; - } - - return ret; + return no_seek_end_llseek(file, offset, orig); } static const struct file_operations dev_mem_ops = { diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c index 0fdedadff7bc..2a67b496a9e2 100644 --- a/drivers/s390/char/vmcp.c +++ b/drivers/s390/char/vmcp.c @@ -88,14 +88,9 @@ vmcp_write(struct file *file, const char __user *buff, size_t count, if (count > 240) return -EINVAL; - cmd = kmalloc(count + 1, GFP_KERNEL); - if (!cmd) - return -ENOMEM; - if (copy_from_user(cmd, buff, count)) { - kfree(cmd); - return -EFAULT; - } - cmd[count] = '\0'; + cmd = memdup_user_nul(buff, count); + if (IS_ERR(cmd)) + return PTR_ERR(cmd); session = file->private_data; if (mutex_lock_interruptible(&session->mutex)) { kfree(cmd); diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c index 0efb27f6f199..6c30e93ab8fa 100644 --- a/drivers/s390/char/vmur.c +++ b/drivers/s390/char/vmur.c @@ -782,24 +782,11 @@ static int ur_release(struct inode *inode, struct file *file) static loff_t ur_llseek(struct file *file, loff_t offset, int whence) { - loff_t newpos; - if ((file->f_flags & O_ACCMODE) != O_RDONLY) return -ESPIPE; /* seek allowed only for reader */ if (offset % PAGE_SIZE) return -ESPIPE; /* only multiples of 4K allowed */ - switch (whence) { - case 0: /* SEEK_SET */ - newpos = offset; - break; - case 1: /* SEEK_CUR */ - newpos = file->f_pos + offset; - break; - default: - return -EINVAL; - } - file->f_pos = newpos; - return newpos; + return no_seek_end_llseek(file, offset, whence); } static const struct file_operations ur_fops = { diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index 823f41fc4bbd..3339b862ec17 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c @@ -385,18 +385,7 @@ static loff_t zcore_lseek(struct file *file, loff_t offset, int orig) loff_t rc; mutex_lock(&zcore_mutex); - switch (orig) { - case 0: - file->f_pos = offset; - rc = file->f_pos; - break; - case 1: - file->f_pos += offset; - rc = file->f_pos; - break; - default: - rc = -EINVAL; - } + rc = no_seek_end_llseek(file, offset, orig); mutex_unlock(&zcore_mutex); return rc; } diff --git a/drivers/sbus/char/openprom.c b/drivers/sbus/char/openprom.c index 5843288f64bc..e077ebd89319 100644 --- a/drivers/sbus/char/openprom.c +++ b/drivers/sbus/char/openprom.c @@ -390,16 +390,9 @@ static int copyin_string(char __user *user, size_t len, char **ptr) if ((ssize_t)len < 0 || (ssize_t)(len + 1) < 0) return -EINVAL; - tmp = kmalloc(len + 1, GFP_KERNEL); - if (!tmp) - return -ENOMEM; - - if (copy_from_user(tmp, user, len)) { - kfree(tmp); - return -EFAULT; - } - - tmp[len] = '\0'; + tmp = memdup_user_nul(user, len); + if (IS_ERR(tmp)) + return PTR_ERR(tmp); *ptr = tmp; diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c index 02f27593013e..31cd6b323a39 100644 --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@ -3139,7 +3139,7 @@ struct file_operations ll_file_operations_noflock = { .lock = ll_file_noflock }; -struct inode_operations ll_file_inode_operations = { +const struct inode_operations ll_file_inode_operations = { .setattr = ll_setattr, .getattr = ll_getattr, .permission = ll_inode_permission, diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index 9096d311e45d..6102b29dbf30 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -705,7 +705,7 @@ extern const struct address_space_operations ll_aops; extern struct file_operations ll_file_operations; extern struct file_operations ll_file_operations_flock; extern struct file_operations ll_file_operations_noflock; -extern struct inode_operations ll_file_inode_operations; +extern const struct inode_operations ll_file_inode_operations; int ll_have_md_lock(struct inode *inode, __u64 *bits, ldlm_mode_t l_req_mode); ldlm_mode_t ll_take_md_lock(struct inode *inode, __u64 bits, @@ -805,7 +805,7 @@ struct inode *search_inode_for_lustre(struct super_block *sb, const struct lu_fid *fid); /* llite/symlink.c */ -extern struct inode_operations ll_fast_symlink_inode_operations; +extern const struct inode_operations ll_fast_symlink_inode_operations; /* llite/llite_close.c */ struct ll_close_queue { diff --git a/drivers/staging/lustre/lustre/llite/namei.c b/drivers/staging/lustre/lustre/llite/namei.c index 2ca22001a534..64db5e86672f 100644 --- a/drivers/staging/lustre/lustre/llite/namei.c +++ b/drivers/staging/lustre/lustre/llite/namei.c @@ -126,9 +126,7 @@ struct inode *ll_iget(struct super_block *sb, ino_t hash, rc = cl_file_inode_init(inode, md); } if (rc != 0) { - make_bad_inode(inode); - unlock_new_inode(inode); - iput(inode); + iget_failed(inode); inode = ERR_PTR(rc); } else unlock_new_inode(inode); diff --git a/drivers/staging/lustre/lustre/llite/symlink.c b/drivers/staging/lustre/lustre/llite/symlink.c index e489a3271f06..2610348f6c72 100644 --- a/drivers/staging/lustre/lustre/llite/symlink.c +++ b/drivers/staging/lustre/lustre/llite/symlink.c @@ -149,7 +149,7 @@ static const char *ll_get_link(struct dentry *dentry, return symname; } -struct inode_operations ll_fast_symlink_inode_operations = { +const struct inode_operations ll_fast_symlink_inode_operations = { .readlink = generic_readlink, .setattr = ll_setattr, .get_link = ll_get_link, diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index 2a3bbdf7eb94..cffa0a0d7de2 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c @@ -661,32 +661,8 @@ static unsigned int usb_device_poll(struct file *file, return 0; } -static loff_t usb_device_lseek(struct file *file, loff_t offset, int orig) -{ - loff_t ret; - - mutex_lock(&file_inode(file)->i_mutex); - - switch (orig) { - case 0: - file->f_pos = offset; - ret = file->f_pos; - break; - case 1: - file->f_pos += offset; - ret = file->f_pos; - break; - case 2: - default: - ret = -EINVAL; - } - - mutex_unlock(&file_inode(file)->i_mutex); - return ret; -} - const struct file_operations usbfs_devices_fops = { - .llseek = usb_device_lseek, + .llseek = no_seek_end_llseek, .read = usb_device_read, .poll = usb_device_poll, }; diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 38ae877c46e3..dbc3e143453a 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -157,30 +157,6 @@ static int connected(struct usb_dev_state *ps) ps->dev->state != USB_STATE_NOTATTACHED); } -static loff_t usbdev_lseek(struct file *file, loff_t offset, int orig) -{ - loff_t ret; - - mutex_lock(&file_inode(file)->i_mutex); - - switch (orig) { - case 0: - file->f_pos = offset; - ret = file->f_pos; - break; - case 1: - file->f_pos += offset; - ret = file->f_pos; - break; - case 2: - default: - ret = -EINVAL; - } - - mutex_unlock(&file_inode(file)->i_mutex); - return ret; -} - static ssize_t usbdev_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) { @@ -2366,7 +2342,7 @@ static unsigned int usbdev_poll(struct file *file, const struct file_operations usbdev_file_operations = { .owner = THIS_MODULE, - .llseek = usbdev_lseek, + .llseek = no_seek_end_llseek, .read = usbdev_read, .poll = usbdev_poll, .unlocked_ioctl = usbdev_ioctl, diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index 1b28a000d5c6..9c6635d43db0 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c @@ -584,27 +584,8 @@ static int uhci_debug_open(struct inode *inode, struct file *file) static loff_t uhci_debug_lseek(struct file *file, loff_t off, int whence) { - struct uhci_debug *up; - loff_t new = -1; - - up = file->private_data; - - /* - * XXX: atomic 64bit seek access, but that needs to be fixed in the VFS - */ - switch (whence) { - case 0: - new = off; - break; - case 1: - new = file->f_pos + off; - break; - } - - if (new < 0 || new > up->size) - return -EINVAL; - - return (file->f_pos = new); + struct uhci_debug *up = file->private_data; + return no_seek_end_llseek_size(file, off, whence, up->size); } static ssize_t uhci_debug_read(struct file *file, char __user *buf, diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index 306d6852ebc7..8efbabacc84e 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c @@ -2825,21 +2825,7 @@ sisusb_lseek(struct file *file, loff_t offset, int orig) return -ENODEV; } - switch (orig) { - case 0: - file->f_pos = offset; - ret = file->f_pos; - /* never negative, no force_successful_syscall needed */ - break; - case 1: - file->f_pos += offset; - ret = file->f_pos; - /* never negative, no force_successful_syscall needed */ - break; - default: - /* seeking relative to "end of file" is not supported */ - ret = -EINVAL; - } + ret = no_seek_end_llseek(file, offset, orig); mutex_unlock(&sisusb->lock); return ret; |