lkml.org 
[lkml]   [2011]   [May]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 12/44] printk: /dev/kmsg - properly support writev() to avoid interleaved printk() lines
    Date
    From: Kay Sievers <kay.sievers@vrfy.org>

    printk: /dev/kmsg - properly support writev() to avoid interleaved printk lines

    We should avoid calling printk() in a loop, when we pass a single
    string to /dev/kmsg with writev().

    Cc: Lennart Poettering <lennart@poettering.net>
    Signed-off-by: Kay Sievers <kay.sievers@vrfy.org>
    Cc: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
    ---
    drivers/char/mem.c | 41 ++++++++++++++++++++++++++---------------
    1 files changed, 26 insertions(+), 15 deletions(-)

    diff --git a/drivers/char/mem.c b/drivers/char/mem.c
    index 436a990..78923a9 100644
    --- a/drivers/char/mem.c
    +++ b/drivers/char/mem.c
    @@ -806,29 +806,40 @@ static const struct file_operations oldmem_fops = {
    };
    #endif

    -static ssize_t kmsg_write(struct file *file, const char __user *buf,
    - size_t count, loff_t *ppos)
    +static ssize_t kmsg_writev(struct kiocb *iocb, const struct iovec *iv,
    + unsigned long count, loff_t pos)
    {
    - char *tmp;
    - ssize_t ret;
    + char *line, *p;
    + int len, i;
    + ssize_t ret = -EFAULT;

    - tmp = kmalloc(count + 1, GFP_KERNEL);
    - if (tmp == NULL)
    + len = iov_length(iv, count);
    + line = p = kmalloc(len + 1, GFP_KERNEL);
    + if (line == NULL)
    return -ENOMEM;
    - ret = -EFAULT;
    - if (!copy_from_user(tmp, buf, count)) {
    - tmp[count] = 0;
    - ret = printk("%s", tmp);
    - if (ret > count)
    - /* printk can add a prefix */
    - ret = count;
    +
    + /*
    + * copy all vectors into a single string, to ensure we do
    + * not interleave our log line with other printk calls
    + */
    + for (i = 0; i < count; i++) {
    + if (copy_from_user(p, iv[i].iov_base, iv[i].iov_len))
    + goto out;
    + p += iv[i].iov_len;
    }
    - kfree(tmp);
    + p[0] = '\0';
    +
    + ret = printk("%s", line);
    + /* printk can add a prefix */
    + if (ret > len)
    + ret = len;
    +out:
    + kfree(line);
    return ret;
    }

    static const struct file_operations kmsg_fops = {
    - .write = kmsg_write,
    + .aio_write = kmsg_writev,
    .llseek = noop_llseek,
    };

    --
    1.7.4.2


    \
     
     \ /
      Last update: 2011-05-20 02:21    [W:0.031 / U:0.188 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site