This changes the struct + trailing data pattern to using a void * so that the end of sem_array is found without possibly indexing past the end which can upset some static analyzers. Mostly, this ends up avoiding a cast between different non-void types, which the future randstruct GCC plugin was warning about.
Signed-off-by: Kees Cook <[email protected]> --- ipc/sem.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/ipc/sem.c b/ipc/sem.c index 947dc2348271..f7cae2b35d62 100644 --- a/ipc/sem.c +++ b/ipc/sem.c @@ -475,6 +475,7 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params) { int id; int retval; + void *sem_alloc; struct sem_array *sma; int size; key_t key = params->key; @@ -488,11 +489,14 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params) return -ENOSPC; size = sizeof(*sma) + nsems * sizeof(struct sem); - sma = ipc_rcu_alloc(size); - if (!sma) + sem_alloc = ipc_rcu_alloc(size); + if (!sem_alloc) return -ENOMEM; - memset(sma, 0, size); + memset(sem_alloc, 0, size); + + sma = sem_alloc; + sma->sem_base = sem_alloc + sizeof(*sma); sma->sem_perm.mode = (semflg & S_IRWXUGO); sma->sem_perm.key = key; @@ -504,8 +508,6 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params) return retval; } - sma->sem_base = (struct sem *) &sma[1]; - for (i = 0; i < nsems; i++) { INIT_LIST_HEAD(&sma->sem_base[i].pending_alter); INIT_LIST_HEAD(&sma->sem_base[i].pending_const); -- 2.7.4 -- Kees Cook Pixel Security

