[PATCH 0/2] ipc: Fix <ipc>ctl(..IPC_STAT..) bugs

From: Philippe Mikoyan
Date: Thu Nov 30 2017 - 01:23:34 EST


Hi,

Some applications that uses System V IPC mechanisms rely on data
structures that are returned by <ipc>ctl(..IPC_STAT..) system calls.

However, up to now information in these structures was not reliable,
due to following reasons:
1) Non-atomic data structures filling process, which, for obvious reasons
of not taking ipc lock, performed better - see:
commit ac0ba20ea6f2 ("ipc,msg: make msgctl_nolock lockless")
commit 16df3674efe3 ("ipc,sem: do not hold ipc lock more than necessary")
commit c97cb9ccab8c ("ipc,shm: make shmctl_nolock lockless")
2) [Refer only to shared memory] Because shm_nattch is used by kernel as
a ref_count, as a side effect it has to be increased twice in do_shmat
in order not to lose segment before mmap and shm_open.

These matters can lead, for example, to following unexpectable ipc data
structures values:
1) When there are concurrently running shmat and shmctl(... IPC_STAT ...):
{... shm_lpid = 0, shm_nattch = 1, ...}
2) If a shared memory segment was created just now and first process
attaches, another process, concurrently checking number of shmat-s via
shmctl(... IPC_STAT ...), can, at some point of time, get the following
result:
{... shm_nattch = 2, ...}

Bug reproducing code can be found here:
https://github.com/Phikimon/sysipc_break
To catch bug you have to execute and kill bug reproducing program several
times(one to five times, I guess).

In this patchset I make an attempt to fix these bugs:
1) By taking locks before filling data structure fields. Note that lock
is taken after permissions and security checks in order to increase
performance.
2) By filling certain data structure fields directly in do_shmat in order
to fill shm_nattch and other fields atomically. shm_open call is removed
from shm_mmap.

Philippe Mikoyan (2):
ipc/shm: Fix shm_nattch incorrect value
ipc: Fix ipc data structures inconsistency

ipc/msg.c | 20 +++++++++++-----
ipc/sem.c | 10 ++++++++
ipc/shm.c | 77 +++++++++++++++++++++++++++++++++-----------------------------
ipc/util.c | 5 +++-
4 files changed, 69 insertions(+), 43 deletions(-)

--
2.11.0