summaryrefslogtreecommitdiffstats
path: root/0001-kmsg-Honor-dmesg_restrict-sysctl-on-dev-kmsg.patch
diff options
context:
space:
mode:
authorJosh Boyer <jwboyer@redhat.com>2013-04-09 13:27:49 -0400
committerJosh Boyer <jwboyer@redhat.com>2013-04-09 13:27:49 -0400
commit078da2408e2e65f4ff5d115df71775dde02161bf (patch)
treead98e6928394d591f7e94c9439231aa93f624432 /0001-kmsg-Honor-dmesg_restrict-sysctl-on-dev-kmsg.patch
parent967548beda96535ee533f31bf73e56026bb9ce1e (diff)
downloadkernel-078da2408e2e65f4ff5d115df71775dde02161bf.tar.gz
kernel-078da2408e2e65f4ff5d115df71775dde02161bf.tar.xz
kernel-078da2408e2e65f4ff5d115df71775dde02161bf.zip
Update dmesg_restrict patch to v2
Diffstat (limited to '0001-kmsg-Honor-dmesg_restrict-sysctl-on-dev-kmsg.patch')
-rw-r--r--0001-kmsg-Honor-dmesg_restrict-sysctl-on-dev-kmsg.patch166
1 files changed, 141 insertions, 25 deletions
diff --git a/0001-kmsg-Honor-dmesg_restrict-sysctl-on-dev-kmsg.patch b/0001-kmsg-Honor-dmesg_restrict-sysctl-on-dev-kmsg.patch
index acaf5f881..c42c8c4f1 100644
--- a/0001-kmsg-Honor-dmesg_restrict-sysctl-on-dev-kmsg.patch
+++ b/0001-kmsg-Honor-dmesg_restrict-sysctl-on-dev-kmsg.patch
@@ -1,46 +1,162 @@
-From feaf4959c30d0640093a607c577940d3e9351076 Mon Sep 17 00:00:00 2001
+From ce10d1b72b4da3c98bbbcb1b945687d964c31923 Mon Sep 17 00:00:00 2001
From: Josh Boyer <jwboyer@redhat.com>
-Date: Fri, 22 Feb 2013 11:47:37 -0500
+Date: Tue, 9 Apr 2013 11:08:13 -0400
Subject: [PATCH] kmsg: Honor dmesg_restrict sysctl on /dev/kmsg
-Originally, the addition of the dmesg_restrict covered both the syslog
-method of accessing dmesg, as well as /dev/kmsg itself. This was done
-indirectly by security_syslog calling cap_syslog before doing any LSM
-checks.
+The dmesg_restrict sysctl currently covers the syslog method for access
+dmesg, however /dev/kmsg isn't covered by the same protections. Most
+people haven't noticed because util-linux dmesg(1) defaults to using the
+syslog method for access in older versions. With util-linux dmesg(1)
+defaults to reading directly from /dev/kmsg.
-However, commit 12b3052c3ee (capabilities/syslog: open code cap_syslog
-logic to fix build failure) moved the code around and pushed the checks
-into the caller itself. That seems to have inadvertently dropped the
-checks for dmesg_restrict on /dev/kmsg. Most people haven't noticed
-because util-linux dmesg(1) defaults to using the syslog method for
-access in older versions. With util-linux 2.22 and a kernel newer than
-3.5, dmesg(1) defaults to reading directly from /dev/kmsg.
-
-Fix this by making an explicit check in the devkmsg_open function.
+Fix this by reworking all of the access methods to use the
+check_syslog_permissions function and adding checks to devkmsg_open and
+devkmsg_read.
This fixes https://bugzilla.redhat.com/show_bug.cgi?id=903192
Reported-by: Christian Kujau <lists@nerdbynature.de>
CC: stable@vger.kernel.org
+Signed-off-by: Eric Paris <eparis@redhat.com>
Signed-off-by: Josh Boyer <jwboyer@redhat.com>
---
- kernel/printk.c | 3 +++
- 1 file changed, 3 insertions(+)
+ kernel/printk.c | 91 +++++++++++++++++++++++++++++----------------------------
+ 1 file changed, 47 insertions(+), 44 deletions(-)
diff --git a/kernel/printk.c b/kernel/printk.c
-index f24633a..398ef9a 100644
+index abbdd9e..5541095 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
-@@ -615,6 +615,9 @@ static int devkmsg_open(struct inode *inode, struct file *file)
- struct devkmsg_user *user;
- int err;
+@@ -368,6 +368,46 @@ static void log_store(int facility, int level,
+ log_next_seq++;
+ }
-+ if (dmesg_restrict && !capable(CAP_SYSLOG))
-+ return -EACCES;
++#ifdef CONFIG_SECURITY_DMESG_RESTRICT
++int dmesg_restrict = 1;
++#else
++int dmesg_restrict;
++#endif
++
++static int syslog_action_restricted(int type)
++{
++ if (dmesg_restrict)
++ return 1;
++ /* Unless restricted, we allow "read all" and "get buffer size" for everybody */
++ return type != SYSLOG_ACTION_READ_ALL && type != SYSLOG_ACTION_SIZE_BUFFER;
++}
++
++static int check_syslog_permissions(int type, bool from_file)
++{
++ /*
++ * If this is from /proc/kmsg and we've already opened it, then we've
++ * already done the capabilities checks at open time.
++ */
++ if (from_file && type != SYSLOG_ACTION_OPEN)
++ goto ok;
+
- /* write-only does not need any file context */
++ if (syslog_action_restricted(type)) {
++ if (capable(CAP_SYSLOG))
++ goto ok;
++ /* For historical reasons, accept CAP_SYS_ADMIN too, with a warning */
++ if (capable(CAP_SYS_ADMIN)) {
++ printk_once(KERN_WARNING "%s (%d): "
++ "Attempt to access syslog with CAP_SYS_ADMIN "
++ "but no CAP_SYSLOG (deprecated).\n",
++ current->comm, task_pid_nr(current));
++ goto ok;
++ }
++ return -EPERM;
++ }
++ok:
++ return security_syslog(type);
++}
++
+ /* /dev/kmsg - userspace message inject/listen interface */
+ struct devkmsg_user {
+ u64 seq;
+@@ -443,10 +483,16 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,
+ char cont = '-';
+ size_t len;
+ ssize_t ret;
++ int err;
+
+ if (!user)
+ return -EBADF;
+
++ err = check_syslog_permissions(SYSLOG_ACTION_READ_ALL,
++ SYSLOG_FROM_FILE);
++ if (err)
++ return err;
++
+ ret = mutex_lock_interruptible(&user->lock);
+ if (ret)
+ return ret;
+@@ -624,7 +670,7 @@ static int devkmsg_open(struct inode *inode, struct file *file)
if ((file->f_flags & O_ACCMODE) == O_WRONLY)
return 0;
+
+- err = security_syslog(SYSLOG_ACTION_READ_ALL);
++ err = check_syslog_permissions(SYSLOG_ACTION_OPEN, SYSLOG_FROM_FILE);
+ if (err)
+ return err;
+
+@@ -817,45 +863,6 @@ static inline void boot_delay_msec(int level)
+ }
+ #endif
+
+-#ifdef CONFIG_SECURITY_DMESG_RESTRICT
+-int dmesg_restrict = 1;
+-#else
+-int dmesg_restrict;
+-#endif
+-
+-static int syslog_action_restricted(int type)
+-{
+- if (dmesg_restrict)
+- return 1;
+- /* Unless restricted, we allow "read all" and "get buffer size" for everybody */
+- return type != SYSLOG_ACTION_READ_ALL && type != SYSLOG_ACTION_SIZE_BUFFER;
+-}
+-
+-static int check_syslog_permissions(int type, bool from_file)
+-{
+- /*
+- * If this is from /proc/kmsg and we've already opened it, then we've
+- * already done the capabilities checks at open time.
+- */
+- if (from_file && type != SYSLOG_ACTION_OPEN)
+- return 0;
+-
+- if (syslog_action_restricted(type)) {
+- if (capable(CAP_SYSLOG))
+- return 0;
+- /* For historical reasons, accept CAP_SYS_ADMIN too, with a warning */
+- if (capable(CAP_SYS_ADMIN)) {
+- printk_once(KERN_WARNING "%s (%d): "
+- "Attempt to access syslog with CAP_SYS_ADMIN "
+- "but no CAP_SYSLOG (deprecated).\n",
+- current->comm, task_pid_nr(current));
+- return 0;
+- }
+- return -EPERM;
+- }
+- return 0;
+-}
+-
+ #if defined(CONFIG_PRINTK_TIME)
+ static bool printk_time = 1;
+ #else
+@@ -1131,10 +1138,6 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
+ if (error)
+ goto out;
+
+- error = security_syslog(type);
+- if (error)
+- return error;
+-
+ switch (type) {
+ case SYSLOG_ACTION_CLOSE: /* Close log */
+ break;
--
-1.8.1.2
+1.8.1.4