I've attached a small patch between the latest WireX BitKeeper tree and our tree that adds hooks for System V IPC message queues (by Chris Vance) and for sysctl (by Wayne Salamon). I'm not sure how these should be integrated into the WireX tree - 2.4.5 or 2.4.6-pre3? -- Stephen D. Smalley, NAI Labs ssmalleyat_private On Wed, 20 Jun 2001, Chris Wright wrote: > Latest lsm patch is available. > http://lsm.immunix.org/patches/lsm-2001_06_20-2.4.5.patch.gz > > BitKeeper has been updated. > > This is Stephen Smalley's latest proposal merged into 2.4.5. I backed > out the 2.4.6-pre3 merge. The relevant changes that happened after that > merge are in this patch (and in BitKeeper) against 2.4.5. > > Thanks to everyone who helped, either with code or discussion, produce > this patch. I'd especially like to thank Stephen for this solid > contribution. He did a lot of work to unify the hooks and organize > the framework. Both the dummy and capabilities code are effectively > using this newly organized lsm framework > > Patch includes: > * capable hook is used as coarse grained permissive hook > * fine grained hooks are restrictive and uniform > * default (dummy) security_ops is usable as superuser check > * capabilities is a module and implements capabilities specific bits of > ptrace, compute_creds, etc. > * base logic for compute_creds is in kernel, the rest is done in > module, this fixed the setuid problem with dummy_ops > * added kmod_set_label and post_set*id hooks > * many hooks had additional parameters to make them more useful > * change to kernel to copy userspace info to tmp variable to use some > of the additional parameters added to hooks > * added IPC and fowner/fcntl/sigiotask updates from Chris Vance > <cvanceat_private>, NAI Labs. > * added ioctl from Wayne Salamon. > * initial port to IA64 from Greg Kroah-Hartman > # secondary module registration now takes a module name as well > * ...and some things that i'm forgetting right now ;-) > > -chris > > p.s. for those BitKeeper users that want to re-sync without > re-cloning...there are probably many ways to do this. I know of an easy > fool proof one. In your local repository, simply undo any changes after 1.73: > > bk undo -a1.73 > bk pull > > and you're done. > > _______________________________________________ > linux-security-module mailing list > linux-security-moduleat_private > http://mail.wirex.com/mailman/listinfo/linux-security-module > diff -X exclude -ur wirex/lsm/include/linux/msg.h lsm/lsm-new/include/linux/msg.h --- wirex/lsm/include/linux/msg.h Mon Jun 18 16:40:03 2001 +++ lsm/lsm-new/include/linux/msg.h Thu Jun 21 11:39:49 2001 @@ -63,6 +63,36 @@ #ifdef __KERNEL__ +/* one msg_msg structure for each message */ +struct msg_msg { + struct list_head m_list; + long m_type; + int m_ts; /* message text size */ + struct msg_msgseg* next; + void *security; + /* the actual message follows immediately */ +}; + +#define DATALEN_MSG (PAGE_SIZE-sizeof(struct msg_msg)) +#define DATALEN_SEG (PAGE_SIZE-sizeof(struct msg_msgseg)) + +/* one msq_queue structure for each present queue on the system */ +struct msg_queue { + struct kern_ipc_perm q_perm; + time_t q_stime; /* last msgsnd time */ + time_t q_rtime; /* last msgrcv time */ + time_t q_ctime; /* last change time */ + unsigned long q_cbytes; /* current number of bytes on queue */ + unsigned long q_qnum; /* number of messages in queue */ + unsigned long q_qbytes; /* max number of bytes on queue */ + pid_t q_lspid; /* pid of last msgsnd */ + pid_t q_lrpid; /* last receive pid */ + + struct list_head q_messages; + struct list_head q_receivers; + struct list_head q_senders; +}; + asmlinkage long sys_msgget (key_t key, int msgflg); asmlinkage long sys_msgsnd (int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg); asmlinkage long sys_msgrcv (int msqid, struct msgbuf *msgp, size_t msgsz, long msgtyp, int msgflg); diff -X exclude -ur wirex/lsm/include/linux/security.h lsm/lsm-new/include/linux/security.h --- wirex/lsm/include/linux/security.h Thu Jun 21 08:47:10 2001 +++ lsm/lsm-new/include/linux/security.h Thu Jun 21 11:42:36 2001 @@ -30,6 +30,7 @@ #include <linux/resource.h> #include <linux/ipc.h> #include <linux/sem.h> +#include <linux/sysctl.h> #include <linux/shm.h> #include <linux/msg.h> @@ -138,12 +139,19 @@ int (* getinfo) (int id, int cmd); }; +struct msg_msg_security_ops { + int (* alloc_security) (struct msg_msg *msg); + void (* free_security) (struct msg_msg *msg); + int (* test_message) (struct msg_msg *msg, long type, int mode); +}; + struct msg_queue_security_ops { - int (* create) (key_t key); // can i create - int (* permission) (void); - int (* setmaxqbytes) (void); - int (* setattr) (void); // can i set attributes - int (* delete) (void); // can i delete + int (* alloc_security) (struct msg_queue *msq); + void (* free_security) (struct msg_queue *msq); + int (* associate) (struct msg_queue *msq, int msqid, int msqflg); + int (* msgctl) (struct msg_queue *msq, int msqid, int cmd); + int (* msgsnd) (struct msg_queue *msq, struct msg_msg *msg, int msqid, int msqflg); + int (* msgrcv) (struct msg_queue *msq, struct msg_msg *msg, int msqid, int msgflg); }; struct shm_security_ops { @@ -183,6 +191,7 @@ int (* ptrace) (struct task_struct *parent, struct task_struct *child); int (* setcapability) (void); int (* acct) (struct file *file); + int (* sysctl) (ctl_table * table, int op); int (* capable) (struct task_struct *tsk, int cap); struct binprm_security_ops * bprm_ops; @@ -193,6 +202,7 @@ struct socket_security_ops * socket_ops; struct module_security_ops * module_ops; struct ipc_security_ops * ipc_ops; + struct msg_msg_security_ops * msg_msg_ops; struct msg_queue_security_ops * msg_queue_ops; struct shm_security_ops * shm_ops; struct sem_security_ops * sem_ops; diff -X exclude -ur wirex/lsm/ipc/msg.c lsm/lsm-new/ipc/msg.c --- wirex/lsm/ipc/msg.c Mon Jun 18 16:40:18 2001 +++ lsm/lsm-new/ipc/msg.c Thu Jun 21 11:40:44 2001 @@ -52,34 +52,6 @@ struct msg_msgseg* next; /* the next part of the message follows immediately */ }; -/* one msg_msg structure for each message */ -struct msg_msg { - struct list_head m_list; - long m_type; - int m_ts; /* message text size */ - struct msg_msgseg* next; - /* the actual message follows immediately */ -}; - -#define DATALEN_MSG (PAGE_SIZE-sizeof(struct msg_msg)) -#define DATALEN_SEG (PAGE_SIZE-sizeof(struct msg_msgseg)) - -/* one msq_queue structure for each present queue on the system */ -struct msg_queue { - struct kern_ipc_perm q_perm; - time_t q_stime; /* last msgsnd time */ - time_t q_rtime; /* last msgrcv time */ - time_t q_ctime; /* last change time */ - unsigned long q_cbytes; /* current number of bytes on queue */ - unsigned long q_qnum; /* number of messages in queue */ - unsigned long q_qbytes; /* max number of bytes on queue */ - pid_t q_lspid; /* pid of last msgsnd */ - pid_t q_lrpid; /* last receive pid */ - - struct list_head q_messages; - struct list_head q_receivers; - struct list_head q_senders; -}; #define SEARCH_ANY 1 #define SEARCH_EQUAL 2 @@ -117,11 +89,19 @@ static int newque (key_t key, int msgflg) { int id; + int retval; struct msg_queue *msq; msq = (struct msg_queue *) kmalloc (sizeof (*msq), GFP_KERNEL); if (!msq) return -ENOMEM; + + retval = security_ops->msg_queue_ops->alloc_security(msq); + if (retval) { + kfree(msq); + return retval; + } + id = ipc_addid(&msg_ids, &msq->q_perm, msg_ctlmni); if(id == -1) { kfree(msq); @@ -146,6 +126,9 @@ static void free_msg(struct msg_msg* msg) { struct msg_msgseg* seg; + + security_ops->msg_msg_ops->free_security(msg); + seg = msg->next; kfree(msg); while(seg != NULL) { @@ -200,6 +183,11 @@ len -= alen; src = ((char*)src)+alen; } + + err = security_ops->msg_msg_ops->alloc_security(msg); + if (err) + goto out_err; + return msg; out_err: @@ -285,6 +273,8 @@ msq = msg_rmid(id); + security_ops->msg_queue_ops->free_security(msq); + expunge_all(msq,-EIDRM); ss_wakeup(&msq->q_senders,1); msg_unlock(id); @@ -319,7 +309,8 @@ msq = msg_lock(id); if(msq==NULL) BUG(); - if (ipcperms(&msq->q_perm, msgflg)) + if (ipcperms(&msq->q_perm, msgflg) || + security_ops->msg_queue_ops->associate(msq, msg_buildid(id, msq->q_perm.seq), msgflg)) ret = -EACCES; else ret = msg_buildid(id, msq->q_perm.seq); @@ -444,6 +435,11 @@ * due to padding, it's not enough * to set all member fields. */ + + err = security_ops->ipc_ops->getinfo(msqid, cmd); + if (err) + return err; + memset(&msginfo,0,sizeof(msginfo)); msginfo.msgmni = msg_ctlmni; msginfo.msgmax = msg_ctlmax; @@ -494,6 +490,10 @@ if (ipcperms (&msq->q_perm, S_IRUGO)) goto out_unlock; + err = security_ops->msg_queue_ops->msgctl(msq, msqid, cmd); + if (err) + goto out_unlock; + kernel_to_ipc64_perm(&msq->q_perm, &tbuf.msg_perm); tbuf.msg_stime = msq->q_stime; tbuf.msg_rtime = msq->q_rtime; @@ -541,6 +541,11 @@ { if (setbuf.qbytes > msg_ctlmnb && !capable(CAP_SYS_RESOURCE)) goto out_unlock_up; + + err = security_ops->msg_queue_ops->msgctl(msq, msqid, cmd); + if (err) + goto out_unlock_up; + msq->q_qbytes = setbuf.qbytes; ipcp->uid = setbuf.uid; @@ -560,6 +565,10 @@ break; } case IPC_RMID: + err = security_ops->msg_queue_ops->msgctl(msq, msqid, cmd); + if (err) + goto out_unlock_up; + freeque (msqid); break; } @@ -577,6 +586,9 @@ static int testmsg(struct msg_msg* msg,long type,int mode) { + if (security_ops->msg_msg_ops->test_message(msg, type, mode)) + return 0; + switch(mode) { case SEARCH_ANY: @@ -657,6 +669,10 @@ if (ipcperms(&msq->q_perm, S_IWUGO)) goto out_unlock_free; + err = security_ops->msg_queue_ops->msgsnd(msq, msg, msqid, msgflg); + if (err) + goto out_unlock_free; + if(msgsz + msq->q_cbytes > msq->q_qbytes || 1 + msq->q_qnum > msq->q_qbytes) { struct msg_sender s; @@ -768,6 +784,11 @@ err=-E2BIG; goto out_unlock; } + + err = security_ops->msg_queue_ops->msgrcv(msq, msg, msqid, msgflg); + if (err) + goto out_unlock; + list_del(&msg->m_list); msq->q_qnum--; msq->q_rtime = CURRENT_TIME; diff -X exclude -ur wirex/lsm/kernel/security.c lsm/lsm-new/kernel/security.c --- wirex/lsm/kernel/security.c Thu Jun 21 08:47:10 2001 +++ lsm/lsm-new/kernel/security.c Thu Jun 21 11:48:18 2001 @@ -61,7 +61,8 @@ /* capability denied */ return -EPERM; } - + +static int dummy_sysctl (ctl_table * table, int op) {return 0;} static int dummy_binprm_alloc_security(struct linux_binprm *bprm) {return 0;} static void dummy_binprm_free_security (struct linux_binprm *bprm) {return;} static void dummy_binprm_compute_creds (struct linux_binprm *bprm) {return;} @@ -123,7 +124,9 @@ static int dummy_task_setrlimit (unsigned int resource, struct rlimit *new_rlim) {return 0;} static int dummy_task_setscheduler (struct task_struct *p, int policy) {return 0;} static int dummy_task_wait (struct task_struct *p) {return 0;} + static int dummy_task_kill (struct task_struct *p, struct siginfo *info, int sig) {return 0;} + static int dummy_task_set_label (char *filename) {return 0;} static void dummy_task_reset_label (void) {return;} static void dummy_task_kmod_set_label (void) {return;} @@ -135,11 +138,16 @@ static int dummy_ipc_permission (struct kern_ipc_perm *ipcp, short flag) { return 0; } static int dummy_ipc_getinfo (int id, int cmd) {return 0;} -static int dummy_msg_queue_create (key_t key) {return 0;} -static int dummy_msg_queue_permission (void) {return 0;} -static int dummy_msg_queue_setmaxqbytes (void) {return 0;} -static int dummy_msg_queue_setattr (void) {return 0;} -static int dummy_msg_queue_delete (void) {return 0;} +static int dummy_msg_msg_alloc_security(struct msg_msg *msg) {return 0;} +static void dummy_msg_msg_free_security(struct msg_msg *msg) {return;} +static int dummy_msg_msg_test_message(struct msg_msg* msg, long type, int mode) {return 0;} + +static int dummy_msg_queue_alloc_security(struct msg_queue *msq) {return 0;} +static void dummy_msg_queue_free_security(struct msg_queue *msq) {return;} +static int dummy_msg_queue_associate(struct msg_queue *msq, int msqid, int msqflg) {return 0;} +static int dummy_msg_queue_msgctl(struct msg_queue *msq, int msqid, int cmd) {return 0;} +static int dummy_msg_queue_msgsnd(struct msg_queue *msq) {return 0;} +static int dummy_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, int msqid, int msgflg) {return 0;} static int dummy_shm_alloc_security (struct shmid_kernel *shp) {return 0;} static void dummy_shm_free_security (struct shmid_kernel *shp) {return;} @@ -246,12 +254,19 @@ getinfo: dummy_ipc_getinfo, }; +static struct msg_msg_security_ops dummy_msg_msg_ops = { + alloc_security: dummy_msg_msg_alloc_security, + free_security: dummy_msg_msg_free_security, + test_message: dummy_msg_msg_test_message, +}; + static struct msg_queue_security_ops dummy_msg_queue_ops = { - create: dummy_msg_queue_create, - permission: dummy_msg_queue_permission, - setmaxqbytes: dummy_msg_queue_setmaxqbytes, - setattr: dummy_msg_queue_setattr, - delete: dummy_msg_queue_delete, + alloc_security: dummy_msg_queue_alloc_security, + free_security: dummy_msg_queue_free_security, + associate: dummy_msg_queue_associate, + msgctl: dummy_msg_queue_msgctl, + msgsnd: dummy_msg_queue_msgsnd, + msgrcv: dummy_msg_queue_msgrcv, }; static struct shm_security_ops dummy_shm_ops = { @@ -289,6 +304,7 @@ setcapability: dummy_setcapablity, acct: dummy_acct, capable: dummy_capable, + sysctl: dummy_sysctl, bprm_ops: &dummy_binprm_ops, sb_ops: &dummy_sb_ops, @@ -298,6 +314,7 @@ socket_ops: &dummy_socket_ops, ipc_ops: &dummy_ipc_ops, module_ops: &dummy_module_ops, + msg_msg_ops: &dummy_msg_msg_ops, msg_queue_ops: &dummy_msg_queue_ops, shm_ops: &dummy_shm_ops, sem_ops: &dummy_sem_ops, diff -X exclude -ur wirex/lsm/kernel/sysctl.c lsm/lsm-new/kernel/sysctl.c --- wirex/lsm/kernel/sysctl.c Thu Jun 21 08:47:10 2001 +++ lsm/lsm-new/kernel/sysctl.c Thu Jun 21 11:39:24 2001 @@ -391,6 +391,11 @@ static inline int ctl_perm(ctl_table *table, int op) { + int error; + error = security_ops->sysctl(table, op); + if(error) { + return error; + } return test_perm(table->mode, op); } _______________________________________________ linux-security-module mailing list linux-security-moduleat_private http://mail.wirex.com/mailman/listinfo/linux-security-module
This archive was generated by hypermail 2b30 : Thu Jun 21 2001 - 12:27:50 PDT