This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / ipc / util.c
index f74c5ee..964520e 100644 (file)
 #include <linux/security.h>
 #include <linux/rcupdate.h>
 #include <linux/workqueue.h>
+#include <linux/vs_base.h>
+
+#include <asm/unistd.h>
+
+#include <asm/unistd.h>
 
 #include "util.h"
 
@@ -103,8 +108,10 @@ int ipc_findkey(struct ipc_ids* ids, key_t key)
         */
        for (id = 0; id <= max_id; id++) {
                p = ids->entries[id].p;
-               if(p==NULL)
+               if (p==NULL)
                        continue;
+               if (!vx_check(p->xid, VX_IDENT))
+                       continue;       
                if (key == p->key)
                        return id;
        }
@@ -331,25 +338,40 @@ void* ipc_rcu_alloc(int size)
  * Since RCU callback function is called in bh,
  * we need to defer the vfree to schedule_work
  */
-static void ipc_schedule_free(void* arg)
+static void ipc_schedule_free(struct rcu_head *head)
 {
-       struct ipc_rcu_vmalloc *free = arg;
+       struct ipc_rcu_vmalloc *free =
+               container_of(head, struct ipc_rcu_vmalloc, rcu);
 
        INIT_WORK(&free->work, vfree, free);
        schedule_work(&free->work);
 }
 
+/**
+ *     ipc_immediate_free      - free ipc + rcu space
+ *
+ *     Free from the RCU callback context
+ *
+ */
+static void ipc_immediate_free(struct rcu_head *head)
+{
+       struct ipc_rcu_kmalloc *free =
+               container_of(head, struct ipc_rcu_kmalloc, rcu);
+       kfree(free);
+}
+
+
+
 void ipc_rcu_free(void* ptr, int size)
 {
        if (rcu_use_vmalloc(size)) {
                struct ipc_rcu_vmalloc *free;
                free = ptr - sizeof(*free);
-               call_rcu(&free->rcu, ipc_schedule_free, free);
+               call_rcu(&free->rcu, ipc_schedule_free);
        } else {
                struct ipc_rcu_kmalloc *free;
                free = ptr - sizeof(*free);
-               /* kfree takes a "const void *" so gcc warns.  So we cast. */
-               call_rcu(&free->rcu, (void (*)(void *))kfree, free);
+               call_rcu(&free->rcu, ipc_immediate_free);
        }
 
 }
@@ -367,6 +389,8 @@ int ipcperms (struct kern_ipc_perm *ipcp, short flag)
 {      /* flag will most probably be 0 or S_...UGO from <linux/stat.h> */
        int requested_mode, granted_mode;
 
+       if (!vx_check(ipcp->xid, VX_ADMIN|VX_IDENT)) /* maybe just VX_IDENT? */
+               return -1;
        requested_mode = (flag >> 6) | (flag >> 3) | flag;
        granted_mode = ipcp->mode;
        if (current->euid == ipcp->cuid || current->euid == ipcp->uid)
@@ -375,8 +399,11 @@ int ipcperms (struct kern_ipc_perm *ipcp, short flag)
                granted_mode >>= 3;
        /* is there some bit set in requested_mode but not in granted_mode? */
        if ((requested_mode & ~granted_mode & 0007) && 
-           !capable(CAP_IPC_OWNER))
-               return -1;
+           !capable(CAP_IPC_OWNER)) {
+               if (!can_do_mlock())  {
+                       return -1;
+               }
+       }       
 
        return security_ipc_permission(ipcp, flag);
 }
@@ -507,7 +534,8 @@ int ipc_checkid(struct ipc_ids* ids, struct kern_ipc_perm* ipcp, int uid)
        return 0;
 }
 
-#if !defined(__ia64__) && !defined(__x86_64__) && !defined(__hppa__)
+#ifdef __ARCH_WANT_IPC_PARSE_VERSION
+
 
 /**
  *     ipc_parse_version       -       IPC call version
@@ -528,4 +556,4 @@ int ipc_parse_version (int *cmd)
        }
 }
 
-#endif /* __ia64__ */
+#endif /* __ARCH_WANT_IPC_PARSE_VERSION */