Mediating send_sigurg

From: Stephen Smalley (sds@private)
Date: Fri Aug 27 2004 - 07:15:46 PDT


Hi,

I noticed that send_sigurg is not being mediated at present by a LSM
hook, unlike send_sigio, and wondered whether we should just move the
security_file_send_sigiotask hook into the common sigio_perm helper
function, as in the untested patch below.  This would require dropping
the fd and reason arguments, but those are not being used by SELinux and
I'm not sure that they would ever be used.  One lingering issue here is
that send_sigurg always sends SIGURG, whereas send_sigio sends
fown->signum or SIGIO by default, so the current check performed by
selinux_file_send_sigiotask may check the wrong permission for
send_sigurg.  Typically, that won't be the case, as SIGIO and SIGURG are
both mapped to the same SELinux permission at present, but if
fown->signum was set to a signal that mapped to a different SELinux
permission and send_sigurg were called, then the check would be based on
that other permission.  Comments?

diff -X /home/sds/dontdiff -ru linux-2.6.9-rc1-bk3/fs/fcntl.c linux-2.6.9-rc1-bk3-sigurg/fs/fcntl.c
--- linux-2.6.9-rc1-bk3/fs/fcntl.c	2004-08-14 06:55:35.000000000 -0400
+++ linux-2.6.9-rc1-bk3-sigurg/fs/fcntl.c	2004-08-27 08:56:51.495798232 -0400
@@ -434,9 +434,10 @@
 static inline int sigio_perm(struct task_struct *p,
                              struct fown_struct *fown)
 {
-	return ((fown->euid == 0) ||
- 	        (fown->euid == p->suid) || (fown->euid == p->uid) ||
- 	        (fown->uid == p->suid) || (fown->uid == p->uid));
+	return (((fown->euid == 0) ||
+		 (fown->euid == p->suid) || (fown->euid == p->uid) ||
+		 (fown->uid == p->suid) || (fown->uid == p->uid)) &&
+		!security_file_send_sigiotask(p, fown));
 }
 
 static void send_sigio_to_task(struct task_struct *p,
@@ -447,9 +448,6 @@
 	if (!sigio_perm(p, fown))
 		return;
 
-	if (security_file_send_sigiotask(p, fown, fd, reason))
-		return;
-
 	switch (fown->signum) {
 		siginfo_t si;
 		default:
diff -X /home/sds/dontdiff -ru linux-2.6.9-rc1-bk3/include/linux/security.h linux-2.6.9-rc1-bk3-sigurg/include/linux/security.h
--- linux-2.6.9-rc1-bk3/include/linux/security.h	2004-08-14 06:55:48.000000000 -0400
+++ linux-2.6.9-rc1-bk3-sigurg/include/linux/security.h	2004-08-27 09:03:25.833849736 -0400
@@ -485,16 +485,14 @@
  *	@file contains the file structure to update.
  *	Return 0 on success.
  * @file_send_sigiotask:
- *	Check permission for the file owner @fown to send SIGIO to the process
- *	@tsk.  Note that this hook is always called from interrupt.  Note that
+ *	Check permission for the file owner @fown to send SIGIO or SIGURG to the process
+ *	@tsk.  Note that this hook is sometimes called from interrupt.  Note that
  *	the fown_struct, @fown, is never outside the context of a struct file,
  *	so the file structure (and associated security information) can always
  *	be obtained:
  *		(struct file *)((long)fown - offsetof(struct file,f_owner));
  * 	@tsk contains the structure of task receiving signal.
  *	@fown contains the file owner information.
- *	@fd contains the file descriptor.
- *	@reason contains the operational flags.
  *	Return 0 if permission is granted.
  * @file_receive:
  *	This hook allows security modules to control the ability of a process
@@ -1125,8 +1123,7 @@
 			   unsigned long arg);
 	int (*file_set_fowner) (struct file * file);
 	int (*file_send_sigiotask) (struct task_struct * tsk,
-				    struct fown_struct * fown,
-				    int fd, int reason);
+				    struct fown_struct * fown);
 	int (*file_receive) (struct file * file);
 
 	int (*task_create) (unsigned long clone_flags);
@@ -1640,10 +1637,9 @@
 }
 
 static inline int security_file_send_sigiotask (struct task_struct *tsk,
-						struct fown_struct *fown,
-						int fd, int reason)
+						struct fown_struct *fown)
 {
-	return security_ops->file_send_sigiotask (tsk, fown, fd, reason);
+	return security_ops->file_send_sigiotask (tsk, fown);
 }
 
 static inline int security_file_receive (struct file *file)
@@ -2277,8 +2273,7 @@
 }
 
 static inline int security_file_send_sigiotask (struct task_struct *tsk,
-						struct fown_struct *fown,
-						int fd, int reason)
+						struct fown_struct *fown)
 {
 	return 0;
 }
diff -X /home/sds/dontdiff -ru linux-2.6.9-rc1-bk3/security/dummy.c linux-2.6.9-rc1-bk3-sigurg/security/dummy.c
--- linux-2.6.9-rc1-bk3/security/dummy.c	2004-08-14 06:54:51.000000000 -0400
+++ linux-2.6.9-rc1-bk3-sigurg/security/dummy.c	2004-08-27 09:03:35.188427624 -0400
@@ -511,8 +511,7 @@
 }
 
 static int dummy_file_send_sigiotask (struct task_struct *tsk,
-				      struct fown_struct *fown, int fd,
-				      int reason)
+				      struct fown_struct *fown)
 {
 	return 0;
 }
diff -X /home/sds/dontdiff -ru linux-2.6.9-rc1-bk3/security/selinux/hooks.c linux-2.6.9-rc1-bk3-sigurg/security/selinux/hooks.c
--- linux-2.6.9-rc1-bk3/security/selinux/hooks.c	2004-08-27 09:27:33.498771216 -0400
+++ linux-2.6.9-rc1-bk3-sigurg/security/selinux/hooks.c	2004-08-27 09:27:21.537589592 -0400
@@ -2591,8 +2591,7 @@
 }
 
 static int selinux_file_send_sigiotask(struct task_struct *tsk,
-				       struct fown_struct *fown,
-				       int fd, int reason)
+				       struct fown_struct *fown)
 {
         struct file *file;
 	u32 perm;


-- 
Stephen Smalley <sds@private>
National Security Agency



This archive was generated by hypermail 2.1.3 : Fri Aug 27 2004 - 07:18:04 PDT