X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=ipc%2Fshm.c;h=940b0c9b13aab7c33159760bba2a3a53756779dd;hb=dd8041f16b117f63f40fb844d6cdebe8b03514d2;hp=16fe2786087d003881b76df50a192cafbe8e2b1a;hpb=2e9abdd9bad485970b37cd53a82f92702054984c;p=powerpc.git diff --git a/ipc/shm.c b/ipc/shm.c index 16fe278608..940b0c9b13 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -13,9 +13,10 @@ * Shared /dev/zero support, Kanoj Sarcar * Move the mm functionality over to mm/shmem.c, Christoph Rohland * + * support for audit of ipc object properties and permission changes + * Dustin Kirkland */ -#include #include #include #include @@ -30,6 +31,7 @@ #include #include #include +#include #include @@ -90,8 +92,8 @@ static inline int shm_addid(struct shmid_kernel *shp) static inline void shm_inc (int id) { struct shmid_kernel *shp; - if(!(shp = shm_lock(id))) - BUG(); + shp = shm_lock(id); + BUG_ON(!shp); shp->shm_atim = get_seconds(); shp->shm_lprid = current->tgid; shp->shm_nattch++; @@ -109,7 +111,7 @@ static void shm_open (struct vm_area_struct *shmd) * * @shp: struct to free * - * It has to be called with shp and shm_ids.sem locked, + * It has to be called with shp and shm_ids.mutex locked, * but returns with shp unlocked and freed. */ static void shm_destroy (struct shmid_kernel *shp) @@ -139,10 +141,10 @@ static void shm_close (struct vm_area_struct *shmd) int id = file->f_dentry->d_inode->i_ino; struct shmid_kernel *shp; - down (&shm_ids.sem); + mutex_lock(&shm_ids.mutex); /* remove from the list of attaches of the shm segment */ - if(!(shp = shm_lock(id))) - BUG(); + shp = shm_lock(id); + BUG_ON(!shp); shp->shm_lprid = current->tgid; shp->shm_dtim = get_seconds(); shp->shm_nattch--; @@ -151,7 +153,7 @@ static void shm_close (struct vm_area_struct *shmd) shm_destroy (shp); else shm_unlock(shp); - up (&shm_ids.sem); + mutex_unlock(&shm_ids.mutex); } static int shm_mmap(struct file * file, struct vm_area_struct * vma) @@ -161,6 +163,8 @@ static int shm_mmap(struct file * file, struct vm_area_struct * vma) ret = shmem_mmap(file, vma); if (ret == 0) { vma->vm_ops = &shm_vm_ops; + if (!(vma->vm_flags & VM_WRITE)) + vma->vm_flags &= ~VM_MAYWRITE; shm_inc(file->f_dentry->d_inode->i_ino); } @@ -270,7 +274,7 @@ asmlinkage long sys_shmget (key_t key, size_t size, int shmflg) struct shmid_kernel *shp; int err, id = 0; - down(&shm_ids.sem); + mutex_lock(&shm_ids.mutex); if (key == IPC_PRIVATE) { err = newseg(key, shmflg, size); } else if ((id = ipc_findkey(&shm_ids, key)) == -1) { @@ -282,8 +286,7 @@ asmlinkage long sys_shmget (key_t key, size_t size, int shmflg) err = -EEXIST; } else { shp = shm_lock(id); - if(shp==NULL) - BUG(); + BUG_ON(shp==NULL); if (shp->shm_segsz < size) err = -EINVAL; else if (ipcperms(&shp->shm_perm, shmflg)) @@ -296,7 +299,7 @@ asmlinkage long sys_shmget (key_t key, size_t size, int shmflg) } shm_unlock(shp); } - up(&shm_ids.sem); + mutex_unlock(&shm_ids.mutex); return err; } @@ -467,14 +470,14 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf) return err; memset(&shm_info,0,sizeof(shm_info)); - down(&shm_ids.sem); + mutex_lock(&shm_ids.mutex); shm_info.used_ids = shm_ids.in_use; shm_get_stat (&shm_info.shm_rss, &shm_info.shm_swp); shm_info.shm_tot = shm_tot; shm_info.swap_attempts = 0; shm_info.swap_successes = 0; err = shm_ids.max_id; - up(&shm_ids.sem); + mutex_unlock(&shm_ids.mutex); if(copy_to_user (buf, &shm_info, sizeof(shm_info))) { err = -EFAULT; goto out; @@ -540,6 +543,10 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf) if(err) goto out_unlock; + err = audit_ipc_obj(&(shp->shm_perm)); + if (err) + goto out_unlock; + if (!capable(CAP_IPC_LOCK)) { err = -EPERM; if (current->euid != shp->shm_perm.uid && @@ -583,7 +590,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf) * Instead we set a destroyed flag, and then blow * the name away when the usage hits zero. */ - down(&shm_ids.sem); + mutex_lock(&shm_ids.mutex); shp = shm_lock(shmid); err = -EINVAL; if (shp == NULL) @@ -592,6 +599,10 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf) if(err) goto out_unlock_up; + err = audit_ipc_obj(&(shp->shm_perm)); + if (err) + goto out_unlock_up; + if (current->euid != shp->shm_perm.uid && current->euid != shp->shm_perm.cuid && !capable(CAP_SYS_ADMIN)) { @@ -610,7 +621,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf) shm_unlock(shp); } else shm_destroy (shp); - up(&shm_ids.sem); + mutex_unlock(&shm_ids.mutex); goto out; } @@ -620,9 +631,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf) err = -EFAULT; goto out; } - if ((err = audit_ipc_perms(0, setbuf.uid, setbuf.gid, setbuf.mode))) - return err; - down(&shm_ids.sem); + mutex_lock(&shm_ids.mutex); shp = shm_lock(shmid); err=-EINVAL; if(shp==NULL) @@ -630,6 +639,12 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf) err = shm_checkid(shp,shmid); if(err) goto out_unlock_up; + err = audit_ipc_obj(&(shp->shm_perm)); + if (err) + goto out_unlock_up; + err = audit_ipc_set_perm(0, setbuf.uid, setbuf.gid, setbuf.mode); + if (err) + goto out_unlock_up; err=-EPERM; if (current->euid != shp->shm_perm.uid && current->euid != shp->shm_perm.cuid && @@ -658,7 +673,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf) out_unlock_up: shm_unlock(shp); out_up: - up(&shm_ids.sem); + mutex_unlock(&shm_ids.mutex); goto out; out_unlock: shm_unlock(shp); @@ -682,7 +697,6 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr) int err; unsigned long flags; unsigned long prot; - unsigned long o_flags; int acc_mode; void *user_addr; @@ -709,11 +723,9 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr) if (shmflg & SHM_RDONLY) { prot = PROT_READ; - o_flags = O_RDONLY; acc_mode = S_IRUGO; } else { prot = PROT_READ | PROT_WRITE; - o_flags = O_RDWR; acc_mode = S_IRUGO | S_IWUGO; } if (shmflg & SHM_EXEC) { @@ -771,16 +783,16 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr) invalid: up_write(¤t->mm->mmap_sem); - down (&shm_ids.sem); - if(!(shp = shm_lock(shmid))) - BUG(); + mutex_lock(&shm_ids.mutex); + shp = shm_lock(shmid); + BUG_ON(!shp); shp->shm_nattch--; if(shp->shm_nattch == 0 && shp->shm_perm.mode & SHM_DEST) shm_destroy (shp); else shm_unlock(shp); - up (&shm_ids.sem); + mutex_unlock(&shm_ids.mutex); *raddr = (unsigned long) user_addr; err = 0;