diff options
Diffstat (limited to 'ipc/util.c')
-rw-r--r-- | ipc/util.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/ipc/util.c b/ipc/util.c index 72fd0785ac94..74e1d9c7a98a 100644 --- a/ipc/util.c +++ b/ipc/util.c | |||
@@ -122,6 +122,7 @@ void ipc_init_ids(struct ipc_ids *ids) | |||
122 | 122 | ||
123 | ids->in_use = 0; | 123 | ids->in_use = 0; |
124 | ids->seq = 0; | 124 | ids->seq = 0; |
125 | ids->next_id = -1; | ||
125 | { | 126 | { |
126 | int seq_limit = INT_MAX/SEQ_MULTIPLIER; | 127 | int seq_limit = INT_MAX/SEQ_MULTIPLIER; |
127 | if (seq_limit > USHRT_MAX) | 128 | if (seq_limit > USHRT_MAX) |
@@ -252,6 +253,7 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size) | |||
252 | kuid_t euid; | 253 | kuid_t euid; |
253 | kgid_t egid; | 254 | kgid_t egid; |
254 | int id, err; | 255 | int id, err; |
256 | int next_id = ids->next_id; | ||
255 | 257 | ||
256 | if (size > IPCMNI) | 258 | if (size > IPCMNI) |
257 | size = IPCMNI; | 259 | size = IPCMNI; |
@@ -264,7 +266,8 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size) | |||
264 | rcu_read_lock(); | 266 | rcu_read_lock(); |
265 | spin_lock(&new->lock); | 267 | spin_lock(&new->lock); |
266 | 268 | ||
267 | err = idr_get_new(&ids->ipcs_idr, new, &id); | 269 | err = idr_get_new_above(&ids->ipcs_idr, new, |
270 | (next_id < 0) ? 0 : ipcid_to_idx(next_id), &id); | ||
268 | if (err) { | 271 | if (err) { |
269 | spin_unlock(&new->lock); | 272 | spin_unlock(&new->lock); |
270 | rcu_read_unlock(); | 273 | rcu_read_unlock(); |
@@ -277,9 +280,14 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size) | |||
277 | new->cuid = new->uid = euid; | 280 | new->cuid = new->uid = euid; |
278 | new->gid = new->cgid = egid; | 281 | new->gid = new->cgid = egid; |
279 | 282 | ||
280 | new->seq = ids->seq++; | 283 | if (next_id < 0) { |
281 | if(ids->seq > ids->seq_max) | 284 | new->seq = ids->seq++; |
282 | ids->seq = 0; | 285 | if (ids->seq > ids->seq_max) |
286 | ids->seq = 0; | ||
287 | } else { | ||
288 | new->seq = ipcid_to_seqx(next_id); | ||
289 | ids->next_id = -1; | ||
290 | } | ||
283 | 291 | ||
284 | new->id = ipc_buildid(id, new->seq); | 292 | new->id = ipc_buildid(id, new->seq); |
285 | return id; | 293 | return id; |