Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1422804AbbEOMlb (ORCPT ); Fri, 15 May 2015 08:41:31 -0400 Received: from cantor2.suse.de ([195.135.220.15]:58353 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1030185AbbEOMl2 (ORCPT ); Fri, 15 May 2015 08:41:28 -0400 Date: Fri, 15 May 2015 14:44:11 +0200 From: Petr Mladek To: Tejun Heo Cc: akpm@linux-foundation.org, davem@davemloft.net, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, Kay Sievers Subject: Re: [PATCH 1/7] printk: guard the amount written per line by devkmsg_read() Message-ID: <20150515124411.GB8222@pathway.suse.cz> References: <1431619586-29187-1-git-send-email-tj@kernel.org> <1431619586-29187-2-git-send-email-tj@kernel.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1431619586-29187-2-git-send-email-tj@kernel.org> User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4619 Lines: 156 On Thu 2015-05-14 12:06:20, Tejun Heo wrote: > devkmsg_read() uses 8k buffer and assumes that the formatted output > message won't overrun which seems safe given LOG_LINE_MAX, the current > use of dict and the escaping method being used; however, we're > planning to use devkmsg formatting wider and accounting for the buffer > size properly isn't that complicated. > > This patch defines CONSOLE_EXT_LOG_MAX as 8192 and updates > devkmsg_read() so that it limits output accordingly. > > Signed-off-by: Tejun Heo Reviewed-by: Petr Mladek It is more secure now. Best Regards, Petr > Cc: Kay Sievers > Cc: Petr Mladek > --- > include/linux/printk.h | 2 ++ > kernel/printk/printk.c | 34 ++++++++++++++++++++++------------ > 2 files changed, 24 insertions(+), 12 deletions(-) > > diff --git a/include/linux/printk.h b/include/linux/printk.h > index 9b30871..58b1fec 100644 > --- a/include/linux/printk.h > +++ b/include/linux/printk.h > @@ -30,6 +30,8 @@ static inline const char *printk_skip_level(const char *buffer) > return buffer; > } > > +#define CONSOLE_EXT_LOG_MAX 8192 > + > /* printk's without a loglevel use this.. */ > #define MESSAGE_LOGLEVEL_DEFAULT CONFIG_MESSAGE_LOGLEVEL_DEFAULT > > diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c > index c099b08..a115490 100644 > --- a/kernel/printk/printk.c > +++ b/kernel/printk/printk.c > @@ -505,6 +505,11 @@ int check_syslog_permissions(int type, bool from_file) > return security_syslog(type); > } > > +static void append_char(char **pp, char *e, char c) > +{ > + if (*pp < e) > + *(*pp)++ = c; > +} > > /* /dev/kmsg - userspace message inject/listen interface */ > struct devkmsg_user { > @@ -512,7 +517,7 @@ struct devkmsg_user { > u32 idx; > enum log_flags prev; > struct mutex lock; > - char buf[8192]; > + char buf[CONSOLE_EXT_LOG_MAX]; > }; > > static ssize_t devkmsg_write(struct kiocb *iocb, struct iov_iter *from) > @@ -570,6 +575,7 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf, > { > struct devkmsg_user *user = file->private_data; > struct printk_log *msg; > + char *p, *e; > u64 ts_usec; > size_t i; > char cont = '-'; > @@ -579,6 +585,9 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf, > if (!user) > return -EBADF; > > + p = user->buf; > + e = user->buf + sizeof(user->buf); > + > ret = mutex_lock_interruptible(&user->lock); > if (ret) > return ret; > @@ -625,9 +634,9 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf, > ((user->prev & LOG_CONT) && !(msg->flags & LOG_PREFIX))) > cont = '+'; > > - len = sprintf(user->buf, "%u,%llu,%llu,%c;", > - (msg->facility << 3) | msg->level, > - user->seq, ts_usec, cont); > + p += scnprintf(p, e - p, "%u,%llu,%llu,%c;", > + (msg->facility << 3) | msg->level, > + user->seq, ts_usec, cont); > user->prev = msg->flags; > > /* escape non-printable characters */ > @@ -635,11 +644,11 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf, > unsigned char c = log_text(msg)[i]; > > if (c < ' ' || c >= 127 || c == '\\') > - len += sprintf(user->buf + len, "\\x%02x", c); > + p += scnprintf(p, e - p, "\\x%02x", c); > else > - user->buf[len++] = c; > + append_char(&p, e, c); > } > - user->buf[len++] = '\n'; > + append_char(&p, e, '\n'); > > if (msg->dict_len) { > bool line = true; > @@ -648,30 +657,31 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf, > unsigned char c = log_dict(msg)[i]; > > if (line) { > - user->buf[len++] = ' '; > + append_char(&p, e, ' '); > line = false; > } > > if (c == '\0') { > - user->buf[len++] = '\n'; > + append_char(&p, e, '\n'); > line = true; > continue; > } > > if (c < ' ' || c >= 127 || c == '\\') { > - len += sprintf(user->buf + len, "\\x%02x", c); > + p += scnprintf(p, e - p, "\\x%02x", c); > continue; > } > > - user->buf[len++] = c; > + append_char(&p, e, c); > } > - user->buf[len++] = '\n'; > + append_char(&p, e, '\n'); > } > > user->idx = log_next(user->idx); > user->seq++; > raw_spin_unlock_irq(&logbuf_lock); > > + len = p - user->buf; > if (len > count) { > ret = -EINVAL; > goto out; > -- > 2.1.0 > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/