Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F150347223
D37101.1792199318.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D37101.1792199318.diff
View Options
diff --git a/sys/compat/lindebugfs/lindebugfs.c b/sys/compat/lindebugfs/lindebugfs.c
--- a/sys/compat/lindebugfs/lindebugfs.c
+++ b/sys/compat/lindebugfs/lindebugfs.c
@@ -120,6 +120,7 @@
struct linux_file lf = {};
struct vnode vn;
char *buf;
+ size_t buf_len;
int rc;
off_t off = 0;
@@ -137,20 +138,19 @@
return (-rc);
}
- rc = -ENODEV;
+ buf = uio->uio_iov[0].iov_base;
+
+ rc = -EIO;
if (uio->uio_rw == UIO_READ && d->dm_fops->read) {
- rc = -ENOMEM;
- buf = (char *) malloc(sb->s_size, M_DFSINT, M_ZERO | M_NOWAIT);
- if (buf != NULL) {
- rc = d->dm_fops->read(&lf, buf, sb->s_size, &off);
- if (rc > 0)
- sbuf_bcpy(sb, buf, strlen(buf));
-
- free(buf, M_DFSINT);
- }
+ buf_len = min(uio->uio_iov[0].iov_len, uio->uio_resid);
+ if ((rc = d->dm_fops->read(&lf, buf, buf_len, &off)))
+ sbuf_bcopyin(sb, buf, rc);
} else if (uio->uio_rw == UIO_WRITE && d->dm_fops->write) {
- sbuf_finish(sb);
- rc = d->dm_fops->write(&lf, sbuf_data(sb), sbuf_len(sb), &off);
+ if ((rc = sbuf_finish(sb)) == 0) {
+ buf_len = sbuf_len(sb);
+ memcpy(buf, sbuf_data(sb), buf_len);
+ rc = d->dm_fops->write(&lf, buf, buf_len, &off);
+ }
}
if (d->dm_fops->release)
diff --git a/sys/compat/linuxkpi/common/src/linux_seq_file.c b/sys/compat/linuxkpi/common/src/linux_seq_file.c
--- a/sys/compat/linuxkpi/common/src/linux_seq_file.c
+++ b/sys/compat/linuxkpi/common/src/linux_seq_file.c
@@ -54,24 +54,19 @@
sbuf = m->buf;
p = m->op->start(m, ppos);
- rc = m->op->show(m, p);
- if (rc)
+ if ((rc = m->op->show(m, p)))
return (rc);
- rc = sbuf_finish(sbuf);
- if (rc)
+ if ((rc = sbuf_finish(sbuf)))
return (rc);
rc = sbuf_len(sbuf);
if (*ppos >= rc || size < 1)
return (-EINVAL);
- size = min(rc - *ppos, size);
- rc = strscpy(ubuf, sbuf_data(sbuf) + *ppos, size);
-
- /* add 1 for null terminator */
- if (rc > 0)
- rc += 1;
+ /* increment rc for null terminator */
+ size = min(++rc - *ppos, size);
+ rc = size - copy_to_user(ubuf, sbuf_data(sbuf) + *ppos, size);
return (rc);
}
diff --git a/sys/compat/linuxkpi/common/src/linux_simple_attr.c b/sys/compat/linuxkpi/common/src/linux_simple_attr.c
--- a/sys/compat/linuxkpi/common/src/linux_simple_attr.c
+++ b/sys/compat/linuxkpi/common/src/linux_simple_attr.c
@@ -36,6 +36,8 @@
struct simple_attr {
int (*get)(void *, uint64_t *);
int (*set)(void *, uint64_t);
+ char get_buf[24];
+ char set_buf[24];
void *data;
const char *fmt;
struct mutex mutex;
@@ -102,42 +104,40 @@
* On failure, negative signed ERRNO
*/
ssize_t
-simple_attr_read(struct file *filp, char *buf, size_t read_size, loff_t *ppos)
+simple_attr_read(struct file *filp, char *ubuf, size_t read_size, loff_t *ppos)
{
struct simple_attr *sattr;
uint64_t data;
- ssize_t ret;
- char prebuf[24];
+ ssize_t bytes;
+ char *prebuf;
sattr = filp->private_data;
+ prebuf = sattr->get_buf;
if (sattr->get == NULL)
return (-EFAULT);
mutex_lock(&sattr->mutex);
- ret = sattr->get(sattr->data, &data);
- if (ret)
+ if ((bytes = sattr->get(sattr->data, &data)))
goto unlock;
- scnprintf(prebuf, sizeof(prebuf), sattr->fmt, data);
+ scnprintf(prebuf, sizeof(sattr->get_buf), sattr->fmt, data);
- ret = strlen(prebuf) + 1;
- if (*ppos >= ret || read_size < 1) {
- ret = -EINVAL;
+ bytes = strlen(prebuf);
+ if (*ppos >= bytes || read_size < 1) {
+ bytes = -EINVAL;
goto unlock;
}
- read_size = min(ret - *ppos, read_size);
- ret = strscpy(buf, prebuf + *ppos, read_size);
-
- /* add 1 for null terminator */
- if (ret > 0)
- ret += 1;
+ /* increment bytes for null terminator */
+ read_size = min(++bytes - *ppos, read_size);
+ prebuf[read_size - 1] = '\0';
+ bytes = read_size - copy_to_user(ubuf, prebuf + *ppos, read_size);
unlock:
mutex_unlock(&sattr->mutex);
- return (ret);
+ return (bytes);
}
/*
@@ -157,35 +157,34 @@
* On failure, negative signed ERRNO
*/
ssize_t
-simple_attr_write(struct file *filp, const char *buf, size_t write_size, loff_t *ppos)
+simple_attr_write(struct file *filp, const char *ubuf, size_t write_size, loff_t *ppos)
{
struct simple_attr *sattr;
unsigned long long data;
- size_t bufsize;
- ssize_t ret;
+ ssize_t bytes;
+ char *prebuf;
sattr = filp->private_data;
- bufsize = strlen(buf) + 1;
+ prebuf = sattr->set_buf;
if (sattr->set == NULL)
return (-EFAULT);
- if (*ppos >= bufsize || write_size < 1)
- return (-EINVAL);
-
mutex_lock(&sattr->mutex);
- ret = kstrtoull(buf + *ppos, 0, &data);
- if (ret)
+ write_size = min(write_size, sizeof(sattr->set_buf));
+ write_size -= copy_from_user(prebuf, ubuf + *ppos, write_size);
+ prebuf[write_size - 1] = '\0';
+
+ if ((bytes = kstrtoull(prebuf, 0, &data)))
goto unlock;
- ret = sattr->set(sattr->data, data);
- if (ret)
+ if ((bytes = sattr->set(sattr->data, data)))
goto unlock;
- ret = bufsize - *ppos;
+ bytes = write_size;
unlock:
mutex_unlock(&sattr->mutex);
- return (ret);
+ return (bytes);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Oct 17, 1:08 AM (5 h, 9 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30447881
Default Alt Text
D37101.1792199318.diff (4 KB)
Attached To
Mode
D37101: LinuxKPI: pass userspace buffers for lindebugfs r/w fops
Attached
Detach File
Event Timeline
Log In to Comment