diff options
author | Manfred Spraul <manfred@colorfullife.com> | 2019-05-14 15:46:33 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-14 19:52:52 -0700 |
commit | 3278a2c20cb302d27e6f6ee45a3f57361176e426 (patch) | |
tree | 94ce43abadc5a660dda63662a28c7000e92154d4 /ipc/util.h | |
parent | 5ac893b8cb10fe2a47a77780d37f9bf5b142854b (diff) | |
download | linux-stable-3278a2c20cb302d27e6f6ee45a3f57361176e426.tar.gz linux-stable-3278a2c20cb302d27e6f6ee45a3f57361176e426.tar.bz2 linux-stable-3278a2c20cb302d27e6f6ee45a3f57361176e426.zip |
ipc: conserve sequence numbers in ipcmni_extend mode
Rewrite, based on the patch from Waiman Long:
The mixing in of a sequence number into the IPC IDs is probably to avoid
ID reuse in userspace as much as possible. With ipcmni_extend mode, the
number of usable sequence numbers is greatly reduced leading to higher
chance of ID reuse.
To address this issue, we need to conserve the sequence number space as
much as possible. Right now, the sequence number is incremented for
every new ID created. In reality, we only need to increment the
sequence number when new allocated ID is not greater than the last one
allocated. It is in such case that the new ID may collide with an
existing one. This is being done irrespective of the ipcmni mode.
In order to avoid any races, the index is first allocated and then the
pointer is replaced.
Changes compared to the initial patch:
- Handle failures from idr_alloc().
- Avoid that concurrent operations can see the wrong sequence number.
(This is achieved by using idr_replace()).
- IPCMNI_SEQ_SHIFT is not a constant, thus renamed to
ipcmni_seq_shift().
- IPCMNI_SEQ_MAX is not a constant, thus renamed to ipcmni_seq_max().
Link: http://lkml.kernel.org/r/20190329204930.21620-2-longman@redhat.com
Signed-off-by: Manfred Spraul <manfred@colorfullife.com>
Signed-off-by: Waiman Long <longman@redhat.com>
Suggested-by: Matthew Wilcox <willy@infradead.org>
Acked-by: Waiman Long <longman@redhat.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Davidlohr Bueso <dbueso@suse.de>
Cc: "Eric W . Biederman" <ebiederm@xmission.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Kees Cook <keescook@chromium.org>
Cc: "Luis R. Rodriguez" <mcgrof@kernel.org>
Cc: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'ipc/util.h')
-rw-r--r-- | ipc/util.h | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/ipc/util.h b/ipc/util.h index 9746886757de..8c834ed39012 100644 --- a/ipc/util.h +++ b/ipc/util.h @@ -34,13 +34,13 @@ extern int ipc_mni; extern int ipc_mni_shift; -#define IPCMNI_SEQ_SHIFT ipc_mni_shift +#define ipcmni_seq_shift() ipc_mni_shift #define IPCMNI_IDX_MASK ((1 << ipc_mni_shift) - 1) #else /* CONFIG_SYSVIPC_SYSCTL */ #define ipc_mni IPCMNI -#define IPCMNI_SEQ_SHIFT IPCMNI_SHIFT +#define ipcmni_seq_shift() IPCMNI_SHIFT #define IPCMNI_IDX_MASK ((1 << IPCMNI_SHIFT) - 1) #endif /* CONFIG_SYSVIPC_SYSCTL */ @@ -123,8 +123,8 @@ struct pid_namespace *ipc_seq_pid_ns(struct seq_file *); #define IPC_SHM_IDS 2 #define ipcid_to_idx(id) ((id) & IPCMNI_IDX_MASK) -#define ipcid_to_seqx(id) ((id) >> IPCMNI_SEQ_SHIFT) -#define IPCID_SEQ_MAX (INT_MAX >> IPCMNI_SEQ_SHIFT) +#define ipcid_to_seqx(id) ((id) >> ipcmni_seq_shift()) +#define ipcid_seq_max() (INT_MAX >> ipcmni_seq_shift()) /* must be called with ids->rwsem acquired for writing */ int ipc_addid(struct ipc_ids *, struct kern_ipc_perm *, int); |