Merge branch 'for-linus' into work.misc
diff --git a/Documentation/printk-formats.txt b/Documentation/printk-formats.txt
index b784c27..6389551 100644
--- a/Documentation/printk-formats.txt
+++ b/Documentation/printk-formats.txt
@@ -250,6 +250,12 @@
Passed by reference.
+block_device names:
+
+ %pg sda, sda1 or loop0p1
+
+ For printing name of block_device pointers.
+
struct va_format:
%pV
diff --git a/arch/blackfin/include/asm/uaccess.h b/arch/blackfin/include/asm/uaccess.h
index 90612a7..12f5d68 100644
--- a/arch/blackfin/include/asm/uaccess.h
+++ b/arch/blackfin/include/asm/uaccess.h
@@ -168,12 +168,6 @@
#define __copy_to_user_inatomic __copy_to_user
#define __copy_from_user_inatomic __copy_from_user
-#define copy_to_user_ret(to, from, n, retval) ({ if (copy_to_user(to, from, n))\
- return retval; })
-
-#define copy_from_user_ret(to, from, n, retval) ({ if (copy_from_user(to, from, n))\
- return retval; })
-
static inline unsigned long __must_check
copy_from_user(void *to, const void __user *from, unsigned long n)
{
diff --git a/arch/m68k/include/asm/uaccess_no.h b/arch/m68k/include/asm/uaccess_no.h
index 68bbe9b..1bdf152 100644
--- a/arch/m68k/include/asm/uaccess_no.h
+++ b/arch/m68k/include/asm/uaccess_no.h
@@ -135,10 +135,6 @@
#define __copy_to_user_inatomic __copy_to_user
#define __copy_from_user_inatomic __copy_from_user
-#define copy_to_user_ret(to,from,n,retval) ({ if (copy_to_user(to,from,n)) return retval; })
-
-#define copy_from_user_ret(to,from,n,retval) ({ if (copy_from_user(to,from,n)) return retval; })
-
/*
* Copy a null terminated string from userspace.
*/
diff --git a/arch/mips/lasat/picvue_proc.c b/arch/mips/lasat/picvue_proc.c
index 2bcd839..b420958 100644
--- a/arch/mips/lasat/picvue_proc.c
+++ b/arch/mips/lasat/picvue_proc.c
@@ -22,7 +22,6 @@
static DEFINE_MUTEX(pvc_mutex);
static char pvc_lines[PVC_NLINES][PVC_LINELEN+1];
static int pvc_linedata[PVC_NLINES];
-static struct proc_dir_entry *pvc_display_dir;
static char *pvc_linename[PVC_NLINES] = {"line1", "line2"};
#define DISPLAY_DIR_NAME "display"
static int scroll_dir, scroll_interval;
@@ -169,22 +168,17 @@
static void pvc_proc_cleanup(void)
{
- int i;
- for (i = 0; i < PVC_NLINES; i++)
- remove_proc_entry(pvc_linename[i], pvc_display_dir);
- remove_proc_entry("scroll", pvc_display_dir);
- remove_proc_entry(DISPLAY_DIR_NAME, NULL);
-
+ remove_proc_subtree(DISPLAY_DIR_NAME, NULL);
del_timer_sync(&timer);
}
static int __init pvc_proc_init(void)
{
- struct proc_dir_entry *proc_entry;
+ struct proc_dir_entry *dir, *proc_entry;
int i;
- pvc_display_dir = proc_mkdir(DISPLAY_DIR_NAME, NULL);
- if (pvc_display_dir == NULL)
+ dir = proc_mkdir(DISPLAY_DIR_NAME, NULL);
+ if (dir == NULL)
goto error;
for (i = 0; i < PVC_NLINES; i++) {
@@ -192,12 +186,12 @@
pvc_linedata[i] = i;
}
for (i = 0; i < PVC_NLINES; i++) {
- proc_entry = proc_create_data(pvc_linename[i], 0644, pvc_display_dir,
+ proc_entry = proc_create_data(pvc_linename[i], 0644, dir,
&pvc_line_proc_fops, &pvc_linedata[i]);
if (proc_entry == NULL)
goto error;
}
- proc_entry = proc_create("scroll", 0644, pvc_display_dir,
+ proc_entry = proc_create("scroll", 0644, dir,
&pvc_scroll_proc_fops);
if (proc_entry == NULL)
goto error;
diff --git a/arch/mn10300/include/asm/uaccess.h b/arch/mn10300/include/asm/uaccess.h
index 5372787..20f7bf6 100644
--- a/arch/mn10300/include/asm/uaccess.h
+++ b/arch/mn10300/include/asm/uaccess.h
@@ -110,21 +110,6 @@
#define __put_user(x, ptr) __put_user_nocheck((x), (ptr), sizeof(*(ptr)))
#define __get_user(x, ptr) __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
-/*
- * The "xxx_ret" versions return constant specified in third argument, if
- * something bad happens. These macros can be optimized for the
- * case of just returning from the function xxx_ret is used.
- */
-
-#define put_user_ret(x, ptr, ret) \
- ({ if (put_user((x), (ptr))) return (ret); })
-#define get_user_ret(x, ptr, ret) \
- ({ if (get_user((x), (ptr))) return (ret); })
-#define __put_user_ret(x, ptr, ret) \
- ({ if (__put_user((x), (ptr))) return (ret); })
-#define __get_user_ret(x, ptr, ret) \
- ({ if (__get_user((x), (ptr))) return (ret); })
-
struct __large_struct { unsigned long buf[100]; };
#define __m(x) (*(struct __large_struct *)(x))
diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h
index 2a8ebae..b7c20f0 100644
--- a/arch/powerpc/include/asm/uaccess.h
+++ b/arch/powerpc/include/asm/uaccess.h
@@ -274,21 +274,6 @@
__gu_err; \
})
-#ifndef __powerpc64__
-#define __get_user64_nocheck(x, ptr, size) \
-({ \
- long __gu_err; \
- long long __gu_val; \
- __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
- __chk_user_ptr(ptr); \
- if (!is_kernel_addr((unsigned long)__gu_addr)) \
- might_fault(); \
- __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
- (x) = (__force __typeof__(*(ptr)))__gu_val; \
- __gu_err; \
-})
-#endif /* __powerpc64__ */
-
#define __get_user_check(x, ptr, size) \
({ \
long __gu_err = -EFAULT; \
diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c
index 32e2652..0cab9e8 100644
--- a/arch/powerpc/kernel/nvram_64.c
+++ b/arch/powerpc/kernel/nvram_64.c
@@ -27,6 +27,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/kmsg_dump.h>
+#include <linux/pagemap.h>
#include <linux/pstore.h>
#include <linux/zlib.h>
#include <asm/uaccess.h>
@@ -733,24 +734,10 @@
static loff_t dev_nvram_llseek(struct file *file, loff_t offset, int origin)
{
- int size;
-
if (ppc_md.nvram_size == NULL)
return -ENODEV;
- size = ppc_md.nvram_size();
-
- switch (origin) {
- case 1:
- offset += file->f_pos;
- break;
- case 2:
- offset += size;
- break;
- }
- if (offset < 0)
- return -EINVAL;
- file->f_pos = offset;
- return file->f_pos;
+ return generic_file_llseek_size(file, offset, origin, MAX_LFS_FILESIZE,
+ ppc_md.nvram_size());
}
diff --git a/arch/sparc/include/asm/uaccess_32.h b/arch/sparc/include/asm/uaccess_32.h
index 64ee103..57aca27 100644
--- a/arch/sparc/include/asm/uaccess_32.h
+++ b/arch/sparc/include/asm/uaccess_32.h
@@ -205,31 +205,6 @@
__gu_ret; \
})
-#define __get_user_check_ret(x, addr, size, type, retval) ({ \
- register unsigned long __gu_val __asm__ ("l1"); \
- if (__access_ok(addr, size)) { \
- switch (size) { \
- case 1: \
- __get_user_asm_ret(__gu_val, ub, addr, retval); \
- break; \
- case 2: \
- __get_user_asm_ret(__gu_val, uh, addr, retval); \
- break; \
- case 4: \
- __get_user_asm_ret(__gu_val, , addr, retval); \
- break; \
- case 8: \
- __get_user_asm_ret(__gu_val, d, addr, retval); \
- break; \
- default: \
- if (__get_user_bad()) \
- return retval; \
- } \
- x = (__force type) __gu_val; \
- } else \
- return retval; \
-})
-
#define __get_user_nocheck(x, addr, size, type) ({ \
register int __gu_ret; \
register unsigned long __gu_val; \
@@ -247,20 +222,6 @@
__gu_ret; \
})
-#define __get_user_nocheck_ret(x, addr, size, type, retval) ({ \
- register unsigned long __gu_val __asm__ ("l1"); \
- switch (size) { \
- case 1: __get_user_asm_ret(__gu_val, ub, addr, retval); break; \
- case 2: __get_user_asm_ret(__gu_val, uh, addr, retval); break; \
- case 4: __get_user_asm_ret(__gu_val, , addr, retval); break; \
- case 8: __get_user_asm_ret(__gu_val, d, addr, retval); break; \
- default: \
- if (__get_user_bad()) \
- return retval; \
- } \
- x = (__force type) __gu_val; \
-})
-
#define __get_user_asm(x, size, addr, ret) \
__asm__ __volatile__( \
"/* Get user asm, inline. */\n" \
@@ -281,32 +242,6 @@
: "=&r" (ret), "=&r" (x) : "m" (*__m(addr)), \
"i" (-EFAULT))
-#define __get_user_asm_ret(x, size, addr, retval) \
-if (__builtin_constant_p(retval) && retval == -EFAULT) \
- __asm__ __volatile__( \
- "/* Get user asm ret, inline. */\n" \
- "1:\t" "ld"#size " %1, %0\n\n\t" \
- ".section __ex_table,#alloc\n\t" \
- ".align 4\n\t" \
- ".word 1b,__ret_efault\n\n\t" \
- ".previous\n\t" \
- : "=&r" (x) : "m" (*__m(addr))); \
-else \
- __asm__ __volatile__( \
- "/* Get user asm ret, inline. */\n" \
- "1:\t" "ld"#size " %1, %0\n\n\t" \
- ".section .fixup,#alloc,#execinstr\n\t" \
- ".align 4\n" \
- "3:\n\t" \
- "ret\n\t" \
- " restore %%g0, %2, %%o0\n\n\t" \
- ".previous\n\t" \
- ".section __ex_table,#alloc\n\t" \
- ".align 4\n\t" \
- ".word 1b, 3b\n\n\t" \
- ".previous\n\t" \
- : "=&r" (x) : "m" (*__m(addr)), "i" (retval))
-
int __get_user_bad(void);
unsigned long __copy_user(void __user *to, const void __user *from, unsigned long size);
diff --git a/arch/sparc/include/asm/uaccess_64.h b/arch/sparc/include/asm/uaccess_64.h
index ea6e9a2..e9a51d6 100644
--- a/arch/sparc/include/asm/uaccess_64.h
+++ b/arch/sparc/include/asm/uaccess_64.h
@@ -179,20 +179,6 @@
__gu_ret; \
})
-#define __get_user_nocheck_ret(data, addr, size, type, retval) ({ \
- register unsigned long __gu_val __asm__ ("l1"); \
- switch (size) { \
- case 1: __get_user_asm_ret(__gu_val, ub, addr, retval); break; \
- case 2: __get_user_asm_ret(__gu_val, uh, addr, retval); break; \
- case 4: __get_user_asm_ret(__gu_val, uw, addr, retval); break; \
- case 8: __get_user_asm_ret(__gu_val, x, addr, retval); break; \
- default: \
- if (__get_user_bad()) \
- return retval; \
- } \
- data = (__force type) __gu_val; \
-})
-
#define __get_user_asm(x, size, addr, ret) \
__asm__ __volatile__( \
"/* Get user asm, inline. */\n" \
@@ -214,32 +200,6 @@
: "=r" (ret), "=r" (x) : "r" (__m(addr)), \
"i" (-EFAULT))
-#define __get_user_asm_ret(x, size, addr, retval) \
-if (__builtin_constant_p(retval) && retval == -EFAULT) \
- __asm__ __volatile__( \
- "/* Get user asm ret, inline. */\n" \
- "1:\t" "ld"#size "a [%1] %%asi, %0\n\n\t" \
- ".section __ex_table,\"a\"\n\t" \
- ".align 4\n\t" \
- ".word 1b,__ret_efault\n\n\t" \
- ".previous\n\t" \
- : "=r" (x) : "r" (__m(addr))); \
-else \
- __asm__ __volatile__( \
- "/* Get user asm ret, inline. */\n" \
- "1:\t" "ld"#size "a [%1] %%asi, %0\n\n\t" \
- ".section .fixup,#alloc,#execinstr\n\t" \
- ".align 4\n" \
- "3:\n\t" \
- "ret\n\t" \
- " restore %%g0, %2, %%o0\n\n\t" \
- ".previous\n\t" \
- ".section __ex_table,\"a\"\n\t" \
- ".align 4\n\t" \
- ".word 1b, 3b\n\n\t" \
- ".previous\n\t" \
- : "=r" (x) : "r" (__m(addr)), "i" (retval))
-
int __get_user_bad(void);
unsigned long __must_check ___copy_from_user(void *to,
diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c
index 6f80936..1122886 100644
--- a/arch/sparc/kernel/mdesc.c
+++ b/arch/sparc/kernel/mdesc.c
@@ -1033,25 +1033,9 @@
static loff_t mdesc_llseek(struct file *file, loff_t offset, int whence)
{
- struct mdesc_handle *hp;
+ struct mdesc_handle *hp = file->private_data;
- switch (whence) {
- case SEEK_CUR:
- offset += file->f_pos;
- break;
- case SEEK_SET:
- break;
- default:
- return -EINVAL;
- }
-
- hp = file->private_data;
- if (offset > hp->handle_size)
- return -EINVAL;
- else
- file->f_pos = offset;
-
- return offset;
+ return no_seek_end_llseek_size(file, offset, whence, hp->handle_size);
}
/* mdesc_close() - /dev/mdesc is being closed, release the reference to
diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c
index f6b911c..3a4b587 100644
--- a/arch/um/drivers/hostaudio_kern.c
+++ b/arch/um/drivers/hostaudio_kern.c
@@ -105,13 +105,9 @@
printk(KERN_DEBUG "hostaudio: write called, count = %d\n", count);
#endif
- kbuf = kmalloc(count, GFP_KERNEL);
- if (kbuf == NULL)
- return -ENOMEM;
-
- err = -EFAULT;
- if (copy_from_user(kbuf, buffer, count))
- goto out;
+ kbuf = memdup_user(buffer, count);
+ if (IS_ERR(kbuf))
+ return PTR_ERR(kbuf);
err = os_write_file(state->fd, kbuf, count);
if (err < 0)
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index 29880c9..b821b13 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -748,19 +748,11 @@
{
char *buf;
- buf = kmalloc(count + 1, GFP_KERNEL);
- if (buf == NULL)
- return -ENOMEM;
-
- if (copy_from_user(buf, buffer, count)) {
- count = -EFAULT;
- goto out;
- }
-
- buf[count] = '\0';
+ buf = memdup_user_nul(buffer, count);
+ if (IS_ERR(buf))
+ return PTR_ERR(buf);
mconsole_notify(notify_socket, MCONSOLE_USER_NOTIFY, buf, count);
- out:
kfree(buf);
return count;
}
diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c
index bd3507d..2836de3 100644
--- a/arch/x86/kernel/cpuid.c
+++ b/arch/x86/kernel/cpuid.c
@@ -58,28 +58,6 @@
&cmd->eax, &cmd->ebx, &cmd->ecx, &cmd->edx);
}
-static loff_t cpuid_seek(struct file *file, loff_t offset, int orig)
-{
- loff_t ret;
- struct inode *inode = file->f_mapping->host;
-
- mutex_lock(&inode->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;
- default:
- ret = -EINVAL;
- }
- mutex_unlock(&inode->i_mutex);
- return ret;
-}
-
static ssize_t cpuid_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
@@ -132,7 +110,7 @@
*/
static const struct file_operations cpuid_fops = {
.owner = THIS_MODULE,
- .llseek = cpuid_seek,
+ .llseek = no_seek_end_llseek,
.read = cpuid_read,
.open = cpuid_open,
};
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c
index 113e707..64f9616 100644
--- a/arch/x86/kernel/msr.c
+++ b/arch/x86/kernel/msr.c
@@ -45,28 +45,6 @@
static struct class *msr_class;
-static loff_t msr_seek(struct file *file, loff_t offset, int orig)
-{
- loff_t ret;
- struct inode *inode = file_inode(file);
-
- mutex_lock(&inode->i_mutex);
- 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;
- }
- mutex_unlock(&inode->i_mutex);
- return ret;
-}
-
static ssize_t msr_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
@@ -194,7 +172,7 @@
*/
static const struct file_operations msr_fops = {
.owner = THIS_MODULE,
- .llseek = msr_seek,
+ .llseek = no_seek_end_llseek,
.read = msr_read,
.write = msr_write,
.open = msr_open,
diff --git a/arch/xtensa/platforms/iss/simdisk.c b/arch/xtensa/platforms/iss/simdisk.c
index 3c3ace2..f58a4e6 100644
--- a/arch/xtensa/platforms/iss/simdisk.c
+++ b/arch/xtensa/platforms/iss/simdisk.c
@@ -227,16 +227,12 @@
static ssize_t proc_write_simdisk(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
- char *tmp = kmalloc(count + 1, GFP_KERNEL);
+ char *tmp = memdup_user_nul(buf, count);
struct simdisk *dev = PDE_DATA(file_inode(file));
int err;
- if (tmp == NULL)
- return -ENOMEM;
- if (copy_from_user(tmp, buf, count)) {
- err = -EFAULT;
- goto out_free;
- }
+ if (IS_ERR(tmp))
+ return PTR_ERR(tmp);
err = simdisk_detach(dev);
if (err != 0)
@@ -244,8 +240,6 @@
if (count > 0 && tmp[count - 1] == '\n')
tmp[count - 1] = 0;
- else
- tmp[count] = 0;
if (tmp[0])
err = simdisk_attach(dev, tmp);
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 0422c47..b38bd06 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -514,14 +514,9 @@
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 @@
/* 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 3457ac8..34997d8 100644
--- a/drivers/block/mtip32xx/mtip32xx.c
+++ b/drivers/block/mtip32xx/mtip32xx.c
@@ -2029,13 +2029,10 @@
}
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 @@
}
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/rsxx/core.c b/drivers/block/rsxx/core.c
index d8b2488..34997df 100644
--- a/drivers/block/rsxx/core.c
+++ b/drivers/block/rsxx/core.c
@@ -203,14 +203,11 @@
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 c206ccd..1b257ea 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -3186,15 +3186,11 @@
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 6c4f4b5..073db95 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 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 e5d3e3f..67d4264 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 @@
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 97c2d8d..0129232 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 @@
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 e371480..dbe598d 100644
--- a/drivers/char/nwflash.c
+++ b/drivers/char/nwflash.c
@@ -277,36 +277,7 @@
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 c6a1b4c..d321222 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
@@ -559,19 +559,10 @@
/* 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 @@
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 9abcaa5..f17cb04 100644
--- a/drivers/gpu/vga/vgaarb.c
+++ b/drivers/gpu/vga/vgaarb.c
@@ -1163,12 +1163,8 @@
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 @@
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 db3ae4c..dde6172 100644
--- a/drivers/md/bcache/util.c
+++ b/drivers/md/bcache/util.c
@@ -230,7 +230,7 @@
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 2dd3308..adeb8d0 100644
--- a/drivers/md/dm-bufio.c
+++ b/drivers/md/dm-bufio.c
@@ -630,7 +630,7 @@
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 81c5e1a..06d426e 100644
--- a/drivers/md/dm-io.c
+++ b/drivers/md/dm-io.c
@@ -246,7 +246,7 @@
{
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 @@
{
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 3dad211..70bb403 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 @@
/* 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 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_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 @@
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_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_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 @@
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 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_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 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_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_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_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 97bc186..a1d10b8 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -580,16 +580,10 @@
long channel;
bool on;
- char *kbuf = kmalloc(len + 1, GFP_KERNEL);
+ char *kbuf = memdup_user_nul(buf, len);
- if (!kbuf)
- return -ENOMEM;
- if (copy_from_user(kbuf, buf, len)) {
- kfree(kbuf);
- return -EIO;
- }
-
- 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 26cbf1d..faed182 100644
--- a/drivers/net/wireless/libertas/debugfs.c
+++ b/drivers/net/wireless/libertas/debugfs.c
@@ -56,19 +56,15 @@
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_size = min(count, len - 1);
- if (copy_from_user(buf, user_buf, buf_size)) {
- ret = -EFAULT;
- goto out_unlock;
- }
+ buf = memdup_user_nul(user_buf, min(count, len - 1));
+ if (IS_ERR(buf))
+ return PTR_ERR(buf);
+
ret = sscanf(buf, "%d %d %d %d %d %d", &p1, &p2, &p3, &p4, &p5, &p6);
if (ret != 6) {
ret = -EINVAL;
@@ -88,7 +84,7 @@
ret = -EINVAL;
out_unlock:
- free_page(addr);
+ kfree(buf);
return ret;
}
@@ -125,18 +121,14 @@
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_size = min(count, len - 1);
- if (copy_from_user(buf, user_buf, buf_size)) {
- ret = -EFAULT;
- goto out_unlock;
- }
+ buf = memdup_user_nul(user_buf, min(count, len - 1));
+ if (IS_ERR(buf))
+ return PTR_ERR(buf);
+
ret = sscanf(buf, "%d", &host_sleep);
if (ret != 1) {
ret = -EINVAL;
@@ -162,7 +154,7 @@
ret = count;
out_unlock:
- free_page(addr);
+ kfree(buf);
return ret;
}
@@ -281,21 +273,15 @@
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 @@
out_events:
kfree(events);
out_page:
- free_page((unsigned long)buf);
+ kfree(buf);
return ret;
}
@@ -472,22 +458,15 @@
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_size = min(count, len - 1);
- if (copy_from_user(buf, userbuf, buf_size)) {
- res = -EFAULT;
- goto out_unlock;
- }
+ buf = memdup_user_nul(userbuf, min(count, len - 1));
+ if (IS_ERR(buf))
+ return PTR_ERR(buf);
+
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 @@
{
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_size = min(count, len - 1);
- if (copy_from_user(buf, userbuf, buf_size)) {
- res = -EFAULT;
- goto out_unlock;
- }
+ buf = memdup_user_nul(userbuf, min(count, len - 1));
+ if (IS_ERR(buf))
+ return PTR_ERR(buf);
+
res = sscanf(buf, "%x %x", &offset, &value);
if (res != 2) {
res = -EFAULT;
@@ -520,7 +495,7 @@
if (!res)
res = count;
out_unlock:
- free_page(addr);
+ kfree(buf);
return res;
}
@@ -554,22 +529,16 @@
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_size = min(count, len - 1);
- if (copy_from_user(buf, userbuf, buf_size)) {
- res = -EFAULT;
- goto out_unlock;
- }
+ buf = memdup_user_nul(userbuf, min(count, len - 1));
+ if (IS_ERR(buf))
+ return PTR_ERR(buf);
+
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 @@
{
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_size = min(count, len - 1);
- if (copy_from_user(buf, userbuf, buf_size)) {
- res = -EFAULT;
- goto out_unlock;
- }
+ buf = memdup_user_nul(userbuf, min(count, len - 1));
+ if (IS_ERR(buf))
+ return PTR_ERR(buf);
+
res = sscanf(buf, "%x %x", &offset, &value);
if (res != 2) {
res = -EFAULT;
@@ -602,7 +567,7 @@
if (!res)
res = count;
out_unlock:
- free_page(addr);
+ kfree(buf);
return res;
}
@@ -636,22 +601,15 @@
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_size = min(count, len - 1);
- if (copy_from_user(buf, userbuf, buf_size)) {
- res = -EFAULT;
- goto out_unlock;
- }
+ buf = memdup_user_nul(userbuf, min(count, len - 1));
+ if (IS_ERR(buf))
+ return PTR_ERR(buf);
+
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 @@
{
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_size = min(count, len - 1);
- if (copy_from_user(buf, userbuf, buf_size)) {
- res = -EFAULT;
- goto out_unlock;
- }
+ buf = memdup_user_nul(userbuf, min(count, len - 1));
+ if (IS_ERR(buf))
+ return PTR_ERR(buf);
+
res = sscanf(buf, "%x %x", &offset, &value);
if (res != 2) {
res = -EFAULT;
@@ -684,7 +638,7 @@
if (!res)
res = count;
out_unlock:
- free_page(addr);
+ kfree(buf);
return res;
}
@@ -915,16 +869,9 @@
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 9824d8d..241e1c3 100644
--- a/drivers/net/wireless/mwifiex/debugfs.c
+++ b/drivers/net/wireless/mwifiex/debugfs.c
@@ -447,20 +447,13 @@
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 @@
ret = count;
}
done:
- free_page(addr);
+ kfree(buf);
return ret;
}
@@ -572,17 +565,11 @@
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 @@
priv->adapter->debug_mask = debug_mask;
ret = count;
done:
- free_page(addr);
+ kfree(buf);
return ret;
}
@@ -609,17 +596,11 @@
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));
+ 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);
ret = sscanf(buf, "%c %x %x", &cmd, &mem_rw.addr, &mem_rw.value);
if (ret != 3) {
@@ -645,7 +626,7 @@
ret = count;
done:
- free_page(addr);
+ kfree(buf);
return ret;
}
@@ -686,20 +667,13 @@
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 @@
ret = count;
}
done:
- free_page(addr);
+ kfree(buf);
return ret;
}
@@ -771,21 +745,15 @@
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 @@
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 eb43f94..be72306 100644
--- a/drivers/net/wireless/ti/wlcore/debugfs.c
+++ b/drivers/net/wireless/ti/wlcore/debugfs.c
@@ -1205,26 +1205,11 @@
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 0fdedad..2a67b49 100644
--- a/drivers/s390/char/vmcp.c
+++ b/drivers/s390/char/vmcp.c
@@ -88,14 +88,9 @@
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 0efb27f..6c30e93a 100644
--- a/drivers/s390/char/vmur.c
+++ b/drivers/s390/char/vmur.c
@@ -782,24 +782,11 @@
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 823f41f..3339b86 100644
--- a/drivers/s390/char/zcore.c
+++ b/drivers/s390/char/zcore.c
@@ -385,18 +385,7 @@
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 5843288..e077ebd 100644
--- a/drivers/sbus/char/openprom.c
+++ b/drivers/sbus/char/openprom.c
@@ -390,16 +390,9 @@
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 02f2759..31cd6b3 100644
--- a/drivers/staging/lustre/lustre/llite/file.c
+++ b/drivers/staging/lustre/lustre/llite/file.c
@@ -3139,7 +3139,7 @@
.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 9096d31..6102b29 100644
--- a/drivers/staging/lustre/lustre/llite/llite_internal.h
+++ b/drivers/staging/lustre/lustre/llite/llite_internal.h
@@ -705,7 +705,7 @@
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 @@
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 2ca2200..64db5e8 100644
--- a/drivers/staging/lustre/lustre/llite/namei.c
+++ b/drivers/staging/lustre/lustre/llite/namei.c
@@ -126,9 +126,7 @@
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 69b2036..32c4cf4 100644
--- a/drivers/staging/lustre/lustre/llite/symlink.c
+++ b/drivers/staging/lustre/lustre/llite/symlink.c
@@ -146,7 +146,7 @@
ptlrpc_req_finished(cookie);
}
-struct inode_operations ll_fast_symlink_inode_operations = {
+const struct inode_operations ll_fast_symlink_inode_operations = {
.readlink = generic_readlink,
.setattr = ll_setattr,
.follow_link = ll_follow_link,
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c
index 2a3bbdf..cffa0a0 100644
--- a/drivers/usb/core/devices.c
+++ b/drivers/usb/core/devices.c
@@ -661,32 +661,8 @@
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 38ae877c..dbc3e14 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -157,30 +157,6 @@
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 @@
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 1b28a00..9c6635d 100644
--- a/drivers/usb/host/uhci-debug.c
+++ b/drivers/usb/host/uhci-debug.c
@@ -584,27 +584,8 @@
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 306d685..8efbaba 100644
--- a/drivers/usb/misc/sisusbvga/sisusb.c
+++ b/drivers/usb/misc/sisusbvga/sisusb.c
@@ -2825,21 +2825,7 @@
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;
diff --git a/fs/adfs/adfs.h b/fs/adfs/adfs.h
index 24575d9..ea4aba5 100644
--- a/fs/adfs/adfs.h
+++ b/fs/adfs/adfs.h
@@ -45,7 +45,7 @@
struct adfs_sb_info {
union { struct {
struct adfs_discmap *s_map; /* bh list containing map */
- struct adfs_dir_ops *s_dir; /* directory operations */
+ const struct adfs_dir_ops *s_dir; /* directory operations */
};
struct rcu_head rcu; /* used only at shutdown time */
};
@@ -168,8 +168,8 @@
extern const struct inode_operations adfs_dir_inode_operations;
extern const struct file_operations adfs_dir_operations;
extern const struct dentry_operations adfs_dentry_operations;
-extern struct adfs_dir_ops adfs_f_dir_ops;
-extern struct adfs_dir_ops adfs_fplus_dir_ops;
+extern const struct adfs_dir_ops adfs_f_dir_ops;
+extern const struct adfs_dir_ops adfs_fplus_dir_ops;
extern int adfs_dir_update(struct super_block *sb, struct object_info *obj,
int wait);
diff --git a/fs/adfs/dir.c b/fs/adfs/dir.c
index 51c279a..fd4cf2c 100644
--- a/fs/adfs/dir.c
+++ b/fs/adfs/dir.c
@@ -21,7 +21,7 @@
{
struct inode *inode = file_inode(file);
struct super_block *sb = inode->i_sb;
- struct adfs_dir_ops *ops = ADFS_SB(sb)->s_dir;
+ const struct adfs_dir_ops *ops = ADFS_SB(sb)->s_dir;
struct object_info obj;
struct adfs_dir dir;
int ret = 0;
@@ -69,7 +69,7 @@
{
int ret = -EINVAL;
#ifdef CONFIG_ADFS_FS_RW
- struct adfs_dir_ops *ops = ADFS_SB(sb)->s_dir;
+ const struct adfs_dir_ops *ops = ADFS_SB(sb)->s_dir;
struct adfs_dir dir;
printk(KERN_INFO "adfs_dir_update: object %06X in dir %06X\n",
@@ -129,7 +129,7 @@
adfs_dir_lookup_byname(struct inode *inode, struct qstr *name, struct object_info *obj)
{
struct super_block *sb = inode->i_sb;
- struct adfs_dir_ops *ops = ADFS_SB(sb)->s_dir;
+ const struct adfs_dir_ops *ops = ADFS_SB(sb)->s_dir;
struct adfs_dir dir;
int ret;
diff --git a/fs/adfs/dir_f.c b/fs/adfs/dir_f.c
index 4bbe853..0fbfd0b 100644
--- a/fs/adfs/dir_f.c
+++ b/fs/adfs/dir_f.c
@@ -476,7 +476,7 @@
dir->sb = NULL;
}
-struct adfs_dir_ops adfs_f_dir_ops = {
+const struct adfs_dir_ops adfs_f_dir_ops = {
.read = adfs_f_read,
.setpos = adfs_f_setpos,
.getnext = adfs_f_getnext,
diff --git a/fs/adfs/dir_fplus.c b/fs/adfs/dir_fplus.c
index 82d14cd..c92cfb6 100644
--- a/fs/adfs/dir_fplus.c
+++ b/fs/adfs/dir_fplus.c
@@ -256,7 +256,7 @@
dir->sb = NULL;
}
-struct adfs_dir_ops adfs_fplus_dir_ops = {
+const struct adfs_dir_ops adfs_fplus_dir_ops = {
.read = adfs_fplus_read,
.setpos = adfs_fplus_setpos,
.getnext = adfs_fplus_getnext,
diff --git a/fs/afs/proc.c b/fs/afs/proc.c
index 24a905b..2853b40 100644
--- a/fs/afs/proc.c
+++ b/fs/afs/proc.c
@@ -230,14 +230,9 @@
if (size <= 1 || size >= PAGE_SIZE)
return -EINVAL;
- kbuf = kmalloc(size + 1, GFP_KERNEL);
- if (!kbuf)
- return -ENOMEM;
-
- ret = -EFAULT;
- if (copy_from_user(kbuf, buf, size) != 0)
- goto done;
- kbuf[size] = 0;
+ kbuf = memdup_user_nul(buf, size);
+ if (IS_ERR(kbuf))
+ return PTR_ERR(kbuf);
/* trim to first NL */
name = memchr(kbuf, '\n', size);
@@ -315,15 +310,9 @@
if (size <= 1 || size >= PAGE_SIZE)
return -EINVAL;
- ret = -ENOMEM;
- kbuf = kmalloc(size + 1, GFP_KERNEL);
- if (!kbuf)
- goto nomem;
-
- ret = -EFAULT;
- if (copy_from_user(kbuf, buf, size) != 0)
- goto infault;
- kbuf[size] = 0;
+ kbuf = memdup_user_nul(buf, size);
+ if (IS_ERR(kbuf))
+ return PTR_ERR(kbuf);
/* trim to first NL */
s = memchr(kbuf, '\n', size);
@@ -337,9 +326,7 @@
if (ret >= 0)
ret = size; /* consume everything, always */
-infault:
kfree(kbuf);
-nomem:
_leave(" = %d", ret);
return ret;
}
diff --git a/fs/bad_inode.c b/fs/bad_inode.c
index 861b1e1..103f5d7 100644
--- a/fs/bad_inode.c
+++ b/fs/bad_inode.c
@@ -192,7 +192,7 @@
* Returns true if the inode in question has been marked as bad.
*/
-int is_bad_inode(struct inode *inode)
+bool is_bad_inode(struct inode *inode)
{
return (inode->i_op == &bad_inode_ops);
}
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 44d4a1e..01b8e0d 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1042,12 +1042,9 @@
static void flush_disk(struct block_device *bdev, bool kill_dirty)
{
if (__invalidate_device(bdev, kill_dirty)) {
- char name[BDEVNAME_SIZE] = "";
-
- if (bdev->bd_disk)
- disk_name(bdev->bd_disk, 0, name);
printk(KERN_WARNING "VFS: busy inodes on changed media or "
- "resized disk %s\n", name);
+ "resized disk %s\n",
+ bdev->bd_disk ? bdev->bd_disk->disk_name : "");
}
if (!bdev->bd_disk)
@@ -1071,12 +1068,9 @@
disk_size = (loff_t)get_capacity(disk) << 9;
bdev_size = i_size_read(bdev->bd_inode);
if (disk_size != bdev_size) {
- char name[BDEVNAME_SIZE];
-
- disk_name(disk, 0, name);
printk(KERN_INFO
"%s: detected capacity change from %lld to %lld\n",
- name, bdev_size, disk_size);
+ disk->disk_name, bdev_size, disk_size);
i_size_write(bdev->bd_inode, disk_size);
flush_disk(bdev, false);
}
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 24154e4..a0434c17 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -1514,9 +1514,7 @@
if ((flags ^ s->s_flags) & MS_RDONLY)
error = -EBUSY;
} else {
- char b[BDEVNAME_SIZE];
-
- strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
+ snprintf(s->s_id, sizeof(s->s_id), "%pg", bdev);
btrfs_sb(s)->bdev_holder = fs_type;
error = btrfs_fill_super(s, fs_devices, data,
flags & MS_SILENT ? 1 : 0);
diff --git a/fs/buffer.c b/fs/buffer.c
index 4f4cd95..e1632ab 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -134,13 +134,10 @@
static void buffer_io_error(struct buffer_head *bh, char *msg)
{
- char b[BDEVNAME_SIZE];
-
if (!test_bit(BH_Quiet, &bh->b_state))
printk_ratelimited(KERN_ERR
- "Buffer I/O error on dev %s, logical block %llu%s\n",
- bdevname(bh->b_bdev, b),
- (unsigned long long)bh->b_blocknr, msg);
+ "Buffer I/O error on dev %pg, logical block %llu%s\n",
+ bh->b_bdev, (unsigned long long)bh->b_blocknr, msg);
}
/*
@@ -237,15 +234,13 @@
* elsewhere, don't buffer_error if we had some unmapped buffers
*/
if (all_mapped) {
- char b[BDEVNAME_SIZE];
-
printk("__find_get_block_slow() failed. "
"block=%llu, b_blocknr=%llu\n",
(unsigned long long)block,
(unsigned long long)bh->b_blocknr);
printk("b_state=0x%08lx, b_size=%zu\n",
bh->b_state, bh->b_size);
- printk("device %s blocksize: %d\n", bdevname(bdev, b),
+ printk("device %pg blocksize: %d\n", bdev,
1 << bd_inode->i_blkbits);
}
out_unlock:
@@ -531,10 +526,8 @@
static void do_thaw_one(struct super_block *sb, void *unused)
{
- char b[BDEVNAME_SIZE];
while (sb->s_bdev && !thaw_bdev(sb->s_bdev, sb))
- printk(KERN_WARNING "Emergency Thaw on %s\n",
- bdevname(sb->s_bdev, b));
+ printk(KERN_WARNING "Emergency Thaw on %pg\n", sb->s_bdev);
}
static void do_thaw_all(struct work_struct *work)
@@ -1074,12 +1067,10 @@
* pagecache index. (this comparison is done using sector_t types).
*/
if (unlikely(index != block >> sizebits)) {
- char b[BDEVNAME_SIZE];
-
printk(KERN_ERR "%s: requested out-of-range block %llu for "
- "device %s\n",
+ "device %pg\n",
__func__, (unsigned long long)block,
- bdevname(bdev, b));
+ bdev);
return -EIO;
}
diff --git a/fs/cachefiles/daemon.c b/fs/cachefiles/daemon.c
index f601def..452e98d 100644
--- a/fs/cachefiles/daemon.c
+++ b/fs/cachefiles/daemon.c
@@ -226,15 +226,9 @@
return -EOPNOTSUPP;
/* drag the command string into the kernel so we can parse it */
- data = kmalloc(datalen + 1, GFP_KERNEL);
- if (!data)
- return -ENOMEM;
-
- ret = -EFAULT;
- if (copy_from_user(data, _data, datalen) != 0)
- goto error;
-
- data[datalen] = '\0';
+ data = memdup_user_nul(_data, datalen);
+ if (IS_ERR(data))
+ return PTR_ERR(data);
ret = -EINVAL;
if (memchr(data, '\0', datalen))
diff --git a/fs/compat.c b/fs/compat.c
index 6fd272d..a71936a 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -792,7 +792,7 @@
const void __user *, data)
{
char *kernel_type;
- unsigned long data_page;
+ void *options;
char *kernel_dev;
int retval;
@@ -806,26 +806,25 @@
if (IS_ERR(kernel_dev))
goto out1;
- retval = copy_mount_options(data, &data_page);
- if (retval < 0)
+ options = copy_mount_options(data);
+ retval = PTR_ERR(options);
+ if (IS_ERR(options))
goto out2;
- retval = -EINVAL;
-
- if (kernel_type && data_page) {
+ if (kernel_type && options) {
if (!strcmp(kernel_type, NCPFS_NAME)) {
- do_ncp_super_data_conv((void *)data_page);
+ do_ncp_super_data_conv(options);
} else if (!strcmp(kernel_type, NFS4_NAME)) {
- if (do_nfs4_super_data_conv((void *) data_page))
+ retval = -EINVAL;
+ if (do_nfs4_super_data_conv(options))
goto out3;
}
}
- retval = do_mount(kernel_dev, dir_name, kernel_type,
- flags, (void*)data_page);
+ retval = do_mount(kernel_dev, dir_name, kernel_type, flags, options);
out3:
- free_page(data_page);
+ kfree(options);
out2:
kfree(kernel_dev);
out1:
diff --git a/fs/coredump.c b/fs/coredump.c
index 1777331..b3c153c 100644
--- a/fs/coredump.c
+++ b/fs/coredump.c
@@ -32,6 +32,7 @@
#include <linux/pipe_fs_i.h>
#include <linux/oom.h>
#include <linux/compat.h>
+#include <linux/timekeeping.h>
#include <asm/uaccess.h>
#include <asm/mmu_context.h>
@@ -232,9 +233,10 @@
break;
/* UNIX time of coredump */
case 't': {
- struct timeval tv;
- do_gettimeofday(&tv);
- err = cn_printf(cn, "%lu", tv.tv_sec);
+ time64_t time;
+
+ time = ktime_get_real_seconds();
+ err = cn_printf(cn, "%lld", time);
break;
}
/* hostname */
diff --git a/fs/dcache.c b/fs/dcache.c
index 5c33aeb..670f789 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -3303,18 +3303,18 @@
* @new_dentry: new dentry
* @old_dentry: old dentry
*
- * Returns 1 if new_dentry is a subdirectory of the parent (at any depth).
- * Returns 0 otherwise.
+ * Returns true if new_dentry is a subdirectory of the parent (at any depth).
+ * Returns false otherwise.
* Caller must ensure that "new_dentry" is pinned before calling is_subdir()
*/
-int is_subdir(struct dentry *new_dentry, struct dentry *old_dentry)
+bool is_subdir(struct dentry *new_dentry, struct dentry *old_dentry)
{
- int result;
+ bool result;
unsigned seq;
if (new_dentry == old_dentry)
- return 1;
+ return true;
do {
/* for restarting inner loop in case of seq retry */
@@ -3325,9 +3325,9 @@
*/
rcu_read_lock();
if (d_ancestor(old_dentry, new_dentry))
- result = 1;
+ result = true;
else
- result = 0;
+ result = false;
rcu_read_unlock();
} while (read_seqretry(&rename_lock, seq));
diff --git a/fs/dlm/user.c b/fs/dlm/user.c
index 173b387..1925d6d 100644
--- a/fs/dlm/user.c
+++ b/fs/dlm/user.c
@@ -515,14 +515,9 @@
if (count > sizeof(struct dlm_write_request) + DLM_RESNAME_MAXLEN)
return -EINVAL;
- kbuf = kzalloc(count + 1, GFP_NOFS);
- if (!kbuf)
- return -ENOMEM;
-
- if (copy_from_user(kbuf, buf, count)) {
- error = -EFAULT;
- goto out_free;
- }
+ kbuf = memdup_user_nul(buf, count);
+ if (!IS_ERR(kbuf))
+ return PTR_ERR(kbuf);
if (check_version(kbuf)) {
error = -EBADE;
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index e2e47ba..92c5dae 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -282,9 +282,7 @@
if (rc) {
ecryptfs_do_unlink(directory_inode, ecryptfs_dentry,
ecryptfs_inode);
- make_bad_inode(ecryptfs_inode);
- unlock_new_inode(ecryptfs_inode);
- iput(ecryptfs_inode);
+ iget_failed(ecryptfs_inode);
goto out;
}
unlock_new_inode(ecryptfs_inode);
diff --git a/fs/exec.c b/fs/exec.c
index b06623a..828ec5f 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -119,7 +119,7 @@
int error = PTR_ERR(tmp);
static const struct open_flags uselib_flags = {
.open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC,
- .acc_mode = MAY_READ | MAY_EXEC | MAY_OPEN,
+ .acc_mode = MAY_READ | MAY_EXEC,
.intent = LOOKUP_OPEN,
.lookup_flags = LOOKUP_FOLLOW,
};
@@ -763,7 +763,7 @@
int err;
struct open_flags open_exec_flags = {
.open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC,
- .acc_mode = MAY_EXEC | MAY_OPEN,
+ .acc_mode = MAY_EXEC,
.intent = LOOKUP_OPEN,
.lookup_flags = LOOKUP_FOLLOW,
};
diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c
index fa70848..a21c259 100644
--- a/fs/ext2/xattr.c
+++ b/fs/ext2/xattr.c
@@ -77,10 +77,8 @@
printk("\n"); \
} while (0)
# define ea_bdebug(bh, f...) do { \
- char b[BDEVNAME_SIZE]; \
- printk(KERN_DEBUG "block %s:%lu: ", \
- bdevname(bh->b_bdev, b), \
- (unsigned long) bh->b_blocknr); \
+ printk(KERN_DEBUG "block %pg:%lu: ", \
+ bh->b_bdev, (unsigned long) bh->b_blocknr); \
printk(f); \
printk("\n"); \
} while (0)
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c
index 17fbe38..090b349 100644
--- a/fs/ext4/page-io.c
+++ b/fs/ext4/page-io.c
@@ -52,9 +52,8 @@
*/
static void buffer_io_error(struct buffer_head *bh)
{
- char b[BDEVNAME_SIZE];
- printk_ratelimited(KERN_ERR "Buffer I/O error on device %s, logical block %llu\n",
- bdevname(bh->b_bdev, b),
+ printk_ratelimited(KERN_ERR "Buffer I/O error on device %pg, logical block %llu\n",
+ bh->b_bdev,
(unsigned long long)bh->b_blocknr);
}
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index 6b6b3e7..ec4e50c 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -68,10 +68,8 @@
printk("\n"); \
} while (0)
# define ea_bdebug(bh, f...) do { \
- char b[BDEVNAME_SIZE]; \
- printk(KERN_DEBUG "block %s:%lu: ", \
- bdevname(bh->b_bdev, b), \
- (unsigned long) bh->b_blocknr); \
+ printk(KERN_DEBUG "block %pg:%lu: ", \
+ bh->b_bdev, (unsigned long) bh->b_blocknr); \
printk(f); \
printk("\n"); \
} while (0)
diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c
index 478e5d5..ad1b18a 100644
--- a/fs/f2fs/debug.c
+++ b/fs/f2fs/debug.c
@@ -211,12 +211,10 @@
mutex_lock(&f2fs_stat_mutex);
list_for_each_entry(si, &f2fs_stat_list, stat_list) {
- char devname[BDEVNAME_SIZE];
-
update_general_status(si->sbi);
- seq_printf(s, "\n=====[ partition info(%s). #%d ]=====\n",
- bdevname(si->sbi->sb->s_bdev, devname), i++);
+ seq_printf(s, "\n=====[ partition info(%pg). #%d ]=====\n",
+ si->sbi->sb->s_bdev, i++);
seq_printf(s, "[SB: 1] [CP: 2] [SIT: %d] [NAT: %d] ",
si->sit_area_segs, si->nat_area_segs);
seq_printf(s, "[SSA: %d] [MAIN: %d",
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 9db5500..ec6067c 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1602,13 +1602,11 @@
static inline bool f2fs_may_extent_tree(struct inode *inode)
{
- mode_t mode = inode->i_mode;
-
if (!test_opt(F2FS_I_SB(inode), EXTENT_CACHE) ||
is_inode_flag_set(F2FS_I(inode), FI_NO_EXTENT))
return false;
- return S_ISREG(mode);
+ return S_ISREG(inode->i_mode);
}
static inline void *f2fs_kvmalloc(size_t size, gfp_t flags)
@@ -2121,7 +2119,7 @@
static inline bool f2fs_may_encrypt(struct inode *inode)
{
#ifdef CONFIG_F2FS_FS_ENCRYPTION
- mode_t mode = inode->i_mode;
+ umode_t mode = inode->i_mode;
return (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode));
#else
diff --git a/fs/file.c b/fs/file.c
index 39f8f15..1aed0ad 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -25,9 +25,9 @@
int sysctl_nr_open __read_mostly = 1024*1024;
int sysctl_nr_open_min = BITS_PER_LONG;
-/* our max() is unusable in constant expressions ;-/ */
-#define __const_max(x, y) ((x) < (y) ? (x) : (y))
-int sysctl_nr_open_max = __const_max(INT_MAX, ~(size_t)0/sizeof(void *)) &
+/* our min() is unusable in constant expressions ;-/ */
+#define __const_min(x, y) ((x) < (y) ? (x) : (y))
+int sysctl_nr_open_max = __const_min(INT_MAX, ~(size_t)0/sizeof(void *)) &
-BITS_PER_LONG;
static void *alloc_fdmem(size_t size)
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index baab99b..001c666 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -1315,9 +1315,7 @@
if ((flags ^ s->s_flags) & MS_RDONLY)
goto error_super;
} else {
- char b[BDEVNAME_SIZE];
-
- strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
+ snprintf(s->s_id, sizeof(s->s_id), "%pg", bdev);
sb_set_blocksize(s, block_size(bdev));
error = fill_super(s, &args, flags & MS_SILENT ? 1 : 0);
if (error)
diff --git a/fs/hfs/mdb.c b/fs/hfs/mdb.c
index aa3f0d6..a3ec3ae 100644
--- a/fs/hfs/mdb.c
+++ b/fs/hfs/mdb.c
@@ -166,7 +166,7 @@
pr_warn("continuing without an alternate MDB\n");
}
- HFS_SB(sb)->bitmap = (__be32 *)__get_free_pages(GFP_KERNEL, PAGE_SIZE < 8192 ? 1 : 0);
+ HFS_SB(sb)->bitmap = kmalloc(8192, GFP_KERNEL);
if (!HFS_SB(sb)->bitmap)
goto out;
@@ -360,7 +360,7 @@
unload_nls(HFS_SB(sb)->nls_io);
unload_nls(HFS_SB(sb)->nls_disk);
- free_pages((unsigned long)HFS_SB(sb)->bitmap, PAGE_SIZE < 8192 ? 1 : 0);
+ kfree(HFS_SB(sb)->bitmap);
kfree(HFS_SB(sb));
sb->s_fs_info = NULL;
}
diff --git a/fs/hpfs/map.c b/fs/hpfs/map.c
index a69bbc1..a136929 100644
--- a/fs/hpfs/map.c
+++ b/fs/hpfs/map.c
@@ -133,7 +133,7 @@
void hpfs_load_hotfix_map(struct super_block *s, struct hpfs_spare_block *spareblock)
{
struct quad_buffer_head qbh;
- u32 *directory;
+ __le32 *directory;
u32 n_hotfixes, n_used_hotfixes;
unsigned i;
diff --git a/fs/internal.h b/fs/internal.h
index e38c08c..b71deee 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -55,7 +55,7 @@
/*
* namespace.c
*/
-extern int copy_mount_options(const void __user *, unsigned long *);
+extern void *copy_mount_options(const void __user *);
extern char *copy_mount_string(const void __user *);
extern struct vfsmount *lookup_mnt(struct path *);
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
index ca181e8..081dff0 100644
--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/transaction.c
@@ -764,13 +764,11 @@
static void warn_dirty_buffer(struct buffer_head *bh)
{
- char b[BDEVNAME_SIZE];
-
printk(KERN_WARNING
- "JBD2: Spotted dirty metadata buffer (dev = %s, blocknr = %llu). "
+ "JBD2: Spotted dirty metadata buffer (dev = %pg, blocknr = %llu). "
"There's a risk of filesystem corruption in case of system "
"crash.\n",
- bdevname(bh->b_bdev, b), (unsigned long long)bh->b_blocknr);
+ bh->b_bdev, (unsigned long long)bh->b_blocknr);
}
/* Call t_frozen trigger and copy buffer data into jh->b_frozen_data. */
diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c
index a69bdf2..a270cb7 100644
--- a/fs/jfs/jfs_logmgr.c
+++ b/fs/jfs/jfs_logmgr.c
@@ -1835,17 +1835,16 @@
for (i = 0; i < LOGPAGES;) {
char *buffer;
uint offset;
- struct page *page;
+ struct page *page = alloc_page(GFP_KERNEL | __GFP_ZERO);
- buffer = (char *) get_zeroed_page(GFP_KERNEL);
- if (buffer == NULL)
+ if (!page)
goto error;
- page = virt_to_page(buffer);
+ buffer = page_address(page);
for (offset = 0; offset < PAGE_SIZE; offset += LOGPSIZE) {
lbuf = kmalloc(sizeof(struct lbuf), GFP_KERNEL);
if (lbuf == NULL) {
if (offset == 0)
- free_page((unsigned long) buffer);
+ __free_page(page);
goto error;
}
if (offset) /* we already have one reference */
diff --git a/fs/minix/itree_v1.c b/fs/minix/itree_v1.c
index 282e15a..46ca39d 100644
--- a/fs/minix/itree_v1.c
+++ b/fs/minix/itree_v1.c
@@ -24,16 +24,15 @@
static int block_to_path(struct inode * inode, long block, int offsets[DEPTH])
{
int n = 0;
- char b[BDEVNAME_SIZE];
if (block < 0) {
- printk("MINIX-fs: block_to_path: block %ld < 0 on dev %s\n",
- block, bdevname(inode->i_sb->s_bdev, b));
+ printk("MINIX-fs: block_to_path: block %ld < 0 on dev %pg\n",
+ block, inode->i_sb->s_bdev);
} else if (block >= (minix_sb(inode->i_sb)->s_max_size/BLOCK_SIZE)) {
if (printk_ratelimit())
printk("MINIX-fs: block_to_path: "
- "block %ld too big on dev %s\n",
- block, bdevname(inode->i_sb->s_bdev, b));
+ "block %ld too big on dev %pg\n",
+ block, inode->i_sb->s_bdev);
} else if (block < 7) {
offsets[n++] = block;
} else if ((block -= 7) < 512) {
diff --git a/fs/minix/itree_v2.c b/fs/minix/itree_v2.c
index 78e2d93..1ee1013 100644
--- a/fs/minix/itree_v2.c
+++ b/fs/minix/itree_v2.c
@@ -26,18 +26,17 @@
static int block_to_path(struct inode * inode, long block, int offsets[DEPTH])
{
int n = 0;
- char b[BDEVNAME_SIZE];
struct super_block *sb = inode->i_sb;
if (block < 0) {
- printk("MINIX-fs: block_to_path: block %ld < 0 on dev %s\n",
- block, bdevname(sb->s_bdev, b));
+ printk("MINIX-fs: block_to_path: block %ld < 0 on dev %pg\n",
+ block, sb->s_bdev);
} else if ((u64)block * (u64)sb->s_blocksize >=
minix_sb(sb)->s_max_size) {
if (printk_ratelimit())
printk("MINIX-fs: block_to_path: "
- "block %ld too big on dev %s\n",
- block, bdevname(sb->s_bdev, b));
+ "block %ld too big on dev %pg\n",
+ block, sb->s_bdev);
} else if (block < DIRCOUNT) {
offsets[n++] = block;
} else if ((block -= DIRCOUNT) < INDIRCOUNT(sb)) {
diff --git a/fs/namei.c b/fs/namei.c
index 0c3974c..45c702e 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -534,10 +534,8 @@
current->nameidata = old;
if (old)
old->total_link_count = now->total_link_count;
- if (now->stack != now->internal) {
+ if (now->stack != now->internal)
kfree(now->stack);
- now->stack = now->internal;
- }
}
static int __nd_alloc_stack(struct nameidata *nd)
@@ -657,7 +655,7 @@
* Path walking has 2 modes, rcu-walk and ref-walk (see
* Documentation/filesystems/path-lookup.txt). In situations when we can't
* continue in RCU mode, we attempt to drop out of rcu-walk mode and grab
- * normal reference counts on dentries and vfsmounts to transition to rcu-walk
+ * normal reference counts on dentries and vfsmounts to transition to ref-walk
* mode. Refcounts are grabbed at the last known good point before rcu-walk
* got stuck, so ref-walk may continue from there. If this is not successful
* (eg. a seqcount has changed), then failure is returned and it's up to caller
@@ -807,19 +805,19 @@
static void set_root(struct nameidata *nd)
{
- get_fs_root(current->fs, &nd->root);
-}
-
-static void set_root_rcu(struct nameidata *nd)
-{
struct fs_struct *fs = current->fs;
- unsigned seq;
- do {
- seq = read_seqcount_begin(&fs->seq);
- nd->root = fs->root;
- nd->root_seq = __read_seqcount_begin(&nd->root.dentry->d_seq);
- } while (read_seqcount_retry(&fs->seq, seq));
+ if (nd->flags & LOOKUP_RCU) {
+ unsigned seq;
+
+ do {
+ seq = read_seqcount_begin(&fs->seq);
+ nd->root = fs->root;
+ nd->root_seq = __read_seqcount_begin(&nd->root.dentry->d_seq);
+ } while (read_seqcount_retry(&fs->seq, seq));
+ } else {
+ get_fs_root(fs, &nd->root);
+ }
}
static void path_put_conditional(struct path *path, struct nameidata *nd)
@@ -841,6 +839,26 @@
nd->path.dentry = path->dentry;
}
+static int nd_jump_root(struct nameidata *nd)
+{
+ if (nd->flags & LOOKUP_RCU) {
+ struct dentry *d;
+ nd->path = nd->root;
+ d = nd->path.dentry;
+ nd->inode = d->d_inode;
+ nd->seq = nd->root_seq;
+ if (unlikely(read_seqcount_retry(&d->d_seq, nd->seq)))
+ return -ECHILD;
+ } else {
+ path_put(&nd->path);
+ nd->path = nd->root;
+ path_get(&nd->path);
+ nd->inode = nd->path.dentry->d_inode;
+ }
+ nd->flags |= LOOKUP_JUMPED;
+ return 0;
+}
+
/*
* Helper to directly jump to a known parsed path from ->follow_link,
* caller must have taken a reference to path beforehand.
@@ -1015,25 +1033,10 @@
}
}
if (*res == '/') {
- if (nd->flags & LOOKUP_RCU) {
- struct dentry *d;
- if (!nd->root.mnt)
- set_root_rcu(nd);
- nd->path = nd->root;
- d = nd->path.dentry;
- nd->inode = d->d_inode;
- nd->seq = nd->root_seq;
- if (unlikely(read_seqcount_retry(&d->d_seq, nd->seq)))
- return ERR_PTR(-ECHILD);
- } else {
- if (!nd->root.mnt)
- set_root(nd);
- path_put(&nd->path);
- nd->path = nd->root;
- path_get(&nd->root);
- nd->inode = nd->path.dentry->d_inode;
- }
- nd->flags |= LOOKUP_JUMPED;
+ if (!nd->root.mnt)
+ set_root(nd);
+ if (unlikely(nd_jump_root(nd)))
+ return ERR_PTR(-ECHILD);
while (unlikely(*++res == '/'))
;
}
@@ -1294,8 +1297,6 @@
static int follow_dotdot_rcu(struct nameidata *nd)
{
struct inode *inode = nd->inode;
- if (!nd->root.mnt)
- set_root_rcu(nd);
while (1) {
if (path_equal(&nd->path, &nd->root))
@@ -1415,9 +1416,6 @@
static int follow_dotdot(struct nameidata *nd)
{
- if (!nd->root.mnt)
- set_root(nd);
-
while(1) {
struct dentry *old = nd->path.dentry;
@@ -1655,6 +1653,8 @@
static inline int handle_dots(struct nameidata *nd, int type)
{
if (type == LAST_DOTDOT) {
+ if (!nd->root.mnt)
+ set_root(nd);
if (nd->flags & LOOKUP_RCU) {
return follow_dotdot_rcu(nd);
} else
@@ -2020,18 +2020,19 @@
}
nd->root.mnt = NULL;
+ nd->path.mnt = NULL;
+ nd->path.dentry = NULL;
nd->m_seq = read_seqbegin(&mount_lock);
if (*s == '/') {
- if (flags & LOOKUP_RCU) {
+ if (flags & LOOKUP_RCU)
rcu_read_lock();
- set_root_rcu(nd);
- nd->seq = nd->root_seq;
- } else {
- set_root(nd);
- path_get(&nd->root);
- }
- nd->path = nd->root;
+ set_root(nd);
+ if (likely(!nd_jump_root(nd)))
+ return s;
+ nd->root.mnt = NULL;
+ rcu_read_unlock();
+ return ERR_PTR(-ECHILD);
} else if (nd->dfd == AT_FDCWD) {
if (flags & LOOKUP_RCU) {
struct fs_struct *fs = current->fs;
@@ -2042,11 +2043,14 @@
do {
seq = read_seqcount_begin(&fs->seq);
nd->path = fs->pwd;
+ nd->inode = nd->path.dentry->d_inode;
nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq);
} while (read_seqcount_retry(&fs->seq, seq));
} else {
get_fs_pwd(current->fs, &nd->path);
+ nd->inode = nd->path.dentry->d_inode;
}
+ return s;
} else {
/* Caller must check execute permissions on the starting path component */
struct fd f = fdget_raw(nd->dfd);
@@ -2076,16 +2080,6 @@
fdput(f);
return s;
}
-
- nd->inode = nd->path.dentry->d_inode;
- if (!(flags & LOOKUP_RCU))
- return s;
- if (likely(!read_seqcount_retry(&nd->path.dentry->d_seq, nd->seq)))
- return s;
- if (!(nd->flags & LOOKUP_ROOT))
- nd->root.mnt = NULL;
- rcu_read_unlock();
- return ERR_PTR(-ECHILD);
}
static const char *trailing_symlink(struct nameidata *nd)
@@ -2669,10 +2663,6 @@
struct inode *inode = dentry->d_inode;
int error;
- /* O_PATH? */
- if (!acc_mode)
- return 0;
-
if (!inode)
return -ENOENT;
@@ -2694,7 +2684,7 @@
break;
}
- error = inode_permission(inode, acc_mode);
+ error = inode_permission(inode, MAY_OPEN | acc_mode);
if (error)
return error;
@@ -2886,7 +2876,7 @@
if (*opened & FILE_CREATED) {
WARN_ON(!(open_flag & O_CREAT));
fsnotify_create(dir, dentry);
- acc_mode = MAY_OPEN;
+ acc_mode = 0;
}
error = may_open(&file->f_path, acc_mode, open_flag);
if (error)
@@ -3099,7 +3089,7 @@
/* Don't check for write permission, don't truncate */
open_flag &= ~O_TRUNC;
will_truncate = false;
- acc_mode = MAY_OPEN;
+ acc_mode = 0;
path_to_nameidata(&path, nd);
goto finish_open_created;
}
@@ -3183,10 +3173,11 @@
got_write = true;
}
finish_open_created:
- error = may_open(&nd->path, acc_mode, open_flag);
- if (error)
- goto out;
-
+ if (likely(!(open_flag & O_PATH))) {
+ error = may_open(&nd->path, acc_mode, open_flag);
+ if (error)
+ goto out;
+ }
BUG_ON(*opened & FILE_OPENED); /* once it's opened, it's opened */
error = vfs_open(&nd->path, file, current_cred());
if (!error) {
@@ -3273,7 +3264,7 @@
goto out2;
audit_inode(nd->name, child, 0);
/* Don't check for other permissions, the inode was just created */
- error = may_open(&path, MAY_OPEN, op->open_flag);
+ error = may_open(&path, 0, op->open_flag);
if (error)
goto out2;
file->f_path.mnt = path.mnt;
diff --git a/fs/namespace.c b/fs/namespace.c
index 0570729..33a75c8 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2601,18 +2601,18 @@
return n;
}
-int copy_mount_options(const void __user * data, unsigned long *where)
+void *copy_mount_options(const void __user * data)
{
int i;
- unsigned long page;
unsigned long size;
+ char *copy;
- *where = 0;
if (!data)
- return 0;
+ return NULL;
- if (!(page = __get_free_page(GFP_KERNEL)))
- return -ENOMEM;
+ copy = kmalloc(PAGE_SIZE, GFP_KERNEL);
+ if (!copy)
+ return ERR_PTR(-ENOMEM);
/* We only care that *some* data at the address the user
* gave us is valid. Just in case, we'll zero
@@ -2623,15 +2623,14 @@
if (size > PAGE_SIZE)
size = PAGE_SIZE;
- i = size - exact_copy_from_user((void *)page, data, size);
+ i = size - exact_copy_from_user(copy, data, size);
if (!i) {
- free_page(page);
- return -EFAULT;
+ kfree(copy);
+ return ERR_PTR(-EFAULT);
}
if (i != PAGE_SIZE)
- memset((char *)page + i, 0, PAGE_SIZE - i);
- *where = page;
- return 0;
+ memset(copy + i, 0, PAGE_SIZE - i);
+ return copy;
}
char *copy_mount_string(const void __user *data)
@@ -2896,7 +2895,7 @@
int ret;
char *kernel_type;
char *kernel_dev;
- unsigned long data_page;
+ void *options;
kernel_type = copy_mount_string(type);
ret = PTR_ERR(kernel_type);
@@ -2908,14 +2907,14 @@
if (IS_ERR(kernel_dev))
goto out_dev;
- ret = copy_mount_options(data, &data_page);
- if (ret < 0)
+ options = copy_mount_options(data);
+ ret = PTR_ERR(options);
+ if (IS_ERR(options))
goto out_data;
- ret = do_mount(kernel_dev, dir_name, kernel_type, flags,
- (void *) data_page);
+ ret = do_mount(kernel_dev, dir_name, kernel_type, flags, options);
- free_page(data_page);
+ kfree(options);
out_data:
kfree(kernel_dev);
out_dev:
@@ -2939,9 +2938,9 @@
return &mnt->mnt == root->mnt && is_subdir(dentry, root->dentry);
}
-int path_is_under(struct path *path1, struct path *path2)
+bool path_is_under(struct path *path1, struct path *path2)
{
- int res;
+ bool res;
read_seqlock_excl(&mount_lock);
res = is_path_reachable(real_mount(path1->mnt), path1->dentry, path2);
read_sequnlock_excl(&mount_lock);
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
index 354013e..c734384 100644
--- a/fs/nilfs2/super.c
+++ b/fs/nilfs2/super.c
@@ -1316,13 +1316,11 @@
}
if (!s->s_root) {
- char b[BDEVNAME_SIZE];
-
- s_new = true;
+ s_new = true;
/* New superblock instance created */
s->s_mode = mode;
- strlcpy(s->s_id, bdevname(sd.bdev, b), sizeof(s->s_id));
+ snprintf(s->s_id, sizeof(s->s_id), "%pg", sd.bdev);
sb_set_blocksize(s, block_size(sd.bdev));
err = nilfs_fill_super(s, data, flags & MS_SILENT ? 1 : 0);
diff --git a/fs/open.c b/fs/open.c
index b6f1e96..b25b154 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -887,7 +887,7 @@
static inline int build_open_flags(int flags, umode_t mode, struct open_flags *op)
{
int lookup_flags = 0;
- int acc_mode;
+ int acc_mode = ACC_MODE(flags);
if (flags & (O_CREAT | __O_TMPFILE))
op->mode = (mode & S_IALLUGO) | S_IFREG;
@@ -909,7 +909,6 @@
if (flags & __O_TMPFILE) {
if ((flags & O_TMPFILE_MASK) != O_TMPFILE)
return -EINVAL;
- acc_mode = MAY_OPEN | ACC_MODE(flags);
if (!(acc_mode & MAY_WRITE))
return -EINVAL;
} else if (flags & O_PATH) {
@@ -919,8 +918,6 @@
*/
flags &= O_DIRECTORY | O_NOFOLLOW | O_PATH;
acc_mode = 0;
- } else {
- acc_mode = MAY_OPEN | ACC_MODE(flags);
}
op->open_flag = flags;
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 4bd5d31..1b0f470 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -2359,7 +2359,7 @@
size_t count, loff_t *ppos)
{
struct inode * inode = file_inode(file);
- char *page;
+ void *page;
ssize_t length;
struct task_struct *task = get_proc_task(inode);
@@ -2374,14 +2374,11 @@
if (*ppos != 0)
goto out;
- length = -ENOMEM;
- page = (char*)__get_free_page(GFP_TEMPORARY);
- if (!page)
+ page = memdup_user(buf, count);
+ if (IS_ERR(page)) {
+ length = PTR_ERR(page);
goto out;
-
- length = -EFAULT;
- if (copy_from_user(page, buf, count))
- goto out_free;
+ }
/* Guard against adverse ptrace interaction */
length = mutex_lock_interruptible(&task->signal->cred_guard_mutex);
@@ -2390,10 +2387,10 @@
length = security_setprocattr(task,
(char*)file->f_path.dentry->d_name.name,
- (void*)page, count);
+ page, count);
mutex_unlock(&task->signal->cred_guard_mutex);
out_free:
- free_page((unsigned long) page);
+ kfree(page);
out:
put_task_struct(task);
out_no_task:
diff --git a/fs/proc_namespace.c b/fs/proc_namespace.c
index 8ebd9a3..2256e7e 100644
--- a/fs/proc_namespace.c
+++ b/fs/proc_namespace.c
@@ -95,9 +95,9 @@
{
struct proc_mounts *p = m->private;
struct mount *r = real_mount(mnt);
- int err = 0;
struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt };
struct super_block *sb = mnt_path.dentry->d_sb;
+ int err;
if (sb->s_op->show_devname) {
err = sb->s_op->show_devname(m, mnt_path.dentry);
@@ -131,16 +131,17 @@
struct mount *r = real_mount(mnt);
struct super_block *sb = mnt->mnt_sb;
struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt };
- int err = 0;
+ int err;
seq_printf(m, "%i %i %u:%u ", r->mnt_id, r->mnt_parent->mnt_id,
MAJOR(sb->s_dev), MINOR(sb->s_dev));
- if (sb->s_op->show_path)
+ if (sb->s_op->show_path) {
err = sb->s_op->show_path(m, mnt->mnt_root);
- else
+ if (err)
+ goto out;
+ } else {
seq_dentry(m, mnt->mnt_root, " \t\n\\");
- if (err)
- goto out;
+ }
seq_putc(m, ' ');
/* mountpoints outside of chroot jail will give SEQ_SKIP on this */
@@ -168,12 +169,13 @@
seq_puts(m, " - ");
show_type(m, sb);
seq_putc(m, ' ');
- if (sb->s_op->show_devname)
+ if (sb->s_op->show_devname) {
err = sb->s_op->show_devname(m, mnt->mnt_root);
- else
+ if (err)
+ goto out;
+ } else {
mangle(m, r->mnt_devname ? r->mnt_devname : "none");
- if (err)
- goto out;
+ }
seq_puts(m, sb->s_flags & MS_RDONLY ? " ro" : " rw");
err = show_sb_opts(m, sb);
if (err)
@@ -191,7 +193,7 @@
struct mount *r = real_mount(mnt);
struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt };
struct super_block *sb = mnt_path.dentry->d_sb;
- int err = 0;
+ int err;
/* device */
if (sb->s_op->show_devname) {
@@ -220,8 +222,7 @@
/* optional statistics */
if (sb->s_op->show_stats) {
seq_putc(m, ' ');
- if (!err)
- err = sb->s_op->show_stats(m, mnt_path.dentry);
+ err = sb->s_op->show_stats(m, mnt_path.dentry);
}
seq_putc(m, '\n');
diff --git a/fs/read_write.c b/fs/read_write.c
index 819ef3f..acb1713 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -171,6 +171,45 @@
EXPORT_SYMBOL(fixed_size_llseek);
/**
+ * no_seek_end_llseek - llseek implementation for fixed-sized devices
+ * @file: file structure to seek on
+ * @offset: file offset to seek to
+ * @whence: type of seek
+ *
+ */
+loff_t no_seek_end_llseek(struct file *file, loff_t offset, int whence)
+{
+ switch (whence) {
+ case SEEK_SET: case SEEK_CUR:
+ return generic_file_llseek_size(file, offset, whence,
+ ~0ULL, 0);
+ default:
+ return -EINVAL;
+ }
+}
+EXPORT_SYMBOL(no_seek_end_llseek);
+
+/**
+ * no_seek_end_llseek_size - llseek implementation for fixed-sized devices
+ * @file: file structure to seek on
+ * @offset: file offset to seek to
+ * @whence: type of seek
+ * @size: maximal offset allowed
+ *
+ */
+loff_t no_seek_end_llseek_size(struct file *file, loff_t offset, int whence, loff_t size)
+{
+ switch (whence) {
+ case SEEK_SET: case SEEK_CUR:
+ return generic_file_llseek_size(file, offset, whence,
+ size, 0);
+ default:
+ return -EINVAL;
+ }
+}
+EXPORT_SYMBOL(no_seek_end_llseek_size);
+
+/**
* noop_llseek - No Operation Performed llseek implementation
* @file: file structure to seek on
* @offset: file offset to seek to
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
index 9d6486d..44c2bdc 100644
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -618,12 +618,10 @@
static void reiserfs_end_buffer_io_sync(struct buffer_head *bh, int uptodate)
{
- char b[BDEVNAME_SIZE];
-
if (buffer_journaled(bh)) {
reiserfs_warning(NULL, "clm-2084",
- "pinned buffer %lu:%s sent to disk",
- bh->b_blocknr, bdevname(bh->b_bdev, b));
+ "pinned buffer %lu:%pg sent to disk",
+ bh->b_blocknr, bh->b_bdev);
}
if (uptodate)
set_buffer_uptodate(bh);
@@ -2387,11 +2385,10 @@
int replay_count = 0;
int continue_replay = 1;
int ret;
- char b[BDEVNAME_SIZE];
cur_dblock = SB_ONDISK_JOURNAL_1st_BLOCK(sb);
- reiserfs_info(sb, "checking transaction log (%s)\n",
- bdevname(journal->j_dev_bd, b));
+ reiserfs_info(sb, "checking transaction log (%pg)\n",
+ journal->j_dev_bd);
start = get_seconds();
/*
@@ -2651,8 +2648,8 @@
set_blocksize(journal->j_dev_bd, super->s_blocksize);
reiserfs_info(super,
- "journal_init_dev: journal device: %s\n",
- bdevname(journal->j_dev_bd, b));
+ "journal_init_dev: journal device: %pg\n",
+ journal->j_dev_bd);
return 0;
}
@@ -2724,7 +2721,6 @@
struct reiserfs_journal_header *jh;
struct reiserfs_journal *journal;
struct reiserfs_journal_list *jl;
- char b[BDEVNAME_SIZE];
int ret;
journal = SB_JOURNAL(sb) = vzalloc(sizeof(struct reiserfs_journal));
@@ -2794,10 +2790,10 @@
&& (le32_to_cpu(jh->jh_journal.jp_journal_magic) !=
sb_jp_journal_magic(rs))) {
reiserfs_warning(sb, "sh-460",
- "journal header magic %x (device %s) does "
+ "journal header magic %x (device %pg) does "
"not match to magic found in super block %x",
jh->jh_journal.jp_journal_magic,
- bdevname(journal->j_dev_bd, b),
+ journal->j_dev_bd,
sb_jp_journal_magic(rs));
brelse(bhjh);
goto free_and_return;
@@ -2818,10 +2814,10 @@
journal->j_max_trans_age = commit_max_age;
}
- reiserfs_info(sb, "journal params: device %s, size %u, "
+ reiserfs_info(sb, "journal params: device %pg, size %u, "
"journal first block %u, max trans len %u, max batch %u, "
"max commit age %u, max trans age %u\n",
- bdevname(journal->j_dev_bd, b),
+ journal->j_dev_bd,
SB_ONDISK_JOURNAL_SIZE(sb),
SB_ONDISK_JOURNAL_1st_BLOCK(sb),
journal->j_trans_max,
diff --git a/fs/reiserfs/prints.c b/fs/reiserfs/prints.c
index ae1dc84..4f3f928 100644
--- a/fs/reiserfs/prints.c
+++ b/fs/reiserfs/prints.c
@@ -139,11 +139,9 @@
static void sprintf_buffer_head(char *buf, struct buffer_head *bh)
{
- char b[BDEVNAME_SIZE];
-
sprintf(buf,
- "dev %s, size %zd, blocknr %llu, count %d, state 0x%lx, page %p, (%s, %s, %s)",
- bdevname(bh->b_bdev, b), bh->b_size,
+ "dev %pg, size %zd, blocknr %llu, count %d, state 0x%lx, page %p, (%s, %s, %s)",
+ bh->b_bdev, bh->b_size,
(unsigned long long)bh->b_blocknr, atomic_read(&(bh->b_count)),
bh->b_state, bh->b_page,
buffer_uptodate(bh) ? "UPTODATE" : "!UPTODATE",
@@ -530,7 +528,6 @@
(struct reiserfs_super_block *)(bh->b_data);
int skipped, data_blocks;
char *version;
- char b[BDEVNAME_SIZE];
if (is_reiserfs_3_5(rs)) {
version = "3.5";
@@ -543,7 +540,7 @@
return 1;
}
- printk("%s\'s super block is in block %llu\n", bdevname(bh->b_bdev, b),
+ printk("%pg\'s super block is in block %llu\n", bh->b_bdev,
(unsigned long long)bh->b_blocknr);
printk("Reiserfs version %s\n", version);
printk("Block count %u\n", sb_block_count(rs));
diff --git a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c
index 621b9f3..fe99915 100644
--- a/fs/reiserfs/procfs.c
+++ b/fs/reiserfs/procfs.c
@@ -303,11 +303,10 @@
struct reiserfs_sb_info *r = REISERFS_SB(sb);
struct reiserfs_super_block *rs = r->s_rs;
struct journal_params *jp = &rs->s_v1.s_journal;
- char b[BDEVNAME_SIZE];
seq_printf(m, /* on-disk fields */
"jp_journal_1st_block: \t%i\n"
- "jp_journal_dev: \t%s[%x]\n"
+ "jp_journal_dev: \t%pg[%x]\n"
"jp_journal_size: \t%i\n"
"jp_journal_trans_max: \t%i\n"
"jp_journal_magic: \t%i\n"
@@ -348,7 +347,7 @@
"prepare: \t%12lu\n"
"prepare_retry: \t%12lu\n",
DJP(jp_journal_1st_block),
- bdevname(SB_JOURNAL(sb)->j_dev_bd, b),
+ SB_JOURNAL(sb)->j_dev_bd,
DJP(jp_journal_dev),
DJP(jp_journal_size),
DJP(jp_journal_trans_max),
diff --git a/fs/select.c b/fs/select.c
index 0155473..79d0d49 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -778,8 +778,8 @@
return mask;
}
-static int do_poll(unsigned int nfds, struct poll_list *list,
- struct poll_wqueues *wait, struct timespec *end_time)
+static int do_poll(struct poll_list *list, struct poll_wqueues *wait,
+ struct timespec *end_time)
{
poll_table* pt = &wait->pt;
ktime_t expire, *to = NULL;
@@ -908,7 +908,7 @@
}
poll_initwait(&table);
- fdcount = do_poll(nfds, head, &table, end_time);
+ fdcount = do_poll(head, &table, end_time);
poll_freewait(&table);
for (walk = head; walk; walk = walk->next) {
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c
index 5056bab..dded920 100644
--- a/fs/squashfs/super.c
+++ b/fs/squashfs/super.c
@@ -80,7 +80,6 @@
{
struct squashfs_sb_info *msblk;
struct squashfs_super_block *sblk = NULL;
- char b[BDEVNAME_SIZE];
struct inode *root;
long long root_inode;
unsigned short flags;
@@ -124,8 +123,8 @@
sb->s_magic = le32_to_cpu(sblk->s_magic);
if (sb->s_magic != SQUASHFS_MAGIC) {
if (!silent)
- ERROR("Can't find a SQUASHFS superblock on %s\n",
- bdevname(sb->s_bdev, b));
+ ERROR("Can't find a SQUASHFS superblock on %pg\n",
+ sb->s_bdev);
goto failed_mount;
}
@@ -178,7 +177,7 @@
msblk->inodes = le32_to_cpu(sblk->inodes);
flags = le16_to_cpu(sblk->flags);
- TRACE("Found valid superblock on %s\n", bdevname(sb->s_bdev, b));
+ TRACE("Found valid superblock on %pg\n", sb->s_bdev);
TRACE("Inodes are %scompressed\n", SQUASHFS_UNCOMPRESSED_INODES(flags)
? "un" : "");
TRACE("Data is %scompressed\n", SQUASHFS_UNCOMPRESSED_DATA(flags)
diff --git a/fs/super.c b/fs/super.c
index 954aeb8..cc658a20 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -1012,10 +1012,8 @@
blkdev_put(bdev, mode);
down_write(&s->s_umount);
} else {
- char b[BDEVNAME_SIZE];
-
s->s_mode = mode;
- strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
+ snprintf(s->s_id, sizeof(s->s_id), "%pg", bdev);
sb_set_blocksize(s, block_size(bdev));
error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);
if (error) {
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
index 3243cdf..ace91e7 100644
--- a/fs/xfs/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -1632,13 +1632,9 @@
btp->bt_meta_sectormask = sectorsize - 1;
if (set_blocksize(btp->bt_bdev, sectorsize)) {
- char name[BDEVNAME_SIZE];
-
- bdevname(btp->bt_bdev, name);
-
xfs_warn(btp->bt_mount,
- "Cannot set_blocksize to %u on device %s",
- sectorsize, name);
+ "Cannot set_blocksize to %u on device %pg",
+ sectorsize, btp->bt_bdev);
return -EINVAL;
}
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 51f9f8d..8793d43 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2291,9 +2291,9 @@
{
}
-static inline int sb_is_blkdev_sb(struct super_block *sb)
+static inline bool sb_is_blkdev_sb(struct super_block *sb)
{
- return 0;
+ return false;
}
#endif
extern int sync_filesystem(struct super_block *);
@@ -2371,7 +2371,7 @@
/* Invalid inode operations -- fs/bad_inode.c */
extern void make_bad_inode(struct inode *);
-extern int is_bad_inode(struct inode *);
+extern bool is_bad_inode(struct inode *);
#ifdef CONFIG_BLOCK
/*
@@ -2532,8 +2532,8 @@
extern struct file * open_exec(const char *);
/* fs/dcache.c -- generic fs support functions */
-extern int is_subdir(struct dentry *, struct dentry *);
-extern int path_is_under(struct path *, struct path *);
+extern bool is_subdir(struct dentry *, struct dentry *);
+extern bool path_is_under(struct path *, struct path *);
extern char *file_path(struct file *, char *, int);
@@ -2660,6 +2660,8 @@
int whence, loff_t maxsize, loff_t eof);
extern loff_t fixed_size_llseek(struct file *file, loff_t offset,
int whence, loff_t size);
+extern loff_t no_seek_end_llseek_size(struct file *, loff_t, int, loff_t);
+extern loff_t no_seek_end_llseek(struct file *, loff_t, int);
extern int generic_file_open(struct inode * inode, struct file * filp);
extern int nonseekable_open(struct inode * inode, struct file * filp);
@@ -2961,7 +2963,7 @@
#define OPEN_FMODE(flag) ((__force fmode_t)(((flag + 1) & O_ACCMODE) | \
(flag & __FMODE_NONOTIFY)))
-static inline int is_sxid(umode_t mode)
+static inline bool is_sxid(umode_t mode)
{
return (mode & S_ISUID) || ((mode & S_ISGID) && (mode & S_IXGRP));
}
diff --git a/include/linux/string.h b/include/linux/string.h
index 9ef7795..9eebc66 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -10,6 +10,7 @@
extern char *strndup_user(const char __user *, long);
extern void *memdup_user(const void __user *, size_t);
+extern void *memdup_user_nul(const void __user *, size_t);
/*
* Include machine specific inline routines
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index dc6858d..5faf89a 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -2047,9 +2047,8 @@
void *data)
{
int *i, vleft, first = 1, err = 0;
- unsigned long page = 0;
size_t left;
- char *kbuf;
+ char *kbuf = NULL, *p;
if (!tbl_data || !table->maxlen || !*lenp || (*ppos && !write)) {
*lenp = 0;
@@ -2078,15 +2077,9 @@
if (left > PAGE_SIZE - 1)
left = PAGE_SIZE - 1;
- page = __get_free_page(GFP_TEMPORARY);
- kbuf = (char *) page;
- if (!kbuf)
- return -ENOMEM;
- if (copy_from_user(kbuf, buffer, left)) {
- err = -EFAULT;
- goto free;
- }
- kbuf[left] = 0;
+ p = kbuf = memdup_user_nul(buffer, left);
+ if (IS_ERR(kbuf))
+ return PTR_ERR(kbuf);
}
for (; left && vleft--; i++, first=0) {
@@ -2094,11 +2087,11 @@
bool neg;
if (write) {
- left -= proc_skip_spaces(&kbuf);
+ left -= proc_skip_spaces(&p);
if (!left)
break;
- err = proc_get_long(&kbuf, &left, &lval, &neg,
+ err = proc_get_long(&p, &left, &lval, &neg,
proc_wspace_sep,
sizeof(proc_wspace_sep), NULL);
if (err)
@@ -2125,10 +2118,9 @@
if (!write && !first && left && !err)
err = proc_put_char(&buffer, &left, '\n');
if (write && !err && left)
- left -= proc_skip_spaces(&kbuf);
-free:
+ left -= proc_skip_spaces(&p);
if (write) {
- free_page(page);
+ kfree(kbuf);
if (first)
return err ? : -EINVAL;
}
@@ -2310,9 +2302,8 @@
{
unsigned long *i, *min, *max;
int vleft, first = 1, err = 0;
- unsigned long page = 0;
size_t left;
- char *kbuf;
+ char *kbuf = NULL, *p;
if (!data || !table->maxlen || !*lenp || (*ppos && !write)) {
*lenp = 0;
@@ -2340,15 +2331,9 @@
if (left > PAGE_SIZE - 1)
left = PAGE_SIZE - 1;
- page = __get_free_page(GFP_TEMPORARY);
- kbuf = (char *) page;
- if (!kbuf)
- return -ENOMEM;
- if (copy_from_user(kbuf, buffer, left)) {
- err = -EFAULT;
- goto free;
- }
- kbuf[left] = 0;
+ p = kbuf = memdup_user_nul(buffer, left);
+ if (IS_ERR(kbuf))
+ return PTR_ERR(kbuf);
}
for (; left && vleft--; i++, first = 0) {
@@ -2357,9 +2342,9 @@
if (write) {
bool neg;
- left -= proc_skip_spaces(&kbuf);
+ left -= proc_skip_spaces(&p);
- err = proc_get_long(&kbuf, &left, &val, &neg,
+ err = proc_get_long(&p, &left, &val, &neg,
proc_wspace_sep,
sizeof(proc_wspace_sep), NULL);
if (err)
@@ -2385,10 +2370,9 @@
if (!write && !first && left && !err)
err = proc_put_char(&buffer, &left, '\n');
if (write && !err)
- left -= proc_skip_spaces(&kbuf);
-free:
+ left -= proc_skip_spaces(&p);
if (write) {
- free_page(page);
+ kfree(kbuf);
if (first)
return err ? : -EINVAL;
}
@@ -2650,34 +2634,27 @@
}
if (write) {
- unsigned long page = 0;
- char *kbuf;
+ char *kbuf, *p;
if (left > PAGE_SIZE - 1)
left = PAGE_SIZE - 1;
- page = __get_free_page(GFP_TEMPORARY);
- kbuf = (char *) page;
- if (!kbuf)
- return -ENOMEM;
- if (copy_from_user(kbuf, buffer, left)) {
- free_page(page);
- return -EFAULT;
- }
- kbuf[left] = 0;
+ p = kbuf = memdup_user_nul(buffer, left);
+ if (IS_ERR(kbuf))
+ return PTR_ERR(kbuf);
tmp_bitmap = kzalloc(BITS_TO_LONGS(bitmap_len) * sizeof(unsigned long),
GFP_KERNEL);
if (!tmp_bitmap) {
- free_page(page);
+ kfree(kbuf);
return -ENOMEM;
}
- proc_skip_char(&kbuf, &left, '\n');
+ proc_skip_char(&p, &left, '\n');
while (!err && left) {
unsigned long val_a, val_b;
bool neg;
- err = proc_get_long(&kbuf, &left, &val_a, &neg, tr_a,
+ err = proc_get_long(&p, &left, &val_a, &neg, tr_a,
sizeof(tr_a), &c);
if (err)
break;
@@ -2688,12 +2665,12 @@
val_b = val_a;
if (left) {
- kbuf++;
+ p++;
left--;
}
if (c == '-') {
- err = proc_get_long(&kbuf, &left, &val_b,
+ err = proc_get_long(&p, &left, &val_b,
&neg, tr_b, sizeof(tr_b),
&c);
if (err)
@@ -2704,16 +2681,16 @@
break;
}
if (left) {
- kbuf++;
+ p++;
left--;
}
}
bitmap_set(tmp_bitmap, val_a, val_b - val_a + 1);
first = 0;
- proc_skip_char(&kbuf, &left, '\n');
+ proc_skip_char(&p, &left, '\n');
}
- free_page(page);
+ kfree(kbuf);
} else {
unsigned long bit_a, bit_b = 0;
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index a990824..2aeb6ff 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -349,16 +349,10 @@
if (count >= BLK_TN_MAX_MSG)
return -EINVAL;
- msg = kmalloc(count + 1, GFP_KERNEL);
- if (msg == NULL)
- return -ENOMEM;
+ msg = memdup_user_nul(buffer, count);
+ if (IS_ERR(msg))
+ return PTR_ERR(msg);
- if (copy_from_user(msg, buffer, count)) {
- kfree(msg);
- return -EFAULT;
- }
-
- msg[count] = '\0';
bt = filp->private_data;
__trace_note_message(bt, "%s", msg);
kfree(msg);
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 4f6ef69..f333e57 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -1340,15 +1340,9 @@
if (cnt >= PAGE_SIZE)
return -EINVAL;
- buf = (char *)__get_free_page(GFP_TEMPORARY);
- if (!buf)
- return -ENOMEM;
-
- if (copy_from_user(buf, ubuf, cnt)) {
- free_page((unsigned long) buf);
- return -EFAULT;
- }
- buf[cnt] = '\0';
+ buf = memdup_user_nul(ubuf, cnt);
+ if (IS_ERR(buf))
+ return PTR_ERR(buf);
mutex_lock(&event_mutex);
file = event_file_data(filp);
@@ -1356,7 +1350,7 @@
err = apply_event_filter(file, buf);
mutex_unlock(&event_mutex);
- free_page((unsigned long) buf);
+ kfree(buf);
if (err < 0)
return err;
@@ -1507,18 +1501,12 @@
if (cnt >= PAGE_SIZE)
return -EINVAL;
- buf = (char *)__get_free_page(GFP_TEMPORARY);
- if (!buf)
- return -ENOMEM;
-
- if (copy_from_user(buf, ubuf, cnt)) {
- free_page((unsigned long) buf);
- return -EFAULT;
- }
- buf[cnt] = '\0';
+ buf = memdup_user_nul(ubuf, cnt);
+ if (IS_ERR(buf))
+ return PTR_ERR(buf);
err = apply_subsystem_event_filter(dir, buf);
- free_page((unsigned long) buf);
+ kfree(buf);
if (err < 0)
return err;
diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c
index 42a4009..4b5e8ed6 100644
--- a/kernel/trace/trace_events_trigger.c
+++ b/kernel/trace/trace_events_trigger.c
@@ -237,28 +237,23 @@
if (cnt >= PAGE_SIZE)
return -EINVAL;
- buf = (char *)__get_free_page(GFP_TEMPORARY);
- if (!buf)
- return -ENOMEM;
+ buf = memdup_user_nul(ubuf, cnt);
+ if (IS_ERR(buf))
+ return PTR_ERR(buf);
- if (copy_from_user(buf, ubuf, cnt)) {
- free_page((unsigned long)buf);
- return -EFAULT;
- }
- buf[cnt] = '\0';
strim(buf);
mutex_lock(&event_mutex);
event_file = event_file_data(file);
if (unlikely(!event_file)) {
mutex_unlock(&event_mutex);
- free_page((unsigned long)buf);
+ kfree(buf);
return -ENODEV;
}
ret = trigger_process_regex(event_file, buf);
mutex_unlock(&event_mutex);
- free_page((unsigned long)buf);
+ kfree(buf);
if (ret < 0)
goto out;
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index 88fefa6..9bafc21 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -602,8 +602,7 @@
struct uid_gid_map new_map;
unsigned idx;
struct uid_gid_extent *extent = NULL;
- unsigned long page = 0;
- char *kbuf, *pos, *next_line;
+ char *kbuf = NULL, *pos, *next_line;
ssize_t ret = -EINVAL;
/*
@@ -638,23 +637,18 @@
if (cap_valid(cap_setid) && !file_ns_capable(file, ns, CAP_SYS_ADMIN))
goto out;
- /* Get a buffer */
- ret = -ENOMEM;
- page = __get_free_page(GFP_TEMPORARY);
- kbuf = (char *) page;
- if (!page)
- goto out;
-
/* Only allow < page size writes at the beginning of the file */
ret = -EINVAL;
if ((*ppos != 0) || (count >= PAGE_SIZE))
goto out;
/* Slurp in the user data */
- ret = -EFAULT;
- if (copy_from_user(kbuf, buf, count))
+ kbuf = memdup_user_nul(buf, count);
+ if (IS_ERR(kbuf)) {
+ ret = PTR_ERR(kbuf);
+ kbuf = NULL;
goto out;
- kbuf[count] = '\0';
+ }
/* Parse the user data */
ret = -EINVAL;
@@ -756,8 +750,7 @@
ret = count;
out:
mutex_unlock(&userns_state_mutex);
- if (page)
- free_page(page);
+ kfree(kbuf);
return ret;
}
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index e3952e9..fe42b6e 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -657,14 +657,9 @@
pr_warn("expected <%d bytes into control\n", USER_BUF_PAGE);
return -E2BIG;
}
- tmpbuf = kmalloc(len + 1, GFP_KERNEL);
- if (!tmpbuf)
- return -ENOMEM;
- if (copy_from_user(tmpbuf, ubuf, len)) {
- kfree(tmpbuf);
- return -EFAULT;
- }
- tmpbuf[len] = '\0';
+ tmpbuf = memdup_user_nul(ubuf, len);
+ if (IS_ERR(tmpbuf))
+ return PTR_ERR(tmpbuf);
vpr_info("read %d bytes from userspace\n", (int)len);
ret = ddebug_exec_queries(tmpbuf, NULL);
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index f9cee8e..ac3f947 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -31,6 +31,9 @@
#include <linux/dcache.h>
#include <linux/cred.h>
#include <net/addrconf.h>
+#ifdef CONFIG_BLOCK
+#include <linux/blkdev.h>
+#endif
#include <asm/page.h> /* for PAGE_SIZE */
#include <asm/sections.h> /* for dereference_function_descriptor() */
@@ -613,6 +616,26 @@
return buf;
}
+#ifdef CONFIG_BLOCK
+static noinline_for_stack
+char *bdev_name(char *buf, char *end, struct block_device *bdev,
+ struct printf_spec spec, const char *fmt)
+{
+ struct gendisk *hd = bdev->bd_disk;
+
+ buf = string(buf, end, hd->disk_name, spec);
+ if (bdev->bd_part->partno) {
+ if (isdigit(hd->disk_name[strlen(hd->disk_name)-1])) {
+ if (buf < end)
+ *buf = 'p';
+ buf++;
+ }
+ buf = number(buf, end, bdev->bd_part->partno, spec);
+ }
+ return buf;
+}
+#endif
+
static noinline_for_stack
char *symbol_string(char *buf, char *end, void *ptr,
struct printf_spec spec, const char *fmt)
@@ -1443,6 +1466,7 @@
* (default assumed to be phys_addr_t, passed by reference)
* - 'd[234]' For a dentry name (optionally 2-4 last components)
* - 'D[234]' Same as 'd' but for a struct file
+ * - 'g' For block_device name (gendisk + partition number)
* - 'C' For a clock, it prints the name (Common Clock Framework) or address
* (legacy clock framework) of the clock
* - 'Cn' For a clock, it prints the name (Common Clock Framework) or address
@@ -1600,6 +1624,11 @@
return dentry_name(buf, end,
((const struct file *)ptr)->f_path.dentry,
spec, fmt);
+#ifdef CONFIG_BLOCK
+ case 'g':
+ return bdev_name(buf, end, ptr, spec, fmt);
+#endif
+
}
spec.flags |= SMALL;
if (spec.field_width == -1) {
diff --git a/mm/util.c b/mm/util.c
index 9af1c12..2d28f79 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -176,6 +176,37 @@
}
EXPORT_SYMBOL(strndup_user);
+/**
+ * memdup_user_nul - duplicate memory region from user space and NUL-terminate
+ *
+ * @src: source address in user space
+ * @len: number of bytes to copy
+ *
+ * Returns an ERR_PTR() on failure.
+ */
+void *memdup_user_nul(const void __user *src, size_t len)
+{
+ char *p;
+
+ /*
+ * Always use GFP_KERNEL, since copy_from_user() can sleep and
+ * cause pagefault, which makes it pointless to use GFP_NOFS
+ * or GFP_ATOMIC.
+ */
+ p = kmalloc_track_caller(len + 1, GFP_KERNEL);
+ if (!p)
+ return ERR_PTR(-ENOMEM);
+
+ if (copy_from_user(p, src, len)) {
+ kfree(p);
+ return ERR_PTR(-EFAULT);
+ }
+ p[len] = '\0';
+
+ return p;
+}
+EXPORT_SYMBOL(memdup_user_nul);
+
void __vma_link_list(struct mm_struct *mm, struct vm_area_struct *vma,
struct vm_area_struct *prev, struct rb_node *rb_parent)
{
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
index 6e70ddb..199bc76 100644
--- a/net/9p/trans_virtio.c
+++ b/net/9p/trans_virtio.c
@@ -105,7 +105,7 @@
/* How many bytes left in this page. */
static unsigned int rest_of_page(void *data)
{
- return PAGE_SIZE - ((unsigned long)data % PAGE_SIZE);
+ return PAGE_SIZE - offset_in_page(data);
}
/**
@@ -143,7 +143,6 @@
static void req_done(struct virtqueue *vq)
{
struct virtio_chan *chan = vq->vdev->priv;
- struct p9_fcall *rc;
unsigned int len;
struct p9_req_t *req;
unsigned long flags;
@@ -152,8 +151,8 @@
while (1) {
spin_lock_irqsave(&chan->lock, flags);
- rc = virtqueue_get_buf(chan->vq, &len);
- if (rc == NULL) {
+ req = virtqueue_get_buf(chan->vq, &len);
+ if (req == NULL) {
spin_unlock_irqrestore(&chan->lock, flags);
break;
}
@@ -161,9 +160,6 @@
spin_unlock_irqrestore(&chan->lock, flags);
/* Wakeup if anyone waiting for VirtIO ring space. */
wake_up(chan->vc_wq);
- p9_debug(P9_DEBUG_TRANS, ": rc %p\n", rc);
- p9_debug(P9_DEBUG_TRANS, ": lookup tag %d\n", rc->tag);
- req = p9_tag_lookup(chan->client, rc->tag);
p9_client_cb(chan->client, req, REQ_STATUS_RCVD);
}
}
@@ -284,7 +280,7 @@
if (in)
sgs[out_sgs + in_sgs++] = chan->sg + out;
- err = virtqueue_add_sgs(chan->vq, sgs, out_sgs, in_sgs, req->tc,
+ err = virtqueue_add_sgs(chan->vq, sgs, out_sgs, in_sgs, req,
GFP_ATOMIC);
if (err < 0) {
if (err == -ENOSPC) {
@@ -369,7 +365,7 @@
return -ENOMEM;
*need_drop = 0;
- p -= (*offs = (unsigned long)p % PAGE_SIZE);
+ p -= (*offs = offset_in_page(p));
for (index = 0; index < nr_pages; index++) {
if (is_vmalloc_addr(p))
(*pages)[index] = vmalloc_to_page(p);
@@ -469,7 +465,7 @@
}
BUG_ON(out_sgs + in_sgs > ARRAY_SIZE(sgs));
- err = virtqueue_add_sgs(chan->vq, sgs, out_sgs, in_sgs, req->tc,
+ err = virtqueue_add_sgs(chan->vq, sgs, out_sgs, in_sgs, req,
GFP_ATOMIC);
if (err < 0) {
if (err == -ENOSPC) {
diff --git a/net/rxrpc/ar-key.c b/net/rxrpc/ar-key.c
index da3cc09..3f65716 100644
--- a/net/rxrpc/ar-key.c
+++ b/net/rxrpc/ar-key.c
@@ -896,15 +896,9 @@
if (optlen <= 0 || optlen > PAGE_SIZE - 1)
return -EINVAL;
- description = kmalloc(optlen + 1, GFP_KERNEL);
- if (!description)
- return -ENOMEM;
-
- if (copy_from_user(description, optval, optlen)) {
- kfree(description);
- return -EFAULT;
- }
- description[optlen] = 0;
+ description = memdup_user_nul(optval, optlen);
+ if (IS_ERR(description))
+ return PTR_ERR(description);
key = request_key(&key_type_rxrpc, description, NULL);
if (IS_ERR(key)) {
@@ -933,15 +927,9 @@
if (optlen <= 0 || optlen > PAGE_SIZE - 1)
return -EINVAL;
- description = kmalloc(optlen + 1, GFP_KERNEL);
- if (!description)
- return -ENOMEM;
-
- if (copy_from_user(description, optval, optlen)) {
- kfree(description);
- return -EFAULT;
- }
- description[optlen] = 0;
+ description = memdup_user_nul(optval, optlen);
+ if (IS_ERR(description))
+ return PTR_ERR(description);
key = request_key(&key_type_keyring, description, NULL);
if (IS_ERR(key)) {
diff --git a/security/integrity/iint.c b/security/integrity/iint.c
index 3d2f5b4..c2e3ccd 100644
--- a/security/integrity/iint.c
+++ b/security/integrity/iint.c
@@ -234,12 +234,13 @@
}
rc = integrity_kernel_read(file, 0, buf, size);
- if (rc < 0)
- kfree(buf);
- else if (rc != size)
- rc = -EIO;
- else
+ if (rc == size) {
*data = buf;
+ } else {
+ kfree(buf);
+ if (rc >= 0)
+ rc = -EIO;
+ }
out:
fput(file);
return rc;
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index c02da25..73c60ba 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -147,23 +147,16 @@
ssize_t length;
int new_value;
- length = -ENOMEM;
if (count >= PAGE_SIZE)
- goto out;
+ return -ENOMEM;
/* No partial writes. */
- length = -EINVAL;
if (*ppos != 0)
- goto out;
+ return -EINVAL;
- length = -ENOMEM;
- page = (char *)get_zeroed_page(GFP_KERNEL);
- if (!page)
- goto out;
-
- length = -EFAULT;
- if (copy_from_user(page, buf, count))
- goto out;
+ page = memdup_user_nul(buf, count);
+ if (IS_ERR(page))
+ return PTR_ERR(page);
length = -EINVAL;
if (sscanf(page, "%d", &new_value) != 1)
@@ -186,7 +179,7 @@
}
length = count;
out:
- free_page((unsigned long) page);
+ kfree(page);
return length;
}
#else
@@ -275,27 +268,20 @@
size_t count, loff_t *ppos)
{
- char *page = NULL;
+ char *page;
ssize_t length;
int new_value;
- length = -ENOMEM;
if (count >= PAGE_SIZE)
- goto out;
+ return -ENOMEM;
/* No partial writes. */
- length = -EINVAL;
if (*ppos != 0)
- goto out;
+ return -EINVAL;
- length = -ENOMEM;
- page = (char *)get_zeroed_page(GFP_KERNEL);
- if (!page)
- goto out;
-
- length = -EFAULT;
- if (copy_from_user(page, buf, count))
- goto out;
+ page = memdup_user_nul(buf, count);
+ if (IS_ERR(page))
+ return PTR_ERR(page);
length = -EINVAL;
if (sscanf(page, "%d", &new_value) != 1)
@@ -313,7 +299,7 @@
length = count;
out:
- free_page((unsigned long) page);
+ kfree(page);
return length;
}
#else
@@ -611,31 +597,24 @@
static ssize_t sel_write_checkreqprot(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
- char *page = NULL;
+ char *page;
ssize_t length;
unsigned int new_value;
length = task_has_security(current, SECURITY__SETCHECKREQPROT);
if (length)
- goto out;
+ return length;
- length = -ENOMEM;
if (count >= PAGE_SIZE)
- goto out;
+ return -ENOMEM;
/* No partial writes. */
- length = -EINVAL;
if (*ppos != 0)
- goto out;
+ return -EINVAL;
- length = -ENOMEM;
- page = (char *)get_zeroed_page(GFP_KERNEL);
- if (!page)
- goto out;
-
- length = -EFAULT;
- if (copy_from_user(page, buf, count))
- goto out;
+ page = memdup_user_nul(buf, count);
+ if (IS_ERR(page))
+ return PTR_ERR(page);
length = -EINVAL;
if (sscanf(page, "%u", &new_value) != 1)
@@ -644,7 +623,7 @@
selinux_checkreqprot = new_value ? 1 : 0;
length = count;
out:
- free_page((unsigned long) page);
+ kfree(page);
return length;
}
static const struct file_operations sel_checkreqprot_ops = {
@@ -1100,14 +1079,12 @@
if (*ppos != 0)
goto out;
- length = -ENOMEM;
- page = (char *)get_zeroed_page(GFP_KERNEL);
- if (!page)
+ page = memdup_user_nul(buf, count);
+ if (IS_ERR(page)) {
+ length = PTR_ERR(page);
+ page = NULL;
goto out;
-
- length = -EFAULT;
- if (copy_from_user(page, buf, count))
- goto out;
+ }
length = -EINVAL;
if (sscanf(page, "%d", &new_value) != 1)
@@ -1121,7 +1098,7 @@
out:
mutex_unlock(&sel_mutex);
- free_page((unsigned long) page);
+ kfree(page);
return length;
}
@@ -1154,14 +1131,12 @@
if (*ppos != 0)
goto out;
- length = -ENOMEM;
- page = (char *)get_zeroed_page(GFP_KERNEL);
- if (!page)
+ page = memdup_user_nul(buf, count);
+ if (IS_ERR(page)) {
+ length = PTR_ERR(page);
+ page = NULL;
goto out;
-
- length = -EFAULT;
- if (copy_from_user(page, buf, count))
- goto out;
+ }
length = -EINVAL;
if (sscanf(page, "%d", &new_value) != 1)
@@ -1176,7 +1151,7 @@
out:
mutex_unlock(&sel_mutex);
- free_page((unsigned long) page);
+ kfree(page);
return length;
}
@@ -1292,31 +1267,24 @@
size_t count, loff_t *ppos)
{
- char *page = NULL;
+ char *page;
ssize_t ret;
int new_value;
ret = task_has_security(current, SECURITY__SETSECPARAM);
if (ret)
- goto out;
+ return ret;
- ret = -ENOMEM;
if (count >= PAGE_SIZE)
- goto out;
+ return -ENOMEM;
/* No partial writes. */
- ret = -EINVAL;
if (*ppos != 0)
- goto out;
+ return -EINVAL;
- ret = -ENOMEM;
- page = (char *)get_zeroed_page(GFP_KERNEL);
- if (!page)
- goto out;
-
- ret = -EFAULT;
- if (copy_from_user(page, buf, count))
- goto out;
+ page = memdup_user_nul(buf, count);
+ if (IS_ERR(page))
+ return PTR_ERR(page);
ret = -EINVAL;
if (sscanf(page, "%u", &new_value) != 1)
@@ -1326,7 +1294,7 @@
ret = count;
out:
- free_page((unsigned long)page);
+ kfree(page);
return ret;
}
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 94bd9e4..e249a66 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -497,14 +497,9 @@
}
}
- data = kmalloc(count + 1, GFP_KERNEL);
- if (data == NULL)
- return -ENOMEM;
-
- if (copy_from_user(data, buf, count) != 0) {
- rc = -EFAULT;
- goto out;
- }
+ data = memdup_user_nul(buf, count);
+ if (IS_ERR(data))
+ return PTR_ERR(data);
/*
* In case of parsing only part of user buf,
@@ -884,16 +879,10 @@
(count < SMK_CIPSOMIN || count > SMK_CIPSOMAX))
return -EINVAL;
- data = kzalloc(count + 1, GFP_KERNEL);
- if (data == NULL)
- return -ENOMEM;
+ data = memdup_user_nul(buf, count);
+ if (IS_ERR(data))
+ return PTR_ERR(data);
- if (copy_from_user(data, buf, count) != 0) {
- rc = -EFAULT;
- goto unlockedout;
- }
-
- data[count] = '\0';
rule = data;
/*
* Only allow one writer at a time. Writes should be
@@ -946,7 +935,6 @@
out:
mutex_unlock(&smack_cipso_lock);
-unlockedout:
kfree(data);
return rc;
}
@@ -1187,14 +1175,9 @@
if (count < SMK_NETLBLADDRMIN)
return -EINVAL;
- data = kzalloc(count + 1, GFP_KERNEL);
- if (data == NULL)
- return -ENOMEM;
-
- if (copy_from_user(data, buf, count) != 0) {
- rc = -EFAULT;
- goto free_data_out;
- }
+ data = memdup_user_nul(buf, count);
+ if (IS_ERR(data))
+ return PTR_ERR(data);
smack = kzalloc(count + 1, GFP_KERNEL);
if (smack == NULL) {
@@ -1202,8 +1185,6 @@
goto free_data_out;
}
- data[count] = '\0';
-
rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd/%u %s",
&host[0], &host[1], &host[2], &host[3], &masks, smack);
if (rc != 6) {
@@ -1454,14 +1435,9 @@
if (count < SMK_NETLBLADDRMIN)
return -EINVAL;
- data = kzalloc(count + 1, GFP_KERNEL);
- if (data == NULL)
- return -ENOMEM;
-
- if (copy_from_user(data, buf, count) != 0) {
- rc = -EFAULT;
- goto free_data_out;
- }
+ data = memdup_user_nul(buf, count);
+ if (IS_ERR(data))
+ return PTR_ERR(data);
smack = kzalloc(count + 1, GFP_KERNEL);
if (smack == NULL) {
@@ -1469,8 +1445,6 @@
goto free_data_out;
}
- data[count] = '\0';
-
i = sscanf(data, "%x:%x:%x:%x:%x:%x:%x:%x/%u %s",
&scanned[0], &scanned[1], &scanned[2], &scanned[3],
&scanned[4], &scanned[5], &scanned[6], &scanned[7],
@@ -1865,14 +1839,9 @@
if (!smack_privileged(CAP_MAC_ADMIN))
return -EPERM;
- data = kzalloc(count + 1, GFP_KERNEL);
- if (data == NULL)
- return -ENOMEM;
-
- if (copy_from_user(data, buf, count) != 0) {
- rc = -EFAULT;
- goto out;
- }
+ data = memdup_user_nul(buf, count);
+ if (IS_ERR(data))
+ return PTR_ERR(data);
skp = smk_import_entry(data, count);
if (IS_ERR(skp)) {
@@ -2041,14 +2010,9 @@
if (!smack_privileged(CAP_MAC_ADMIN))
return -EPERM;
- data = kzalloc(count + 1, GFP_KERNEL);
- if (data == NULL)
- return -ENOMEM;
-
- if (copy_from_user(data, buf, count) != 0) {
- kfree(data);
- return -EFAULT;
- }
+ data = memdup_user_nul(buf, count);
+ if (IS_ERR(data))
+ return PTR_ERR(data);
rc = smk_parse_label_list(data, &list_tmp);
kfree(data);
@@ -2133,14 +2097,9 @@
if (!smack_privileged(CAP_MAC_ADMIN))
return -EPERM;
- data = kzalloc(count + 1, GFP_KERNEL);
- if (data == NULL)
- return -ENOMEM;
-
- if (copy_from_user(data, buf, count) != 0) {
- rc = -EFAULT;
- goto freeout;
- }
+ data = memdup_user_nul(buf, count);
+ if (IS_ERR(data))
+ return PTR_ERR(data);
/*
* Clear the smack_unconfined on invalid label errors. This means
@@ -2696,19 +2655,15 @@
if (!smack_privileged(CAP_MAC_ADMIN))
return -EPERM;
- data = kzalloc(count + 1, GFP_KERNEL);
- if (data == NULL)
- return -ENOMEM;
+ data = memdup_user_nul(buf, count);
+ if (IS_ERR(data))
+ return PTR_ERR(data);
- if (copy_from_user(data, buf, count) != 0)
- rc = -EFAULT;
- else {
- skp = smk_import_entry(data, count);
- if (IS_ERR(skp))
- rc = PTR_ERR(skp);
- else
- smack_syslog_label = skp;
- }
+ skp = smk_import_entry(data, count);
+ if (IS_ERR(skp))
+ rc = PTR_ERR(skp);
+ else
+ smack_syslog_label = skp;
kfree(data);
return rc;
@@ -2798,14 +2753,9 @@
if (*ppos != 0)
return -EINVAL;
- data = kzalloc(count + 1, GFP_KERNEL);
- if (data == NULL)
- return -ENOMEM;
-
- if (copy_from_user(data, buf, count) != 0) {
- kfree(data);
- return -EFAULT;
- }
+ data = memdup_user_nul(buf, count);
+ if (IS_ERR(data))
+ return PTR_ERR(data);
rc = smk_parse_label_list(data, &list_tmp);
kfree(data);
diff --git a/security/tomoyo/securityfs_if.c b/security/tomoyo/securityfs_if.c
index 179a955..06ab41b1 100644
--- a/security/tomoyo/securityfs_if.c
+++ b/security/tomoyo/securityfs_if.c
@@ -43,13 +43,9 @@
int error;
if (!count || count >= TOMOYO_EXEC_TMPSIZE - 10)
return -ENOMEM;
- data = kzalloc(count + 1, GFP_NOFS);
- if (!data)
- return -ENOMEM;
- if (copy_from_user(data, buf, count)) {
- error = -EFAULT;
- goto out;
- }
+ data = memdup_user_nul(buf, count);
+ if (IS_ERR(data))
+ return PTR_ERR(data);
tomoyo_normalize_line(data);
if (tomoyo_correct_domain(data)) {
const int idx = tomoyo_read_lock();
@@ -87,7 +83,6 @@
tomoyo_read_unlock(idx);
} else
error = -EINVAL;
-out:
kfree(data);
return error ? error : count;
}