From patchwork Wed Jul 11 16:55:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 942606 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=lists.linux.it (client-ip=2001:1418:10:5::2; helo=picard.linux.it; envelope-from=ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="kUaY/usm"; dkim-atps=neutral Received: from picard.linux.it (picard.linux.it [IPv6:2001:1418:10:5::2]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41Qlbs1BMQz9s0n for ; Thu, 12 Jul 2018 02:57:12 +1000 (AEST) Received: from picard.linux.it (localhost [IPv6:::1]) by picard.linux.it (Postfix) with ESMTP id 276423E6AF1 for ; Wed, 11 Jul 2018 18:57:10 +0200 (CEST) X-Original-To: ltp@lists.linux.it Delivered-To: ltp@picard.linux.it Received: from in-6.smtp.seeweb.it (in-6.smtp.seeweb.it [IPv6:2001:4b78:1:20::6]) by picard.linux.it (Postfix) with ESMTP id 9EA4D3E6714 for ; Wed, 11 Jul 2018 18:57:07 +0200 (CEST) Received: from mail-pl0-x244.google.com (mail-pl0-x244.google.com [IPv6:2607:f8b0:400e:c01::244]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by in-6.smtp.seeweb.it (Postfix) with ESMTPS id B2F6B140125D for ; Wed, 11 Jul 2018 18:57:06 +0200 (CEST) Received: by mail-pl0-x244.google.com with SMTP id a17-v6so3576816plm.12 for ; Wed, 11 Jul 2018 09:57:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=qevoirZAzubQVvvmBewGB4BixQxmEeZAugluSzYForw=; b=kUaY/usmX8mklR8AusFmqt0yiIY3wGd7p4LuQfZc3PaaS5yemFVhacMkaJV/LtBLz+ ngSJ0neV5BoMjri8cVCICUeS6jvgZ1INtnwv/BJWH5TzRIEY79+9gD63i+FEHoZ11Vic V7Av2pWpJRVwBmqNQMNyzYf914fpeusXgbZsFzO4EIZI+p7FNDFfGv6RSqn5IiiZmggS xBfuQYvr150hInM04raOZuVvZ+6pJlYxRB0rKEED6USxkyI2IF/Iu2tOYex9YeHgjM5K W/4m6lqPdUV1vgram5oCIU8JfOTZK0zgYXwfb2IXU51MpIKWrzT+g21l2hQiXqzC/CpP uMpw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=qevoirZAzubQVvvmBewGB4BixQxmEeZAugluSzYForw=; b=LTaZKa4TlVDcIVWHa30MnxGGduhlyn8HJXfsA8mEnV7n/Mn9Yw7vik++LG3j/HOaTg 1EtX4ZIX7wFexSLyZy+8nXytAGHI1keFLwgi59rscTuZI6lHSaOpfEcULeZzHqgHjNyM CNm0JUDAetdPyGSwdmIosmdNzVytIwOgoELNlCLvmWEBDeJtrY54edtLTgBaTtoZinpj ni/9yKgBqTYyCVi1JOW8985QL1e+tDpwjxx+W0pYfNrRTzKsAm6ggqEUUQRaGVFphV1M oNRPN1B8yBKBV5VjsRNACin++qyuYLnWfjKXy2H7DQ+ZHwFhhUNDB4qsEkq3XIkb3mzc 5o4A== X-Gm-Message-State: APt69E2RtjtPjzehyF3H4bp/nCyZfBw7X1uL1UPPnHUO3LVH5XHPI9tW lMhPZeUwzJJP/AE1wia/MTEGc2H3 X-Google-Smtp-Source: AAOMgpdYZ1GnuHruyueW9Rls/P9dO04P7bd61w3fZr/8KD5dPyBGpbXL51aDrqXT6LPiwQN9X90egQ== X-Received: by 2002:a17:902:2d24:: with SMTP id o33-v6mr29597161plb.14.1531328224953; Wed, 11 Jul 2018 09:57:04 -0700 (PDT) Received: from ebiggers-linuxstation.kir.corp.google.com ([2620:15c:17:3:dc28:5c82:b905:e8a8]) by smtp.gmail.com with ESMTPSA id 86-v6sm24452644pfh.0.2018.07.11.09.57.04 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 11 Jul 2018 09:57:04 -0700 (PDT) From: Eric Biggers To: ltp@lists.linux.it Date: Wed, 11 Jul 2018 09:55:47 -0700 Message-Id: <20180711165547.175982-1-ebiggers3@gmail.com> X-Mailer: git-send-email 2.18.0.203.gfac676dfb9-goog X-Virus-Scanned: clamav-milter 0.99.2 at in-6.smtp.seeweb.it X-Virus-Status: Clean X-Spam-Status: No, score=0.3 required=7.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM,SPF_PASS autolearn=disabled version=3.4.0 X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on in-6.smtp.seeweb.it Cc: Eric Biggers Subject: [LTP] [PATCH v3] syscalls/shmctl05: new test for IPC file use-after-free bug X-BeenThere: ltp@lists.linux.it X-Mailman-Version: 2.1.18 Precedence: list List-Id: Linux Test Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it Sender: "ltp" From: Eric Biggers Test for a bug in the System V IPC subsystem that resulted in a shared memory file being used after it was freed (or being freed). Signed-off-by: Eric Biggers --- Changed since v2: - Add tst_timer_check(CLOCK_MONOTONIC). - Use 'CFLAGS += -pthread' instead of 'LDLIBS += -lpthread'. - Add 'LDLIBS += -lrt' (for timer functions). Changed since v1: - Use "fuzzy sync" spinlocks instead of random sleeps. - Use threads with .timeout instead of processes. - Use SAFE_SHMAT() instead of shmat() directly. - Use tst_timer_expired_ms() instead of tst_timer_stop() + tst_timer_elapsed_ms(). runtest/syscalls | 1 + runtest/syscalls-ipc | 1 + .../kernel/syscalls/ipc/shmctl/.gitignore | 1 + testcases/kernel/syscalls/ipc/shmctl/Makefile | 3 + .../kernel/syscalls/ipc/shmctl/shmctl05.c | 114 ++++++++++++++++++ 5 files changed, 120 insertions(+) create mode 100644 testcases/kernel/syscalls/ipc/shmctl/shmctl05.c diff --git a/runtest/syscalls b/runtest/syscalls index a9afecf57..9eafd75d6 100644 --- a/runtest/syscalls +++ b/runtest/syscalls @@ -1187,6 +1187,7 @@ shmctl01 shmctl01 shmctl02 shmctl02 shmctl03 shmctl03 shmctl04 shmctl04 +shmctl05 shmctl05 shmdt01 shmdt01 shmdt02 shmdt02 diff --git a/runtest/syscalls-ipc b/runtest/syscalls-ipc index 00d7eed3a..54d8622d4 100644 --- a/runtest/syscalls-ipc +++ b/runtest/syscalls-ipc @@ -53,6 +53,7 @@ shmctl01 shmctl01 shmctl02 shmctl02 shmctl03 shmctl03 shmctl04 shmctl04 +shmctl05 shmctl05 shmdt01 shmdt01 shmdt02 shmdt02 diff --git a/testcases/kernel/syscalls/ipc/shmctl/.gitignore b/testcases/kernel/syscalls/ipc/shmctl/.gitignore index 9f5ac37ff..d6777e3b8 100644 --- a/testcases/kernel/syscalls/ipc/shmctl/.gitignore +++ b/testcases/kernel/syscalls/ipc/shmctl/.gitignore @@ -2,3 +2,4 @@ /shmctl02 /shmctl03 /shmctl04 +/shmctl05 diff --git a/testcases/kernel/syscalls/ipc/shmctl/Makefile b/testcases/kernel/syscalls/ipc/shmctl/Makefile index f467389b9..16da31b03 100644 --- a/testcases/kernel/syscalls/ipc/shmctl/Makefile +++ b/testcases/kernel/syscalls/ipc/shmctl/Makefile @@ -18,6 +18,9 @@ top_srcdir ?= ../../../../.. +shmctl05: CFLAGS += -pthread +shmctl05: LDLIBS += -lrt + include $(top_srcdir)/include/mk/testcases.mk include $(abs_srcdir)/../Makefile.inc include $(top_srcdir)/include/mk/generic_leaf_target.mk diff --git a/testcases/kernel/syscalls/ipc/shmctl/shmctl05.c b/testcases/kernel/syscalls/ipc/shmctl/shmctl05.c new file mode 100644 index 000000000..6fbc6b6c3 --- /dev/null +++ b/testcases/kernel/syscalls/ipc/shmctl/shmctl05.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2018 Google, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program, if not, see . + */ + +/* + * Regression test for commit 3f05317d9889 ("ipc/shm: fix use-after-free of shm + * file via remap_file_pages()"). This bug allowed the remap_file_pages() + * syscall to use the file of a System V shared memory segment after its ID had + * been reallocated and the file freed. This test reproduces the bug as a NULL + * pointer dereference in touch_atime(), although it's a race condition so it's + * not guaranteed to work. This test is based on the reproducer provided in the + * fix's commit message. + */ + +#include "lapi/syscalls.h" +#include "tst_test.h" +#include "tst_fuzzy_sync.h" +#include "tst_safe_pthread.h" +#include "tst_safe_sysv_ipc.h" +#include "tst_timer.h" + +static struct tst_fzsync_pair fzsync_pair = TST_FZSYNC_PAIR_INIT; + +static pthread_t thrd; + +/* + * Thread 2: repeatedly remove the shm ID and reallocate it again for a + * new shm segment. + */ +static void *thrproc(void *unused) +{ + int id = SAFE_SHMGET(0xF00F, 4096, IPC_CREAT|0700); + + for (;;) { + if (!tst_fzsync_wait_b(&fzsync_pair)) + break; + SAFE_SHMCTL(id, IPC_RMID, NULL); + id = SAFE_SHMGET(0xF00F, 4096, IPC_CREAT|0700); + if (!tst_fzsync_wait_b(&fzsync_pair)) + break; + } + return unused; +} + +static void setup(void) +{ + tst_timer_check(CLOCK_MONOTONIC); + + /* Skip test if either remap_file_pages() or SysV IPC is unavailable */ + tst_syscall(__NR_remap_file_pages, NULL, 0, 0, 0, 0); + tst_syscall(__NR_shmctl, 0xF00F, IPC_RMID, NULL); + + SAFE_PTHREAD_CREATE(&thrd, NULL, thrproc, NULL); +} + +static void do_test(void) +{ + tst_timer_start(CLOCK_MONOTONIC); + + /* + * Thread 1: repeatedly attach a shm segment, then remap it until the ID + * seems to have been removed by the other process. + */ + while (!tst_timer_expired_ms(5000)) { + int id; + void *addr; + + id = SAFE_SHMGET(0xF00F, 4096, IPC_CREAT|0700); + addr = SAFE_SHMAT(id, NULL, 0); + tst_fzsync_wait_a(&fzsync_pair); + do { + /* This is the system call that crashed */ + TEST(syscall(__NR_remap_file_pages, addr, 4096, + 0, 0, 0)); + } while (TEST_RETURN == 0); + + if (TEST_ERRNO != EIDRM && TEST_ERRNO != EINVAL) { + tst_brk(TBROK | TTERRNO, + "Unexpected remap_file_pages() error"); + } + tst_fzsync_wait_a(&fzsync_pair); + } + + tst_res(TPASS, "didn't crash"); +} + +static void cleanup(void) +{ + if (thrd) { + tst_fzsync_pair_exit(&fzsync_pair); + SAFE_PTHREAD_JOIN(thrd, NULL); + } + shmctl(0xF00F, IPC_RMID, NULL); +} + +static struct tst_test test = { + .timeout = 20, + .setup = setup, + .test_all = do_test, + .cleanup = cleanup, +};