forked from rpms/kernel
		
	Update dmesg_restrict patch to v2
This commit is contained in:
		
							parent
							
								
									967548beda
								
							
						
					
					
						commit
						078da2408e
					
				| @ -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> | 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 | Subject: [PATCH] kmsg: Honor dmesg_restrict sysctl on /dev/kmsg | ||||||
| 
 | 
 | ||||||
| Originally, the addition of the dmesg_restrict covered both the syslog | The dmesg_restrict sysctl currently covers the syslog method for access | ||||||
| method of accessing dmesg, as well as /dev/kmsg itself.  This was done | dmesg, however /dev/kmsg isn't covered by the same protections.  Most | ||||||
| indirectly by security_syslog calling cap_syslog before doing any LSM | people haven't noticed because util-linux dmesg(1) defaults to using the | ||||||
| checks. | 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 | Fix this by reworking all of the access methods to use the | ||||||
| logic to fix build failure) moved the code around and pushed the checks | check_syslog_permissions function and adding checks to devkmsg_open and | ||||||
| into the caller itself.  That seems to have inadvertently dropped the | devkmsg_read. | ||||||
| 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. |  | ||||||
| 
 | 
 | ||||||
| This fixes https://bugzilla.redhat.com/show_bug.cgi?id=903192 | This fixes https://bugzilla.redhat.com/show_bug.cgi?id=903192 | ||||||
| 
 | 
 | ||||||
| Reported-by: Christian Kujau <lists@nerdbynature.de> | Reported-by: Christian Kujau <lists@nerdbynature.de> | ||||||
| CC: stable@vger.kernel.org | CC: stable@vger.kernel.org | ||||||
|  | Signed-off-by: Eric Paris <eparis@redhat.com> | ||||||
| Signed-off-by: Josh Boyer <jwboyer@redhat.com> | Signed-off-by: Josh Boyer <jwboyer@redhat.com> | ||||||
| ---
 | ---
 | ||||||
|  kernel/printk.c | 3 +++ |  kernel/printk.c | 91 +++++++++++++++++++++++++++++---------------------------- | ||||||
|  1 file changed, 3 insertions(+) |  1 file changed, 47 insertions(+), 44 deletions(-) | ||||||
| 
 | 
 | ||||||
| diff --git a/kernel/printk.c b/kernel/printk.c
 | diff --git a/kernel/printk.c b/kernel/printk.c
 | ||||||
| index f24633a..398ef9a 100644
 | index abbdd9e..5541095 100644
 | ||||||
| --- a/kernel/printk.c
 | --- a/kernel/printk.c
 | ||||||
| +++ b/kernel/printk.c
 | +++ b/kernel/printk.c
 | ||||||
| @@ -615,6 +615,9 @@ static int devkmsg_open(struct inode *inode, struct file *file)
 | @@ -368,6 +368,46 @@ static void log_store(int facility, int level,
 | ||||||
|  	struct devkmsg_user *user; |  	log_next_seq++; | ||||||
|  	int err; |  } | ||||||
|   |   | ||||||
| +	if (dmesg_restrict && !capable(CAP_SYSLOG))
 | +#ifdef CONFIG_SECURITY_DMESG_RESTRICT
 | ||||||
| +		return -EACCES;
 | +int dmesg_restrict = 1;
 | ||||||
|  | +#else
 | ||||||
|  | +int dmesg_restrict;
 | ||||||
|  | +#endif
 | ||||||
| +
 | +
 | ||||||
|  	/* write-only does not need any file context */ | +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;
 | ||||||
|  | +
 | ||||||
|  | +	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) |  	if ((file->f_flags & O_ACCMODE) == O_WRONLY) | ||||||
|  		return 0; |  		return 0; | ||||||
| -- 
 |   | ||||||
| 1.8.1.2 | -	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.4 | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user