diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index 43839e805531..8d105cd900d4 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -1408,8 +1408,8 @@ svcauth_gss_proc_init(struct svc_rqst *rqstp, struct rpc_gss_wire_cred *gc)
#ifdef CONFIG_PROC_FS
-static ssize_t write_gssp(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
+static ssize_t write_gssp(struct file *file, char *buf, size_t count,
+ loff_t *ppos)
{
struct net *net = pde_data(file_inode(file));
char tbuf[20];@@ -1418,9 +1418,7 @@ static ssize_t write_gssp(struct file *file, const char __user *buf,
if (*ppos || count > sizeof(tbuf)-1)
return -EINVAL;
- if (copy_from_user(tbuf, buf, count))
- return -EFAULT;
-
+ memcpy(tbuf, buf, count);
tbuf[count] = 0;
res = kstrtoul(tbuf, 0, &i);
if (res)
@@ -1468,7 +1466,7 @@ static ssize_t read_gssp(struct file *file, char __user *buf,
static const struct proc_ops use_gss_proxy_proc_ops = {
.proc_open = nonseekable_open,
- .proc_write = write_gssp,
+ .proc_write_buf = write_gssp,
.proc_read = read_gssp,
};
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index 007521e8a57f..a257598768fa 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -924,6 +924,9 @@ static ssize_t cache_do_downcall(char *kaddr, const char __user *buf,
return ret;
}
+/* 32k is max userland buffer, lets check anyway */
+#define CACHE_DOWNCALL_MAX (32768 - 1)
+
static ssize_t cache_downcall(struct address_space *mapping,
const char __user *buf,
size_t count, struct cache_detail *cd)
@@ -931,7 +934,7 @@ static ssize_t cache_downcall(struct address_space *mapping,
char *write_buf;
ssize_t ret = -ENOMEM;
- if (count >= 32768) { /* 32k is max userland buffer, lets check anyway */
+ if (count > CACHE_DOWNCALL_MAX) {
ret = -EINVAL;
goto out;
}@@ -1508,19 +1511,15 @@ static ssize_t read_flush(struct file *file, char __user *buf,
return simple_read_from_buffer(buf, count, ppos, tbuf, len);
}
-static ssize_t write_flush(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos,
- struct cache_detail *cd)
+/* longest number the flush files take */
+#define CACHE_FLUSH_MAX 19
+
+static ssize_t do_write_flush(char *tbuf, size_t count, loff_t *ppos,
+ struct cache_detail *cd)
{
- char tbuf[20];
char *ep;
time64_t now;
- if (*ppos || count > sizeof(tbuf)-1)
- return -EINVAL;
- if (copy_from_user(tbuf, buf, count))
- return -EFAULT;
- tbuf[count] = 0;
simple_strtoul(tbuf, &ep, 0);
if (*ep && *ep != '\n')
return -EINVAL;@@ -1551,6 +1550,20 @@ static ssize_t write_flush(struct file *file, const char __user *buf,
return count;
}
+static ssize_t write_flush(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos,
+ struct cache_detail *cd)
+{
+ char tbuf[CACHE_FLUSH_MAX + 1];
+
+ if (*ppos || count > CACHE_FLUSH_MAX)
+ return -EINVAL;
+ if (copy_from_user(tbuf, buf, count))
+ return -EFAULT;
+ tbuf[count] = 0;
+ return do_write_flush(tbuf, count, ppos, cd);
+}
+
static ssize_t cache_read_procfs(struct file *filp, char __user *buf,
size_t count, loff_t *ppos)
{@@ -1559,12 +1572,21 @@ static ssize_t cache_read_procfs(struct file *filp, char __user *buf,
return cache_read(filp, buf, count, ppos, cd);
}
-static ssize_t cache_write_procfs(struct file *filp, const char __user *buf,
- size_t count, loff_t *ppos)
+/* procfs copied in what was written */
+static ssize_t cache_write_procfs(struct file *filp, char *buf, size_t count,
+ loff_t *ppos)
{
struct cache_detail *cd = pde_data(file_inode(filp));
+ struct inode *inode = file_inode(filp);
+ ssize_t ret;
- return cache_write(filp, buf, count, ppos, cd);
+ if (!cd->cache_parse || !count)
+ return -EINVAL;
+
+ inode_lock(inode);
+ ret = cd->cache_parse(cd, buf, count);
+ inode_unlock(inode);
+ return ret ? ret : count;
}
static __poll_t cache_poll_procfs(struct file *filp, poll_table *wait)@@ -1599,7 +1621,8 @@ static int cache_release_procfs(struct inode *inode, struct file *filp)
static const struct proc_ops cache_channel_proc_ops = {
.proc_read = cache_read_procfs,
- .proc_write = cache_write_procfs,
+ .proc_write_buf = cache_write_procfs,
+ .proc_write_size = CACHE_DOWNCALL_MAX,
.proc_poll = cache_poll_procfs,
.proc_ioctl = cache_ioctl_procfs, /* for FIONREAD */
.proc_open = cache_open_procfs,@@ -1653,19 +1676,21 @@ static ssize_t read_flush_procfs(struct file *filp, char __user *buf,
return read_flush(filp, buf, count, ppos, cd);
}
-static ssize_t write_flush_procfs(struct file *filp,
- const char __user *buf,
- size_t count, loff_t *ppos)
+static ssize_t write_flush_procfs(struct file *filp, char *buf, size_t count,
+ loff_t *ppos)
{
struct cache_detail *cd = pde_data(file_inode(filp));
- return write_flush(filp, buf, count, ppos, cd);
+ if (*ppos)
+ return -EINVAL;
+ return do_write_flush(buf, count, ppos, cd);
}
static const struct proc_ops cache_flush_proc_ops = {
.proc_open = open_flush_procfs,
.proc_read = read_flush_procfs,
- .proc_write = write_flush_procfs,
+ .proc_write_buf = write_flush_procfs,
+ .proc_write_size = CACHE_FLUSH_MAX,
.proc_release = release_flush_procfs,
};
--
2.53.0