Page MenuHomeFreeBSD

D37101.diff
No OneTemporary

D37101.diff

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

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)

Event Timeline