aboutsummaryrefslogtreecommitdiffstats
path: root/ipc
diff options
context:
space:
mode:
authorStephen D. Smalley <sds@epoch.ncsc.mil>2003-01-09 20:30:59 -0800
committerLinus Torvalds <torvalds@penguin.transmeta.com>2003-01-09 20:30:59 -0800
commit3afa49eb7facd0b5d84152094200a00704c1b5cf (patch)
treed280dceec5bceb95d07032a56fe9466f9f05e634 /ipc
parent60e7fd5ede56305f4f05d24c4ae2b5491767efe6 (diff)
downloadhistory-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.c41
-rw-r--r--ipc/sem.c32
-rw-r--r--ipc/shm.c41
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++;