]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - ipc/util.c
[SCSI] sr: fix corrupt CD data after media change and delay
[linux-2.6-omap-h63xx.git] / ipc / util.c
index 7a5d5e393c4bce64df495242a3bf1437a1793f66..3339177b336cae51c0b5a8085ad9a087891bb0b2 100644 (file)
@@ -133,8 +133,8 @@ void ipc_init_ids(struct ipc_ids *ids)
        ids->seq = 0;
        {
                int seq_limit = INT_MAX/SEQ_MULTIPLIER;
-               if(seq_limit > USHRT_MAX)
-                       ids->seq_max = USHRT_MAX;
+               if (seq_limit > USHORT_MAX)
+                       ids->seq_max = USHORT_MAX;
                 else
                        ids->seq_max = seq_limit;
        }
@@ -165,13 +165,12 @@ void __init ipc_init_proc_interface(const char *path, const char *header,
        iface->ids      = ids;
        iface->show     = show;
 
-       pde = create_proc_entry(path,
-                               S_IRUGO,        /* world readable */
-                               NULL            /* parent dir */);
-       if (pde) {
-               pde->data = iface;
-               pde->proc_fops = &sysvipc_proc_fops;
-       } else {
+       pde = proc_create_data(path,
+                              S_IRUGO,        /* world readable */
+                              NULL,           /* parent dir */
+                              &sysvipc_proc_fops,
+                              iface);
+       if (!pde) {
                kfree(iface);
        }
 }
@@ -811,6 +810,70 @@ int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids,
                return ipcget_public(ns, ids, ops, params);
 }
 
+/**
+ * ipc_update_perm - update the permissions of an IPC.
+ * @in:  the permission given as input.
+ * @out: the permission of the ipc to set.
+ */
+void ipc_update_perm(struct ipc64_perm *in, struct kern_ipc_perm *out)
+{
+       out->uid = in->uid;
+       out->gid = in->gid;
+       out->mode = (out->mode & ~S_IRWXUGO)
+               | (in->mode & S_IRWXUGO);
+}
+
+/**
+ * ipcctl_pre_down - retrieve an ipc and check permissions for some IPC_XXX cmd
+ * @ids:  the table of ids where to look for the ipc
+ * @id:   the id of the ipc to retrieve
+ * @cmd:  the cmd to check
+ * @perm: the permission to set
+ * @extra_perm: one extra permission parameter used by msq
+ *
+ * This function does some common audit and permissions check for some IPC_XXX
+ * cmd and is called from semctl_down, shmctl_down and msgctl_down.
+ * It must be called without any lock held and
+ *  - retrieves the ipc with the given id in the given table.
+ *  - performs some audit and permission check, depending on the given cmd
+ *  - returns the ipc with both ipc and rw_mutex locks held in case of success
+ *    or an err-code without any lock held otherwise.
+ */
+struct kern_ipc_perm *ipcctl_pre_down(struct ipc_ids *ids, int id, int cmd,
+                                     struct ipc64_perm *perm, int extra_perm)
+{
+       struct kern_ipc_perm *ipcp;
+       int err;
+
+       down_write(&ids->rw_mutex);
+       ipcp = ipc_lock_check_down(ids, id);
+       if (IS_ERR(ipcp)) {
+               err = PTR_ERR(ipcp);
+               goto out_up;
+       }
+
+       err = audit_ipc_obj(ipcp);
+       if (err)
+               goto out_unlock;
+
+       if (cmd == IPC_SET) {
+               err = audit_ipc_set_perm(extra_perm, perm->uid,
+                                        perm->gid, perm->mode);
+               if (err)
+                       goto out_unlock;
+       }
+       if (current->euid == ipcp->cuid ||
+           current->euid == ipcp->uid || capable(CAP_SYS_ADMIN))
+               return ipcp;
+
+       err = -EPERM;
+out_unlock:
+       ipc_unlock(ipcp);
+out_up:
+       up_write(&ids->rw_mutex);
+       return ERR_PTR(err);
+}
+
 #ifdef __ARCH_WANT_IPC_PARSE_VERSION