From patchwork Tue Jul 10 04:46:49 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 941797 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="OCUC74Rl"; 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 41PqS2147vz9s2L for ; Tue, 10 Jul 2018 14:47:09 +1000 (AEST) Received: from picard.linux.it (localhost [IPv6:::1]) by picard.linux.it (Postfix) with ESMTP id E51DC3E678D for ; Tue, 10 Jul 2018 06:47:05 +0200 (CEST) X-Original-To: ltp@lists.linux.it Delivered-To: ltp@picard.linux.it Received: from in-7.smtp.seeweb.it (in-7.smtp.seeweb.it [IPv6:2001:4b78:1:20::7]) by picard.linux.it (Postfix) with ESMTP id DBCFC3E6B32 for ; Tue, 10 Jul 2018 06:47:03 +0200 (CEST) Received: from mail-pl0-x241.google.com (mail-pl0-x241.google.com [IPv6:2607:f8b0:400e:c01::241]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by in-7.smtp.seeweb.it (Postfix) with ESMTPS id 6E074200911 for ; Tue, 10 Jul 2018 06:47:01 +0200 (CEST) Received: by mail-pl0-x241.google.com with SMTP id w8-v6so7049501ply.8 for ; Mon, 09 Jul 2018 21:47:01 -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=ZGDUwYkzf6kGH35d6COy/HGy0vT+moUJA0IDkn+N4rs=; b=OCUC74RliHfIxUV6TH63vA+f2uxCsuyBgZxs8+kCiIqLo8zE5oOiT1aZ+5POSw28uc iHtFyoEfUOfOX2ml2DJIp3omIMwl7E7N4DsgkWKQUcZGf2T4XQuyJyMnvCEYZssgLbq1 beDnLbzJIvbvnY+cAeEVh1vzCriZQM+COgmHMDzkK08aAH36J5hE3RgybbaC7rYdRYdb FRmrh2Tsu4bJSeLbNb4HV2YO5c8kutf0hplVoB+oQMajQcijJQSiTxHdDSUV85aKdE4Y rrEAJLW7CgT3LIIk/VZHsZwoM8kmYf53n8lYUUq/3xwSmtxVo7SaG+dsblIcMYMkXeHc n0fQ== 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=ZGDUwYkzf6kGH35d6COy/HGy0vT+moUJA0IDkn+N4rs=; b=ImDexZc3+2idfTuicRdvqJtTcMFxpOq1kgK/AkHFD0JfJoslGJPkjgB7fTd6BDPhxe 06ChepA4Lt2/im8vW9MiTOuiU7BYD/mmp+KXzc9w2MK7LilOS/FlENRQ/RhLV8XhbKft IWb77xp4InyWaB7ivWYjoRLEjgrn0dvpa02PbSHWPMy3w6CHEVa7iv0h596BpVnBupwQ 5m6zp4Bl1q+im1t6Qm5YjzYwmHtwnjYMS15Fkrkk8o5cn/Ey/CoE8/S09K+6Cy3+F3f0 Nnks9NNBPpJybALfOKsC/7BTckBNn1ZM6WxudVwxRT6rKoaG99730zRb97uY6D4CXQpF 6UMw== X-Gm-Message-State: APt69E0JCmFmTcHNue5Au4Hz41j4ZoxMbce+LjdE0xmfzjM0rOawt4Tb zhjG1j2xL2kVWyMhIJMjD7m5rD46 X-Google-Smtp-Source: AAOMgpdmYjLttxyc4jGGMtJ23KL37J5zXrVqVekd7ZH3dJeqYps8SZ+5INvbrSCRDLeL3aT7Wa+gjA== X-Received: by 2002:a17:902:1703:: with SMTP id i3-v6mr22606651pli.263.1531198019712; Mon, 09 Jul 2018 21:46:59 -0700 (PDT) Received: from sol.localdomain (c-67-185-97-198.hsd1.wa.comcast.net. [67.185.97.198]) by smtp.gmail.com with ESMTPSA id 66-v6sm2829186pfd.71.2018.07.09.21.46.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 09 Jul 2018 21:46:58 -0700 (PDT) From: Eric Biggers To: ltp@lists.linux.it Date: Mon, 9 Jul 2018 21:46:49 -0700 Message-Id: <20180710044649.13829-1-ebiggers3@gmail.com> X-Mailer: git-send-email 2.18.0 X-Virus-Scanned: clamav-milter 0.99.2 at in-7.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-7.smtp.seeweb.it Cc: Eric Biggers Subject: [LTP] [PATCH v2] 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 v1: - Use using "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 | 2 + .../kernel/syscalls/ipc/shmctl/shmctl05.c | 112 ++++++++++++++++++ 5 files changed, 117 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..ad5ea2507 100644 --- a/testcases/kernel/syscalls/ipc/shmctl/Makefile +++ b/testcases/kernel/syscalls/ipc/shmctl/Makefile @@ -18,6 +18,8 @@ top_srcdir ?= ../../../../.. +shmctl05: LDLIBS += -lpthread + 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..ae39ee382 --- /dev/null +++ b/testcases/kernel/syscalls/ipc/shmctl/shmctl05.c @@ -0,0 +1,112 @@ +/* + * 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) +{ + /* 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, +};