* [PATCH] syslog: distinguish between /proc/kmsg and syscalls
@ 2010-02-02 5:53 Kees Cook
2010-02-02 6:15 ` Casey Schaufler
0 siblings, 1 reply; 22+ messages in thread
From: Kees Cook @ 2010-02-02 5:53 UTC (permalink / raw)
To: linux-security-module
Cc: James Morris, Eric Paris, David Howells, Serge Hallyn,
Alexey Dobriyan, Ingo Molnar, Andrew Morton, Simon Kagstrom,
David Woodhouse, Robin Getz, Greg Kroah-Hartman, Paul Moore,
Tetsuo Handa, Stephen Smalley, Casey Schaufler, Etienne Basset,
David P. Quigley, linux-kernel
This allows the LSM to distinguish between syslog functions originating
from /proc/kmsg access and direct syscalls. By default, the commoncaps
will now no longer require CAP_SYS_ADMIN to read an opened /proc/kmsg
file descriptor. For example the kernel syslog reader can now drop
privileges after opening /proc/kmsg, instead of staying privileged with
CAP_SYS_ADMIN. MAC systems that implement security_syslog have unchanged
behavior.
Signed-off-by: Kees Cook <kees.cook@canonical.com>
---
fs/proc/kmsg.c | 14 +++++++-------
include/linux/security.h | 11 ++++++-----
include/linux/syslog.h | 29 +++++++++++++++++++++++++++++
kernel/printk.c | 7 ++++---
security/commoncap.c | 7 ++++++-
security/security.c | 4 ++--
security/selinux/hooks.c | 4 ++--
security/smack/smack_lsm.c | 4 ++--
8 files changed, 58 insertions(+), 22 deletions(-)
create mode 100644 include/linux/syslog.h
diff --git a/fs/proc/kmsg.c b/fs/proc/kmsg.c
index 7ca7834..4f52b68 100644
--- a/fs/proc/kmsg.c
+++ b/fs/proc/kmsg.c
@@ -12,37 +12,37 @@
#include <linux/poll.h>
#include <linux/proc_fs.h>
#include <linux/fs.h>
+#include <linux/syslog.h>
#include <asm/uaccess.h>
#include <asm/io.h>
extern wait_queue_head_t log_wait;
-extern int do_syslog(int type, char __user *bug, int count);
-
static int kmsg_open(struct inode * inode, struct file * file)
{
- return do_syslog(1,NULL,0);
+ return do_syslog(1, NULL, 0, SYSLOG_CONTEXT_PROC);
}
static int kmsg_release(struct inode * inode, struct file * file)
{
- (void) do_syslog(0,NULL,0);
+ (void) do_syslog(0, NULL, 0, SYSLOG_CONTEXT_PROC);
return 0;
}
static ssize_t kmsg_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
- if ((file->f_flags & O_NONBLOCK) && !do_syslog(9, NULL, 0))
+ if ((file->f_flags & O_NONBLOCK) &&
+ !do_syslog(9, NULL, 0, SYSLOG_CONTEXT_PROC))
return -EAGAIN;
- return do_syslog(2, buf, count);
+ return do_syslog(2, buf, count, SYSLOG_CONTEXT_PROC);
}
static unsigned int kmsg_poll(struct file *file, poll_table *wait)
{
poll_wait(file, &log_wait, wait);
- if (do_syslog(9, NULL, 0))
+ if (do_syslog(9, NULL, 0, SYSLOG_CONTEXT_PROC))
return POLLIN | POLLRDNORM;
return 0;
}
diff --git a/include/linux/security.h b/include/linux/security.h
index 2c627d3..174f834 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -76,7 +76,7 @@ extern int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
extern int cap_task_setscheduler(struct task_struct *p, int policy, struct sched_param *lp);
extern int cap_task_setioprio(struct task_struct *p, int ioprio);
extern int cap_task_setnice(struct task_struct *p, int nice);
-extern int cap_syslog(int type);
+extern int cap_syslog(int type, int context);
extern int cap_vm_enough_memory(struct mm_struct *mm, long pages);
struct msghdr;
@@ -1348,6 +1348,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
* logging to the console.
* See the syslog(2) manual page for an explanation of the @type values.
* @type contains the type of action.
+ * @context contains the context of action (/proc or syscall).
* Return 0 if permission is granted.
* @settime:
* Check permission to change the system time.
@@ -1462,7 +1463,7 @@ struct security_operations {
int (*sysctl) (struct ctl_table *table, int op);
int (*quotactl) (int cmds, int type, int id, struct super_block *sb);
int (*quota_on) (struct dentry *dentry);
- int (*syslog) (int type);
+ int (*syslog) (int type, int context);
int (*settime) (struct timespec *ts, struct timezone *tz);
int (*vm_enough_memory) (struct mm_struct *mm, long pages);
@@ -1761,7 +1762,7 @@ int security_acct(struct file *file);
int security_sysctl(struct ctl_table *table, int op);
int security_quotactl(int cmds, int type, int id, struct super_block *sb);
int security_quota_on(struct dentry *dentry);
-int security_syslog(int type);
+int security_syslog(int type, int context);
int security_settime(struct timespec *ts, struct timezone *tz);
int security_vm_enough_memory(long pages);
int security_vm_enough_memory_mm(struct mm_struct *mm, long pages);
@@ -2007,9 +2008,9 @@ static inline int security_quota_on(struct dentry *dentry)
return 0;
}
-static inline int security_syslog(int type)
+static inline int security_syslog(int type, int context)
{
- return cap_syslog(type);
+ return cap_syslog(type, context);
}
static inline int security_settime(struct timespec *ts, struct timezone *tz)
diff --git a/include/linux/syslog.h b/include/linux/syslog.h
new file mode 100644
index 0000000..563c2a9
--- /dev/null
+++ b/include/linux/syslog.h
@@ -0,0 +1,29 @@
+/* Syslog internals
+ *
+ * Copyright 2010 Canonical, Ltd.
+ * Author: Kees Cook <kees.cook@canonical.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _LINUX_SYSLOG_H
+#define _LINUX_SYSLOG_H
+
+#define SYSLOG_CONTEXT_SYSCALL 0
+#define SYSLOG_CONTEXT_PROC 1
+
+int do_syslog(int type, char __user *buf, int count, int context);
+
+#endif /* _LINUX_SYSLOG_H */
diff --git a/kernel/printk.c b/kernel/printk.c
index 1751c45..a131ad6 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -35,6 +35,7 @@
#include <linux/kexec.h>
#include <linux/ratelimit.h>
#include <linux/kmsg_dump.h>
+#include <linux/syslog.h>
#include <asm/uaccess.h>
@@ -273,14 +274,14 @@ static inline void boot_delay_msec(void)
* 9 -- Return number of unread characters in the log buffer
* 10 -- Return size of the log buffer
*/
-int do_syslog(int type, char __user *buf, int len)
+int do_syslog(int type, char __user *buf, int len, int context)
{
unsigned i, j, limit, count;
int do_clear = 0;
char c;
int error = 0;
- error = security_syslog(type);
+ error = security_syslog(type, context);
if (error)
return error;
@@ -417,7 +418,7 @@ out:
SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len)
{
- return do_syslog(type, buf, len);
+ return do_syslog(type, buf, len, SYSLOG_CONTEXT_SYSCALL);
}
/*
diff --git a/security/commoncap.c b/security/commoncap.c
index f800fdb..9c965dc 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -27,6 +27,7 @@
#include <linux/sched.h>
#include <linux/prctl.h>
#include <linux/securebits.h>
+#include <linux/syslog.h>
/*
* If a non-root user executes a setuid-root binary in
@@ -888,12 +889,16 @@ error:
/**
* cap_syslog - Determine whether syslog function is permitted
* @type: Function requested
+ * @context: What context this request came from (/proc or syscall)
*
* Determine whether the current process is permitted to use a particular
* syslog function, returning 0 if permission is granted, -ve if not.
*/
-int cap_syslog(int type)
+int cap_syslog(int type, int context)
{
+ /* /proc/kmsg can open be opened by CAP_SYS_ADMIN */
+ if (type != 1 && context == SYSLOG_CONTEXT_PROC)
+ return 0;
if ((type != 3 && type != 10) && !capable(CAP_SYS_ADMIN))
return -EPERM;
return 0;
diff --git a/security/security.c b/security/security.c
index 24e060b..38a8994 100644
--- a/security/security.c
+++ b/security/security.c
@@ -203,9 +203,9 @@ int security_quota_on(struct dentry *dentry)
return security_ops->quota_on(dentry);
}
-int security_syslog(int type)
+int security_syslog(int type, int context)
{
- return security_ops->syslog(type);
+ return security_ops->syslog(type, context);
}
int security_settime(struct timespec *ts, struct timezone *tz)
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 9a2ee84..f476afa 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2049,11 +2049,11 @@ static int selinux_quota_on(struct dentry *dentry)
return dentry_has_perm(cred, NULL, dentry, FILE__QUOTAON);
}
-static int selinux_syslog(int type)
+static int selinux_syslog(int type, int context)
{
int rc;
- rc = cap_syslog(type);
+ rc = cap_syslog(type, context);
if (rc)
return rc;
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 529c9ca..a56ab5c 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -157,12 +157,12 @@ static int smack_ptrace_traceme(struct task_struct *ptp)
*
* Returns 0 on success, error code otherwise.
*/
-static int smack_syslog(int type)
+static int smack_syslog(int type, int context)
{
int rc;
char *sp = current_security();
- rc = cap_syslog(type);
+ rc = cap_syslog(type, context);
if (rc != 0)
return rc;
--
1.6.5
--
Kees Cook
Ubuntu Security Team
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH] syslog: distinguish between /proc/kmsg and syscalls
2010-02-02 5:53 [PATCH] syslog: distinguish between /proc/kmsg and syscalls Kees Cook
@ 2010-02-02 6:15 ` Casey Schaufler
2010-02-02 20:20 ` Kees Cook
0 siblings, 1 reply; 22+ messages in thread
From: Casey Schaufler @ 2010-02-02 6:15 UTC (permalink / raw)
To: Kees Cook
Cc: linux-security-module, James Morris, Eric Paris, David Howells,
Serge Hallyn, Alexey Dobriyan, Ingo Molnar, Andrew Morton,
Simon Kagstrom, David Woodhouse, Robin Getz, Greg Kroah-Hartman,
Paul Moore, Tetsuo Handa, Stephen Smalley, Etienne Basset,
David P. Quigley, LKLM, Casey Schaufler
Kees Cook wrote:
> This allows the LSM to distinguish between syslog functions originating
> from /proc/kmsg access and direct syscalls. By default, the commoncaps
> will now no longer require CAP_SYS_ADMIN to read an opened /proc/kmsg
> file descriptor. For example the kernel syslog reader can now drop
> privileges after opening /proc/kmsg, instead of staying privileged with
> CAP_SYS_ADMIN. MAC systems that implement security_syslog have unchanged
> behavior.
>
Might I suggest that you use a term other than "context" in this patch?
I recognize that it is the proper word, but the term has significant and
specific meaning in SELinux, and some of that has spilled over into the
LSM in general. I expect that there might be confusion if it is used to
denote something other than an SELinux "context". Perhaps "method", "type",
or "scheme".
Aside from that, I see no problems.
> Signed-off-by: Kees Cook <kees.cook@canonical.com>
> ---
> fs/proc/kmsg.c | 14 +++++++-------
> include/linux/security.h | 11 ++++++-----
> include/linux/syslog.h | 29 +++++++++++++++++++++++++++++
> kernel/printk.c | 7 ++++---
> security/commoncap.c | 7 ++++++-
> security/security.c | 4 ++--
> security/selinux/hooks.c | 4 ++--
> security/smack/smack_lsm.c | 4 ++--
> 8 files changed, 58 insertions(+), 22 deletions(-)
> create mode 100644 include/linux/syslog.h
>
> diff --git a/fs/proc/kmsg.c b/fs/proc/kmsg.c
> index 7ca7834..4f52b68 100644
> --- a/fs/proc/kmsg.c
> +++ b/fs/proc/kmsg.c
> @@ -12,37 +12,37 @@
> #include <linux/poll.h>
> #include <linux/proc_fs.h>
> #include <linux/fs.h>
> +#include <linux/syslog.h>
>
> #include <asm/uaccess.h>
> #include <asm/io.h>
>
> extern wait_queue_head_t log_wait;
>
> -extern int do_syslog(int type, char __user *bug, int count);
> -
> static int kmsg_open(struct inode * inode, struct file * file)
> {
> - return do_syslog(1,NULL,0);
> + return do_syslog(1, NULL, 0, SYSLOG_CONTEXT_PROC);
> }
>
> static int kmsg_release(struct inode * inode, struct file * file)
> {
> - (void) do_syslog(0,NULL,0);
> + (void) do_syslog(0, NULL, 0, SYSLOG_CONTEXT_PROC);
> return 0;
> }
>
> static ssize_t kmsg_read(struct file *file, char __user *buf,
> size_t count, loff_t *ppos)
> {
> - if ((file->f_flags & O_NONBLOCK) && !do_syslog(9, NULL, 0))
> + if ((file->f_flags & O_NONBLOCK) &&
> + !do_syslog(9, NULL, 0, SYSLOG_CONTEXT_PROC))
> return -EAGAIN;
> - return do_syslog(2, buf, count);
> + return do_syslog(2, buf, count, SYSLOG_CONTEXT_PROC);
> }
>
> static unsigned int kmsg_poll(struct file *file, poll_table *wait)
> {
> poll_wait(file, &log_wait, wait);
> - if (do_syslog(9, NULL, 0))
> + if (do_syslog(9, NULL, 0, SYSLOG_CONTEXT_PROC))
> return POLLIN | POLLRDNORM;
> return 0;
> }
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 2c627d3..174f834 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -76,7 +76,7 @@ extern int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
> extern int cap_task_setscheduler(struct task_struct *p, int policy, struct sched_param *lp);
> extern int cap_task_setioprio(struct task_struct *p, int ioprio);
> extern int cap_task_setnice(struct task_struct *p, int nice);
> -extern int cap_syslog(int type);
> +extern int cap_syslog(int type, int context);
> extern int cap_vm_enough_memory(struct mm_struct *mm, long pages);
>
> struct msghdr;
> @@ -1348,6 +1348,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
> * logging to the console.
> * See the syslog(2) manual page for an explanation of the @type values.
> * @type contains the type of action.
> + * @context contains the context of action (/proc or syscall).
> * Return 0 if permission is granted.
> * @settime:
> * Check permission to change the system time.
> @@ -1462,7 +1463,7 @@ struct security_operations {
> int (*sysctl) (struct ctl_table *table, int op);
> int (*quotactl) (int cmds, int type, int id, struct super_block *sb);
> int (*quota_on) (struct dentry *dentry);
> - int (*syslog) (int type);
> + int (*syslog) (int type, int context);
> int (*settime) (struct timespec *ts, struct timezone *tz);
> int (*vm_enough_memory) (struct mm_struct *mm, long pages);
>
> @@ -1761,7 +1762,7 @@ int security_acct(struct file *file);
> int security_sysctl(struct ctl_table *table, int op);
> int security_quotactl(int cmds, int type, int id, struct super_block *sb);
> int security_quota_on(struct dentry *dentry);
> -int security_syslog(int type);
> +int security_syslog(int type, int context);
> int security_settime(struct timespec *ts, struct timezone *tz);
> int security_vm_enough_memory(long pages);
> int security_vm_enough_memory_mm(struct mm_struct *mm, long pages);
> @@ -2007,9 +2008,9 @@ static inline int security_quota_on(struct dentry *dentry)
> return 0;
> }
>
> -static inline int security_syslog(int type)
> +static inline int security_syslog(int type, int context)
> {
> - return cap_syslog(type);
> + return cap_syslog(type, context);
> }
>
> static inline int security_settime(struct timespec *ts, struct timezone *tz)
> diff --git a/include/linux/syslog.h b/include/linux/syslog.h
> new file mode 100644
> index 0000000..563c2a9
> --- /dev/null
> +++ b/include/linux/syslog.h
> @@ -0,0 +1,29 @@
> +/* Syslog internals
> + *
> + * Copyright 2010 Canonical, Ltd.
> + * Author: Kees Cook <kees.cook@canonical.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2, or (at your option)
> + * any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; see the file COPYING. If not, write to
> + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
> + */
> +
> +#ifndef _LINUX_SYSLOG_H
> +#define _LINUX_SYSLOG_H
> +
> +#define SYSLOG_CONTEXT_SYSCALL 0
> +#define SYSLOG_CONTEXT_PROC 1
> +
> +int do_syslog(int type, char __user *buf, int count, int context);
> +
> +#endif /* _LINUX_SYSLOG_H */
> diff --git a/kernel/printk.c b/kernel/printk.c
> index 1751c45..a131ad6 100644
> --- a/kernel/printk.c
> +++ b/kernel/printk.c
> @@ -35,6 +35,7 @@
> #include <linux/kexec.h>
> #include <linux/ratelimit.h>
> #include <linux/kmsg_dump.h>
> +#include <linux/syslog.h>
>
> #include <asm/uaccess.h>
>
> @@ -273,14 +274,14 @@ static inline void boot_delay_msec(void)
> * 9 -- Return number of unread characters in the log buffer
> * 10 -- Return size of the log buffer
> */
> -int do_syslog(int type, char __user *buf, int len)
> +int do_syslog(int type, char __user *buf, int len, int context)
> {
> unsigned i, j, limit, count;
> int do_clear = 0;
> char c;
> int error = 0;
>
> - error = security_syslog(type);
> + error = security_syslog(type, context);
> if (error)
> return error;
>
> @@ -417,7 +418,7 @@ out:
>
> SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len)
> {
> - return do_syslog(type, buf, len);
> + return do_syslog(type, buf, len, SYSLOG_CONTEXT_SYSCALL);
> }
>
> /*
> diff --git a/security/commoncap.c b/security/commoncap.c
> index f800fdb..9c965dc 100644
> --- a/security/commoncap.c
> +++ b/security/commoncap.c
> @@ -27,6 +27,7 @@
> #include <linux/sched.h>
> #include <linux/prctl.h>
> #include <linux/securebits.h>
> +#include <linux/syslog.h>
>
> /*
> * If a non-root user executes a setuid-root binary in
> @@ -888,12 +889,16 @@ error:
> /**
> * cap_syslog - Determine whether syslog function is permitted
> * @type: Function requested
> + * @context: What context this request came from (/proc or syscall)
> *
> * Determine whether the current process is permitted to use a particular
> * syslog function, returning 0 if permission is granted, -ve if not.
> */
> -int cap_syslog(int type)
> +int cap_syslog(int type, int context)
> {
> + /* /proc/kmsg can open be opened by CAP_SYS_ADMIN */
> + if (type != 1 && context == SYSLOG_CONTEXT_PROC)
> + return 0;
> if ((type != 3 && type != 10) && !capable(CAP_SYS_ADMIN))
> return -EPERM;
> return 0;
> diff --git a/security/security.c b/security/security.c
> index 24e060b..38a8994 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -203,9 +203,9 @@ int security_quota_on(struct dentry *dentry)
> return security_ops->quota_on(dentry);
> }
>
> -int security_syslog(int type)
> +int security_syslog(int type, int context)
> {
> - return security_ops->syslog(type);
> + return security_ops->syslog(type, context);
> }
>
> int security_settime(struct timespec *ts, struct timezone *tz)
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 9a2ee84..f476afa 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -2049,11 +2049,11 @@ static int selinux_quota_on(struct dentry *dentry)
> return dentry_has_perm(cred, NULL, dentry, FILE__QUOTAON);
> }
>
> -static int selinux_syslog(int type)
> +static int selinux_syslog(int type, int context)
> {
> int rc;
>
> - rc = cap_syslog(type);
> + rc = cap_syslog(type, context);
> if (rc)
> return rc;
>
> diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
> index 529c9ca..a56ab5c 100644
> --- a/security/smack/smack_lsm.c
> +++ b/security/smack/smack_lsm.c
> @@ -157,12 +157,12 @@ static int smack_ptrace_traceme(struct task_struct *ptp)
> *
> * Returns 0 on success, error code otherwise.
> */
> -static int smack_syslog(int type)
> +static int smack_syslog(int type, int context)
> {
> int rc;
> char *sp = current_security();
>
> - rc = cap_syslog(type);
> + rc = cap_syslog(type, context);
> if (rc != 0)
> return rc;
>
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] syslog: distinguish between /proc/kmsg and syscalls
2010-02-02 6:15 ` Casey Schaufler
@ 2010-02-02 20:20 ` Kees Cook
2010-02-02 21:25 ` Serge E. Hallyn
0 siblings, 1 reply; 22+ messages in thread
From: Kees Cook @ 2010-02-02 20:20 UTC (permalink / raw)
To: Casey Schaufler
Cc: linux-security-module, James Morris, Eric Paris, David Howells,
Serge Hallyn, Alexey Dobriyan, Ingo Molnar, Andrew Morton,
Simon Kagstrom, David Woodhouse, Robin Getz, Greg Kroah-Hartman,
Paul Moore, Tetsuo Handa, Stephen Smalley, Etienne Basset,
David P. Quigley, LKLM
Hi,
On Mon, Feb 01, 2010 at 10:15:06PM -0800, Casey Schaufler wrote:
> Might I suggest that you use a term other than "context" in this patch?
> I recognize that it is the proper word, but the term has significant and
> specific meaning in SELinux, and some of that has spilled over into the
> LSM in general. I expect that there might be confusion if it is used to
> denote something other than an SELinux "context". Perhaps "method", "type",
> or "scheme".
Yeah, I cringed at "context" too, but since "type" is pretty overloaded
and it was already an argument there, I figured maybe it wouldn't be
too bad.
> > -extern int cap_syslog(int type);
> > +extern int cap_syslog(int type, int context);
Perhaps "source" or "origin"? "mode" is too overloaded with file modes.
Maybe a future patch can change "type" to "action" too.
-Kees
--
Kees Cook
Ubuntu Security Team
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] syslog: distinguish between /proc/kmsg and syscalls
2010-02-02 20:20 ` Kees Cook
@ 2010-02-02 21:25 ` Serge E. Hallyn
2010-02-02 21:59 ` James Morris
0 siblings, 1 reply; 22+ messages in thread
From: Serge E. Hallyn @ 2010-02-02 21:25 UTC (permalink / raw)
To: Kees Cook
Cc: Casey Schaufler, linux-security-module, James Morris, Eric Paris,
David Howells, Alexey Dobriyan, Ingo Molnar, Andrew Morton,
Simon Kagstrom, David Woodhouse, Robin Getz, Greg Kroah-Hartman,
Paul Moore, Tetsuo Handa, Stephen Smalley, Etienne Basset,
David P. Quigley, LKLM
Quoting Kees Cook (kees.cook@canonical.com):
> Hi,
>
> On Mon, Feb 01, 2010 at 10:15:06PM -0800, Casey Schaufler wrote:
> > Might I suggest that you use a term other than "context" in this patch?
> > I recognize that it is the proper word, but the term has significant and
> > specific meaning in SELinux, and some of that has spilled over into the
> > LSM in general. I expect that there might be confusion if it is used to
> > denote something other than an SELinux "context". Perhaps "method", "type",
> > or "scheme".
>
> Yeah, I cringed at "context" too, but since "type" is pretty overloaded
> and it was already an argument there, I figured maybe it wouldn't be
> too bad.
>
> > > -extern int cap_syslog(int type);
> > > +extern int cap_syslog(int type, int context);
>
> Perhaps "source" or "origin"? "mode" is too overloaded with file modes.
> Maybe a future patch can change "type" to "action" too.
'int from_file' or 'int from_sysc'?
Really the special case is that if (from_file) then we take the file
as a validated token allowing us to bypass new privilege checks, right?
so 'from_file' seems appropriate to me.
-serge
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] syslog: distinguish between /proc/kmsg and syscalls
2010-02-02 21:25 ` Serge E. Hallyn
@ 2010-02-02 21:59 ` James Morris
2010-02-03 19:15 ` [PATCH 1/2] " Kees Cook
` (3 more replies)
0 siblings, 4 replies; 22+ messages in thread
From: James Morris @ 2010-02-02 21:59 UTC (permalink / raw)
To: Serge E. Hallyn
Cc: Kees Cook, Casey Schaufler, linux-security-module, Eric Paris,
David Howells, Alexey Dobriyan, Ingo Molnar, Andrew Morton,
Simon Kagstrom, David Woodhouse, Robin Getz, Greg Kroah-Hartman,
Paul Moore, Tetsuo Handa, Stephen Smalley, Etienne Basset,
David P. Quigley, LKLM
On Tue, 2 Feb 2010, Serge E. Hallyn wrote:
> Really the special case is that if (from_file) then we take the file
> as a validated token allowing us to bypass new privilege checks, right?
> so 'from_file' seems appropriate to me.
Yes, I think 'from_file' is simplest, and then the value can just be 1 or
0.
--
James Morris
<jmorris@namei.org>
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 1/2] syslog: distinguish between /proc/kmsg and syscalls
2010-02-02 21:59 ` James Morris
@ 2010-02-03 19:15 ` Kees Cook
2010-02-03 20:44 ` Serge E. Hallyn
2010-02-03 19:23 ` [PATCH 2/2] syslog: use defined constants instead of raw numbers Kees Cook
` (2 subsequent siblings)
3 siblings, 1 reply; 22+ messages in thread
From: Kees Cook @ 2010-02-03 19:15 UTC (permalink / raw)
To: James Morris
Cc: Serge E. Hallyn, Casey Schaufler, linux-security-module,
Eric Paris, David Howells, Alexey Dobriyan, Ingo Molnar,
Andrew Morton, Simon Kagstrom, David Woodhouse, Robin Getz,
Greg Kroah-Hartman, Paul Moore, Tetsuo Handa, Stephen Smalley,
Etienne Basset, David P. Quigley, LKLM
This allows the LSM to distinguish between syslog functions originating
from /proc/kmsg access and direct syscalls. By default, the commoncaps
will now no longer require CAP_SYS_ADMIN to read an opened /proc/kmsg
file descriptor. For example the kernel syslog reader can now drop
privileges after opening /proc/kmsg, instead of staying privileged with
CAP_SYS_ADMIN. MAC systems that implement security_syslog have unchanged
behavior.
Signed-off-by: Kees Cook <kees.cook@canonical.com>
---
fs/proc/kmsg.c | 13 ++++++-------
include/linux/security.h | 11 ++++++-----
include/linux/syslog.h | 26 ++++++++++++++++++++++++++
kernel/printk.c | 7 ++++---
security/commoncap.c | 7 ++++++-
security/security.c | 4 ++--
security/selinux/hooks.c | 5 +++--
security/smack/smack_lsm.c | 4 ++--
8 files changed, 55 insertions(+), 22 deletions(-)
create mode 100644 include/linux/syslog.h
diff --git a/fs/proc/kmsg.c b/fs/proc/kmsg.c
index 7ca7834..4a08999 100644
--- a/fs/proc/kmsg.c
+++ b/fs/proc/kmsg.c
@@ -12,37 +12,36 @@
#include <linux/poll.h>
#include <linux/proc_fs.h>
#include <linux/fs.h>
+#include <linux/syslog.h>
#include <asm/uaccess.h>
#include <asm/io.h>
extern wait_queue_head_t log_wait;
-extern int do_syslog(int type, char __user *bug, int count);
-
static int kmsg_open(struct inode * inode, struct file * file)
{
- return do_syslog(1,NULL,0);
+ return do_syslog(1, NULL, 0, 1);
}
static int kmsg_release(struct inode * inode, struct file * file)
{
- (void) do_syslog(0,NULL,0);
+ (void) do_syslog(0, NULL, 0, 1);
return 0;
}
static ssize_t kmsg_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
- if ((file->f_flags & O_NONBLOCK) && !do_syslog(9, NULL, 0))
+ if ((file->f_flags & O_NONBLOCK) && !do_syslog(9, NULL, 0, 1))
return -EAGAIN;
- return do_syslog(2, buf, count);
+ return do_syslog(2, buf, count, 1);
}
static unsigned int kmsg_poll(struct file *file, poll_table *wait)
{
poll_wait(file, &log_wait, wait);
- if (do_syslog(9, NULL, 0))
+ if (do_syslog(9, NULL, 0, 1))
return POLLIN | POLLRDNORM;
return 0;
}
diff --git a/include/linux/security.h b/include/linux/security.h
index 2c627d3..10955c3 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -76,7 +76,7 @@ extern int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
extern int cap_task_setscheduler(struct task_struct *p, int policy, struct sched_param *lp);
extern int cap_task_setioprio(struct task_struct *p, int ioprio);
extern int cap_task_setnice(struct task_struct *p, int nice);
-extern int cap_syslog(int type);
+extern int cap_syslog(int type, int from_file);
extern int cap_vm_enough_memory(struct mm_struct *mm, long pages);
struct msghdr;
@@ -1348,6 +1348,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
* logging to the console.
* See the syslog(2) manual page for an explanation of the @type values.
* @type contains the type of action.
+ * @from_file indicates the context of action (if it came from /proc).
* Return 0 if permission is granted.
* @settime:
* Check permission to change the system time.
@@ -1462,7 +1463,7 @@ struct security_operations {
int (*sysctl) (struct ctl_table *table, int op);
int (*quotactl) (int cmds, int type, int id, struct super_block *sb);
int (*quota_on) (struct dentry *dentry);
- int (*syslog) (int type);
+ int (*syslog) (int type, int from_file);
int (*settime) (struct timespec *ts, struct timezone *tz);
int (*vm_enough_memory) (struct mm_struct *mm, long pages);
@@ -1761,7 +1762,7 @@ int security_acct(struct file *file);
int security_sysctl(struct ctl_table *table, int op);
int security_quotactl(int cmds, int type, int id, struct super_block *sb);
int security_quota_on(struct dentry *dentry);
-int security_syslog(int type);
+int security_syslog(int type, int from_file);
int security_settime(struct timespec *ts, struct timezone *tz);
int security_vm_enough_memory(long pages);
int security_vm_enough_memory_mm(struct mm_struct *mm, long pages);
@@ -2007,9 +2008,9 @@ static inline int security_quota_on(struct dentry *dentry)
return 0;
}
-static inline int security_syslog(int type)
+static inline int security_syslog(int type, int from_file)
{
- return cap_syslog(type);
+ return cap_syslog(type, from_file);
}
static inline int security_settime(struct timespec *ts, struct timezone *tz)
diff --git a/include/linux/syslog.h b/include/linux/syslog.h
new file mode 100644
index 0000000..f8c9d94
--- /dev/null
+++ b/include/linux/syslog.h
@@ -0,0 +1,26 @@
+/* Syslog internals
+ *
+ * Copyright 2010 Canonical, Ltd.
+ * Author: Kees Cook <kees.cook@canonical.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _LINUX_SYSLOG_H
+#define _LINUX_SYSLOG_H
+
+int do_syslog(int type, char __user *buf, int count, int from_file);
+
+#endif /* _LINUX_SYSLOG_H */
diff --git a/kernel/printk.c b/kernel/printk.c
index 1751c45..4bc1412 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -35,6 +35,7 @@
#include <linux/kexec.h>
#include <linux/ratelimit.h>
#include <linux/kmsg_dump.h>
+#include <linux/syslog.h>
#include <asm/uaccess.h>
@@ -273,14 +274,14 @@ static inline void boot_delay_msec(void)
* 9 -- Return number of unread characters in the log buffer
* 10 -- Return size of the log buffer
*/
-int do_syslog(int type, char __user *buf, int len)
+int do_syslog(int type, char __user *buf, int len, int from_file)
{
unsigned i, j, limit, count;
int do_clear = 0;
char c;
int error = 0;
- error = security_syslog(type);
+ error = security_syslog(type, from_file);
if (error)
return error;
@@ -417,7 +418,7 @@ out:
SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len)
{
- return do_syslog(type, buf, len);
+ return do_syslog(type, buf, len, 0);
}
/*
diff --git a/security/commoncap.c b/security/commoncap.c
index f800fdb..aaf123f 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -27,6 +27,7 @@
#include <linux/sched.h>
#include <linux/prctl.h>
#include <linux/securebits.h>
+#include <linux/syslog.h>
/*
* If a non-root user executes a setuid-root binary in
@@ -888,12 +889,16 @@ error:
/**
* cap_syslog - Determine whether syslog function is permitted
* @type: Function requested
+ * @from_file: Whether this request came from an open file (i.e. /proc)
*
* Determine whether the current process is permitted to use a particular
* syslog function, returning 0 if permission is granted, -ve if not.
*/
-int cap_syslog(int type)
+int cap_syslog(int type, int from_file)
{
+ /* /proc/kmsg can open be opened by CAP_SYS_ADMIN */
+ if (type != 1 && from_file)
+ return 0;
if ((type != 3 && type != 10) && !capable(CAP_SYS_ADMIN))
return -EPERM;
return 0;
diff --git a/security/security.c b/security/security.c
index 24e060b..568b1bd 100644
--- a/security/security.c
+++ b/security/security.c
@@ -203,9 +203,9 @@ int security_quota_on(struct dentry *dentry)
return security_ops->quota_on(dentry);
}
-int security_syslog(int type)
+int security_syslog(int type, int from_file)
{
- return security_ops->syslog(type);
+ return security_ops->syslog(type, from_file);
}
int security_settime(struct timespec *ts, struct timezone *tz)
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 9a2ee84..744785c 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -76,6 +76,7 @@
#include <linux/selinux.h>
#include <linux/mutex.h>
#include <linux/posix-timers.h>
+#include <linux/syslog.h>
#include "avc.h"
#include "objsec.h"
@@ -2049,11 +2050,11 @@ static int selinux_quota_on(struct dentry *dentry)
return dentry_has_perm(cred, NULL, dentry, FILE__QUOTAON);
}
-static int selinux_syslog(int type)
+static int selinux_syslog(int type, int from_file)
{
int rc;
- rc = cap_syslog(type);
+ rc = cap_syslog(type, from_file);
if (rc)
return rc;
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 529c9ca..b271e18 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -157,12 +157,12 @@ static int smack_ptrace_traceme(struct task_struct *ptp)
*
* Returns 0 on success, error code otherwise.
*/
-static int smack_syslog(int type)
+static int smack_syslog(int type, int from_file)
{
int rc;
char *sp = current_security();
- rc = cap_syslog(type);
+ rc = cap_syslog(type, from_file);
if (rc != 0)
return rc;
--
1.6.5
--
Kees Cook
Ubuntu Security Team
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 2/2] syslog: use defined constants instead of raw numbers
2010-02-02 21:59 ` James Morris
2010-02-03 19:15 ` [PATCH 1/2] " Kees Cook
@ 2010-02-03 19:23 ` Kees Cook
2010-02-03 20:47 ` Serge E. Hallyn
2010-02-03 23:36 ` [PATCH v2 1/2] syslog: distinguish between /proc/kmsg and syscalls Kees Cook
2010-02-03 23:37 ` [PATCH v2 2/2] syslog: use defined constants instead of raw numbers Kees Cook
3 siblings, 1 reply; 22+ messages in thread
From: Kees Cook @ 2010-02-03 19:23 UTC (permalink / raw)
To: James Morris
Cc: Serge E. Hallyn, Casey Schaufler, linux-security-module,
Eric Paris, David Howells, Alexey Dobriyan, Ingo Molnar,
Andrew Morton, Simon Kagstrom, David Woodhouse, Robin Getz,
Greg Kroah-Hartman, Paul Moore, Tetsuo Handa, Stephen Smalley,
Etienne Basset, David P. Quigley, LKLM
Right now the syslog "type" actions are just raw numbers which makes
the source difficult to follow. This patch replaces the raw numbers
with defined constants for some level of sanity.
Signed-off-by: Kees Cook <kees.cook@canonical.com>
---
fs/proc/kmsg.c | 11 ++++++-----
include/linux/syslog.h | 23 +++++++++++++++++++++++
kernel/printk.c | 45 +++++++++++++++++++--------------------------
security/commoncap.c | 5 +++--
security/selinux/hooks.c | 21 +++++++++++----------
5 files changed, 62 insertions(+), 43 deletions(-)
diff --git a/fs/proc/kmsg.c b/fs/proc/kmsg.c
index 4a08999..1ac9d2b 100644
--- a/fs/proc/kmsg.c
+++ b/fs/proc/kmsg.c
@@ -21,27 +21,28 @@ extern wait_queue_head_t log_wait;
static int kmsg_open(struct inode * inode, struct file * file)
{
- return do_syslog(1, NULL, 0, 1);
+ return do_syslog(SYSLOG_ACTION_OPEN, NULL, 0, 1);
}
static int kmsg_release(struct inode * inode, struct file * file)
{
- (void) do_syslog(0, NULL, 0, 1);
+ (void) do_syslog(SYSLOG_ACTION_CLOSE, NULL, 0, 1);
return 0;
}
static ssize_t kmsg_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
- if ((file->f_flags & O_NONBLOCK) && !do_syslog(9, NULL, 0, 1))
+ if ((file->f_flags & O_NONBLOCK) &&
+ !do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, 1))
return -EAGAIN;
- return do_syslog(2, buf, count, 1);
+ return do_syslog(SYSLOG_ACTION_READ, buf, count, 1);
}
static unsigned int kmsg_poll(struct file *file, poll_table *wait)
{
poll_wait(file, &log_wait, wait);
- if (do_syslog(9, NULL, 0, 1))
+ if (do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, 1))
return POLLIN | POLLRDNORM;
return 0;
}
diff --git a/include/linux/syslog.h b/include/linux/syslog.h
index f8c9d94..8c2c422 100644
--- a/include/linux/syslog.h
+++ b/include/linux/syslog.h
@@ -21,6 +21,29 @@
#ifndef _LINUX_SYSLOG_H
#define _LINUX_SYSLOG_H
+/* Close the log. Currently a NOP. */
+#define SYSLOG_ACTION_CLOSE 0
+/* Open the log. Currently a NOP. */
+#define SYSLOG_ACTION_OPEN 1
+/* Read from the log. */
+#define SYSLOG_ACTION_READ 2
+/* Read all messages remaining in the ring buffer. */
+#define SYSLOG_ACTION_READ_ALL 3
+/* Read and clear all messages remaining in the ring buffer */
+#define SYSLOG_ACTION_READ_CLEAR 4
+/* Clear ring buffer. */
+#define SYSLOG_ACTION_CLEAR 5
+/* Disable printk's to console */
+#define SYSLOG_ACTION_CONSOLE_OFF 6
+/* Enable printk's to console */
+#define SYSLOG_ACTION_CONSOLE_ON 7
+/* Set level of messages printed to console */
+#define SYSLOG_ACTION_CONSOLE_LEVEL 8
+/* Return number of unread characters in the log buffer */
+#define SYSLOG_ACTION_SIZE_UNREAD 9
+/* Return size of the log buffer */
+#define SYSLOG_ACTION_SIZE_BUFFER 10
+
int do_syslog(int type, char __user *buf, int count, int from_file);
#endif /* _LINUX_SYSLOG_H */
diff --git a/kernel/printk.c b/kernel/printk.c
index 4bc1412..ca1d970 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -259,21 +259,6 @@ static inline void boot_delay_msec(void)
}
#endif
-/*
- * Commands to do_syslog:
- *
- * 0 -- Close the log. Currently a NOP.
- * 1 -- Open the log. Currently a NOP.
- * 2 -- Read from the log.
- * 3 -- Read all messages remaining in the ring buffer.
- * 4 -- Read and clear all messages remaining in the ring buffer
- * 5 -- Clear ring buffer.
- * 6 -- Disable printk's to console
- * 7 -- Enable printk's to console
- * 8 -- Set level of messages printed to console
- * 9 -- Return number of unread characters in the log buffer
- * 10 -- Return size of the log buffer
- */
int do_syslog(int type, char __user *buf, int len, int from_file)
{
unsigned i, j, limit, count;
@@ -286,11 +271,11 @@ int do_syslog(int type, char __user *buf, int len, int from_file)
return error;
switch (type) {
- case 0: /* Close log */
+ case SYSLOG_ACTION_CLOSE: /* Close log */
break;
- case 1: /* Open log */
+ case SYSLOG_ACTION_OPEN: /* Open log */
break;
- case 2: /* Read from log */
+ case SYSLOG_ACTION_READ: /* Read from log */
error = -EINVAL;
if (!buf || len < 0)
goto out;
@@ -321,10 +306,12 @@ int do_syslog(int type, char __user *buf, int len, int from_file)
if (!error)
error = i;
break;
- case 4: /* Read/clear last kernel messages */
+ /* Read/clear last kernel messages */
+ case SYSLOG_ACTION_READ_CLEAR:
do_clear = 1;
/* FALL THRU */
- case 3: /* Read last kernel messages */
+ /* Read last kernel messages */
+ case SYSLOG_ACTION_READ_ALL:
error = -EINVAL;
if (!buf || len < 0)
goto out;
@@ -377,21 +364,25 @@ int do_syslog(int type, char __user *buf, int len, int from_file)
}
}
break;
- case 5: /* Clear ring buffer */
+ /* Clear ring buffer */
+ case SYSLOG_ACTION_CLEAR:
logged_chars = 0;
break;
- case 6: /* Disable logging to console */
+ /* Disable logging to console */
+ case SYSLOG_ACTION_CONSOLE_OFF:
if (saved_console_loglevel == -1)
saved_console_loglevel = console_loglevel;
console_loglevel = minimum_console_loglevel;
break;
- case 7: /* Enable logging to console */
+ /* Enable logging to console */
+ case SYSLOG_ACTION_CONSOLE_ON:
if (saved_console_loglevel != -1) {
console_loglevel = saved_console_loglevel;
saved_console_loglevel = -1;
}
break;
- case 8: /* Set level of messages printed to console */
+ /* Set level of messages printed to console */
+ case SYSLOG_ACTION_CONSOLE_LEVEL:
error = -EINVAL;
if (len < 1 || len > 8)
goto out;
@@ -402,10 +393,12 @@ int do_syslog(int type, char __user *buf, int len, int from_file)
saved_console_loglevel = -1;
error = 0;
break;
- case 9: /* Number of chars in the log buffer */
+ /* Number of chars in the log buffer */
+ case SYSLOG_ACTION_SIZE_UNREAD:
error = log_end - log_start;
break;
- case 10: /* Size of the log buffer */
+ /* Size of the log buffer */
+ case SYSLOG_ACTION_SIZE_BUFFER:
error = log_buf_len;
break;
default:
diff --git a/security/commoncap.c b/security/commoncap.c
index aaf123f..0705afe 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -897,9 +897,10 @@ error:
int cap_syslog(int type, int from_file)
{
/* /proc/kmsg can open be opened by CAP_SYS_ADMIN */
- if (type != 1 && from_file)
+ if (type != SYSLOG_ACTION_OPEN && from_file)
return 0;
- if ((type != 3 && type != 10) && !capable(CAP_SYS_ADMIN))
+ if ((type != SYSLOG_ACTION_READ_ALL &&
+ type != SYSLOG_ACTION_SIZE_BUFFER) && !capable(CAP_SYS_ADMIN))
return -EPERM;
return 0;
}
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 744785c..d242ab7 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2059,20 +2059,21 @@ static int selinux_syslog(int type, int from_file)
return rc;
switch (type) {
- case 3: /* Read last kernel messages */
- case 10: /* Return size of the log buffer */
+ case SYSLOG_ACTION_READ_ALL: /* Read last kernel messages */
+ case SYSLOG_ACTION_SIZE_BUFFER: /* Return size of the log buffer */
rc = task_has_system(current, SYSTEM__SYSLOG_READ);
break;
- case 6: /* Disable logging to console */
- case 7: /* Enable logging to console */
- case 8: /* Set level of messages printed to console */
+ case SYSLOG_ACTION_CONSOLE_OFF: /* Disable logging to console */
+ case SYSLOG_ACTION_CONSOLE_ON: /* Enable logging to console */
+ /* Set level of messages printed to console */
+ case SYSLOG_ACTION_CONSOLE_LEVEL:
rc = task_has_system(current, SYSTEM__SYSLOG_CONSOLE);
break;
- case 0: /* Close log */
- case 1: /* Open log */
- case 2: /* Read from log */
- case 4: /* Read/clear last kernel messages */
- case 5: /* Clear ring buffer */
+ case SYSLOG_ACTION_CLOSE: /* Close log */
+ case SYSLOG_ACTION_OPEN: /* Open log */
+ case SYSLOG_ACTION_READ: /* Read from log */
+ case SYSLOG_ACTION_READ_CLEAR: /* Read/clear last kernel messages */
+ case SYSLOG_ACTION_CLEAR: /* Clear ring buffer */
default:
rc = task_has_system(current, SYSTEM__SYSLOG_MOD);
break;
--
1.6.5
--
Kees Cook
Ubuntu Security Team
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH 1/2] syslog: distinguish between /proc/kmsg and syscalls
2010-02-03 19:15 ` [PATCH 1/2] " Kees Cook
@ 2010-02-03 20:44 ` Serge E. Hallyn
0 siblings, 0 replies; 22+ messages in thread
From: Serge E. Hallyn @ 2010-02-03 20:44 UTC (permalink / raw)
To: Kees Cook
Cc: James Morris, Casey Schaufler, linux-security-module, Eric Paris,
David Howells, Alexey Dobriyan, Ingo Molnar, Andrew Morton,
Simon Kagstrom, David Woodhouse, Robin Getz, Greg Kroah-Hartman,
Paul Moore, Tetsuo Handa, Stephen Smalley, Etienne Basset,
David P. Quigley, LKLM
Quoting Kees Cook (kees.cook@canonical.com):
> This allows the LSM to distinguish between syslog functions originating
> from /proc/kmsg access and direct syscalls. By default, the commoncaps
> will now no longer require CAP_SYS_ADMIN to read an opened /proc/kmsg
> file descriptor. For example the kernel syslog reader can now drop
> privileges after opening /proc/kmsg, instead of staying privileged with
> CAP_SYS_ADMIN. MAC systems that implement security_syslog have unchanged
> behavior.
>
> Signed-off-by: Kees Cook <kees.cook@canonical.com>
Acked-by: Serge Hallyn <serue@us.ibm.com>
However, I know James said 'you can just pass in 0 or 1', but
I think the callers will be much clearer if you
#define SYSLOG_FROM_CALL 0
#define SYSLOG_FROM_FILE 1
or something shorter if you can think of it
> ---
> fs/proc/kmsg.c | 13 ++++++-------
> include/linux/security.h | 11 ++++++-----
> include/linux/syslog.h | 26 ++++++++++++++++++++++++++
> kernel/printk.c | 7 ++++---
> security/commoncap.c | 7 ++++++-
> security/security.c | 4 ++--
> security/selinux/hooks.c | 5 +++--
> security/smack/smack_lsm.c | 4 ++--
> 8 files changed, 55 insertions(+), 22 deletions(-)
> create mode 100644 include/linux/syslog.h
>
> diff --git a/fs/proc/kmsg.c b/fs/proc/kmsg.c
> index 7ca7834..4a08999 100644
> --- a/fs/proc/kmsg.c
> +++ b/fs/proc/kmsg.c
> @@ -12,37 +12,36 @@
> #include <linux/poll.h>
> #include <linux/proc_fs.h>
> #include <linux/fs.h>
> +#include <linux/syslog.h>
>
> #include <asm/uaccess.h>
> #include <asm/io.h>
>
> extern wait_queue_head_t log_wait;
>
> -extern int do_syslog(int type, char __user *bug, int count);
> -
> static int kmsg_open(struct inode * inode, struct file * file)
> {
> - return do_syslog(1,NULL,0);
> + return do_syslog(1, NULL, 0, 1);
> }
>
> static int kmsg_release(struct inode * inode, struct file * file)
> {
> - (void) do_syslog(0,NULL,0);
> + (void) do_syslog(0, NULL, 0, 1);
> return 0;
> }
>
> static ssize_t kmsg_read(struct file *file, char __user *buf,
> size_t count, loff_t *ppos)
> {
> - if ((file->f_flags & O_NONBLOCK) && !do_syslog(9, NULL, 0))
> + if ((file->f_flags & O_NONBLOCK) && !do_syslog(9, NULL, 0, 1))
> return -EAGAIN;
> - return do_syslog(2, buf, count);
> + return do_syslog(2, buf, count, 1);
> }
>
> static unsigned int kmsg_poll(struct file *file, poll_table *wait)
> {
> poll_wait(file, &log_wait, wait);
> - if (do_syslog(9, NULL, 0))
> + if (do_syslog(9, NULL, 0, 1))
> return POLLIN | POLLRDNORM;
> return 0;
> }
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 2c627d3..10955c3 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -76,7 +76,7 @@ extern int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
> extern int cap_task_setscheduler(struct task_struct *p, int policy, struct sched_param *lp);
> extern int cap_task_setioprio(struct task_struct *p, int ioprio);
> extern int cap_task_setnice(struct task_struct *p, int nice);
> -extern int cap_syslog(int type);
> +extern int cap_syslog(int type, int from_file);
> extern int cap_vm_enough_memory(struct mm_struct *mm, long pages);
>
> struct msghdr;
> @@ -1348,6 +1348,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
> * logging to the console.
> * See the syslog(2) manual page for an explanation of the @type values.
> * @type contains the type of action.
> + * @from_file indicates the context of action (if it came from /proc).
> * Return 0 if permission is granted.
> * @settime:
> * Check permission to change the system time.
> @@ -1462,7 +1463,7 @@ struct security_operations {
> int (*sysctl) (struct ctl_table *table, int op);
> int (*quotactl) (int cmds, int type, int id, struct super_block *sb);
> int (*quota_on) (struct dentry *dentry);
> - int (*syslog) (int type);
> + int (*syslog) (int type, int from_file);
> int (*settime) (struct timespec *ts, struct timezone *tz);
> int (*vm_enough_memory) (struct mm_struct *mm, long pages);
>
> @@ -1761,7 +1762,7 @@ int security_acct(struct file *file);
> int security_sysctl(struct ctl_table *table, int op);
> int security_quotactl(int cmds, int type, int id, struct super_block *sb);
> int security_quota_on(struct dentry *dentry);
> -int security_syslog(int type);
> +int security_syslog(int type, int from_file);
> int security_settime(struct timespec *ts, struct timezone *tz);
> int security_vm_enough_memory(long pages);
> int security_vm_enough_memory_mm(struct mm_struct *mm, long pages);
> @@ -2007,9 +2008,9 @@ static inline int security_quota_on(struct dentry *dentry)
> return 0;
> }
>
> -static inline int security_syslog(int type)
> +static inline int security_syslog(int type, int from_file)
> {
> - return cap_syslog(type);
> + return cap_syslog(type, from_file);
> }
>
> static inline int security_settime(struct timespec *ts, struct timezone *tz)
> diff --git a/include/linux/syslog.h b/include/linux/syslog.h
> new file mode 100644
> index 0000000..f8c9d94
> --- /dev/null
> +++ b/include/linux/syslog.h
> @@ -0,0 +1,26 @@
> +/* Syslog internals
> + *
> + * Copyright 2010 Canonical, Ltd.
> + * Author: Kees Cook <kees.cook@canonical.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2, or (at your option)
> + * any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; see the file COPYING. If not, write to
> + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
> + */
> +
> +#ifndef _LINUX_SYSLOG_H
> +#define _LINUX_SYSLOG_H
> +
> +int do_syslog(int type, char __user *buf, int count, int from_file);
> +
> +#endif /* _LINUX_SYSLOG_H */
> diff --git a/kernel/printk.c b/kernel/printk.c
> index 1751c45..4bc1412 100644
> --- a/kernel/printk.c
> +++ b/kernel/printk.c
> @@ -35,6 +35,7 @@
> #include <linux/kexec.h>
> #include <linux/ratelimit.h>
> #include <linux/kmsg_dump.h>
> +#include <linux/syslog.h>
>
> #include <asm/uaccess.h>
>
> @@ -273,14 +274,14 @@ static inline void boot_delay_msec(void)
> * 9 -- Return number of unread characters in the log buffer
> * 10 -- Return size of the log buffer
> */
> -int do_syslog(int type, char __user *buf, int len)
> +int do_syslog(int type, char __user *buf, int len, int from_file)
> {
> unsigned i, j, limit, count;
> int do_clear = 0;
> char c;
> int error = 0;
>
> - error = security_syslog(type);
> + error = security_syslog(type, from_file);
> if (error)
> return error;
>
> @@ -417,7 +418,7 @@ out:
>
> SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len)
> {
> - return do_syslog(type, buf, len);
> + return do_syslog(type, buf, len, 0);
> }
>
> /*
> diff --git a/security/commoncap.c b/security/commoncap.c
> index f800fdb..aaf123f 100644
> --- a/security/commoncap.c
> +++ b/security/commoncap.c
> @@ -27,6 +27,7 @@
> #include <linux/sched.h>
> #include <linux/prctl.h>
> #include <linux/securebits.h>
> +#include <linux/syslog.h>
>
> /*
> * If a non-root user executes a setuid-root binary in
> @@ -888,12 +889,16 @@ error:
> /**
> * cap_syslog - Determine whether syslog function is permitted
> * @type: Function requested
> + * @from_file: Whether this request came from an open file (i.e. /proc)
> *
> * Determine whether the current process is permitted to use a particular
> * syslog function, returning 0 if permission is granted, -ve if not.
> */
> -int cap_syslog(int type)
> +int cap_syslog(int type, int from_file)
> {
> + /* /proc/kmsg can open be opened by CAP_SYS_ADMIN */
Egads this comment confused me for a minute - can you change
that to something like 'requires CAP_SYS_ADMIN'? I then misread
the '!=' to be == and thought you were inverting your logic.
> + if (type != 1 && from_file)
> + return 0;
> if ((type != 3 && type != 10) && !capable(CAP_SYS_ADMIN))
> return -EPERM;
> return 0;
> diff --git a/security/security.c b/security/security.c
> index 24e060b..568b1bd 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -203,9 +203,9 @@ int security_quota_on(struct dentry *dentry)
> return security_ops->quota_on(dentry);
> }
>
> -int security_syslog(int type)
> +int security_syslog(int type, int from_file)
> {
> - return security_ops->syslog(type);
> + return security_ops->syslog(type, from_file);
> }
>
> int security_settime(struct timespec *ts, struct timezone *tz)
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 9a2ee84..744785c 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -76,6 +76,7 @@
> #include <linux/selinux.h>
> #include <linux/mutex.h>
> #include <linux/posix-timers.h>
> +#include <linux/syslog.h>
>
> #include "avc.h"
> #include "objsec.h"
> @@ -2049,11 +2050,11 @@ static int selinux_quota_on(struct dentry *dentry)
> return dentry_has_perm(cred, NULL, dentry, FILE__QUOTAON);
> }
>
> -static int selinux_syslog(int type)
> +static int selinux_syslog(int type, int from_file)
> {
> int rc;
>
> - rc = cap_syslog(type);
> + rc = cap_syslog(type, from_file);
> if (rc)
> return rc;
>
> diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
> index 529c9ca..b271e18 100644
> --- a/security/smack/smack_lsm.c
> +++ b/security/smack/smack_lsm.c
> @@ -157,12 +157,12 @@ static int smack_ptrace_traceme(struct task_struct *ptp)
> *
> * Returns 0 on success, error code otherwise.
> */
> -static int smack_syslog(int type)
> +static int smack_syslog(int type, int from_file)
> {
> int rc;
> char *sp = current_security();
>
> - rc = cap_syslog(type);
> + rc = cap_syslog(type, from_file);
> if (rc != 0)
> return rc;
>
> --
> 1.6.5
>
>
> --
> Kees Cook
> Ubuntu Security Team
> --
> To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 2/2] syslog: use defined constants instead of raw numbers
2010-02-03 19:23 ` [PATCH 2/2] syslog: use defined constants instead of raw numbers Kees Cook
@ 2010-02-03 20:47 ` Serge E. Hallyn
0 siblings, 0 replies; 22+ messages in thread
From: Serge E. Hallyn @ 2010-02-03 20:47 UTC (permalink / raw)
To: Kees Cook
Cc: James Morris, Casey Schaufler, linux-security-module, Eric Paris,
David Howells, Alexey Dobriyan, Ingo Molnar, Andrew Morton,
Simon Kagstrom, David Woodhouse, Robin Getz, Greg Kroah-Hartman,
Paul Moore, Tetsuo Handa, Stephen Smalley, Etienne Basset,
David P. Quigley, LKLM
Quoting Kees Cook (kees.cook@canonical.com):
> Right now the syslog "type" actions are just raw numbers which makes
> the source difficult to follow. This patch replaces the raw numbers
> with defined constants for some level of sanity.
>
> Signed-off-by: Kees Cook <kees.cook@canonical.com>
yes please!
Acked-by: Serge Hallyn <serue@us.ibm.com>
> ---
> fs/proc/kmsg.c | 11 ++++++-----
> include/linux/syslog.h | 23 +++++++++++++++++++++++
> kernel/printk.c | 45 +++++++++++++++++++--------------------------
> security/commoncap.c | 5 +++--
> security/selinux/hooks.c | 21 +++++++++++----------
> 5 files changed, 62 insertions(+), 43 deletions(-)
>
> diff --git a/fs/proc/kmsg.c b/fs/proc/kmsg.c
> index 4a08999..1ac9d2b 100644
> --- a/fs/proc/kmsg.c
> +++ b/fs/proc/kmsg.c
> @@ -21,27 +21,28 @@ extern wait_queue_head_t log_wait;
>
> static int kmsg_open(struct inode * inode, struct file * file)
> {
> - return do_syslog(1, NULL, 0, 1);
> + return do_syslog(SYSLOG_ACTION_OPEN, NULL, 0, 1);
> }
>
> static int kmsg_release(struct inode * inode, struct file * file)
> {
> - (void) do_syslog(0, NULL, 0, 1);
> + (void) do_syslog(SYSLOG_ACTION_CLOSE, NULL, 0, 1);
> return 0;
> }
>
> static ssize_t kmsg_read(struct file *file, char __user *buf,
> size_t count, loff_t *ppos)
> {
> - if ((file->f_flags & O_NONBLOCK) && !do_syslog(9, NULL, 0, 1))
> + if ((file->f_flags & O_NONBLOCK) &&
> + !do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, 1))
> return -EAGAIN;
> - return do_syslog(2, buf, count, 1);
> + return do_syslog(SYSLOG_ACTION_READ, buf, count, 1);
> }
>
> static unsigned int kmsg_poll(struct file *file, poll_table *wait)
> {
> poll_wait(file, &log_wait, wait);
> - if (do_syslog(9, NULL, 0, 1))
> + if (do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, 1))
> return POLLIN | POLLRDNORM;
> return 0;
> }
> diff --git a/include/linux/syslog.h b/include/linux/syslog.h
> index f8c9d94..8c2c422 100644
> --- a/include/linux/syslog.h
> +++ b/include/linux/syslog.h
> @@ -21,6 +21,29 @@
> #ifndef _LINUX_SYSLOG_H
> #define _LINUX_SYSLOG_H
>
> +/* Close the log. Currently a NOP. */
> +#define SYSLOG_ACTION_CLOSE 0
> +/* Open the log. Currently a NOP. */
> +#define SYSLOG_ACTION_OPEN 1
> +/* Read from the log. */
> +#define SYSLOG_ACTION_READ 2
> +/* Read all messages remaining in the ring buffer. */
> +#define SYSLOG_ACTION_READ_ALL 3
> +/* Read and clear all messages remaining in the ring buffer */
> +#define SYSLOG_ACTION_READ_CLEAR 4
> +/* Clear ring buffer. */
> +#define SYSLOG_ACTION_CLEAR 5
> +/* Disable printk's to console */
> +#define SYSLOG_ACTION_CONSOLE_OFF 6
> +/* Enable printk's to console */
> +#define SYSLOG_ACTION_CONSOLE_ON 7
> +/* Set level of messages printed to console */
> +#define SYSLOG_ACTION_CONSOLE_LEVEL 8
> +/* Return number of unread characters in the log buffer */
> +#define SYSLOG_ACTION_SIZE_UNREAD 9
> +/* Return size of the log buffer */
> +#define SYSLOG_ACTION_SIZE_BUFFER 10
> +
> int do_syslog(int type, char __user *buf, int count, int from_file);
>
> #endif /* _LINUX_SYSLOG_H */
> diff --git a/kernel/printk.c b/kernel/printk.c
> index 4bc1412..ca1d970 100644
> --- a/kernel/printk.c
> +++ b/kernel/printk.c
> @@ -259,21 +259,6 @@ static inline void boot_delay_msec(void)
> }
> #endif
>
> -/*
> - * Commands to do_syslog:
> - *
> - * 0 -- Close the log. Currently a NOP.
> - * 1 -- Open the log. Currently a NOP.
> - * 2 -- Read from the log.
> - * 3 -- Read all messages remaining in the ring buffer.
> - * 4 -- Read and clear all messages remaining in the ring buffer
> - * 5 -- Clear ring buffer.
> - * 6 -- Disable printk's to console
> - * 7 -- Enable printk's to console
> - * 8 -- Set level of messages printed to console
> - * 9 -- Return number of unread characters in the log buffer
> - * 10 -- Return size of the log buffer
> - */
> int do_syslog(int type, char __user *buf, int len, int from_file)
> {
> unsigned i, j, limit, count;
> @@ -286,11 +271,11 @@ int do_syslog(int type, char __user *buf, int len, int from_file)
> return error;
>
> switch (type) {
> - case 0: /* Close log */
> + case SYSLOG_ACTION_CLOSE: /* Close log */
> break;
> - case 1: /* Open log */
> + case SYSLOG_ACTION_OPEN: /* Open log */
> break;
> - case 2: /* Read from log */
> + case SYSLOG_ACTION_READ: /* Read from log */
> error = -EINVAL;
> if (!buf || len < 0)
> goto out;
> @@ -321,10 +306,12 @@ int do_syslog(int type, char __user *buf, int len, int from_file)
> if (!error)
> error = i;
> break;
> - case 4: /* Read/clear last kernel messages */
> + /* Read/clear last kernel messages */
> + case SYSLOG_ACTION_READ_CLEAR:
> do_clear = 1;
> /* FALL THRU */
> - case 3: /* Read last kernel messages */
> + /* Read last kernel messages */
> + case SYSLOG_ACTION_READ_ALL:
> error = -EINVAL;
> if (!buf || len < 0)
> goto out;
> @@ -377,21 +364,25 @@ int do_syslog(int type, char __user *buf, int len, int from_file)
> }
> }
> break;
> - case 5: /* Clear ring buffer */
> + /* Clear ring buffer */
> + case SYSLOG_ACTION_CLEAR:
> logged_chars = 0;
> break;
> - case 6: /* Disable logging to console */
> + /* Disable logging to console */
> + case SYSLOG_ACTION_CONSOLE_OFF:
> if (saved_console_loglevel == -1)
> saved_console_loglevel = console_loglevel;
> console_loglevel = minimum_console_loglevel;
> break;
> - case 7: /* Enable logging to console */
> + /* Enable logging to console */
> + case SYSLOG_ACTION_CONSOLE_ON:
> if (saved_console_loglevel != -1) {
> console_loglevel = saved_console_loglevel;
> saved_console_loglevel = -1;
> }
> break;
> - case 8: /* Set level of messages printed to console */
> + /* Set level of messages printed to console */
> + case SYSLOG_ACTION_CONSOLE_LEVEL:
> error = -EINVAL;
> if (len < 1 || len > 8)
> goto out;
> @@ -402,10 +393,12 @@ int do_syslog(int type, char __user *buf, int len, int from_file)
> saved_console_loglevel = -1;
> error = 0;
> break;
> - case 9: /* Number of chars in the log buffer */
> + /* Number of chars in the log buffer */
> + case SYSLOG_ACTION_SIZE_UNREAD:
> error = log_end - log_start;
> break;
> - case 10: /* Size of the log buffer */
> + /* Size of the log buffer */
> + case SYSLOG_ACTION_SIZE_BUFFER:
> error = log_buf_len;
> break;
> default:
> diff --git a/security/commoncap.c b/security/commoncap.c
> index aaf123f..0705afe 100644
> --- a/security/commoncap.c
> +++ b/security/commoncap.c
> @@ -897,9 +897,10 @@ error:
> int cap_syslog(int type, int from_file)
> {
> /* /proc/kmsg can open be opened by CAP_SYS_ADMIN */
> - if (type != 1 && from_file)
> + if (type != SYSLOG_ACTION_OPEN && from_file)
> return 0;
> - if ((type != 3 && type != 10) && !capable(CAP_SYS_ADMIN))
> + if ((type != SYSLOG_ACTION_READ_ALL &&
> + type != SYSLOG_ACTION_SIZE_BUFFER) && !capable(CAP_SYS_ADMIN))
> return -EPERM;
> return 0;
> }
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 744785c..d242ab7 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -2059,20 +2059,21 @@ static int selinux_syslog(int type, int from_file)
> return rc;
>
> switch (type) {
> - case 3: /* Read last kernel messages */
> - case 10: /* Return size of the log buffer */
> + case SYSLOG_ACTION_READ_ALL: /* Read last kernel messages */
> + case SYSLOG_ACTION_SIZE_BUFFER: /* Return size of the log buffer */
> rc = task_has_system(current, SYSTEM__SYSLOG_READ);
> break;
> - case 6: /* Disable logging to console */
> - case 7: /* Enable logging to console */
> - case 8: /* Set level of messages printed to console */
> + case SYSLOG_ACTION_CONSOLE_OFF: /* Disable logging to console */
> + case SYSLOG_ACTION_CONSOLE_ON: /* Enable logging to console */
> + /* Set level of messages printed to console */
> + case SYSLOG_ACTION_CONSOLE_LEVEL:
> rc = task_has_system(current, SYSTEM__SYSLOG_CONSOLE);
> break;
> - case 0: /* Close log */
> - case 1: /* Open log */
> - case 2: /* Read from log */
> - case 4: /* Read/clear last kernel messages */
> - case 5: /* Clear ring buffer */
> + case SYSLOG_ACTION_CLOSE: /* Close log */
> + case SYSLOG_ACTION_OPEN: /* Open log */
> + case SYSLOG_ACTION_READ: /* Read from log */
> + case SYSLOG_ACTION_READ_CLEAR: /* Read/clear last kernel messages */
> + case SYSLOG_ACTION_CLEAR: /* Clear ring buffer */
> default:
> rc = task_has_system(current, SYSTEM__SYSLOG_MOD);
> break;
> --
> 1.6.5
>
>
> --
> Kees Cook
> Ubuntu Security Team
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2 1/2] syslog: distinguish between /proc/kmsg and syscalls
2010-02-02 21:59 ` James Morris
2010-02-03 19:15 ` [PATCH 1/2] " Kees Cook
2010-02-03 19:23 ` [PATCH 2/2] syslog: use defined constants instead of raw numbers Kees Cook
@ 2010-02-03 23:36 ` Kees Cook
2010-02-04 0:30 ` Serge E. Hallyn
` (2 more replies)
2010-02-03 23:37 ` [PATCH v2 2/2] syslog: use defined constants instead of raw numbers Kees Cook
3 siblings, 3 replies; 22+ messages in thread
From: Kees Cook @ 2010-02-03 23:36 UTC (permalink / raw)
To: James Morris
Cc: Serge E. Hallyn, Casey Schaufler, linux-security-module,
Eric Paris, David Howells, Alexey Dobriyan, Ingo Molnar,
Andrew Morton, Simon Kagstrom, David Woodhouse, Robin Getz,
Greg Kroah-Hartman, Paul Moore, Tetsuo Handa, Stephen Smalley,
Etienne Basset, David P. Quigley, LKLM
This allows the LSM to distinguish between syslog functions originating
from /proc/kmsg access and direct syscalls. By default, the commoncaps
will now no longer require CAP_SYS_ADMIN to read an opened /proc/kmsg
file descriptor. For example the kernel syslog reader can now drop
privileges after opening /proc/kmsg, instead of staying privileged with
CAP_SYS_ADMIN. MAC systems that implement security_syslog have unchanged
behavior.
Signed-off-by: Kees Cook <kees.cook@canonical.com>
---
fs/proc/kmsg.c | 14 +++++++-------
include/linux/security.h | 11 ++++++-----
include/linux/syslog.h | 29 +++++++++++++++++++++++++++++
kernel/printk.c | 7 ++++---
security/commoncap.c | 7 ++++++-
security/security.c | 4 ++--
security/selinux/hooks.c | 5 +++--
security/smack/smack_lsm.c | 4 ++--
8 files changed, 59 insertions(+), 22 deletions(-)
create mode 100644 include/linux/syslog.h
diff --git a/fs/proc/kmsg.c b/fs/proc/kmsg.c
index 7ca7834..6a3d843 100644
--- a/fs/proc/kmsg.c
+++ b/fs/proc/kmsg.c
@@ -12,37 +12,37 @@
#include <linux/poll.h>
#include <linux/proc_fs.h>
#include <linux/fs.h>
+#include <linux/syslog.h>
#include <asm/uaccess.h>
#include <asm/io.h>
extern wait_queue_head_t log_wait;
-extern int do_syslog(int type, char __user *bug, int count);
-
static int kmsg_open(struct inode * inode, struct file * file)
{
- return do_syslog(1,NULL,0);
+ return do_syslog(1, NULL, 0, SYSLOG_FROM_FILE);
}
static int kmsg_release(struct inode * inode, struct file * file)
{
- (void) do_syslog(0,NULL,0);
+ (void) do_syslog(0, NULL, 0, SYSLOG_FROM_FILE);
return 0;
}
static ssize_t kmsg_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
- if ((file->f_flags & O_NONBLOCK) && !do_syslog(9, NULL, 0))
+ if ((file->f_flags & O_NONBLOCK) &&
+ !do_syslog(9, NULL, 0, SYSLOG_FROM_FILE))
return -EAGAIN;
- return do_syslog(2, buf, count);
+ return do_syslog(2, buf, count, SYSLOG_FROM_FILE);
}
static unsigned int kmsg_poll(struct file *file, poll_table *wait)
{
poll_wait(file, &log_wait, wait);
- if (do_syslog(9, NULL, 0))
+ if (do_syslog(9, NULL, 0, SYSLOG_FROM_FILE))
return POLLIN | POLLRDNORM;
return 0;
}
diff --git a/include/linux/security.h b/include/linux/security.h
index 2c627d3..106786e 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -76,7 +76,7 @@ extern int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
extern int cap_task_setscheduler(struct task_struct *p, int policy, struct sched_param *lp);
extern int cap_task_setioprio(struct task_struct *p, int ioprio);
extern int cap_task_setnice(struct task_struct *p, int nice);
-extern int cap_syslog(int type);
+extern int cap_syslog(int type, bool from_file);
extern int cap_vm_enough_memory(struct mm_struct *mm, long pages);
struct msghdr;
@@ -1348,6 +1348,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
* logging to the console.
* See the syslog(2) manual page for an explanation of the @type values.
* @type contains the type of action.
+ * @from_file indicates the context of action (if it came from /proc).
* Return 0 if permission is granted.
* @settime:
* Check permission to change the system time.
@@ -1462,7 +1463,7 @@ struct security_operations {
int (*sysctl) (struct ctl_table *table, int op);
int (*quotactl) (int cmds, int type, int id, struct super_block *sb);
int (*quota_on) (struct dentry *dentry);
- int (*syslog) (int type);
+ int (*syslog) (int type, bool from_file);
int (*settime) (struct timespec *ts, struct timezone *tz);
int (*vm_enough_memory) (struct mm_struct *mm, long pages);
@@ -1761,7 +1762,7 @@ int security_acct(struct file *file);
int security_sysctl(struct ctl_table *table, int op);
int security_quotactl(int cmds, int type, int id, struct super_block *sb);
int security_quota_on(struct dentry *dentry);
-int security_syslog(int type);
+int security_syslog(int type, bool from_file);
int security_settime(struct timespec *ts, struct timezone *tz);
int security_vm_enough_memory(long pages);
int security_vm_enough_memory_mm(struct mm_struct *mm, long pages);
@@ -2007,9 +2008,9 @@ static inline int security_quota_on(struct dentry *dentry)
return 0;
}
-static inline int security_syslog(int type)
+static inline int security_syslog(int type, bool from_file)
{
- return cap_syslog(type);
+ return cap_syslog(type, from_file);
}
static inline int security_settime(struct timespec *ts, struct timezone *tz)
diff --git a/include/linux/syslog.h b/include/linux/syslog.h
new file mode 100644
index 0000000..5f02b18
--- /dev/null
+++ b/include/linux/syslog.h
@@ -0,0 +1,29 @@
+/* Syslog internals
+ *
+ * Copyright 2010 Canonical, Ltd.
+ * Author: Kees Cook <kees.cook@canonical.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _LINUX_SYSLOG_H
+#define _LINUX_SYSLOG_H
+
+#define SYSLOG_FROM_CALL 0
+#define SYSLOG_FROM_FILE 1
+
+int do_syslog(int type, char __user *buf, int count, bool from_file);
+
+#endif /* _LINUX_SYSLOG_H */
diff --git a/kernel/printk.c b/kernel/printk.c
index 1751c45..1771b34 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -35,6 +35,7 @@
#include <linux/kexec.h>
#include <linux/ratelimit.h>
#include <linux/kmsg_dump.h>
+#include <linux/syslog.h>
#include <asm/uaccess.h>
@@ -273,14 +274,14 @@ static inline void boot_delay_msec(void)
* 9 -- Return number of unread characters in the log buffer
* 10 -- Return size of the log buffer
*/
-int do_syslog(int type, char __user *buf, int len)
+int do_syslog(int type, char __user *buf, int len, bool from_file)
{
unsigned i, j, limit, count;
int do_clear = 0;
char c;
int error = 0;
- error = security_syslog(type);
+ error = security_syslog(type, from_file);
if (error)
return error;
@@ -417,7 +418,7 @@ out:
SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len)
{
- return do_syslog(type, buf, len);
+ return do_syslog(type, buf, len, SYSLOG_FROM_CALL);
}
/*
diff --git a/security/commoncap.c b/security/commoncap.c
index f800fdb..677fad9 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -27,6 +27,7 @@
#include <linux/sched.h>
#include <linux/prctl.h>
#include <linux/securebits.h>
+#include <linux/syslog.h>
/*
* If a non-root user executes a setuid-root binary in
@@ -888,12 +889,16 @@ error:
/**
* cap_syslog - Determine whether syslog function is permitted
* @type: Function requested
+ * @from_file: Whether this request came from an open file (i.e. /proc)
*
* Determine whether the current process is permitted to use a particular
* syslog function, returning 0 if permission is granted, -ve if not.
*/
-int cap_syslog(int type)
+int cap_syslog(int type, bool from_file)
{
+ /* /proc/kmsg can open be opened by CAP_SYS_ADMIN */
+ if (type != 1 && from_file)
+ return 0;
if ((type != 3 && type != 10) && !capable(CAP_SYS_ADMIN))
return -EPERM;
return 0;
diff --git a/security/security.c b/security/security.c
index 24e060b..9a127ae 100644
--- a/security/security.c
+++ b/security/security.c
@@ -203,9 +203,9 @@ int security_quota_on(struct dentry *dentry)
return security_ops->quota_on(dentry);
}
-int security_syslog(int type)
+int security_syslog(int type, bool from_file)
{
- return security_ops->syslog(type);
+ return security_ops->syslog(type, from_file);
}
int security_settime(struct timespec *ts, struct timezone *tz)
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 9a2ee84..a4862a0 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -76,6 +76,7 @@
#include <linux/selinux.h>
#include <linux/mutex.h>
#include <linux/posix-timers.h>
+#include <linux/syslog.h>
#include "avc.h"
#include "objsec.h"
@@ -2049,11 +2050,11 @@ static int selinux_quota_on(struct dentry *dentry)
return dentry_has_perm(cred, NULL, dentry, FILE__QUOTAON);
}
-static int selinux_syslog(int type)
+static int selinux_syslog(int type, bool from_file)
{
int rc;
- rc = cap_syslog(type);
+ rc = cap_syslog(type, from_file);
if (rc)
return rc;
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 529c9ca..a5721b3 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -157,12 +157,12 @@ static int smack_ptrace_traceme(struct task_struct *ptp)
*
* Returns 0 on success, error code otherwise.
*/
-static int smack_syslog(int type)
+static int smack_syslog(int type, bool from_file)
{
int rc;
char *sp = current_security();
- rc = cap_syslog(type);
+ rc = cap_syslog(type, from_file);
if (rc != 0)
return rc;
--
1.6.5
--
Kees Cook
Ubuntu Security Team
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 2/2] syslog: use defined constants instead of raw numbers
2010-02-02 21:59 ` James Morris
` (2 preceding siblings ...)
2010-02-03 23:36 ` [PATCH v2 1/2] syslog: distinguish between /proc/kmsg and syscalls Kees Cook
@ 2010-02-03 23:37 ` Kees Cook
2010-02-04 0:35 ` Serge E. Hallyn
` (2 more replies)
3 siblings, 3 replies; 22+ messages in thread
From: Kees Cook @ 2010-02-03 23:37 UTC (permalink / raw)
To: James Morris
Cc: Serge E. Hallyn, Casey Schaufler, linux-security-module,
Eric Paris, David Howells, Alexey Dobriyan, Ingo Molnar,
Andrew Morton, Simon Kagstrom, David Woodhouse, Robin Getz,
Greg Kroah-Hartman, Paul Moore, Tetsuo Handa, Stephen Smalley,
Etienne Basset, David P. Quigley, LKLM
Right now the syslog "type" action are just raw numbers which makes
the source difficult to follow. This patch replaces the raw numbers
with defined constants for some level of sanity.
Signed-off-by: Kees Cook <kees.cook@canonical.com>
---
fs/proc/kmsg.c | 10 +++++-----
include/linux/syslog.h | 23 +++++++++++++++++++++++
kernel/printk.c | 45 +++++++++++++++++++--------------------------
security/commoncap.c | 5 +++--
security/selinux/hooks.c | 21 +++++++++++----------
5 files changed, 61 insertions(+), 43 deletions(-)
diff --git a/fs/proc/kmsg.c b/fs/proc/kmsg.c
index 6a3d843..cfe90a4 100644
--- a/fs/proc/kmsg.c
+++ b/fs/proc/kmsg.c
@@ -21,12 +21,12 @@ extern wait_queue_head_t log_wait;
static int kmsg_open(struct inode * inode, struct file * file)
{
- return do_syslog(1, NULL, 0, SYSLOG_FROM_FILE);
+ return do_syslog(SYSLOG_ACTION_OPEN, NULL, 0, SYSLOG_FROM_FILE);
}
static int kmsg_release(struct inode * inode, struct file * file)
{
- (void) do_syslog(0, NULL, 0, SYSLOG_FROM_FILE);
+ (void) do_syslog(SYSLOG_ACTION_CLOSE, NULL, 0, SYSLOG_FROM_FILE);
return 0;
}
@@ -34,15 +34,15 @@ static ssize_t kmsg_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
if ((file->f_flags & O_NONBLOCK) &&
- !do_syslog(9, NULL, 0, SYSLOG_FROM_FILE))
+ !do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, SYSLOG_FROM_FILE))
return -EAGAIN;
- return do_syslog(2, buf, count, SYSLOG_FROM_FILE);
+ return do_syslog(SYSLOG_ACTION_READ, buf, count, SYSLOG_FROM_FILE);
}
static unsigned int kmsg_poll(struct file *file, poll_table *wait)
{
poll_wait(file, &log_wait, wait);
- if (do_syslog(9, NULL, 0, SYSLOG_FROM_FILE))
+ if (do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, SYSLOG_FROM_FILE))
return POLLIN | POLLRDNORM;
return 0;
}
diff --git a/include/linux/syslog.h b/include/linux/syslog.h
index 5f02b18..3891139 100644
--- a/include/linux/syslog.h
+++ b/include/linux/syslog.h
@@ -21,6 +21,29 @@
#ifndef _LINUX_SYSLOG_H
#define _LINUX_SYSLOG_H
+/* Close the log. Currently a NOP. */
+#define SYSLOG_ACTION_CLOSE 0
+/* Open the log. Currently a NOP. */
+#define SYSLOG_ACTION_OPEN 1
+/* Read from the log. */
+#define SYSLOG_ACTION_READ 2
+/* Read all messages remaining in the ring buffer. */
+#define SYSLOG_ACTION_READ_ALL 3
+/* Read and clear all messages remaining in the ring buffer */
+#define SYSLOG_ACTION_READ_CLEAR 4
+/* Clear ring buffer. */
+#define SYSLOG_ACTION_CLEAR 5
+/* Disable printk's to console */
+#define SYSLOG_ACTION_CONSOLE_OFF 6
+/* Enable printk's to console */
+#define SYSLOG_ACTION_CONSOLE_ON 7
+/* Set level of messages printed to console */
+#define SYSLOG_ACTION_CONSOLE_LEVEL 8
+/* Return number of unread characters in the log buffer */
+#define SYSLOG_ACTION_SIZE_UNREAD 9
+/* Return size of the log buffer */
+#define SYSLOG_ACTION_SIZE_BUFFER 10
+
#define SYSLOG_FROM_CALL 0
#define SYSLOG_FROM_FILE 1
diff --git a/kernel/printk.c b/kernel/printk.c
index 1771b34..4067412 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -259,21 +259,6 @@ static inline void boot_delay_msec(void)
}
#endif
-/*
- * Commands to do_syslog:
- *
- * 0 -- Close the log. Currently a NOP.
- * 1 -- Open the log. Currently a NOP.
- * 2 -- Read from the log.
- * 3 -- Read all messages remaining in the ring buffer.
- * 4 -- Read and clear all messages remaining in the ring buffer
- * 5 -- Clear ring buffer.
- * 6 -- Disable printk's to console
- * 7 -- Enable printk's to console
- * 8 -- Set level of messages printed to console
- * 9 -- Return number of unread characters in the log buffer
- * 10 -- Return size of the log buffer
- */
int do_syslog(int type, char __user *buf, int len, bool from_file)
{
unsigned i, j, limit, count;
@@ -286,11 +271,11 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
return error;
switch (type) {
- case 0: /* Close log */
+ case SYSLOG_ACTION_CLOSE: /* Close log */
break;
- case 1: /* Open log */
+ case SYSLOG_ACTION_OPEN: /* Open log */
break;
- case 2: /* Read from log */
+ case SYSLOG_ACTION_READ: /* Read from log */
error = -EINVAL;
if (!buf || len < 0)
goto out;
@@ -321,10 +306,12 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
if (!error)
error = i;
break;
- case 4: /* Read/clear last kernel messages */
+ /* Read/clear last kernel messages */
+ case SYSLOG_ACTION_READ_CLEAR:
do_clear = 1;
/* FALL THRU */
- case 3: /* Read last kernel messages */
+ /* Read last kernel messages */
+ case SYSLOG_ACTION_READ_ALL:
error = -EINVAL;
if (!buf || len < 0)
goto out;
@@ -377,21 +364,25 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
}
}
break;
- case 5: /* Clear ring buffer */
+ /* Clear ring buffer */
+ case SYSLOG_ACTION_CLEAR:
logged_chars = 0;
break;
- case 6: /* Disable logging to console */
+ /* Disable logging to console */
+ case SYSLOG_ACTION_CONSOLE_OFF:
if (saved_console_loglevel == -1)
saved_console_loglevel = console_loglevel;
console_loglevel = minimum_console_loglevel;
break;
- case 7: /* Enable logging to console */
+ /* Enable logging to console */
+ case SYSLOG_ACTION_CONSOLE_ON:
if (saved_console_loglevel != -1) {
console_loglevel = saved_console_loglevel;
saved_console_loglevel = -1;
}
break;
- case 8: /* Set level of messages printed to console */
+ /* Set level of messages printed to console */
+ case SYSLOG_ACTION_CONSOLE_LEVEL:
error = -EINVAL;
if (len < 1 || len > 8)
goto out;
@@ -402,10 +393,12 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
saved_console_loglevel = -1;
error = 0;
break;
- case 9: /* Number of chars in the log buffer */
+ /* Number of chars in the log buffer */
+ case SYSLOG_ACTION_SIZE_UNREAD:
error = log_end - log_start;
break;
- case 10: /* Size of the log buffer */
+ /* Size of the log buffer */
+ case SYSLOG_ACTION_SIZE_BUFFER:
error = log_buf_len;
break;
default:
diff --git a/security/commoncap.c b/security/commoncap.c
index 677fad9..cf01b2e 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -897,9 +897,10 @@ error:
int cap_syslog(int type, bool from_file)
{
/* /proc/kmsg can open be opened by CAP_SYS_ADMIN */
- if (type != 1 && from_file)
+ if (type != SYSLOG_ACTION_OPEN && from_file)
return 0;
- if ((type != 3 && type != 10) && !capable(CAP_SYS_ADMIN))
+ if ((type != SYSLOG_ACTION_READ_ALL &&
+ type != SYSLOG_ACTION_SIZE_BUFFER) && !capable(CAP_SYS_ADMIN))
return -EPERM;
return 0;
}
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index a4862a0..6b36ce2 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2059,20 +2059,21 @@ static int selinux_syslog(int type, bool from_file)
return rc;
switch (type) {
- case 3: /* Read last kernel messages */
- case 10: /* Return size of the log buffer */
+ case SYSLOG_ACTION_READ_ALL: /* Read last kernel messages */
+ case SYSLOG_ACTION_SIZE_BUFFER: /* Return size of the log buffer */
rc = task_has_system(current, SYSTEM__SYSLOG_READ);
break;
- case 6: /* Disable logging to console */
- case 7: /* Enable logging to console */
- case 8: /* Set level of messages printed to console */
+ case SYSLOG_ACTION_CONSOLE_OFF: /* Disable logging to console */
+ case SYSLOG_ACTION_CONSOLE_ON: /* Enable logging to console */
+ /* Set level of messages printed to console */
+ case SYSLOG_ACTION_CONSOLE_LEVEL:
rc = task_has_system(current, SYSTEM__SYSLOG_CONSOLE);
break;
- case 0: /* Close log */
- case 1: /* Open log */
- case 2: /* Read from log */
- case 4: /* Read/clear last kernel messages */
- case 5: /* Clear ring buffer */
+ case SYSLOG_ACTION_CLOSE: /* Close log */
+ case SYSLOG_ACTION_OPEN: /* Open log */
+ case SYSLOG_ACTION_READ: /* Read from log */
+ case SYSLOG_ACTION_READ_CLEAR: /* Read/clear last kernel messages */
+ case SYSLOG_ACTION_CLEAR: /* Clear ring buffer */
default:
rc = task_has_system(current, SYSTEM__SYSLOG_MOD);
break;
--
1.6.5
--
Kees Cook
Ubuntu Security Team
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH v2 1/2] syslog: distinguish between /proc/kmsg and syscalls
2010-02-03 23:36 ` [PATCH v2 1/2] syslog: distinguish between /proc/kmsg and syscalls Kees Cook
@ 2010-02-04 0:30 ` Serge E. Hallyn
2010-02-04 1:39 ` John Johansen
2010-02-04 3:52 ` James Morris
2010-02-04 7:58 ` Alex Riesen
2 siblings, 1 reply; 22+ messages in thread
From: Serge E. Hallyn @ 2010-02-04 0:30 UTC (permalink / raw)
To: Kees Cook
Cc: James Morris, Casey Schaufler, linux-security-module, Eric Paris,
David Howells, Alexey Dobriyan, Ingo Molnar, Andrew Morton,
Simon Kagstrom, David Woodhouse, Robin Getz, Greg Kroah-Hartman,
Paul Moore, Tetsuo Handa, Stephen Smalley, Etienne Basset,
David P. Quigley, LKLM
Quoting Kees Cook (kees.cook@canonical.com):
> This allows the LSM to distinguish between syslog functions originating
> from /proc/kmsg access and direct syscalls. By default, the commoncaps
> will now no longer require CAP_SYS_ADMIN to read an opened /proc/kmsg
> file descriptor. For example the kernel syslog reader can now drop
> privileges after opening /proc/kmsg, instead of staying privileged with
> CAP_SYS_ADMIN. MAC systems that implement security_syslog have unchanged
> behavior.
>
> Signed-off-by: Kees Cook <kees.cook@canonical.com>
Acked-by: Serge Hallyn <serue@us.ibm.com>
> ---
> fs/proc/kmsg.c | 14 +++++++-------
> include/linux/security.h | 11 ++++++-----
> include/linux/syslog.h | 29 +++++++++++++++++++++++++++++
> kernel/printk.c | 7 ++++---
> security/commoncap.c | 7 ++++++-
> security/security.c | 4 ++--
> security/selinux/hooks.c | 5 +++--
> security/smack/smack_lsm.c | 4 ++--
> 8 files changed, 59 insertions(+), 22 deletions(-)
> create mode 100644 include/linux/syslog.h
>
> diff --git a/fs/proc/kmsg.c b/fs/proc/kmsg.c
> index 7ca7834..6a3d843 100644
> --- a/fs/proc/kmsg.c
> +++ b/fs/proc/kmsg.c
> @@ -12,37 +12,37 @@
> #include <linux/poll.h>
> #include <linux/proc_fs.h>
> #include <linux/fs.h>
> +#include <linux/syslog.h>
>
> #include <asm/uaccess.h>
> #include <asm/io.h>
>
> extern wait_queue_head_t log_wait;
>
> -extern int do_syslog(int type, char __user *bug, int count);
> -
> static int kmsg_open(struct inode * inode, struct file * file)
> {
> - return do_syslog(1,NULL,0);
> + return do_syslog(1, NULL, 0, SYSLOG_FROM_FILE);
> }
>
> static int kmsg_release(struct inode * inode, struct file * file)
> {
> - (void) do_syslog(0,NULL,0);
> + (void) do_syslog(0, NULL, 0, SYSLOG_FROM_FILE);
> return 0;
> }
>
> static ssize_t kmsg_read(struct file *file, char __user *buf,
> size_t count, loff_t *ppos)
> {
> - if ((file->f_flags & O_NONBLOCK) && !do_syslog(9, NULL, 0))
> + if ((file->f_flags & O_NONBLOCK) &&
> + !do_syslog(9, NULL, 0, SYSLOG_FROM_FILE))
> return -EAGAIN;
> - return do_syslog(2, buf, count);
> + return do_syslog(2, buf, count, SYSLOG_FROM_FILE);
> }
>
> static unsigned int kmsg_poll(struct file *file, poll_table *wait)
> {
> poll_wait(file, &log_wait, wait);
> - if (do_syslog(9, NULL, 0))
> + if (do_syslog(9, NULL, 0, SYSLOG_FROM_FILE))
> return POLLIN | POLLRDNORM;
> return 0;
> }
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 2c627d3..106786e 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -76,7 +76,7 @@ extern int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
> extern int cap_task_setscheduler(struct task_struct *p, int policy, struct sched_param *lp);
> extern int cap_task_setioprio(struct task_struct *p, int ioprio);
> extern int cap_task_setnice(struct task_struct *p, int nice);
> -extern int cap_syslog(int type);
> +extern int cap_syslog(int type, bool from_file);
> extern int cap_vm_enough_memory(struct mm_struct *mm, long pages);
>
> struct msghdr;
> @@ -1348,6 +1348,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
> * logging to the console.
> * See the syslog(2) manual page for an explanation of the @type values.
> * @type contains the type of action.
> + * @from_file indicates the context of action (if it came from /proc).
> * Return 0 if permission is granted.
> * @settime:
> * Check permission to change the system time.
> @@ -1462,7 +1463,7 @@ struct security_operations {
> int (*sysctl) (struct ctl_table *table, int op);
> int (*quotactl) (int cmds, int type, int id, struct super_block *sb);
> int (*quota_on) (struct dentry *dentry);
> - int (*syslog) (int type);
> + int (*syslog) (int type, bool from_file);
> int (*settime) (struct timespec *ts, struct timezone *tz);
> int (*vm_enough_memory) (struct mm_struct *mm, long pages);
>
> @@ -1761,7 +1762,7 @@ int security_acct(struct file *file);
> int security_sysctl(struct ctl_table *table, int op);
> int security_quotactl(int cmds, int type, int id, struct super_block *sb);
> int security_quota_on(struct dentry *dentry);
> -int security_syslog(int type);
> +int security_syslog(int type, bool from_file);
> int security_settime(struct timespec *ts, struct timezone *tz);
> int security_vm_enough_memory(long pages);
> int security_vm_enough_memory_mm(struct mm_struct *mm, long pages);
> @@ -2007,9 +2008,9 @@ static inline int security_quota_on(struct dentry *dentry)
> return 0;
> }
>
> -static inline int security_syslog(int type)
> +static inline int security_syslog(int type, bool from_file)
> {
> - return cap_syslog(type);
> + return cap_syslog(type, from_file);
> }
>
> static inline int security_settime(struct timespec *ts, struct timezone *tz)
> diff --git a/include/linux/syslog.h b/include/linux/syslog.h
> new file mode 100644
> index 0000000..5f02b18
> --- /dev/null
> +++ b/include/linux/syslog.h
> @@ -0,0 +1,29 @@
> +/* Syslog internals
> + *
> + * Copyright 2010 Canonical, Ltd.
> + * Author: Kees Cook <kees.cook@canonical.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2, or (at your option)
> + * any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; see the file COPYING. If not, write to
> + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
> + */
> +
> +#ifndef _LINUX_SYSLOG_H
> +#define _LINUX_SYSLOG_H
> +
> +#define SYSLOG_FROM_CALL 0
> +#define SYSLOG_FROM_FILE 1
> +
> +int do_syslog(int type, char __user *buf, int count, bool from_file);
> +
> +#endif /* _LINUX_SYSLOG_H */
> diff --git a/kernel/printk.c b/kernel/printk.c
> index 1751c45..1771b34 100644
> --- a/kernel/printk.c
> +++ b/kernel/printk.c
> @@ -35,6 +35,7 @@
> #include <linux/kexec.h>
> #include <linux/ratelimit.h>
> #include <linux/kmsg_dump.h>
> +#include <linux/syslog.h>
>
> #include <asm/uaccess.h>
>
> @@ -273,14 +274,14 @@ static inline void boot_delay_msec(void)
> * 9 -- Return number of unread characters in the log buffer
> * 10 -- Return size of the log buffer
> */
> -int do_syslog(int type, char __user *buf, int len)
> +int do_syslog(int type, char __user *buf, int len, bool from_file)
> {
> unsigned i, j, limit, count;
> int do_clear = 0;
> char c;
> int error = 0;
>
> - error = security_syslog(type);
> + error = security_syslog(type, from_file);
> if (error)
> return error;
>
> @@ -417,7 +418,7 @@ out:
>
> SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len)
> {
> - return do_syslog(type, buf, len);
> + return do_syslog(type, buf, len, SYSLOG_FROM_CALL);
> }
>
> /*
> diff --git a/security/commoncap.c b/security/commoncap.c
> index f800fdb..677fad9 100644
> --- a/security/commoncap.c
> +++ b/security/commoncap.c
> @@ -27,6 +27,7 @@
> #include <linux/sched.h>
> #include <linux/prctl.h>
> #include <linux/securebits.h>
> +#include <linux/syslog.h>
>
> /*
> * If a non-root user executes a setuid-root binary in
> @@ -888,12 +889,16 @@ error:
> /**
> * cap_syslog - Determine whether syslog function is permitted
> * @type: Function requested
> + * @from_file: Whether this request came from an open file (i.e. /proc)
> *
> * Determine whether the current process is permitted to use a particular
> * syslog function, returning 0 if permission is granted, -ve if not.
> */
> -int cap_syslog(int type)
> +int cap_syslog(int type, bool from_file)
> {
> + /* /proc/kmsg can open be opened by CAP_SYS_ADMIN */
> + if (type != 1 && from_file)
> + return 0;
> if ((type != 3 && type != 10) && !capable(CAP_SYS_ADMIN))
> return -EPERM;
> return 0;
> diff --git a/security/security.c b/security/security.c
> index 24e060b..9a127ae 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -203,9 +203,9 @@ int security_quota_on(struct dentry *dentry)
> return security_ops->quota_on(dentry);
> }
>
> -int security_syslog(int type)
> +int security_syslog(int type, bool from_file)
> {
> - return security_ops->syslog(type);
> + return security_ops->syslog(type, from_file);
> }
>
> int security_settime(struct timespec *ts, struct timezone *tz)
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 9a2ee84..a4862a0 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -76,6 +76,7 @@
> #include <linux/selinux.h>
> #include <linux/mutex.h>
> #include <linux/posix-timers.h>
> +#include <linux/syslog.h>
>
> #include "avc.h"
> #include "objsec.h"
> @@ -2049,11 +2050,11 @@ static int selinux_quota_on(struct dentry *dentry)
> return dentry_has_perm(cred, NULL, dentry, FILE__QUOTAON);
> }
>
> -static int selinux_syslog(int type)
> +static int selinux_syslog(int type, bool from_file)
> {
> int rc;
>
> - rc = cap_syslog(type);
> + rc = cap_syslog(type, from_file);
> if (rc)
> return rc;
>
> diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
> index 529c9ca..a5721b3 100644
> --- a/security/smack/smack_lsm.c
> +++ b/security/smack/smack_lsm.c
> @@ -157,12 +157,12 @@ static int smack_ptrace_traceme(struct task_struct *ptp)
> *
> * Returns 0 on success, error code otherwise.
> */
> -static int smack_syslog(int type)
> +static int smack_syslog(int type, bool from_file)
> {
> int rc;
> char *sp = current_security();
>
> - rc = cap_syslog(type);
> + rc = cap_syslog(type, from_file);
> if (rc != 0)
> return rc;
>
> --
> 1.6.5
>
>
> --
> Kees Cook
> Ubuntu Security Team
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 2/2] syslog: use defined constants instead of raw numbers
2010-02-03 23:37 ` [PATCH v2 2/2] syslog: use defined constants instead of raw numbers Kees Cook
@ 2010-02-04 0:35 ` Serge E. Hallyn
2010-02-04 1:38 ` John Johansen
2010-02-04 3:51 ` James Morris
2 siblings, 0 replies; 22+ messages in thread
From: Serge E. Hallyn @ 2010-02-04 0:35 UTC (permalink / raw)
To: Kees Cook
Cc: James Morris, Casey Schaufler, linux-security-module, Eric Paris,
David Howells, Alexey Dobriyan, Ingo Molnar, Andrew Morton,
Simon Kagstrom, David Woodhouse, Robin Getz, Greg Kroah-Hartman,
Paul Moore, Tetsuo Handa, Stephen Smalley, Etienne Basset,
David P. Quigley, LKLM
Quoting Kees Cook (kees.cook@canonical.com):
> Right now the syslog "type" action are just raw numbers which makes
> the source difficult to follow. This patch replaces the raw numbers
> with defined constants for some level of sanity.
>
> Signed-off-by: Kees Cook <kees.cook@canonical.com>
Acked-by: Serge Hallyn <serue@us.ibm.com>
> ---
> fs/proc/kmsg.c | 10 +++++-----
> include/linux/syslog.h | 23 +++++++++++++++++++++++
> kernel/printk.c | 45 +++++++++++++++++++--------------------------
> security/commoncap.c | 5 +++--
> security/selinux/hooks.c | 21 +++++++++++----------
> 5 files changed, 61 insertions(+), 43 deletions(-)
>
> diff --git a/fs/proc/kmsg.c b/fs/proc/kmsg.c
> index 6a3d843..cfe90a4 100644
> --- a/fs/proc/kmsg.c
> +++ b/fs/proc/kmsg.c
> @@ -21,12 +21,12 @@ extern wait_queue_head_t log_wait;
>
> static int kmsg_open(struct inode * inode, struct file * file)
> {
> - return do_syslog(1, NULL, 0, SYSLOG_FROM_FILE);
> + return do_syslog(SYSLOG_ACTION_OPEN, NULL, 0, SYSLOG_FROM_FILE);
> }
>
> static int kmsg_release(struct inode * inode, struct file * file)
> {
> - (void) do_syslog(0, NULL, 0, SYSLOG_FROM_FILE);
> + (void) do_syslog(SYSLOG_ACTION_CLOSE, NULL, 0, SYSLOG_FROM_FILE);
> return 0;
> }
>
> @@ -34,15 +34,15 @@ static ssize_t kmsg_read(struct file *file, char __user *buf,
> size_t count, loff_t *ppos)
> {
> if ((file->f_flags & O_NONBLOCK) &&
> - !do_syslog(9, NULL, 0, SYSLOG_FROM_FILE))
> + !do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, SYSLOG_FROM_FILE))
> return -EAGAIN;
> - return do_syslog(2, buf, count, SYSLOG_FROM_FILE);
> + return do_syslog(SYSLOG_ACTION_READ, buf, count, SYSLOG_FROM_FILE);
> }
>
> static unsigned int kmsg_poll(struct file *file, poll_table *wait)
> {
> poll_wait(file, &log_wait, wait);
> - if (do_syslog(9, NULL, 0, SYSLOG_FROM_FILE))
> + if (do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, SYSLOG_FROM_FILE))
> return POLLIN | POLLRDNORM;
> return 0;
> }
> diff --git a/include/linux/syslog.h b/include/linux/syslog.h
> index 5f02b18..3891139 100644
> --- a/include/linux/syslog.h
> +++ b/include/linux/syslog.h
> @@ -21,6 +21,29 @@
> #ifndef _LINUX_SYSLOG_H
> #define _LINUX_SYSLOG_H
>
> +/* Close the log. Currently a NOP. */
> +#define SYSLOG_ACTION_CLOSE 0
> +/* Open the log. Currently a NOP. */
> +#define SYSLOG_ACTION_OPEN 1
> +/* Read from the log. */
> +#define SYSLOG_ACTION_READ 2
> +/* Read all messages remaining in the ring buffer. */
> +#define SYSLOG_ACTION_READ_ALL 3
> +/* Read and clear all messages remaining in the ring buffer */
> +#define SYSLOG_ACTION_READ_CLEAR 4
> +/* Clear ring buffer. */
> +#define SYSLOG_ACTION_CLEAR 5
> +/* Disable printk's to console */
> +#define SYSLOG_ACTION_CONSOLE_OFF 6
> +/* Enable printk's to console */
> +#define SYSLOG_ACTION_CONSOLE_ON 7
> +/* Set level of messages printed to console */
> +#define SYSLOG_ACTION_CONSOLE_LEVEL 8
> +/* Return number of unread characters in the log buffer */
> +#define SYSLOG_ACTION_SIZE_UNREAD 9
> +/* Return size of the log buffer */
> +#define SYSLOG_ACTION_SIZE_BUFFER 10
> +
> #define SYSLOG_FROM_CALL 0
> #define SYSLOG_FROM_FILE 1
>
> diff --git a/kernel/printk.c b/kernel/printk.c
> index 1771b34..4067412 100644
> --- a/kernel/printk.c
> +++ b/kernel/printk.c
> @@ -259,21 +259,6 @@ static inline void boot_delay_msec(void)
> }
> #endif
>
> -/*
> - * Commands to do_syslog:
> - *
> - * 0 -- Close the log. Currently a NOP.
> - * 1 -- Open the log. Currently a NOP.
> - * 2 -- Read from the log.
> - * 3 -- Read all messages remaining in the ring buffer.
> - * 4 -- Read and clear all messages remaining in the ring buffer
> - * 5 -- Clear ring buffer.
> - * 6 -- Disable printk's to console
> - * 7 -- Enable printk's to console
> - * 8 -- Set level of messages printed to console
> - * 9 -- Return number of unread characters in the log buffer
> - * 10 -- Return size of the log buffer
> - */
> int do_syslog(int type, char __user *buf, int len, bool from_file)
> {
> unsigned i, j, limit, count;
> @@ -286,11 +271,11 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
> return error;
>
> switch (type) {
> - case 0: /* Close log */
> + case SYSLOG_ACTION_CLOSE: /* Close log */
> break;
> - case 1: /* Open log */
> + case SYSLOG_ACTION_OPEN: /* Open log */
> break;
> - case 2: /* Read from log */
> + case SYSLOG_ACTION_READ: /* Read from log */
> error = -EINVAL;
> if (!buf || len < 0)
> goto out;
> @@ -321,10 +306,12 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
> if (!error)
> error = i;
> break;
> - case 4: /* Read/clear last kernel messages */
> + /* Read/clear last kernel messages */
> + case SYSLOG_ACTION_READ_CLEAR:
> do_clear = 1;
> /* FALL THRU */
> - case 3: /* Read last kernel messages */
> + /* Read last kernel messages */
> + case SYSLOG_ACTION_READ_ALL:
> error = -EINVAL;
> if (!buf || len < 0)
> goto out;
> @@ -377,21 +364,25 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
> }
> }
> break;
> - case 5: /* Clear ring buffer */
> + /* Clear ring buffer */
> + case SYSLOG_ACTION_CLEAR:
> logged_chars = 0;
> break;
> - case 6: /* Disable logging to console */
> + /* Disable logging to console */
> + case SYSLOG_ACTION_CONSOLE_OFF:
> if (saved_console_loglevel == -1)
> saved_console_loglevel = console_loglevel;
> console_loglevel = minimum_console_loglevel;
> break;
> - case 7: /* Enable logging to console */
> + /* Enable logging to console */
> + case SYSLOG_ACTION_CONSOLE_ON:
> if (saved_console_loglevel != -1) {
> console_loglevel = saved_console_loglevel;
> saved_console_loglevel = -1;
> }
> break;
> - case 8: /* Set level of messages printed to console */
> + /* Set level of messages printed to console */
> + case SYSLOG_ACTION_CONSOLE_LEVEL:
> error = -EINVAL;
> if (len < 1 || len > 8)
> goto out;
> @@ -402,10 +393,12 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
> saved_console_loglevel = -1;
> error = 0;
> break;
> - case 9: /* Number of chars in the log buffer */
> + /* Number of chars in the log buffer */
> + case SYSLOG_ACTION_SIZE_UNREAD:
> error = log_end - log_start;
> break;
> - case 10: /* Size of the log buffer */
> + /* Size of the log buffer */
> + case SYSLOG_ACTION_SIZE_BUFFER:
> error = log_buf_len;
> break;
> default:
> diff --git a/security/commoncap.c b/security/commoncap.c
> index 677fad9..cf01b2e 100644
> --- a/security/commoncap.c
> +++ b/security/commoncap.c
> @@ -897,9 +897,10 @@ error:
> int cap_syslog(int type, bool from_file)
> {
> /* /proc/kmsg can open be opened by CAP_SYS_ADMIN */
> - if (type != 1 && from_file)
> + if (type != SYSLOG_ACTION_OPEN && from_file)
> return 0;
> - if ((type != 3 && type != 10) && !capable(CAP_SYS_ADMIN))
> + if ((type != SYSLOG_ACTION_READ_ALL &&
> + type != SYSLOG_ACTION_SIZE_BUFFER) && !capable(CAP_SYS_ADMIN))
> return -EPERM;
> return 0;
> }
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index a4862a0..6b36ce2 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -2059,20 +2059,21 @@ static int selinux_syslog(int type, bool from_file)
> return rc;
>
> switch (type) {
> - case 3: /* Read last kernel messages */
> - case 10: /* Return size of the log buffer */
> + case SYSLOG_ACTION_READ_ALL: /* Read last kernel messages */
> + case SYSLOG_ACTION_SIZE_BUFFER: /* Return size of the log buffer */
> rc = task_has_system(current, SYSTEM__SYSLOG_READ);
> break;
> - case 6: /* Disable logging to console */
> - case 7: /* Enable logging to console */
> - case 8: /* Set level of messages printed to console */
> + case SYSLOG_ACTION_CONSOLE_OFF: /* Disable logging to console */
> + case SYSLOG_ACTION_CONSOLE_ON: /* Enable logging to console */
> + /* Set level of messages printed to console */
> + case SYSLOG_ACTION_CONSOLE_LEVEL:
> rc = task_has_system(current, SYSTEM__SYSLOG_CONSOLE);
> break;
> - case 0: /* Close log */
> - case 1: /* Open log */
> - case 2: /* Read from log */
> - case 4: /* Read/clear last kernel messages */
> - case 5: /* Clear ring buffer */
> + case SYSLOG_ACTION_CLOSE: /* Close log */
> + case SYSLOG_ACTION_OPEN: /* Open log */
> + case SYSLOG_ACTION_READ: /* Read from log */
> + case SYSLOG_ACTION_READ_CLEAR: /* Read/clear last kernel messages */
> + case SYSLOG_ACTION_CLEAR: /* Clear ring buffer */
> default:
> rc = task_has_system(current, SYSTEM__SYSLOG_MOD);
> break;
> --
> 1.6.5
>
>
> --
> Kees Cook
> Ubuntu Security Team
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 2/2] syslog: use defined constants instead of raw numbers
2010-02-03 23:37 ` [PATCH v2 2/2] syslog: use defined constants instead of raw numbers Kees Cook
2010-02-04 0:35 ` Serge E. Hallyn
@ 2010-02-04 1:38 ` John Johansen
2010-02-04 3:51 ` James Morris
2 siblings, 0 replies; 22+ messages in thread
From: John Johansen @ 2010-02-04 1:38 UTC (permalink / raw)
To: Kees Cook
Cc: James Morris, Serge E. Hallyn, Casey Schaufler,
linux-security-module, Eric Paris, David Howells, Alexey Dobriyan,
Ingo Molnar, Andrew Morton, Simon Kagstrom, David Woodhouse,
Robin Getz, Greg Kroah-Hartman, Paul Moore, Tetsuo Handa,
Stephen Smalley, Etienne Basset, David P. Quigley, LKLM
Kees Cook wrote:
> Right now the syslog "type" action are just raw numbers which makes
> the source difficult to follow. This patch replaces the raw numbers
> with defined constants for some level of sanity.
>
> Signed-off-by: Kees Cook <kees.cook@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
> ---
> fs/proc/kmsg.c | 10 +++++-----
> include/linux/syslog.h | 23 +++++++++++++++++++++++
> kernel/printk.c | 45 +++++++++++++++++++--------------------------
> security/commoncap.c | 5 +++--
> security/selinux/hooks.c | 21 +++++++++++----------
> 5 files changed, 61 insertions(+), 43 deletions(-)
>
> diff --git a/fs/proc/kmsg.c b/fs/proc/kmsg.c
> index 6a3d843..cfe90a4 100644
> --- a/fs/proc/kmsg.c
> +++ b/fs/proc/kmsg.c
> @@ -21,12 +21,12 @@ extern wait_queue_head_t log_wait;
>
> static int kmsg_open(struct inode * inode, struct file * file)
> {
> - return do_syslog(1, NULL, 0, SYSLOG_FROM_FILE);
> + return do_syslog(SYSLOG_ACTION_OPEN, NULL, 0, SYSLOG_FROM_FILE);
> }
>
> static int kmsg_release(struct inode * inode, struct file * file)
> {
> - (void) do_syslog(0, NULL, 0, SYSLOG_FROM_FILE);
> + (void) do_syslog(SYSLOG_ACTION_CLOSE, NULL, 0, SYSLOG_FROM_FILE);
> return 0;
> }
>
> @@ -34,15 +34,15 @@ static ssize_t kmsg_read(struct file *file, char __user *buf,
> size_t count, loff_t *ppos)
> {
> if ((file->f_flags & O_NONBLOCK) &&
> - !do_syslog(9, NULL, 0, SYSLOG_FROM_FILE))
> + !do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, SYSLOG_FROM_FILE))
> return -EAGAIN;
> - return do_syslog(2, buf, count, SYSLOG_FROM_FILE);
> + return do_syslog(SYSLOG_ACTION_READ, buf, count, SYSLOG_FROM_FILE);
> }
>
> static unsigned int kmsg_poll(struct file *file, poll_table *wait)
> {
> poll_wait(file, &log_wait, wait);
> - if (do_syslog(9, NULL, 0, SYSLOG_FROM_FILE))
> + if (do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, SYSLOG_FROM_FILE))
> return POLLIN | POLLRDNORM;
> return 0;
> }
> diff --git a/include/linux/syslog.h b/include/linux/syslog.h
> index 5f02b18..3891139 100644
> --- a/include/linux/syslog.h
> +++ b/include/linux/syslog.h
> @@ -21,6 +21,29 @@
> #ifndef _LINUX_SYSLOG_H
> #define _LINUX_SYSLOG_H
>
> +/* Close the log. Currently a NOP. */
> +#define SYSLOG_ACTION_CLOSE 0
> +/* Open the log. Currently a NOP. */
> +#define SYSLOG_ACTION_OPEN 1
> +/* Read from the log. */
> +#define SYSLOG_ACTION_READ 2
> +/* Read all messages remaining in the ring buffer. */
> +#define SYSLOG_ACTION_READ_ALL 3
> +/* Read and clear all messages remaining in the ring buffer */
> +#define SYSLOG_ACTION_READ_CLEAR 4
> +/* Clear ring buffer. */
> +#define SYSLOG_ACTION_CLEAR 5
> +/* Disable printk's to console */
> +#define SYSLOG_ACTION_CONSOLE_OFF 6
> +/* Enable printk's to console */
> +#define SYSLOG_ACTION_CONSOLE_ON 7
> +/* Set level of messages printed to console */
> +#define SYSLOG_ACTION_CONSOLE_LEVEL 8
> +/* Return number of unread characters in the log buffer */
> +#define SYSLOG_ACTION_SIZE_UNREAD 9
> +/* Return size of the log buffer */
> +#define SYSLOG_ACTION_SIZE_BUFFER 10
> +
> #define SYSLOG_FROM_CALL 0
> #define SYSLOG_FROM_FILE 1
>
> diff --git a/kernel/printk.c b/kernel/printk.c
> index 1771b34..4067412 100644
> --- a/kernel/printk.c
> +++ b/kernel/printk.c
> @@ -259,21 +259,6 @@ static inline void boot_delay_msec(void)
> }
> #endif
>
> -/*
> - * Commands to do_syslog:
> - *
> - * 0 -- Close the log. Currently a NOP.
> - * 1 -- Open the log. Currently a NOP.
> - * 2 -- Read from the log.
> - * 3 -- Read all messages remaining in the ring buffer.
> - * 4 -- Read and clear all messages remaining in the ring buffer
> - * 5 -- Clear ring buffer.
> - * 6 -- Disable printk's to console
> - * 7 -- Enable printk's to console
> - * 8 -- Set level of messages printed to console
> - * 9 -- Return number of unread characters in the log buffer
> - * 10 -- Return size of the log buffer
> - */
> int do_syslog(int type, char __user *buf, int len, bool from_file)
> {
> unsigned i, j, limit, count;
> @@ -286,11 +271,11 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
> return error;
>
> switch (type) {
> - case 0: /* Close log */
> + case SYSLOG_ACTION_CLOSE: /* Close log */
> break;
> - case 1: /* Open log */
> + case SYSLOG_ACTION_OPEN: /* Open log */
> break;
> - case 2: /* Read from log */
> + case SYSLOG_ACTION_READ: /* Read from log */
> error = -EINVAL;
> if (!buf || len < 0)
> goto out;
> @@ -321,10 +306,12 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
> if (!error)
> error = i;
> break;
> - case 4: /* Read/clear last kernel messages */
> + /* Read/clear last kernel messages */
> + case SYSLOG_ACTION_READ_CLEAR:
> do_clear = 1;
> /* FALL THRU */
> - case 3: /* Read last kernel messages */
> + /* Read last kernel messages */
> + case SYSLOG_ACTION_READ_ALL:
> error = -EINVAL;
> if (!buf || len < 0)
> goto out;
> @@ -377,21 +364,25 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
> }
> }
> break;
> - case 5: /* Clear ring buffer */
> + /* Clear ring buffer */
> + case SYSLOG_ACTION_CLEAR:
> logged_chars = 0;
> break;
> - case 6: /* Disable logging to console */
> + /* Disable logging to console */
> + case SYSLOG_ACTION_CONSOLE_OFF:
> if (saved_console_loglevel == -1)
> saved_console_loglevel = console_loglevel;
> console_loglevel = minimum_console_loglevel;
> break;
> - case 7: /* Enable logging to console */
> + /* Enable logging to console */
> + case SYSLOG_ACTION_CONSOLE_ON:
> if (saved_console_loglevel != -1) {
> console_loglevel = saved_console_loglevel;
> saved_console_loglevel = -1;
> }
> break;
> - case 8: /* Set level of messages printed to console */
> + /* Set level of messages printed to console */
> + case SYSLOG_ACTION_CONSOLE_LEVEL:
> error = -EINVAL;
> if (len < 1 || len > 8)
> goto out;
> @@ -402,10 +393,12 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
> saved_console_loglevel = -1;
> error = 0;
> break;
> - case 9: /* Number of chars in the log buffer */
> + /* Number of chars in the log buffer */
> + case SYSLOG_ACTION_SIZE_UNREAD:
> error = log_end - log_start;
> break;
> - case 10: /* Size of the log buffer */
> + /* Size of the log buffer */
> + case SYSLOG_ACTION_SIZE_BUFFER:
> error = log_buf_len;
> break;
> default:
> diff --git a/security/commoncap.c b/security/commoncap.c
> index 677fad9..cf01b2e 100644
> --- a/security/commoncap.c
> +++ b/security/commoncap.c
> @@ -897,9 +897,10 @@ error:
> int cap_syslog(int type, bool from_file)
> {
> /* /proc/kmsg can open be opened by CAP_SYS_ADMIN */
> - if (type != 1 && from_file)
> + if (type != SYSLOG_ACTION_OPEN && from_file)
> return 0;
> - if ((type != 3 && type != 10) && !capable(CAP_SYS_ADMIN))
> + if ((type != SYSLOG_ACTION_READ_ALL &&
> + type != SYSLOG_ACTION_SIZE_BUFFER) && !capable(CAP_SYS_ADMIN))
> return -EPERM;
> return 0;
> }
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index a4862a0..6b36ce2 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -2059,20 +2059,21 @@ static int selinux_syslog(int type, bool from_file)
> return rc;
>
> switch (type) {
> - case 3: /* Read last kernel messages */
> - case 10: /* Return size of the log buffer */
> + case SYSLOG_ACTION_READ_ALL: /* Read last kernel messages */
> + case SYSLOG_ACTION_SIZE_BUFFER: /* Return size of the log buffer */
> rc = task_has_system(current, SYSTEM__SYSLOG_READ);
> break;
> - case 6: /* Disable logging to console */
> - case 7: /* Enable logging to console */
> - case 8: /* Set level of messages printed to console */
> + case SYSLOG_ACTION_CONSOLE_OFF: /* Disable logging to console */
> + case SYSLOG_ACTION_CONSOLE_ON: /* Enable logging to console */
> + /* Set level of messages printed to console */
> + case SYSLOG_ACTION_CONSOLE_LEVEL:
> rc = task_has_system(current, SYSTEM__SYSLOG_CONSOLE);
> break;
> - case 0: /* Close log */
> - case 1: /* Open log */
> - case 2: /* Read from log */
> - case 4: /* Read/clear last kernel messages */
> - case 5: /* Clear ring buffer */
> + case SYSLOG_ACTION_CLOSE: /* Close log */
> + case SYSLOG_ACTION_OPEN: /* Open log */
> + case SYSLOG_ACTION_READ: /* Read from log */
> + case SYSLOG_ACTION_READ_CLEAR: /* Read/clear last kernel messages */
> + case SYSLOG_ACTION_CLEAR: /* Clear ring buffer */
> default:
> rc = task_has_system(current, SYSTEM__SYSLOG_MOD);
> break;
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 1/2] syslog: distinguish between /proc/kmsg and syscalls
2010-02-04 0:30 ` Serge E. Hallyn
@ 2010-02-04 1:39 ` John Johansen
0 siblings, 0 replies; 22+ messages in thread
From: John Johansen @ 2010-02-04 1:39 UTC (permalink / raw)
To: Serge E. Hallyn
Cc: Kees Cook, James Morris, Casey Schaufler, linux-security-module,
Eric Paris, David Howells, Alexey Dobriyan, Ingo Molnar,
Andrew Morton, Simon Kagstrom, David Woodhouse, Robin Getz,
Greg Kroah-Hartman, Paul Moore, Tetsuo Handa, Stephen Smalley,
Etienne Basset, David P. Quigley, LKLM
Serge E. Hallyn wrote:
> Quoting Kees Cook (kees.cook@canonical.com):
>> This allows the LSM to distinguish between syslog functions originating
>> from /proc/kmsg access and direct syscalls. By default, the commoncaps
>> will now no longer require CAP_SYS_ADMIN to read an opened /proc/kmsg
>> file descriptor. For example the kernel syslog reader can now drop
>> privileges after opening /proc/kmsg, instead of staying privileged with
>> CAP_SYS_ADMIN. MAC systems that implement security_syslog have unchanged
>> behavior.
>>
>> Signed-off-by: Kees Cook <kees.cook@canonical.com>
>
> Acked-by: Serge Hallyn <serue@us.ibm.com>
Acked-by: John Johansen <john.johansen@canonical.com>
>
>> ---
>> fs/proc/kmsg.c | 14 +++++++-------
>> include/linux/security.h | 11 ++++++-----
>> include/linux/syslog.h | 29 +++++++++++++++++++++++++++++
>> kernel/printk.c | 7 ++++---
>> security/commoncap.c | 7 ++++++-
>> security/security.c | 4 ++--
>> security/selinux/hooks.c | 5 +++--
>> security/smack/smack_lsm.c | 4 ++--
>> 8 files changed, 59 insertions(+), 22 deletions(-)
>> create mode 100644 include/linux/syslog.h
>>
>> diff --git a/fs/proc/kmsg.c b/fs/proc/kmsg.c
>> index 7ca7834..6a3d843 100644
>> --- a/fs/proc/kmsg.c
>> +++ b/fs/proc/kmsg.c
>> @@ -12,37 +12,37 @@
>> #include <linux/poll.h>
>> #include <linux/proc_fs.h>
>> #include <linux/fs.h>
>> +#include <linux/syslog.h>
>>
>> #include <asm/uaccess.h>
>> #include <asm/io.h>
>>
>> extern wait_queue_head_t log_wait;
>>
>> -extern int do_syslog(int type, char __user *bug, int count);
>> -
>> static int kmsg_open(struct inode * inode, struct file * file)
>> {
>> - return do_syslog(1,NULL,0);
>> + return do_syslog(1, NULL, 0, SYSLOG_FROM_FILE);
>> }
>>
>> static int kmsg_release(struct inode * inode, struct file * file)
>> {
>> - (void) do_syslog(0,NULL,0);
>> + (void) do_syslog(0, NULL, 0, SYSLOG_FROM_FILE);
>> return 0;
>> }
>>
>> static ssize_t kmsg_read(struct file *file, char __user *buf,
>> size_t count, loff_t *ppos)
>> {
>> - if ((file->f_flags & O_NONBLOCK) && !do_syslog(9, NULL, 0))
>> + if ((file->f_flags & O_NONBLOCK) &&
>> + !do_syslog(9, NULL, 0, SYSLOG_FROM_FILE))
>> return -EAGAIN;
>> - return do_syslog(2, buf, count);
>> + return do_syslog(2, buf, count, SYSLOG_FROM_FILE);
>> }
>>
>> static unsigned int kmsg_poll(struct file *file, poll_table *wait)
>> {
>> poll_wait(file, &log_wait, wait);
>> - if (do_syslog(9, NULL, 0))
>> + if (do_syslog(9, NULL, 0, SYSLOG_FROM_FILE))
>> return POLLIN | POLLRDNORM;
>> return 0;
>> }
>> diff --git a/include/linux/security.h b/include/linux/security.h
>> index 2c627d3..106786e 100644
>> --- a/include/linux/security.h
>> +++ b/include/linux/security.h
>> @@ -76,7 +76,7 @@ extern int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
>> extern int cap_task_setscheduler(struct task_struct *p, int policy, struct sched_param *lp);
>> extern int cap_task_setioprio(struct task_struct *p, int ioprio);
>> extern int cap_task_setnice(struct task_struct *p, int nice);
>> -extern int cap_syslog(int type);
>> +extern int cap_syslog(int type, bool from_file);
>> extern int cap_vm_enough_memory(struct mm_struct *mm, long pages);
>>
>> struct msghdr;
>> @@ -1348,6 +1348,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
>> * logging to the console.
>> * See the syslog(2) manual page for an explanation of the @type values.
>> * @type contains the type of action.
>> + * @from_file indicates the context of action (if it came from /proc).
>> * Return 0 if permission is granted.
>> * @settime:
>> * Check permission to change the system time.
>> @@ -1462,7 +1463,7 @@ struct security_operations {
>> int (*sysctl) (struct ctl_table *table, int op);
>> int (*quotactl) (int cmds, int type, int id, struct super_block *sb);
>> int (*quota_on) (struct dentry *dentry);
>> - int (*syslog) (int type);
>> + int (*syslog) (int type, bool from_file);
>> int (*settime) (struct timespec *ts, struct timezone *tz);
>> int (*vm_enough_memory) (struct mm_struct *mm, long pages);
>>
>> @@ -1761,7 +1762,7 @@ int security_acct(struct file *file);
>> int security_sysctl(struct ctl_table *table, int op);
>> int security_quotactl(int cmds, int type, int id, struct super_block *sb);
>> int security_quota_on(struct dentry *dentry);
>> -int security_syslog(int type);
>> +int security_syslog(int type, bool from_file);
>> int security_settime(struct timespec *ts, struct timezone *tz);
>> int security_vm_enough_memory(long pages);
>> int security_vm_enough_memory_mm(struct mm_struct *mm, long pages);
>> @@ -2007,9 +2008,9 @@ static inline int security_quota_on(struct dentry *dentry)
>> return 0;
>> }
>>
>> -static inline int security_syslog(int type)
>> +static inline int security_syslog(int type, bool from_file)
>> {
>> - return cap_syslog(type);
>> + return cap_syslog(type, from_file);
>> }
>>
>> static inline int security_settime(struct timespec *ts, struct timezone *tz)
>> diff --git a/include/linux/syslog.h b/include/linux/syslog.h
>> new file mode 100644
>> index 0000000..5f02b18
>> --- /dev/null
>> +++ b/include/linux/syslog.h
>> @@ -0,0 +1,29 @@
>> +/* Syslog internals
>> + *
>> + * Copyright 2010 Canonical, Ltd.
>> + * Author: Kees Cook <kees.cook@canonical.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2, or (at your option)
>> + * any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; see the file COPYING. If not, write to
>> + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
>> + */
>> +
>> +#ifndef _LINUX_SYSLOG_H
>> +#define _LINUX_SYSLOG_H
>> +
>> +#define SYSLOG_FROM_CALL 0
>> +#define SYSLOG_FROM_FILE 1
>> +
>> +int do_syslog(int type, char __user *buf, int count, bool from_file);
>> +
>> +#endif /* _LINUX_SYSLOG_H */
>> diff --git a/kernel/printk.c b/kernel/printk.c
>> index 1751c45..1771b34 100644
>> --- a/kernel/printk.c
>> +++ b/kernel/printk.c
>> @@ -35,6 +35,7 @@
>> #include <linux/kexec.h>
>> #include <linux/ratelimit.h>
>> #include <linux/kmsg_dump.h>
>> +#include <linux/syslog.h>
>>
>> #include <asm/uaccess.h>
>>
>> @@ -273,14 +274,14 @@ static inline void boot_delay_msec(void)
>> * 9 -- Return number of unread characters in the log buffer
>> * 10 -- Return size of the log buffer
>> */
>> -int do_syslog(int type, char __user *buf, int len)
>> +int do_syslog(int type, char __user *buf, int len, bool from_file)
>> {
>> unsigned i, j, limit, count;
>> int do_clear = 0;
>> char c;
>> int error = 0;
>>
>> - error = security_syslog(type);
>> + error = security_syslog(type, from_file);
>> if (error)
>> return error;
>>
>> @@ -417,7 +418,7 @@ out:
>>
>> SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len)
>> {
>> - return do_syslog(type, buf, len);
>> + return do_syslog(type, buf, len, SYSLOG_FROM_CALL);
>> }
>>
>> /*
>> diff --git a/security/commoncap.c b/security/commoncap.c
>> index f800fdb..677fad9 100644
>> --- a/security/commoncap.c
>> +++ b/security/commoncap.c
>> @@ -27,6 +27,7 @@
>> #include <linux/sched.h>
>> #include <linux/prctl.h>
>> #include <linux/securebits.h>
>> +#include <linux/syslog.h>
>>
>> /*
>> * If a non-root user executes a setuid-root binary in
>> @@ -888,12 +889,16 @@ error:
>> /**
>> * cap_syslog - Determine whether syslog function is permitted
>> * @type: Function requested
>> + * @from_file: Whether this request came from an open file (i.e. /proc)
>> *
>> * Determine whether the current process is permitted to use a particular
>> * syslog function, returning 0 if permission is granted, -ve if not.
>> */
>> -int cap_syslog(int type)
>> +int cap_syslog(int type, bool from_file)
>> {
>> + /* /proc/kmsg can open be opened by CAP_SYS_ADMIN */
>> + if (type != 1 && from_file)
>> + return 0;
>> if ((type != 3 && type != 10) && !capable(CAP_SYS_ADMIN))
>> return -EPERM;
>> return 0;
>> diff --git a/security/security.c b/security/security.c
>> index 24e060b..9a127ae 100644
>> --- a/security/security.c
>> +++ b/security/security.c
>> @@ -203,9 +203,9 @@ int security_quota_on(struct dentry *dentry)
>> return security_ops->quota_on(dentry);
>> }
>>
>> -int security_syslog(int type)
>> +int security_syslog(int type, bool from_file)
>> {
>> - return security_ops->syslog(type);
>> + return security_ops->syslog(type, from_file);
>> }
>>
>> int security_settime(struct timespec *ts, struct timezone *tz)
>> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
>> index 9a2ee84..a4862a0 100644
>> --- a/security/selinux/hooks.c
>> +++ b/security/selinux/hooks.c
>> @@ -76,6 +76,7 @@
>> #include <linux/selinux.h>
>> #include <linux/mutex.h>
>> #include <linux/posix-timers.h>
>> +#include <linux/syslog.h>
>>
>> #include "avc.h"
>> #include "objsec.h"
>> @@ -2049,11 +2050,11 @@ static int selinux_quota_on(struct dentry *dentry)
>> return dentry_has_perm(cred, NULL, dentry, FILE__QUOTAON);
>> }
>>
>> -static int selinux_syslog(int type)
>> +static int selinux_syslog(int type, bool from_file)
>> {
>> int rc;
>>
>> - rc = cap_syslog(type);
>> + rc = cap_syslog(type, from_file);
>> if (rc)
>> return rc;
>>
>> diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
>> index 529c9ca..a5721b3 100644
>> --- a/security/smack/smack_lsm.c
>> +++ b/security/smack/smack_lsm.c
>> @@ -157,12 +157,12 @@ static int smack_ptrace_traceme(struct task_struct *ptp)
>> *
>> * Returns 0 on success, error code otherwise.
>> */
>> -static int smack_syslog(int type)
>> +static int smack_syslog(int type, bool from_file)
>> {
>> int rc;
>> char *sp = current_security();
>>
>> - rc = cap_syslog(type);
>> + rc = cap_syslog(type, from_file);
>> if (rc != 0)
>> return rc;
>>
>> --
>> 1.6.5
>>
>>
>> --
>> Kees Cook
>> Ubuntu Security Team
> --
> To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 2/2] syslog: use defined constants instead of raw numbers
2010-02-03 23:37 ` [PATCH v2 2/2] syslog: use defined constants instead of raw numbers Kees Cook
2010-02-04 0:35 ` Serge E. Hallyn
2010-02-04 1:38 ` John Johansen
@ 2010-02-04 3:51 ` James Morris
2 siblings, 0 replies; 22+ messages in thread
From: James Morris @ 2010-02-04 3:51 UTC (permalink / raw)
To: Kees Cook
Cc: Serge E. Hallyn, Casey Schaufler, linux-security-module,
Eric Paris, David Howells, Alexey Dobriyan, Ingo Molnar,
Andrew Morton, Simon Kagstrom, David Woodhouse, Robin Getz,
Greg Kroah-Hartman, Paul Moore, Tetsuo Handa, Stephen Smalley,
Etienne Basset, David P. Quigley, LKLM
On Wed, 3 Feb 2010, Kees Cook wrote:
> Right now the syslog "type" action are just raw numbers which makes
> the source difficult to follow. This patch replaces the raw numbers
> with defined constants for some level of sanity.
>
> Signed-off-by: Kees Cook <kees.cook@canonical.com>
Applied to
git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6#next
--
James Morris
<jmorris@namei.org>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 1/2] syslog: distinguish between /proc/kmsg and syscalls
2010-02-03 23:36 ` [PATCH v2 1/2] syslog: distinguish between /proc/kmsg and syscalls Kees Cook
2010-02-04 0:30 ` Serge E. Hallyn
@ 2010-02-04 3:52 ` James Morris
2010-02-04 7:58 ` Alex Riesen
2 siblings, 0 replies; 22+ messages in thread
From: James Morris @ 2010-02-04 3:52 UTC (permalink / raw)
To: Kees Cook
Cc: Serge E. Hallyn, Casey Schaufler, linux-security-module,
Eric Paris, David Howells, Alexey Dobriyan, Ingo Molnar,
Andrew Morton, Simon Kagstrom, David Woodhouse, Robin Getz,
Greg Kroah-Hartman, Paul Moore, Tetsuo Handa, Stephen Smalley,
Etienne Basset, David P. Quigley, LKLM
On Wed, 3 Feb 2010, Kees Cook wrote:
> This allows the LSM to distinguish between syslog functions originating
> from /proc/kmsg access and direct syscalls. By default, the commoncaps
> will now no longer require CAP_SYS_ADMIN to read an opened /proc/kmsg
> file descriptor. For example the kernel syslog reader can now drop
> privileges after opening /proc/kmsg, instead of staying privileged with
> CAP_SYS_ADMIN. MAC systems that implement security_syslog have unchanged
> behavior.
>
> Signed-off-by: Kees Cook <kees.cook@canonical.com>
Applied to
git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6#next
--
James Morris
<jmorris@namei.org>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 1/2] syslog: distinguish between /proc/kmsg and syscalls
2010-02-03 23:36 ` [PATCH v2 1/2] syslog: distinguish between /proc/kmsg and syscalls Kees Cook
2010-02-04 0:30 ` Serge E. Hallyn
2010-02-04 3:52 ` James Morris
@ 2010-02-04 7:58 ` Alex Riesen
2010-02-04 8:09 ` Kees Cook
2 siblings, 1 reply; 22+ messages in thread
From: Alex Riesen @ 2010-02-04 7:58 UTC (permalink / raw)
To: Kees Cook
Cc: James Morris, Serge E. Hallyn, Casey Schaufler,
linux-security-module, Eric Paris, David Howells, Alexey Dobriyan,
Ingo Molnar, Andrew Morton, Simon Kagstrom, David Woodhouse,
Robin Getz, Greg Kroah-Hartman, Paul Moore, Tetsuo Handa,
Stephen Smalley, Etienne Basset, David P. Quigley, LKLM
On Thu, Feb 4, 2010 at 00:36, Kees Cook <kees.cook@canonical.com> wrote:
> @@ -888,12 +889,16 @@ error:
> /**
> * cap_syslog - Determine whether syslog function is permitted
> * @type: Function requested
> + * @from_file: Whether this request came from an open file (i.e. /proc)
> *
> * Determine whether the current process is permitted to use a particular
> * syslog function, returning 0 if permission is granted, -ve if not.
> */
> -int cap_syslog(int type)
> +int cap_syslog(int type, bool from_file)
> {
> + /* /proc/kmsg can open be opened by CAP_SYS_ADMIN */
> + if (type != 1 && from_file)
> + return 0;
"can open be opened"?
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 1/2] syslog: distinguish between /proc/kmsg and syscalls
2010-02-04 7:58 ` Alex Riesen
@ 2010-02-04 8:09 ` Kees Cook
2010-02-04 21:17 ` James Morris
0 siblings, 1 reply; 22+ messages in thread
From: Kees Cook @ 2010-02-04 8:09 UTC (permalink / raw)
To: Alex Riesen
Cc: James Morris, Serge E. Hallyn, Casey Schaufler,
linux-security-module, Eric Paris, David Howells, Alexey Dobriyan,
Ingo Molnar, Andrew Morton, Simon Kagstrom, David Woodhouse,
Robin Getz, Greg Kroah-Hartman, Paul Moore, Tetsuo Handa,
Stephen Smalley, Etienne Basset, David P. Quigley, LKLM
Hi Alex,
On Thu, Feb 04, 2010 at 08:58:43AM +0100, Alex Riesen wrote:
> > + /* /proc/kmsg can open be opened by CAP_SYS_ADMIN */
> > + if (type != 1 && from_file)
> > + return 0;
>
> "can open be opened"?
Erk, sorry. s/open //
James, do you want a patch for that?
-Kees
--
Kees Cook
Ubuntu Security Team
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 1/2] syslog: distinguish between /proc/kmsg and syscalls
2010-02-04 8:09 ` Kees Cook
@ 2010-02-04 21:17 ` James Morris
2010-02-04 21:31 ` Serge E. Hallyn
0 siblings, 1 reply; 22+ messages in thread
From: James Morris @ 2010-02-04 21:17 UTC (permalink / raw)
To: Kees Cook
Cc: Alex Riesen, Serge E. Hallyn, Casey Schaufler,
linux-security-module, Eric Paris, David Howells, Alexey Dobriyan,
Ingo Molnar, Andrew Morton, Simon Kagstrom, David Woodhouse,
Robin Getz, Greg Kroah-Hartman, Paul Moore, Tetsuo Handa,
Stephen Smalley, Etienne Basset, David P. Quigley, LKLM
[-- Attachment #1: Type: TEXT/PLAIN, Size: 442 bytes --]
On Thu, 4 Feb 2010, Kees Cook wrote:
> Hi Alex,
>
> On Thu, Feb 04, 2010 at 08:58:43AM +0100, Alex Riesen wrote:
> > > + /* /proc/kmsg can open be opened by CAP_SYS_ADMIN */
> > > + if (type != 1 && from_file)
> > > + return 0;
> >
> > "can open be opened"?
>
> Erk, sorry. s/open //
>
> James, do you want a patch for that?
I guess... and 'opened with' might be better.
--
James Morris
<jmorris@namei.org>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 1/2] syslog: distinguish between /proc/kmsg and syscalls
2010-02-04 21:17 ` James Morris
@ 2010-02-04 21:31 ` Serge E. Hallyn
2010-02-04 21:49 ` Eric Paris
0 siblings, 1 reply; 22+ messages in thread
From: Serge E. Hallyn @ 2010-02-04 21:31 UTC (permalink / raw)
To: James Morris
Cc: Kees Cook, Alex Riesen, Casey Schaufler, linux-security-module,
Eric Paris, David Howells, Alexey Dobriyan, Ingo Molnar,
Andrew Morton, Simon Kagstrom, David Woodhouse, Robin Getz,
Greg Kroah-Hartman, Paul Moore, Tetsuo Handa, Stephen Smalley,
Etienne Basset, David P. Quigley, LKLM
Quoting James Morris (jmorris@namei.org):
> On Thu, 4 Feb 2010, Kees Cook wrote:
>
> > Hi Alex,
> >
> > On Thu, Feb 04, 2010 at 08:58:43AM +0100, Alex Riesen wrote:
> > > > + /* /proc/kmsg can open be opened by CAP_SYS_ADMIN */
> > > > + if (type != 1 && from_file)
> > > > + return 0;
> > >
> > > "can open be opened"?
> >
> > Erk, sorry. s/open //
> >
> > James, do you want a patch for that?
>
> I guess... and 'opened with' might be better.
I'd still as mentioned yesterday prefer "requires CAP_SYS_ADMIN to open"
Otherwise, every time I see the comment I expect stricter requirements,
not laxer ones, on the other actions. However, I think with the second
patch switching 1 for a meaningful name, the comment isn't even necessary
or noticable any more.
-serge
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 1/2] syslog: distinguish between /proc/kmsg and syscalls
2010-02-04 21:31 ` Serge E. Hallyn
@ 2010-02-04 21:49 ` Eric Paris
0 siblings, 0 replies; 22+ messages in thread
From: Eric Paris @ 2010-02-04 21:49 UTC (permalink / raw)
To: Serge E. Hallyn
Cc: James Morris, Kees Cook, Alex Riesen, Casey Schaufler,
linux-security-module, David Howells, Alexey Dobriyan,
Ingo Molnar, Andrew Morton, Simon Kagstrom, David Woodhouse,
Robin Getz, Greg Kroah-Hartman, Paul Moore, Tetsuo Handa,
Stephen Smalley, Etienne Basset, David P. Quigley, LKLM
On Thu, 2010-02-04 at 15:31 -0600, Serge E. Hallyn wrote:
> Quoting James Morris (jmorris@namei.org):
> > On Thu, 4 Feb 2010, Kees Cook wrote:
> >
> > > Hi Alex,
> > >
> > > On Thu, Feb 04, 2010 at 08:58:43AM +0100, Alex Riesen wrote:
> > > > > + /* /proc/kmsg can open be opened by CAP_SYS_ADMIN */
> > > > > + if (type != 1 && from_file)
> > > > > + return 0;
> > > >
> > > > "can open be opened"?
> > >
> > > Erk, sorry. s/open //
> > >
> > > James, do you want a patch for that?
> >
> > I guess... and 'opened with' might be better.
>
> I'd still as mentioned yesterday prefer "requires CAP_SYS_ADMIN to open"
> Otherwise, every time I see the comment I expect stricter requirements,
> not laxer ones, on the other actions. However, I think with the second
> patch switching 1 for a meaningful name, the comment isn't even necessary
> or noticable any more.
Agreed, the names make the function understandable, the comment confused
the mess out of me.
^ permalink raw reply [flat|nested] 22+ messages in thread
end of thread, other threads:[~2010-02-04 21:51 UTC | newest]
Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-02-02 5:53 [PATCH] syslog: distinguish between /proc/kmsg and syscalls Kees Cook
2010-02-02 6:15 ` Casey Schaufler
2010-02-02 20:20 ` Kees Cook
2010-02-02 21:25 ` Serge E. Hallyn
2010-02-02 21:59 ` James Morris
2010-02-03 19:15 ` [PATCH 1/2] " Kees Cook
2010-02-03 20:44 ` Serge E. Hallyn
2010-02-03 19:23 ` [PATCH 2/2] syslog: use defined constants instead of raw numbers Kees Cook
2010-02-03 20:47 ` Serge E. Hallyn
2010-02-03 23:36 ` [PATCH v2 1/2] syslog: distinguish between /proc/kmsg and syscalls Kees Cook
2010-02-04 0:30 ` Serge E. Hallyn
2010-02-04 1:39 ` John Johansen
2010-02-04 3:52 ` James Morris
2010-02-04 7:58 ` Alex Riesen
2010-02-04 8:09 ` Kees Cook
2010-02-04 21:17 ` James Morris
2010-02-04 21:31 ` Serge E. Hallyn
2010-02-04 21:49 ` Eric Paris
2010-02-03 23:37 ` [PATCH v2 2/2] syslog: use defined constants instead of raw numbers Kees Cook
2010-02-04 0:35 ` Serge E. Hallyn
2010-02-04 1:38 ` John Johansen
2010-02-04 3:51 ` James Morris
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).