aboutsummaryrefslogtreecommitdiffstats
path: root/ipc/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/util.c')
-rw-r--r--ipc/util.c16
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;