From 564def71765caf65040f926c0783b9c27cc6c087 Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 18 May 2018 11:46:15 +0100 Subject: proc: Add a way to make network proc files writable Provide two extra functions, proc_create_net_data_write() and proc_create_net_single_write() that act like their non-write versions but also set a write method in the proc_dir_entry struct. An internal simple write function is provided that will copy its buffer and hand it to the pde->write() method if available (or give an error if not). The buffer may be modified by the write method. Signed-off-by: David Howells --- fs/proc/generic.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'fs/proc/generic.c') diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 02bb1914f5f7..d0e5a68ae14a 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c @@ -741,3 +741,27 @@ void *PDE_DATA(const struct inode *inode) return __PDE_DATA(inode); } EXPORT_SYMBOL(PDE_DATA); + +/* + * Pull a user buffer into memory and pass it to the file's write handler if + * one is supplied. The ->write() method is permitted to modify the + * kernel-side buffer. + */ +ssize_t proc_simple_write(struct file *f, const char __user *ubuf, size_t size, + loff_t *_pos) +{ + struct proc_dir_entry *pde = PDE(file_inode(f)); + char *buf; + int ret; + + if (!pde->write) + return -EACCES; + if (size == 0 || size > PAGE_SIZE - 1) + return -EINVAL; + buf = memdup_user_nul(ubuf, size); + if (IS_ERR(buf)) + return PTR_ERR(buf); + ret = pde->write(f, buf, size); + kfree(buf); + return ret == 0 ? size : ret; +} -- cgit From 24074a35c5c975c94cd9691ae962855333aac47f Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 13 Jun 2018 19:43:19 +0100 Subject: proc: Make inline name size calculation automatic Make calculation of the size of the inline name in struct proc_dir_entry automatic, rather than having to manually encode the numbers and failing to allow for lockdep. Require a minimum inline name size of 33+1 to allow for names that look like two hex numbers with a dash between. Reported-by: Al Viro Signed-off-by: David Howells Signed-off-by: Al Viro --- fs/proc/generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/proc/generic.c') diff --git a/fs/proc/generic.c b/fs/proc/generic.c index d0e5a68ae14a..210bd4b16947 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c @@ -410,7 +410,7 @@ static struct proc_dir_entry *__proc_create(struct proc_dir_entry **parent, if (!ent) goto out; - if (qstr.len + 1 <= sizeof(ent->inline_name)) { + if (qstr.len + 1 <= SIZEOF_PDE_INLINE_NAME) { ent->name = ent->inline_name; } else { ent->name = kmalloc(qstr.len + 1, GFP_KERNEL); -- cgit