Skip to content

Commit

Permalink
ipc: add missing container_of()s for randstruct
Browse files Browse the repository at this point in the history
When building with the randstruct gcc plugin, the layout of the IPC
structs will be randomized, which requires any sub-structure accesses to
use container_of().  The proc display handlers were missing the needed
container_of()s since the iterator is passing in the top-level struct
kern_ipc_perm.

This would lead to crashes when running the "lsipc" program after the
system had IPC registered (e.g. after starting up Gnome):

  general protection fault: 0000 [#1] PREEMPT SMP
  ...
  RIP: 0010:shm_add_rss_swap.isra.1+0x13/0xa0
  ...
  Call Trace:
    sysvipc_shm_proc_show+0x5e/0x150
    sysvipc_proc_show+0x1a/0x30
    seq_read+0x2e9/0x3f0
  ...

Link: http://lkml.kernel.org/r/20170730205950.GA55841@beast
Fixes: 3859a27 ("randstruct: Mark various structs for randomization")
Signed-off-by: Kees Cook <[email protected]>
Reported-by: Dominik Brodowski <[email protected]>
Acked-by: Davidlohr Bueso <[email protected]>
Acked-by: Manfred Spraul <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
kees authored and torvalds committed Aug 3, 2017
1 parent 89affbf commit ade9f91
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 3 deletions.
3 changes: 2 additions & 1 deletion ipc/msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -1034,7 +1034,8 @@ void msg_exit_ns(struct ipc_namespace *ns)
static int sysvipc_msg_proc_show(struct seq_file *s, void *it)
{
struct user_namespace *user_ns = seq_user_ns(s);
struct msg_queue *msq = it;
struct kern_ipc_perm *ipcp = it;
struct msg_queue *msq = container_of(ipcp, struct msg_queue, q_perm);

seq_printf(s,
"%10d %10d %4o %10lu %10lu %5u %5u %5u %5u %5u %5u %10lu %10lu %10lu\n",
Expand Down
3 changes: 2 additions & 1 deletion ipc/sem.c
Original file line number Diff line number Diff line change
Expand Up @@ -2179,7 +2179,8 @@ void exit_sem(struct task_struct *tsk)
static int sysvipc_sem_proc_show(struct seq_file *s, void *it)
{
struct user_namespace *user_ns = seq_user_ns(s);
struct sem_array *sma = it;
struct kern_ipc_perm *ipcp = it;
struct sem_array *sma = container_of(ipcp, struct sem_array, sem_perm);
time_t sem_otime;

/*
Expand Down
4 changes: 3 additions & 1 deletion ipc/shm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1380,9 +1380,11 @@ SYSCALL_DEFINE1(shmdt, char __user *, shmaddr)
static int sysvipc_shm_proc_show(struct seq_file *s, void *it)
{
struct user_namespace *user_ns = seq_user_ns(s);
struct shmid_kernel *shp = it;
struct kern_ipc_perm *ipcp = it;
struct shmid_kernel *shp;
unsigned long rss = 0, swp = 0;

shp = container_of(ipcp, struct shmid_kernel, shm_perm);
shm_add_rss_swap(shp, &rss, &swp);

#if BITS_PER_LONG <= 32
Expand Down

0 comments on commit ade9f91

Please sign in to comment.