|
@@ -363,6 +363,53 @@ static void log_store(int facility, int level,
|
|
|
log_next_seq++;
|
|
|
}
|
|
|
|
|
|
+#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)) {
|
|
|
+ pr_warn_once("%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 security_syslog(type);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
/* /dev/kmsg - userspace message inject/listen interface */
|
|
|
struct devkmsg_user {
|
|
|
u64 seq;
|
|
@@ -620,7 +667,8 @@ 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_READ_ALL,
|
|
|
+ SYSLOG_FROM_READER);
|
|
|
if (err)
|
|
|
return err;
|
|
|
|
|
@@ -813,45 +861,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
|
|
@@ -1249,7 +1258,7 @@ out:
|
|
|
|
|
|
SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len)
|
|
|
{
|
|
|
- return do_syslog(type, buf, len, SYSLOG_FROM_CALL);
|
|
|
+ return do_syslog(type, buf, len, SYSLOG_FROM_READER);
|
|
|
}
|
|
|
|
|
|
/*
|