linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / ipc / shm.c
index 4337460..6eb2191 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
  * Shared /dev/zero support, Kanoj Sarcar <kanoj@sgi.com>
  * Move the mm functionality over to mm/shmem.c, Christoph Rohland <cr@sap.com>
  *
- * support for audit of ipc object properties and permission changes
- * Dustin Kirkland <dustin.kirkland@us.ibm.com>
  */
 
+#include <linux/config.h>
 #include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/hugetlb.h>
@@ -31,7 +30,6 @@
 #include <linux/capability.h>
 #include <linux/ptrace.h>
 #include <linux/seq_file.h>
-#include <linux/mutex.h>
 #include <linux/vs_context.h>
 #include <linux/vs_limit.h>
 
@@ -94,8 +92,8 @@ static inline int shm_addid(struct shmid_kernel *shp)
 static inline void shm_inc (int id) {
        struct shmid_kernel *shp;
 
-       shp = shm_lock(id);
-       BUG_ON(!shp);
+       if(!(shp = shm_lock(id)))
+               BUG();
        shp->shm_atim = get_seconds();
        shp->shm_lprid = current->tgid;
        shp->shm_nattch++;
@@ -113,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.mutex locked,
+ * It has to be called with shp and shm_ids.sem locked,
  * but returns with shp unlocked and freed.
  */
 static void shm_destroy (struct shmid_kernel *shp)
@@ -149,10 +147,10 @@ static void shm_close (struct vm_area_struct *shmd)
        int id = file->f_dentry->d_inode->i_ino;
        struct shmid_kernel *shp;
 
-       mutex_lock(&shm_ids.mutex);
+       down (&shm_ids.sem);
        /* remove from the list of attaches of the shm segment */
-       shp = shm_lock(id);
-       BUG_ON(!shp);
+       if(!(shp = shm_lock(id)))
+               BUG();
        shp->shm_lprid = current->tgid;
        shp->shm_dtim = get_seconds();
        shp->shm_nattch--;
@@ -161,7 +159,7 @@ static void shm_close (struct vm_area_struct *shmd)
                shm_destroy (shp);
        else
                shm_unlock(shp);
-       mutex_unlock(&shm_ids.mutex);
+       up (&shm_ids.sem);
 }
 
 static int shm_mmap(struct file * file, struct vm_area_struct * vma)
@@ -286,7 +284,7 @@ asmlinkage long sys_shmget (key_t key, size_t size, int shmflg)
        struct shmid_kernel *shp;
        int err, id = 0;
 
-       mutex_lock(&shm_ids.mutex);
+       down(&shm_ids.sem);
        if (key == IPC_PRIVATE) {
                err = newseg(key, shmflg, size);
        } else if ((id = ipc_findkey(&shm_ids, key)) == -1) {
@@ -298,7 +296,8 @@ asmlinkage long sys_shmget (key_t key, size_t size, int shmflg)
                err = -EEXIST;
        } else {
                shp = shm_lock(id);
-               BUG_ON(shp==NULL);
+               if(shp==NULL)
+                       BUG();
                if (shp->shm_segsz < size)
                        err = -EINVAL;
                else if (ipcperms(&shp->shm_perm, shmflg))
@@ -311,7 +310,7 @@ asmlinkage long sys_shmget (key_t key, size_t size, int shmflg)
                }
                shm_unlock(shp);
        }
-       mutex_unlock(&shm_ids.mutex);
+       up(&shm_ids.sem);
 
        return err;
 }
@@ -482,14 +481,14 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
                        return err;
 
                memset(&shm_info,0,sizeof(shm_info));
-               mutex_lock(&shm_ids.mutex);
+               down(&shm_ids.sem);
                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;
-               mutex_unlock(&shm_ids.mutex);
+               up(&shm_ids.sem);
                if(copy_to_user (buf, &shm_info, sizeof(shm_info))) {
                        err = -EFAULT;
                        goto out;
@@ -555,10 +554,6 @@ 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 &&
@@ -602,7 +597,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.
                 */
-               mutex_lock(&shm_ids.mutex);
+               down(&shm_ids.sem);
                shp = shm_lock(shmid);
                err = -EINVAL;
                if (shp == NULL) 
@@ -611,10 +606,6 @@ 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)) {
@@ -633,7 +624,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
                        shm_unlock(shp);
                } else
                        shm_destroy (shp);
-               mutex_unlock(&shm_ids.mutex);
+               up(&shm_ids.sem);
                goto out;
        }
 
@@ -643,7 +634,9 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
                        err = -EFAULT;
                        goto out;
                }
-               mutex_lock(&shm_ids.mutex);
+               if ((err = audit_ipc_perms(0, setbuf.uid, setbuf.gid, setbuf.mode)))
+                       return err;
+               down(&shm_ids.sem);
                shp = shm_lock(shmid);
                err=-EINVAL;
                if(shp==NULL)
@@ -651,12 +644,6 @@ 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 && 
@@ -685,7 +672,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
 out_unlock_up:
        shm_unlock(shp);
 out_up:
-       mutex_unlock(&shm_ids.mutex);
+       up(&shm_ids.sem);
        goto out;
 out_unlock:
        shm_unlock(shp);
@@ -709,6 +696,7 @@ 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;
 
@@ -735,9 +723,11 @@ 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) {
@@ -795,16 +785,16 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
 invalid:
        up_write(&current->mm->mmap_sem);
 
-       mutex_lock(&shm_ids.mutex);
-       shp = shm_lock(shmid);
-       BUG_ON(!shp);
+       down (&shm_ids.sem);
+       if(!(shp = shm_lock(shmid)))
+               BUG();
        shp->shm_nattch--;
        if(shp->shm_nattch == 0 &&
           shp->shm_perm.mode & SHM_DEST)
                shm_destroy (shp);
        else
                shm_unlock(shp);
-       mutex_unlock(&shm_ids.mutex);
+       up (&shm_ids.sem);
 
        *raddr = (unsigned long) user_addr;
        err = 0;
@@ -838,9 +828,6 @@ asmlinkage long sys_shmdt(char __user *shmaddr)
        loff_t size = 0;
        int retval = -EINVAL;
 
-       if (addr & ~PAGE_MASK)
-               return retval;
-
        down_write(&mm->mmap_sem);
 
        /*