From patchwork Sun May 13 01:23:25 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 912489 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="doMfd/DZ"; 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 40k5f74Rcrz9s1B for ; Sun, 13 May 2018 11:22:07 +1000 (AEST) Received: from picard.linux.it (localhost [IPv6:::1]) by picard.linux.it (Postfix) with ESMTP id B3FD73E7440 for ; Sun, 13 May 2018 03:22:01 +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 [217.194.8.6]) by picard.linux.it (Postfix) with ESMTP id D56103E6744 for ; Sun, 13 May 2018 03:21:59 +0200 (CEST) Received: from mail-pf0-x243.google.com (mail-pf0-x243.google.com [IPv6:2607:f8b0:400e:c00::243]) (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 5AE7B140033A for ; Sun, 13 May 2018 03:21:58 +0200 (CEST) Received: by mail-pf0-x243.google.com with SMTP id p12-v6so4369638pff.13 for ; Sat, 12 May 2018 18:21:58 -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=MBjJUfhPIRfflWYL5/r1eTwI9UYp+8pVz99UvTevI+c=; b=doMfd/DZ1ySgaD9bea8MelMG/yRHrOYi1dJ3MvsDpf8ztl3Nl7/nYMZ9+xVRKiRRO/ hck5Q8xZjWSTI3Wlc2WN6+p/1ohlHGqwP5Nz2yR+5jxZD+lKst9FEPau5nTgK9vi6DEz lBQMLPXKaBeSPeOSNe5QVvroY360HSZ4l4RmumgkhFbQXdLNmNqxrJr3M7/6wbUNhBs4 oRlot0L2yfpZXh8G01cFix9Cz+MmhhineuzfHacZqIRx1qUir96npJCHv+7lDl9ELITI YxU8jv8UrXDyN7P/6Llvrh5WY27zIHwj4MA1MwgGyjpQo9WWYoLbgD+MalPmixwba0Cq Q2zw== 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=MBjJUfhPIRfflWYL5/r1eTwI9UYp+8pVz99UvTevI+c=; b=NS3vBwAkW12KQr+G+Frdr+YH0CugTUamEC2kysdJYHF8viCyn0ffCi7hBM9uf0aLRi OsMZIbsykJfoXJ1N8VCmmvuItzVuMGjOpmLrsjBJyG9cvURd4jVQcemUKiB7UN4nNhYq tFKFS4sATztt3++C/XYn3UAMt4zWwFbDYUIQWZXOnu/YfsXjGS3G/40ebifyQdzEoobu p+rNUoioXDYyAEspl4h1drOsqn6Akx1zBGJjKITJCk0NNVZKj0Wzf0V4OOZcUbTBwv1v w6jeWzZku4kAUpU5XHrPs+YBJ2fSXc3WokBRIX91+9OZVn9fQoabE76ELIqtfT/WTw0N mrgg== X-Gm-Message-State: ALKqPwfhNcAq4/v5u4yRohEJ2HDH9h0jif23dDGxgIvDVx9+DqB1+f4v U+rMtQgijvpG0EQXgCsE9rFtBgIh X-Google-Smtp-Source: AB8JxZqP2Q+IP2RCFU+CAr/O/tdPhg5z/ekufOjQOjyZsiKWjheLf8NGWHfUZ5NIGioY2JZXrfoILQ== X-Received: by 2002:a62:f619:: with SMTP id x25-v6mr4806016pfh.106.1526174516471; Sat, 12 May 2018 18:21:56 -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 v23-v6sm11270601pfe.166.2018.05.12.18.21.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 12 May 2018 18:21:55 -0700 (PDT) From: Eric Biggers To: ltp@lists.linux.it Date: Sat, 12 May 2018 18:23:25 -0700 Message-Id: <20180513012325.877-1-ebiggers3@gmail.com> X-Mailer: git-send-email 2.17.0 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] 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 --- runtest/syscalls | 1 + runtest/syscalls-ipc | 1 + .../kernel/syscalls/ipc/shmctl/.gitignore | 1 + .../kernel/syscalls/ipc/shmctl/shmctl05.c | 113 ++++++++++++++++++ 4 files changed, 116 insertions(+) create mode 100644 testcases/kernel/syscalls/ipc/shmctl/shmctl05.c diff --git a/runtest/syscalls b/runtest/syscalls index 97bda7e45..9d47a9336 100644 --- a/runtest/syscalls +++ b/runtest/syscalls @@ -1188,6 +1188,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 de32c6ba9..7c2c40beb 100644 --- a/runtest/syscalls-ipc +++ b/runtest/syscalls-ipc @@ -57,6 +57,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/shmctl05.c b/testcases/kernel/syscalls/ipc/shmctl/shmctl05.c new file mode 100644 index 000000000..6771b1445 --- /dev/null +++ b/testcases/kernel/syscalls/ipc/shmctl/shmctl05.c @@ -0,0 +1,113 @@ +/* + * 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 +#include + +#include "tst_test.h" +#include "tst_timer.h" +#include "tst_safe_sysv_ipc.h" +#include "lapi/syscalls.h" + +static bool timed_out(void) +{ + tst_timer_stop(); + return tst_timer_elapsed_ms() >= 5000; +} + +static void do_test(void) +{ + pid_t pid; + int status; + + /* 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); + + tst_timer_start(CLOCK_MONOTONIC); + + pid = SAFE_FORK(); + srand(getpid()); + + if (pid == 0) { + /* + * Child process: repeatedly attach a shm segment, then remap it + * until the ID seems to have been removed by the other process. + */ + do { + int id = SAFE_SHMGET(0xF00F, 4096, IPC_CREAT|0700); + void *addr = shmat(id, NULL, 0); + + if (addr == (void *)-1L) { + if (errno == EIDRM || errno == EINVAL) + continue; + tst_brk(TBROK | TERRNO, + "Unexpected shmat() error"); + } + + usleep(rand() % 50); + do { + /* This is the system call that crashed */ + TEST(syscall(__NR_remap_file_pages, addr, 4096, + 0, 0, 0)); + if (TEST_RETURN == 0) + continue; + if (TEST_ERRNO == EIDRM || TEST_ERRNO == EINVAL) + break; + tst_brk(TBROK | TTERRNO, + "Unexpected remap_file_pages() error"); + } while (!timed_out()); + } while (!timed_out()); + exit(0); + } else { + /* + * Parent process: repeatedly remove the shm ID and reallocate + * it again for a new shm segment. + */ + do { + int id = SAFE_SHMGET(0xF00F, 4096, IPC_CREAT|0700); + + usleep(rand() % 50); + SAFE_SHMCTL(id, IPC_RMID, NULL); + } while (!timed_out()); + } + + SAFE_WAIT(&status); + if (WIFEXITED(status) && WEXITSTATUS(status) == 0) + tst_res(TPASS, "no crash observed"); + else if (WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL) + tst_res(TFAIL, "kernel oops observed"); + else + tst_brk(TBROK, "Child %s", tst_strstatus(status)); + + shmctl(0xF00F, IPC_RMID, NULL); +} + +static struct tst_test test = { + .test_all = do_test, + .forks_child = 1, +};