diff options
Diffstat (limited to 'kernel/printk.c')
| -rw-r--r-- | kernel/printk.c | 91 | 
1 files changed, 50 insertions, 41 deletions
diff --git a/kernel/printk.c b/kernel/printk.c index fa36e149442..8212c1aef12 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -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);  }  /*  |