|
@@ -248,7 +248,7 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
|
|
|
* This routine is called by sys_msgget, sys_semget() and sys_shmget()
|
|
|
* when the key is IPC_PRIVATE.
|
|
|
*/
|
|
|
-int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids,
|
|
|
+static int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids,
|
|
|
struct ipc_ops *ops, struct ipc_params *params)
|
|
|
{
|
|
|
int err;
|
|
@@ -312,7 +312,7 @@ static int ipc_check_perms(struct kern_ipc_perm *ipcp, struct ipc_ops *ops,
|
|
|
*
|
|
|
* On success, the ipc id is returned.
|
|
|
*/
|
|
|
-int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids,
|
|
|
+static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids,
|
|
|
struct ipc_ops *ops, struct ipc_params *params)
|
|
|
{
|
|
|
struct kern_ipc_perm *ipcp;
|
|
@@ -710,6 +710,57 @@ struct kern_ipc_perm *ipc_lock_down(struct ipc_ids *ids, int id)
|
|
|
return out;
|
|
|
}
|
|
|
|
|
|
+struct kern_ipc_perm *ipc_lock_check_down(struct ipc_ids *ids, int id)
|
|
|
+{
|
|
|
+ struct kern_ipc_perm *out;
|
|
|
+
|
|
|
+ out = ipc_lock_down(ids, id);
|
|
|
+ if (IS_ERR(out))
|
|
|
+ return out;
|
|
|
+
|
|
|
+ if (ipc_checkid(out, id)) {
|
|
|
+ ipc_unlock(out);
|
|
|
+ return ERR_PTR(-EIDRM);
|
|
|
+ }
|
|
|
+
|
|
|
+ return out;
|
|
|
+}
|
|
|
+
|
|
|
+struct kern_ipc_perm *ipc_lock_check(struct ipc_ids *ids, int id)
|
|
|
+{
|
|
|
+ struct kern_ipc_perm *out;
|
|
|
+
|
|
|
+ out = ipc_lock(ids, id);
|
|
|
+ if (IS_ERR(out))
|
|
|
+ return out;
|
|
|
+
|
|
|
+ if (ipc_checkid(out, id)) {
|
|
|
+ ipc_unlock(out);
|
|
|
+ return ERR_PTR(-EIDRM);
|
|
|
+ }
|
|
|
+
|
|
|
+ return out;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * ipcget - Common sys_*get() code
|
|
|
+ * @ns : namsepace
|
|
|
+ * @ids : IPC identifier set
|
|
|
+ * @ops : operations to be called on ipc object creation, permission checks
|
|
|
+ * and further checks
|
|
|
+ * @params : the parameters needed by the previous operations.
|
|
|
+ *
|
|
|
+ * Common routine called by sys_msgget(), sys_semget() and sys_shmget().
|
|
|
+ */
|
|
|
+int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids,
|
|
|
+ struct ipc_ops *ops, struct ipc_params *params)
|
|
|
+{
|
|
|
+ if (params->key == IPC_PRIVATE)
|
|
|
+ return ipcget_new(ns, ids, ops, params);
|
|
|
+ else
|
|
|
+ return ipcget_public(ns, ids, ops, params);
|
|
|
+}
|
|
|
+
|
|
|
#ifdef __ARCH_WANT_IPC_PARSE_VERSION
|
|
|
|
|
|
|