ACK: [SRU][Trusty][PATCH 1/1] ipc/shm: Fix shmat mmap nil-page protection
Colin Ian King
colin.king at canonical.com
Thu Nov 30 17:47:53 UTC 2017
On 30/11/17 17:43, Kleber Sacilotto de Souza wrote:
> From: Davidlohr Bueso <dave at stgolabs.net>
>
> The issue is described here, with a nice testcase:
>
> https://bugzilla.kernel.org/show_bug.cgi?id=192931
>
> The problem is that shmat() calls do_mmap_pgoff() with MAP_FIXED, and
> the address rounded down to 0. For the regular mmap case, the
> protection mentioned above is that the kernel gets to generate the
> address -- arch_get_unmapped_area() will always check for MAP_FIXED and
> return that address. So by the time we do security_mmap_addr(0) things
> get funky for shmat().
>
> The testcase itself shows that while a regular user crashes, root will
> not have a problem attaching a nil-page. There are two possible fixes
> to this. The first, and which this patch does, is to simply allow root
> to crash as well -- this is also regular mmap behavior, ie when hacking
> up the testcase and adding mmap(... |MAP_FIXED). While this approach
> is the safer option, the second alternative is to ignore SHM_RND if the
> rounded address is 0, thus only having MAP_SHARED flags. This makes the
> behavior of shmat() identical to the mmap() case. The downside of this
> is obviously user visible, but does make sense in that it maintains
> semantics after the round-down wrt 0 address and mmap.
>
> Passes shm related ltp tests.
>
> Link: http://lkml.kernel.org/r/1486050195-18629-1-git-send-email-dave@stgolabs.net
> Signed-off-by: Davidlohr Bueso <dbueso at suse.de>
> Reported-by: Gareth Evans <gareth.evans at contextis.co.uk>
> Cc: Manfred Spraul <manfred at colorfullife.com>
> Cc: Michael Kerrisk <mtk.manpages at googlemail.com>
> Cc: <stable at vger.kernel.org>
> Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
> Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
>
> CVE-2017-5669
> (cherry picked from commit 95e91b831f87ac8e1f8ed50c14d709089b4e01b8)
> Signed-off-by: Kleber Sacilotto de Souza <kleber.souza at canonical.com>
> ---
> ipc/shm.c | 13 +++++++++----
> 1 file changed, 9 insertions(+), 4 deletions(-)
>
> diff --git a/ipc/shm.c b/ipc/shm.c
> index d7805acb44fd..06ea9ef7f54a 100644
> --- a/ipc/shm.c
> +++ b/ipc/shm.c
> @@ -1091,8 +1091,8 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
> * "raddr" thing points to kernel space, and there has to be a wrapper around
> * this.
> */
> -long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr,
> - unsigned long shmlba)
> +long do_shmat(int shmid, char __user *shmaddr, int shmflg,
> + ulong *raddr, unsigned long shmlba)
> {
> struct shmid_kernel *shp;
> unsigned long addr;
> @@ -1113,8 +1113,13 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr,
> goto out;
> else if ((addr = (ulong)shmaddr)) {
> if (addr & (shmlba - 1)) {
> - if (shmflg & SHM_RND)
> - addr &= ~(shmlba - 1); /* round down */
> + /*
> + * Round down to the nearest multiple of shmlba.
> + * For sane do_mmap_pgoff() parameters, avoid
> + * round downs that trigger nil-page and MAP_FIXED.
> + */
> + if ((shmflg & SHM_RND) && addr >= shmlba)
> + addr &= ~(shmlba - 1);
> else
> #ifndef __ARCH_FORCE_SHMLBA
> if (addr & ~PAGE_MASK)
>
Clean upstream cherry pick, looks sane to me.
Acked-by: Colin Ian King <colin.king at canonical.com>
More information about the kernel-team
mailing list