Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F97556323
D37101.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D37101.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)) > 0)
+ 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);
+ copyout(sbuf_data(sb), buf, 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,12 +54,10 @@
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);
@@ -67,11 +65,7 @@
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;
+ 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;
@@ -88,68 +90,66 @@
* simple_attr_read: read simple attr data and transfer into buffer
*
* @filp: file pointer
- * @buf: kernel space buffer
+ * @ubuf: user space buffer
* @read_size: number of bytes to be transferred
* @ppos: starting pointer position for transfer
*
* The simple_attr structure is stored in filp->private_data.
* ->get() retrieves raw file data.
* The ->fmt specifier can format this data to be human readable.
- * This output is then transferred into the @buf buffer.
+ * This output is then transferred into the @ubuf buffer.
*
* Return value:
* On success, number of bytes transferred
* 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);
}
/*
* simple_attr_write: write contents of buffer into simple attribute file
*
* @filp: file pointer
- * @buf: kernel space buffer
+ * @ubuf: user space buffer
* @write_size: number bytes to be transferred
* @ppos: starting pointer position for transfer
*
* The simple_attr structure is stored in filp->private_data.
- * Convert the @buf string to unsigned long long.
+ * Convert the @ubuf string to unsigned long long.
* ->set() writes unsigned long long data into the simple attr file.
*
* Return value:
@@ -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
Tue, Oct 1, 1:31 AM (22 h, 8 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
13219307
Default Alt Text
D37101.diff (5 KB)
Attached To
Mode
D37101: LinuxKPI: pass userspace buffers for lindebugfs r/w fops
Attached
Detach File
Event Timeline
Log In to Comment