diff options
author | Stephen D. Smalley <sds@epoch.ncsc.mil> | 2003-01-09 20:30:59 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@penguin.transmeta.com> | 2003-01-09 20:30:59 -0800 |
commit | 3afa49eb7facd0b5d84152094200a00704c1b5cf (patch) | |
tree | d280dceec5bceb95d07032a56fe9466f9f05e634 /ipc | |
parent | 60e7fd5ede56305f4f05d24c4ae2b5491767efe6 (diff) | |
download | history-3afa49eb7facd0b5d84152094200a00704c1b5cf.tar.gz |
[PATCH] 2.5.52-lsm-{dummy,ipc}.patch
This patch adds the remaining System V IPC hooks, including the inline
documentation for them in security.h. This includes a restored
sem_semop hook, as it does seem to be necessary to support fine-grained
access.
All of these System V IPC hooks are used by SELinux. The SELinux System
V IPC access controls were originally described in the technical report
available from http://www.nsa.gov/selinux/slinux-abs.html, and the
LSM-based implementation is described in the technical report available
from http://www.nsa.gov/selinux/module-abs.html.
Diffstat (limited to 'ipc')
-rw-r--r-- | ipc/msg.c | 41 | ||||
-rw-r--r-- | ipc/sem.c | 32 | ||||
-rw-r--r-- | ipc/shm.c | 41 |
3 files changed, 106 insertions, 8 deletions
diff --git a/ipc/msg.c b/ipc/msg.c index 8a7d035dfefcba..015ff8da13ae73 100644 --- a/ipc/msg.c +++ b/ipc/msg.c @@ -132,6 +132,9 @@ static int newque (key_t key, int msgflg) static void free_msg(struct msg_msg* msg) { struct msg_msgseg* seg; + + security_msg_msg_free(msg); + seg = msg->next; kfree(msg); while(seg != NULL) { @@ -157,6 +160,7 @@ static struct msg_msg* load_msg(void* src, int len) return ERR_PTR(-ENOMEM); msg->next = NULL; + msg->security = NULL; if (copy_from_user(msg+1, src, alen)) { err = -EFAULT; @@ -186,6 +190,11 @@ static struct msg_msg* load_msg(void* src, int len) len -= alen; src = ((char*)src)+alen; } + + err = security_msg_msg_alloc(msg); + if (err) + goto out_err; + return msg; out_err: @@ -308,8 +317,12 @@ asmlinkage long sys_msgget (key_t key, int msgflg) BUG(); if (ipcperms(&msq->q_perm, msgflg)) ret = -EACCES; - else - ret = msg_buildid(id, msq->q_perm.seq); + else { + int qid = msg_buildid(id, msq->q_perm.seq); + ret = security_msg_queue_associate(msq, msgflg); + if (!ret) + ret = qid; + } msg_unlock(msq); } up(&msg_ids.sem); @@ -431,6 +444,11 @@ asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds *buf) * due to padding, it's not enough * to set all member fields. */ + + err = security_msg_queue_msgctl(NULL, cmd); + if (err) + return err; + memset(&msginfo,0,sizeof(msginfo)); msginfo.msgmni = msg_ctlmni; msginfo.msgmax = msg_ctlmax; @@ -481,6 +499,10 @@ asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds *buf) if (ipcperms (&msq->q_perm, S_IRUGO)) goto out_unlock; + err = security_msg_queue_msgctl(msq, 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; @@ -523,11 +545,16 @@ asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds *buf) /* We _could_ check for CAP_CHOWN above, but we don't */ goto out_unlock_up; + err = security_msg_queue_msgctl(msq, cmd); + if (err) + goto out_unlock_up; + switch (cmd) { case IPC_SET: { if (setbuf.qbytes > msg_ctlmnb && !capable(CAP_SYS_RESOURCE)) goto out_unlock_up; + msq->q_qbytes = setbuf.qbytes; ipcp->uid = setbuf.uid; @@ -593,7 +620,8 @@ static inline int pipelined_send(struct msg_queue* msq, struct msg_msg* msg) struct msg_receiver* msr; msr = list_entry(tmp,struct msg_receiver,r_list); tmp = tmp->next; - if(testmsg(msg,msr->r_msgtype,msr->r_mode)) { + if(testmsg(msg,msr->r_msgtype,msr->r_mode) && + !security_msg_queue_msgrcv(msq, msg, msr->r_tsk, msr->r_msgtype, msr->r_mode)) { list_del(&msr->r_list); if(msr->r_maxsize < msg->m_ts) { msr->r_msg = ERR_PTR(-E2BIG); @@ -644,6 +672,10 @@ retry: if (ipcperms(&msq->q_perm, S_IWUGO)) goto out_unlock_free; + err = security_msg_queue_msgsnd(msq, msg, 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; @@ -742,7 +774,8 @@ retry: found_msg=NULL; while (tmp != &msq->q_messages) { msg = list_entry(tmp,struct msg_msg,m_list); - if(testmsg(msg,msgtyp,mode)) { + if(testmsg(msg,msgtyp,mode) && + !security_msg_queue_msgrcv(msq, msg, current, msgtyp, mode)) { found_msg = msg; if(mode == SEARCH_LESSEQUAL && msg->m_type != 1) { found_msg=msg; diff --git a/ipc/sem.c b/ipc/sem.c index c849b9375eebef..d965818ea0ee9a 100644 --- a/ipc/sem.c +++ b/ipc/sem.c @@ -188,8 +188,12 @@ asmlinkage long sys_semget (key_t key, int nsems, int semflg) err = -EINVAL; else if (ipcperms(&sma->sem_perm, semflg)) err = -EACCES; - else - err = sem_buildid(id, sma->sem_perm.seq); + else { + int semid = sem_buildid(id, sma->sem_perm.seq); + err = security_sem_associate(sma, semflg); + if (!err) + err = semid; + } sem_unlock(sma); } @@ -466,6 +470,10 @@ static int semctl_nolock(int semid, int semnum, int cmd, int version, union semu struct seminfo seminfo; int max_id; + err = security_sem_semctl(NULL, cmd); + if (err) + return err; + memset(&seminfo,0,sizeof(seminfo)); seminfo.semmni = sc_semmni; seminfo.semmns = sc_semmns; @@ -506,6 +514,11 @@ static int semctl_nolock(int semid, int semnum, int cmd, int version, union semu err = -EACCES; if (ipcperms (&sma->sem_perm, S_IRUGO)) goto out_unlock; + + err = security_sem_semctl(sma, cmd); + if (err) + goto out_unlock; + id = sem_buildid(semid, sma->sem_perm.seq); kernel_to_ipc64_perm(&sma->sem_perm, &tbuf.sem_perm); @@ -549,6 +562,11 @@ static int semctl_main(int semid, int semnum, int cmd, int version, union semun if (ipcperms (&sma->sem_perm, (cmd==SETVAL||cmd==SETALL)?S_IWUGO:S_IRUGO)) goto out_unlock; + err = security_sem_semctl(sma, cmd); + if (err) + goto out_unlock; + + err = -EACCES; switch (cmd) { case GETALL: { @@ -740,6 +758,10 @@ static int semctl_down(int semid, int semnum, int cmd, int version, union semun goto out_unlock; } + err = security_sem_semctl(sma, cmd); + if (err) + goto out_unlock; + switch(cmd){ case IPC_RMID: freeary(semid); @@ -1035,6 +1057,12 @@ asmlinkage long sys_semtimedop(int semid, struct sembuf *tsops, error = -EACCES; if (ipcperms(&sma->sem_perm, alter ? S_IWUGO : S_IRUGO)) goto out_unlock_semundo_free; + + error = security_sem_semop(sma, sops, nsops, alter); + if (error) + goto out_unlock_semundo_free; + + error = -EACCES; if (undos) { /* Make sure we have an undo structure * for this process and this semaphore set. diff --git a/ipc/shm.c b/ipc/shm.c index a959e40f6244b6..e9726493790029 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -257,8 +257,12 @@ asmlinkage long sys_shmget (key_t key, size_t size, int shmflg) err = -EINVAL; else if (ipcperms(&shp->shm_perm, shmflg)) err = -EACCES; - else - err = shm_buildid(id, shp->shm_perm.seq); + else { + int shmid = shm_buildid(id, shp->shm_perm.seq); + err = security_shm_associate(shp, shmflg); + if (!err) + err = shmid; + } shm_unlock(shp); } up(&shm_ids.sem); @@ -399,6 +403,10 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds *buf) { struct shminfo64 shminfo; + err = security_shm_shmctl(NULL, cmd); + if (err) + return err; + memset(&shminfo,0,sizeof(shminfo)); shminfo.shmmni = shminfo.shmseg = shm_ctlmni; shminfo.shmmax = shm_ctlmax; @@ -417,6 +425,10 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds *buf) { struct shm_info shm_info; + err = security_shm_shmctl(NULL, cmd); + if (err) + return err; + memset(&shm_info,0,sizeof(shm_info)); down(&shm_ids.sem); shm_info.used_ids = shm_ids.in_use; @@ -458,6 +470,9 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds *buf) err=-EACCES; if (ipcperms (&shp->shm_perm, S_IRUGO)) goto out_unlock; + err = security_shm_shmctl(shp, cmd); + if (err) + goto out_unlock; kernel_to_ipc64_perm(&shp->shm_perm, &tbuf.shm_perm); tbuf.shm_segsz = shp->shm_segsz; tbuf.shm_atime = shp->shm_atim; @@ -495,6 +510,11 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds *buf) err = shm_checkid(shp,shmid); if(err) goto out_unlock; + + err = security_shm_shmctl(shp, cmd); + if (err) + goto out_unlock; + if(cmd==SHM_LOCK) { if (!is_file_hugepages(shp->shm_file)) shmem_lock(shp->shm_file, 1); @@ -527,12 +547,18 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds *buf) err = shm_checkid(shp, shmid); if(err) goto out_unlock_up; + if (current->euid != shp->shm_perm.uid && current->euid != shp->shm_perm.cuid && !capable(CAP_SYS_ADMIN)) { err=-EPERM; goto out_unlock_up; } + + err = security_shm_shmctl(shp, cmd); + if (err) + goto out_unlock_up; + if (shp->shm_nattch){ shp->shm_flags |= SHM_DEST; /* Do not find it any more */ @@ -565,6 +591,10 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds *buf) goto out_unlock_up; } + err = security_shm_shmctl(shp, cmd); + if (err) + goto out_unlock_up; + shp->shm_perm.uid = setbuf.uid; shp->shm_perm.gid = setbuf.gid; shp->shm_flags = (shp->shm_flags & ~S_IRWXUGO) @@ -653,6 +683,13 @@ asmlinkage long sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr) err = -EACCES; goto out; } + + err = security_shm_shmat(shp, shmaddr, shmflg); + if (err) { + shm_unlock(shp); + return err; + } + file = shp->shm_file; size = file->f_dentry->d_inode->i_size; shp->shm_nattch++; |