Эх сурвалжийг харах

syslog: check cap_syslog when dmesg_restrict

Eric Paris pointed out that it doesn't make sense to require
both CAP_SYS_ADMIN and CAP_SYSLOG for certain syslog actions.
So require CAP_SYSLOG, not CAP_SYS_ADMIN, when dmesg_restrict
is set.

(I'm also consolidating the now common error path)

Signed-off-by: Serge E. Hallyn <serge.hallyn@canonical.com>
Acked-by: Eric Paris <eparis@redhat.com>
Acked-by: Kees Cook <kees.cook@canonical.com>
Signed-off-by: James Morris <jmorris@namei.org>
Serge E. Hallyn 14 жил өмнө
parent
commit
38ef4c2e43

+ 1 - 1
Documentation/sysctl/kernel.txt

@@ -219,7 +219,7 @@ dmesg_restrict:
 This toggle indicates whether unprivileged users are prevented from using
 This toggle indicates whether unprivileged users are prevented from using
 dmesg(8) to view messages from the kernel's log buffer.  When
 dmesg(8) to view messages from the kernel's log buffer.  When
 dmesg_restrict is set to (0) there are no restrictions.  When
 dmesg_restrict is set to (0) there are no restrictions.  When
-dmesg_restrict is set set to (1), users must have CAP_SYS_ADMIN to use
+dmesg_restrict is set set to (1), users must have CAP_SYSLOG to use
 dmesg(8).
 dmesg(8).
 
 
 The kernel config option CONFIG_SECURITY_DMESG_RESTRICT sets the default
 The kernel config option CONFIG_SECURITY_DMESG_RESTRICT sets the default

+ 10 - 10
kernel/printk.c

@@ -279,18 +279,12 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
 	 * at open time.
 	 * at open time.
 	 */
 	 */
 	if (type == SYSLOG_ACTION_OPEN || !from_file) {
 	if (type == SYSLOG_ACTION_OPEN || !from_file) {
-		if (dmesg_restrict && !capable(CAP_SYS_ADMIN))
-			return -EPERM;
+		if (dmesg_restrict && !capable(CAP_SYSLOG))
+			goto warn; /* switch to return -EPERM after 2.6.39 */
 		if ((type != SYSLOG_ACTION_READ_ALL &&
 		if ((type != SYSLOG_ACTION_READ_ALL &&
 		     type != SYSLOG_ACTION_SIZE_BUFFER) &&
 		     type != SYSLOG_ACTION_SIZE_BUFFER) &&
-		    !capable(CAP_SYSLOG)) {
-			/* remove after 2.6.38 */
-			if (capable(CAP_SYS_ADMIN))
-				WARN_ONCE(1, "Attempt to access syslog with "
-				  "CAP_SYS_ADMIN but no CAP_SYSLOG "
-				  "(deprecated and denied).\n");
-			return -EPERM;
-		}
+		    !capable(CAP_SYSLOG))
+			goto warn; /* switch to return -EPERM after 2.6.39 */
 	}
 	}
 
 
 	error = security_syslog(type);
 	error = security_syslog(type);
@@ -434,6 +428,12 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
 	}
 	}
 out:
 out:
 	return error;
 	return error;
+warn:
+	/* remove after 2.6.39 */
+	if (capable(CAP_SYS_ADMIN))
+		WARN_ONCE(1, "Attempt to access syslog with CAP_SYS_ADMIN "
+		  "but no CAP_SYSLOG (deprecated and denied).\n");
+	return -EPERM;
 }
 }
 
 
 SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len)
 SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len)