From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754026AbcFPJvZ (ORCPT ); Thu, 16 Jun 2016 05:51:25 -0400 Received: from mail.skyhub.de ([78.46.96.112]:49496 "EHLO mail.skyhub.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751619AbcFPJvW (ORCPT ); Thu, 16 Jun 2016 05:51:22 -0400 Date: Thu, 16 Jun 2016 11:51:16 +0200 From: Borislav Petkov To: Linus Torvalds Cc: Steven Rostedt , Ingo Molnar , Greg Kroah-Hartman , Peter Zijlstra , Andrew Morton , Uwe =?utf-8?Q?Kleine-K=C3=B6nig?= , LKML Subject: Re: [PATCH 2/2] printk: Add kernel parameter to control writes to /dev/kmsg Message-ID: <20160616095116.GA4688@pd.tnic> References: <1465899128-4522-1-git-send-email-bp@alien8.de> <1465899128-4522-3-git-send-email-bp@alien8.de> <20160614102135.GA13439@gmail.com> <20160614141456.6876b069@grimm.local.home> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.24 (2015-08-30) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, Jun 15, 2016 at 03:40:04PM -1000, Linus Torvalds wrote: > Possibly we could just say that if a kernel command line option has > been given, that is absolute. > > And then a sysctl for when you do *not* explicitly set if on the > kernel command line? Ok, how about this ontop? It is only lightly tested in a vm but basically I'm using the second byte of devkmsg_log to set a bit in there and the sysctl handler looks at it. It is also visible in sysctl and we know it has been cmdline-disabled: $ cat /proc/sys/kernel/printk_kmsg 256 --- diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt index a3683ce2a2f3..02fe4562953f 100644 --- a/Documentation/sysctl/kernel.txt +++ b/Documentation/sysctl/kernel.txt @@ -752,6 +752,19 @@ send before ratelimiting kicks in. ============================================================== +printk_kmsg: + +Control the logging to /dev/kmsg from userspace: + +0: default, ratelimited +1: unlimited logging to /dev/kmsg from userspace +2: logging to /dev/kmsg disabled + +The kernel command line parameter printk.kmsg= overrides this setting +and once set, it cannot be changed by this sysctl interface anymore. + +============================================================== + randomize_va_space: This option can be used to select the type of process address diff --git a/include/linux/printk.h b/include/linux/printk.h index f4da695fd615..bcf72e756122 100644 --- a/include/linux/printk.h +++ b/include/linux/printk.h @@ -171,6 +171,12 @@ extern bool printk_timed_ratelimit(unsigned long *caller_jiffies, extern int printk_delay_msec; extern int dmesg_restrict; extern int kptr_restrict; +extern unsigned int devkmsg_log; + +struct ctl_table; + +int devkmsg_sysctl_set_loglvl(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos); extern void wake_up_klogd(void); diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 33701a166f26..9f0a885c2718 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -86,12 +86,15 @@ static struct lockdep_map console_lock_dep_map = { }; #endif -#define DEVKMSG_LOG_RATELIMIT 0 -#define DEVKMSG_LOG_ON 1 -#define DEVKMSG_LOG_OFF 2 +#define DEVKMSG_LOG_RATELIMIT 0 +#define DEVKMSG_LOG_ON 1 +#define DEVKMSG_LOG_OFF 2 +#define DEVKMSG_LOCK (1 << 8) +#define DEVKMSG_LOG_MASK (DEVKMSG_LOCK - 1) +#define DEVKMSG_LOCKED_MASK ~DEVKMSG_LOG_MASK /* DEVKMSG_LOG_RATELIMIT by default */ -static unsigned int __read_mostly devkmsg_log; +unsigned int __read_mostly devkmsg_log; static int __init control_devkmsg(char *str) { if (!str) @@ -101,14 +104,30 @@ static int __init control_devkmsg(char *str) devkmsg_log = DEVKMSG_LOG_ON; else if (!strncmp(str, "off", 3)) devkmsg_log = DEVKMSG_LOG_OFF; + else if (!strncmp(str, "ratelimit", 9)) + devkmsg_log = DEVKMSG_LOG_RATELIMIT; else return -EINVAL; + /* Sysctl cannot change it anymore. */ + devkmsg_log |= DEVKMSG_LOCK; + return 0; } __setup("printk.kmsg=", control_devkmsg); +int devkmsg_sysctl_set_loglvl(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + if (devkmsg_log & DEVKMSG_LOCKED_MASK) { + if (write) + return -EINVAL; + } + + return proc_dointvec_minmax(table, write, buffer, lenp, ppos); +} + /* * Number of registered extended console drivers. * @@ -656,11 +675,12 @@ static ssize_t devkmsg_write(struct kiocb *iocb, struct iov_iter *from) return -EINVAL; /* Ignore when user logging is disabled. */ - if (devkmsg_log == DEVKMSG_LOG_OFF) + if ((devkmsg_log & DEVKMSG_LOG_MASK) == DEVKMSG_LOG_OFF) return len; /* Ratelimit when not explicitly enabled or when we're not booting. */ - if ((system_state != SYSTEM_BOOTING) && (devkmsg_log != DEVKMSG_LOG_ON)) { + if ((system_state != SYSTEM_BOOTING) && + ((devkmsg_log & DEVKMSG_LOG_MASK) != DEVKMSG_LOG_ON)) { if (!___ratelimit(&user->rs, current->comm)) return ret; } diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 87b2fc38398b..a29d6c4fa86c 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -814,6 +814,15 @@ static struct ctl_table kern_table[] = { .extra2 = &ten_thousand, }, { + .procname = "printk_kmsg", + .data = &devkmsg_log, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = devkmsg_sysctl_set_loglvl, + .extra1 = &zero, + .extra2 = &two, + }, + { .procname = "dmesg_restrict", .data = &dmesg_restrict, .maxlen = sizeof(int), -- Regards/Gruss, Boris. ECO tip #101: Trim your mails when you reply.