Commit 6f62d840 authored by Chris Wright's avatar Chris Wright Committed by Linus Torvalds

[PATCH] lsm: fix send_sigurg mediation

Stephen Smalley notes that send_sigurg isn't mediated by LSM in the same
manner as send_sigio.  Patch below is a slight modification of Stephen's
original patch.  It moves the security_file_send_sigiotask() hook into the
sigio_perm().  The hook's fd and reason arguments are replaced with the
signum.  sigio_perm() and it's callers are updated to pass the signum
through to the hook.  In send_sigio case, the signum is simply fown->signum
or SIGIO when signum is 0, however in send_sigurg the kernel doesn't use
fown->signum, it always sends SIGURG.

From: Stephen Smalley <sds@epoch.ncsc.mil>
Signed-off-by: default avatarChris Wright <chrisw@osdl.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 0f4b6dfa
...@@ -431,11 +431,12 @@ static long band_table[NSIGPOLL] = { ...@@ -431,11 +431,12 @@ static long band_table[NSIGPOLL] = {
}; };
static inline int sigio_perm(struct task_struct *p, static inline int sigio_perm(struct task_struct *p,
struct fown_struct *fown) struct fown_struct *fown, int sig)
{ {
return ((fown->euid == 0) || return (((fown->euid == 0) ||
(fown->euid == p->suid) || (fown->euid == p->uid) || (fown->euid == p->suid) || (fown->euid == p->uid) ||
(fown->uid == p->suid) || (fown->uid == p->uid)); (fown->uid == p->suid) || (fown->uid == p->uid)) &&
!security_file_send_sigiotask(p, fown, sig));
} }
static void send_sigio_to_task(struct task_struct *p, static void send_sigio_to_task(struct task_struct *p,
...@@ -443,10 +444,7 @@ static void send_sigio_to_task(struct task_struct *p, ...@@ -443,10 +444,7 @@ static void send_sigio_to_task(struct task_struct *p,
int fd, int fd,
int reason) int reason)
{ {
if (!sigio_perm(p, fown)) if (!sigio_perm(p, fown, fown->signum))
return;
if (security_file_send_sigiotask(p, fown, fd, reason))
return; return;
switch (fown->signum) { switch (fown->signum) {
...@@ -508,7 +506,7 @@ void send_sigio(struct fown_struct *fown, int fd, int band) ...@@ -508,7 +506,7 @@ void send_sigio(struct fown_struct *fown, int fd, int band)
static void send_sigurg_to_task(struct task_struct *p, static void send_sigurg_to_task(struct task_struct *p,
struct fown_struct *fown) struct fown_struct *fown)
{ {
if (sigio_perm(p, fown)) if (sigio_perm(p, fown, SIGURG))
send_group_sig_info(SIGURG, SEND_SIG_PRIV, p); send_group_sig_info(SIGURG, SEND_SIG_PRIV, p);
} }
......
...@@ -488,16 +488,15 @@ struct swap_info_struct; ...@@ -488,16 +488,15 @@ struct swap_info_struct;
* @file contains the file structure to update. * @file contains the file structure to update.
* Return 0 on success. * Return 0 on success.
* @file_send_sigiotask: * @file_send_sigiotask:
* Check permission for the file owner @fown to send SIGIO to the process * Check permission for the file owner @fown to send SIGIO or SIGURG to the
* @tsk. Note that this hook is always called from interrupt. Note that * process @tsk. Note that this hook is sometimes called from interrupt.
* the fown_struct, @fown, is never outside the context of a struct file, * Note that the fown_struct, @fown, is never outside the context of a
* so the file structure (and associated security information) can always * struct file, so the file structure (and associated security information)
* be obtained: * can always be obtained:
* (struct file *)((long)fown - offsetof(struct file,f_owner)); * (struct file *)((long)fown - offsetof(struct file,f_owner));
* @tsk contains the structure of task receiving signal. * @tsk contains the structure of task receiving signal.
* @fown contains the file owner information. * @fown contains the file owner information.
* @fd contains the file descriptor. * @sig is the signal that will be sent. When 0, kernel sends SIGIO.
* @reason contains the operational flags.
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @file_receive: * @file_receive:
* This hook allows security modules to control the ability of a process * This hook allows security modules to control the ability of a process
...@@ -1135,8 +1134,7 @@ struct security_operations { ...@@ -1135,8 +1134,7 @@ struct security_operations {
unsigned long arg); unsigned long arg);
int (*file_set_fowner) (struct file * file); int (*file_set_fowner) (struct file * file);
int (*file_send_sigiotask) (struct task_struct * tsk, int (*file_send_sigiotask) (struct task_struct * tsk,
struct fown_struct * fown, struct fown_struct * fown, int sig);
int fd, int reason);
int (*file_receive) (struct file * file); int (*file_receive) (struct file * file);
int (*task_create) (unsigned long clone_flags); int (*task_create) (unsigned long clone_flags);
...@@ -1657,9 +1655,9 @@ static inline int security_file_set_fowner (struct file *file) ...@@ -1657,9 +1655,9 @@ static inline int security_file_set_fowner (struct file *file)
static inline int security_file_send_sigiotask (struct task_struct *tsk, static inline int security_file_send_sigiotask (struct task_struct *tsk,
struct fown_struct *fown, struct fown_struct *fown,
int fd, int reason) int sig)
{ {
return security_ops->file_send_sigiotask (tsk, fown, fd, reason); return security_ops->file_send_sigiotask (tsk, fown, sig);
} }
static inline int security_file_receive (struct file *file) static inline int security_file_receive (struct file *file)
...@@ -2299,7 +2297,7 @@ static inline int security_file_set_fowner (struct file *file) ...@@ -2299,7 +2297,7 @@ static inline int security_file_set_fowner (struct file *file)
static inline int security_file_send_sigiotask (struct task_struct *tsk, static inline int security_file_send_sigiotask (struct task_struct *tsk,
struct fown_struct *fown, struct fown_struct *fown,
int fd, int reason) int sig)
{ {
return 0; return 0;
} }
......
...@@ -518,8 +518,7 @@ static int dummy_file_set_fowner (struct file *file) ...@@ -518,8 +518,7 @@ static int dummy_file_set_fowner (struct file *file)
} }
static int dummy_file_send_sigiotask (struct task_struct *tsk, static int dummy_file_send_sigiotask (struct task_struct *tsk,
struct fown_struct *fown, int fd, struct fown_struct *fown, int sig)
int reason)
{ {
return 0; return 0;
} }
......
...@@ -2562,8 +2562,7 @@ static int selinux_file_set_fowner(struct file *file) ...@@ -2562,8 +2562,7 @@ static int selinux_file_set_fowner(struct file *file)
} }
static int selinux_file_send_sigiotask(struct task_struct *tsk, static int selinux_file_send_sigiotask(struct task_struct *tsk,
struct fown_struct *fown, struct fown_struct *fown, int signum)
int fd, int reason)
{ {
struct file *file; struct file *file;
u32 perm; u32 perm;
...@@ -2576,10 +2575,10 @@ static int selinux_file_send_sigiotask(struct task_struct *tsk, ...@@ -2576,10 +2575,10 @@ static int selinux_file_send_sigiotask(struct task_struct *tsk,
tsec = tsk->security; tsec = tsk->security;
fsec = file->f_security; fsec = file->f_security;
if (!fown->signum) if (!signum)
perm = signal_to_av(SIGIO); /* as per send_sigio_to_task */ perm = signal_to_av(SIGIO); /* as per send_sigio_to_task */
else else
perm = signal_to_av(fown->signum); perm = signal_to_av(signum);
return avc_has_perm(fsec->fown_sid, tsec->sid, return avc_has_perm(fsec->fown_sid, tsec->sid,
SECCLASS_PROCESS, perm, NULL, NULL); SECCLASS_PROCESS, perm, NULL, NULL);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment