diff options
Diffstat (limited to 'ipc/util.h')
-rw-r--r-- | ipc/util.h | 43 |
1 files changed, 39 insertions, 4 deletions
diff --git a/ipc/util.h b/ipc/util.h index 1546eda7d99e..c4b0a9865bf5 100644 --- a/ipc/util.h +++ b/ipc/util.h | |||
@@ -11,6 +11,7 @@ | |||
11 | #define _IPC_UTIL_H | 11 | #define _IPC_UTIL_H |
12 | 12 | ||
13 | #include <linux/idr.h> | 13 | #include <linux/idr.h> |
14 | #include <linux/err.h> | ||
14 | 15 | ||
15 | #define USHRT_MAX 0xffff | 16 | #define USHRT_MAX 0xffff |
16 | #define SEQ_MULTIPLIER (IPCMNI) | 17 | #define SEQ_MULTIPLIER (IPCMNI) |
@@ -103,11 +104,8 @@ void* ipc_rcu_alloc(int size); | |||
103 | void ipc_rcu_getref(void *ptr); | 104 | void ipc_rcu_getref(void *ptr); |
104 | void ipc_rcu_putref(void *ptr); | 105 | void ipc_rcu_putref(void *ptr); |
105 | 106 | ||
106 | struct kern_ipc_perm* ipc_lock(struct ipc_ids* ids, int id); | 107 | struct kern_ipc_perm *ipc_lock(struct ipc_ids *, int); |
107 | void ipc_lock_by_ptr(struct kern_ipc_perm *ipcp); | ||
108 | void ipc_unlock(struct kern_ipc_perm* perm); | ||
109 | int ipc_buildid(struct ipc_ids* ids, int id, int seq); | 108 | int ipc_buildid(struct ipc_ids* ids, int id, int seq); |
110 | int ipc_checkid(struct ipc_ids* ids, struct kern_ipc_perm* ipcp, int uid); | ||
111 | 109 | ||
112 | void kernel_to_ipc64_perm(struct kern_ipc_perm *in, struct ipc64_perm *out); | 110 | void kernel_to_ipc64_perm(struct kern_ipc_perm *in, struct ipc64_perm *out); |
113 | void ipc64_perm_to_ipc_perm(struct ipc64_perm *in, struct ipc_perm *out); | 111 | void ipc64_perm_to_ipc_perm(struct ipc64_perm *in, struct ipc_perm *out); |
@@ -127,6 +125,43 @@ extern int ipcget_new(struct ipc_namespace *, struct ipc_ids *, | |||
127 | extern int ipcget_public(struct ipc_namespace *, struct ipc_ids *, | 125 | extern int ipcget_public(struct ipc_namespace *, struct ipc_ids *, |
128 | struct ipc_ops *, struct ipc_params *); | 126 | struct ipc_ops *, struct ipc_params *); |
129 | 127 | ||
128 | static inline int ipc_checkid(struct ipc_ids *ids, struct kern_ipc_perm *ipcp, | ||
129 | int uid) | ||
130 | { | ||
131 | if (uid / SEQ_MULTIPLIER != ipcp->seq) | ||
132 | return 1; | ||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | static inline void ipc_lock_by_ptr(struct kern_ipc_perm *perm) | ||
137 | { | ||
138 | rcu_read_lock(); | ||
139 | spin_lock(&perm->lock); | ||
140 | } | ||
141 | |||
142 | static inline void ipc_unlock(struct kern_ipc_perm *perm) | ||
143 | { | ||
144 | spin_unlock(&perm->lock); | ||
145 | rcu_read_unlock(); | ||
146 | } | ||
147 | |||
148 | static inline struct kern_ipc_perm *ipc_lock_check(struct ipc_ids *ids, | ||
149 | int id) | ||
150 | { | ||
151 | struct kern_ipc_perm *out; | ||
152 | |||
153 | out = ipc_lock(ids, id); | ||
154 | if (IS_ERR(out)) | ||
155 | return out; | ||
156 | |||
157 | if (ipc_checkid(ids, out, id)) { | ||
158 | ipc_unlock(out); | ||
159 | return ERR_PTR(-EIDRM); | ||
160 | } | ||
161 | |||
162 | return out; | ||
163 | } | ||
164 | |||
130 | static inline int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids, | 165 | static inline int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids, |
131 | struct ipc_ops *ops, struct ipc_params *params) | 166 | struct ipc_ops *ops, struct ipc_params *params) |
132 | { | 167 | { |