[kernel/f19] Update dmesg_restrict patch to v2

Josh Boyer jwboyer at fedoraproject.org
Tue Apr 9 17:31:14 UTC 2013


commit f846a2a17e54edd11e4b1406327fd36a1a499df0
Author: Josh Boyer <jwboyer at redhat.com>
Date:   Tue Apr 9 13:27:49 2013 -0400

    Update dmesg_restrict patch to v2

 ...g-Honor-dmesg_restrict-sysctl-on-dev-kmsg.patch |  166 +++++++++++++++++---
 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 acaf5f8..c42c8c4 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 at 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 at nerdbynature.de>
 CC: stable at vger.kernel.org
+Signed-off-by: Eric Paris <eparis at redhat.com>
 Signed-off-by: Josh Boyer <jwboyer at 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
 


More information about the scm-commits mailing list