From patchwork Thu Feb 28 19:36:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Lawrence X-Patchwork-Id: 1049725 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=213.254.12.146; helo=picard.linux.it; envelope-from=ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="lepXm7nK"; dkim-atps=neutral Received: from picard.linux.it (picard.linux.it [213.254.12.146]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 449N9h4JT4z9s1b for ; Fri, 1 Mar 2019 06:37:25 +1100 (AEDT) Received: from picard.linux.it (localhost [IPv6:::1]) by picard.linux.it (Postfix) with ESMTP id ED4303EA939 for ; Thu, 28 Feb 2019 20:37:20 +0100 (CET) X-Original-To: ltp@lists.linux.it Delivered-To: ltp@picard.linux.it Received: from in-4.smtp.seeweb.it (in-4.smtp.seeweb.it [IPv6:2001:4b78:1:20::4]) by picard.linux.it (Postfix) with ESMTP id D234A3EA938 for ; Thu, 28 Feb 2019 20:37:18 +0100 (CET) Received: from mail-oi1-x249.google.com (mail-oi1-x249.google.com [IPv6:2607:f8b0:4864:20::249]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by in-4.smtp.seeweb.it (Postfix) with ESMTPS id 47DCD1001985 for ; Thu, 28 Feb 2019 20:37:16 +0100 (CET) Received: by mail-oi1-x249.google.com with SMTP id n62so9397374oib.10 for ; Thu, 28 Feb 2019 11:37:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:message-id:mime-version:subject:from:to:cc; bh=qQnRHDtFQXZaQiHf4o95ryk61AMdRy2+nne0K/FfLwg=; b=lepXm7nKEn40lKbIogz/x4Sjzr9C0BX73rNogs9SNaG+xFYw3N8S6G7meQmQ2Wym5c kh/+PhOvsaWWsyI6MyNhhQtea64J226zgFocduA1nH40Gv2ER4KLSjLvejWhuQ1qbkS6 HGFLNVhRTrpVJ9Wh4R1M98lYBQvaVQP/DuQBSkWJTVlj5Nc+lWB99h4wBo72OnRHCc7Y /75d+nnvXouX3aCunIkdZSxl1DGrnc9cxWOwvzQhFS0diSA+auDJ92Wk3od86JV91VYw KSHLO23O/LBEirhpmHPavUeplydDT8UksiiCBP8ko0gqUrLNTmvca2vU5+1oT5PXVamp zNVA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:message-id:mime-version:subject:from:to:cc; bh=qQnRHDtFQXZaQiHf4o95ryk61AMdRy2+nne0K/FfLwg=; b=dMRKSwLD8PdVA4dEsHPnaiiGA6U4s/OG9X+4CuA8fSFDsEmxmEkfrLXsYk7IqVOaAG dcV6ntkjsIgKbExcLYQ/Yo4iCs82lpljbVA8okr+r8iieLMtGRcjfq1UaFzmTMq4axJM 8IAnsrdMwFCxtCujKExSmCbu6+KE/QARXBBu9h7KD+5KTS4Nc6uDTWZwdQEiSBgW9Fxy sTYDKWbxQKDCol+/qjdFoHgh0wTixnw1X0yrIcfoml3mWclFFodCpICRGsIZMxrqPltE gOzN78HkLNAJ8/BcKxT3NG6aqbfBYTIJIQKqE0wvDAuLYpLvn++xJWzX9/qMjAfz5WoC cGtw== X-Gm-Message-State: AHQUAuacxGyPdO5jaK5HD24IekMjAbxVwDj9ZVI20qIDnxd6XZt0lDla b+pHLogeTTFYSKM587NXXdrVvneMuIXj0lxoMW87dMqqZm4oJZKqnrXlUzHDB0xBjO7UEgh5vW1 35RC0JwmWq/Ub6rjirVSi6RSgGQePbPzXxKvCd/GoSvWQzcGl1ldNthzfuiw/OJS/2wuy6Rbf X-Google-Smtp-Source: AHgI3IaEERvYJq9FDLQSX2Bwj1omCrFlnaKsCrkSTgSD8nn0ZUcn3ABx3YyIQfebV7J2LmlQAeEbjSYBMxLKEbvH2l8= X-Received: by 2002:aca:abd0:: with SMTP id u199mr800103oie.3.1551382636129; Thu, 28 Feb 2019 11:37:16 -0800 (PST) Date: Thu, 28 Feb 2019 11:36:45 -0800 Message-Id: <20190228193645.51244-1-paullawrence@google.com> Mime-Version: 1.0 X-Mailer: git-send-email 2.21.0.352.gf09ad66450-goog From: Paul Lawrence To: ltp@lists.linux.it, kernel-team@android.com X-Virus-Scanned: clamav-milter 0.99.2 at in-4.smtp.seeweb.it X-Virus-Status: Clean X-Spam-Status: No, score=-7.4 required=7.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU, SPF_PASS, USER_IN_DEF_DKIM_WL autolearn=disabled version=3.4.0 X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on in-4.smtp.seeweb.it Subject: [LTP] [PATCH] Add ltp pivot_root test 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: , Errors-To: ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it Sender: "ltp" pivot_root03.c is missing - it tests the claim that pivot_root fails with EBUSY if a filesystem is mounted on put_old, but this is no longer true. Signed-off-by: Paul Lawrence --- testcases/kernel/syscalls/pivot_root/Makefile | 23 +++++ .../kernel/syscalls/pivot_root/pivot_root01.c | 66 +++++++++++++ .../kernel/syscalls/pivot_root/pivot_root02.c | 78 +++++++++++++++ .../kernel/syscalls/pivot_root/pivot_root04.c | 82 ++++++++++++++++ .../kernel/syscalls/pivot_root/pivot_root05.c | 76 +++++++++++++++ .../kernel/syscalls/pivot_root/pivot_root06.c | 94 +++++++++++++++++++ 6 files changed, 419 insertions(+) create mode 100644 testcases/kernel/syscalls/pivot_root/Makefile create mode 100644 testcases/kernel/syscalls/pivot_root/pivot_root01.c create mode 100644 testcases/kernel/syscalls/pivot_root/pivot_root02.c create mode 100644 testcases/kernel/syscalls/pivot_root/pivot_root04.c create mode 100644 testcases/kernel/syscalls/pivot_root/pivot_root05.c create mode 100644 testcases/kernel/syscalls/pivot_root/pivot_root06.c diff --git a/testcases/kernel/syscalls/pivot_root/Makefile b/testcases/kernel/syscalls/pivot_root/Makefile new file mode 100644 index 000000000..a6f0e1499 --- /dev/null +++ b/testcases/kernel/syscalls/pivot_root/Makefile @@ -0,0 +1,23 @@ +# +# 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, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# + +top_srcdir ?= ../../../.. + +include $(top_srcdir)/include/mk/testcases.mk + +CFLAGS += -lcap + +include $(top_srcdir)/include/mk/generic_leaf_target.mk diff --git a/testcases/kernel/syscalls/pivot_root/pivot_root01.c b/testcases/kernel/syscalls/pivot_root/pivot_root01.c new file mode 100644 index 000000000..f0b884774 --- /dev/null +++ b/testcases/kernel/syscalls/pivot_root/pivot_root01.c @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// +// Copyright (c) 2019 Google, Inc. + +#define _GNU_SOURCE + +#include +#include +#include +#include + +#include "tst_test.h" + +#ifdef HAVE_UNSHARE + +static void run(void) +{ + const char* chroot_dir = "chroot"; + const char* new_root = "/new_root"; + const char* put_old = "/new_root/put_old"; + + int pid; + + if ((pid = SAFE_FORK()) == -1) { + tst_brk(TBROK, "Could not fork"); + } + + if (pid == 0) { + if (unshare(CLONE_NEWNS | CLONE_FS)) { + tst_res(TFAIL | TERRNO, "unshare failed"); + exit (1); + } + + SAFE_MOUNT("none", "/", NULL, MS_REC|MS_PRIVATE, NULL); + SAFE_MKDIR(chroot_dir, 0777); + SAFE_MOUNT("none", chroot_dir, "tmpfs", 0, 0); + SAFE_CHROOT(chroot_dir); + SAFE_MKDIR(new_root, 0777); + SAFE_MOUNT("none", new_root, "tmpfs", 0, 0); + SAFE_MKDIR(put_old, 0777); + + if (syscall(__NR_pivot_root, new_root, put_old) == -1) { + tst_res(TFAIL | TERRNO, "pivot_root failed"); + exit (1); + } + + tst_res(TPASS, "pivot_root succeeded"); + exit(0); + } + + tst_reap_children(); +} + +#else +static void run(void) +{ + tst_brk(TCONF, NULL, "unshare is undefined."); +} +#endif + +static struct tst_test test = { + .test_all = run, + .needs_tmpdir = 1, + .needs_root = 1, + .forks_child = 1, +}; diff --git a/testcases/kernel/syscalls/pivot_root/pivot_root02.c b/testcases/kernel/syscalls/pivot_root/pivot_root02.c new file mode 100644 index 000000000..41339c768 --- /dev/null +++ b/testcases/kernel/syscalls/pivot_root/pivot_root02.c @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// +// Copyright (c) 2019 Google, Inc. + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include + +#include "tst_test.h" + +#ifdef HAVE_UNSHARE + +static void run(void) +{ + const char* chroot_dir = "chroot"; + const char* new_root = "/new_root"; + const char* put_old = "/new_root/put_old"; + + int pid; + + if ((pid = SAFE_FORK()) == -1) + tst_brk(TBROK, "Could not fork"); + + if (pid == 0) { + if (unshare(CLONE_NEWNS | CLONE_FS)) { + tst_res(TFAIL | TERRNO, "unshare failed"); + exit (1); + } + + SAFE_MOUNT("none", "/", NULL, MS_REC|MS_PRIVATE, NULL); + SAFE_MKDIR(chroot_dir, 0777); + SAFE_MOUNT("none", chroot_dir, "tmpfs", 0, 0); + SAFE_CHROOT(chroot_dir); + SAFE_MKDIR(new_root, 0777); + + // EBUSY + // new_root or put_old are on the current root file system + // + // Comment out to trigger this error + // SAFE_MOUNT("none", new_root, "tmpfs", 0, 0); + + SAFE_MKDIR(put_old, 0777); + + if (syscall(__NR_pivot_root, new_root, put_old) == 0) { + tst_res(TFAIL, "pivot_root succeeded unexpectedly"); + exit (1); + } + + if (errno != EBUSY) { + tst_res(TFAIL | TERRNO, + "pivot_root failed with wrong errno"); + exit (1); + } + + tst_res(TPASS, "pivot_root failed with EBUSY as expected"); + exit(0); + } + + tst_reap_children(); +} + +#else +static void run(void) +{ + tst_brk(TCONF, NULL, "unshare is undefined."); +} +#endif + +static struct tst_test test = { + .test_all = run, + .needs_tmpdir = 1, + .needs_root = 1, + .forks_child = 1, +}; diff --git a/testcases/kernel/syscalls/pivot_root/pivot_root04.c b/testcases/kernel/syscalls/pivot_root/pivot_root04.c new file mode 100644 index 000000000..d2959130d --- /dev/null +++ b/testcases/kernel/syscalls/pivot_root/pivot_root04.c @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// +// Copyright (c) 2019 Google, Inc. + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include + +#include "tst_test.h" + +#ifdef HAVE_UNSHARE + +static void run(void) +{ + const char* chroot_dir = "chroot"; + const char* new_root = "/new_root"; + + // EINVAL + // put_old is not underneath new_root + // Note: if put_old and new_root are on the same fs, + // pivot_root fails with EBUSY before testing reachability + const char* put_old_fs = "/put_old_fs"; + const char* put_old = "/put_old_fs/put_old"; + + int pid; + + if ((pid = SAFE_FORK()) == -1) { + tst_brk(TBROK, "Could not fork"); + } + + if (pid == 0) { + if (unshare(CLONE_NEWNS | CLONE_FS)) { + tst_res(TFAIL | TERRNO, "unshare failed"); + exit (1); + } + + SAFE_MOUNT("none", "/", NULL, MS_REC|MS_PRIVATE, NULL); + SAFE_MKDIR(chroot_dir, 0777); + SAFE_MOUNT("none", chroot_dir, "tmpfs", 0, 0); + SAFE_CHROOT(chroot_dir); + SAFE_MKDIR(new_root, 0777); + SAFE_MOUNT("none", new_root, "tmpfs", 0, 0); + + SAFE_MKDIR(put_old_fs, 0777); + SAFE_MOUNT("none", put_old_fs, "tmpfs", 0, 0); + SAFE_MKDIR(put_old, 0777); + + if (syscall(__NR_pivot_root, new_root, put_old) == 0) { + tst_res(TFAIL, "pivot_root succeeded unexpectedly"); + exit (1); + } + + if (errno != EINVAL) { + tst_res(TFAIL | TERRNO, + "pivot_root failed with wrong errno"); + exit (1); + } + + tst_res(TPASS, "pivot_root failed with EINVAL as expected"); + exit(0); + } + + tst_reap_children(); +} + +#else +static void run(void) +{ + tst_brk(TCONF, NULL, "unshare is undefined."); +} +#endif + +static struct tst_test test = { + .test_all = run, + .needs_tmpdir = 1, + .needs_root = 1, + .forks_child = 1, +}; diff --git a/testcases/kernel/syscalls/pivot_root/pivot_root05.c b/testcases/kernel/syscalls/pivot_root/pivot_root05.c new file mode 100644 index 000000000..7f58fccfc --- /dev/null +++ b/testcases/kernel/syscalls/pivot_root/pivot_root05.c @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// +// Copyright (c) 2019 Google, Inc. + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include + +#include "tst_test.h" + +#ifdef HAVE_UNSHARE + +static void run(void) +{ + const char* chroot_dir = "chroot"; + const char* new_root = "/new_root"; + const char* put_old = "/new_root/put_old"; + + int pid; + + if ((pid = SAFE_FORK()) == -1) { + tst_brk(TBROK, "Could not fork"); + } + + if (pid == 0) { + if (unshare(CLONE_NEWNS | CLONE_FS)) { + tst_res(TFAIL | TERRNO, "unshare failed"); + exit (1); + } + + SAFE_MOUNT("none", "/", NULL, MS_REC|MS_PRIVATE, NULL); + SAFE_MKDIR(chroot_dir, 0777); + SAFE_MOUNT("none", chroot_dir, "tmpfs", 0, 0); + SAFE_CHROOT(chroot_dir); + SAFE_MKDIR(new_root, 0777); + SAFE_MOUNT("none", new_root, "tmpfs", 0, 0); + + // ENOTDIR + // new_root or put_old is not a directory + SAFE_CREAT(put_old, 0777); + + if (syscall(__NR_pivot_root, new_root, put_old) == 0) { + tst_res(TFAIL, "pivot_root succeeded unexpectedly"); + exit (1); + } + + if (errno != ENOTDIR) { + tst_res(TFAIL | TERRNO, + "pivot_root failed with wrong errno"); + exit (1); + } + + tst_res(TPASS, "pivot_root failed with EBUSY as expected"); + exit(0); + } + + tst_reap_children(); +} + +#else +static void run(void) +{ + tst_brk(TCONF, NULL, "unshare is undefined."); +} +#endif + +static struct tst_test test = { + .test_all = run, + .needs_tmpdir = 1, + .needs_root = 1, + .forks_child = 1, +}; diff --git a/testcases/kernel/syscalls/pivot_root/pivot_root06.c b/testcases/kernel/syscalls/pivot_root/pivot_root06.c new file mode 100644 index 000000000..ac3b08321 --- /dev/null +++ b/testcases/kernel/syscalls/pivot_root/pivot_root06.c @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// +// Copyright (c) 2019 Google, Inc. + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include + +#include "tst_test.h" + +#ifdef HAVE_UNSHARE + +static void run(void) +{ + const char* chroot_dir = "chroot"; + const char* new_root = "/new_root"; + const char* put_old = "/new_root/put_old"; + + int pid; + + if ((pid = SAFE_FORK()) == -1) { + tst_brk(TBROK, "Could not fork"); + } + + + if (pid == 0) { + if (unshare(CLONE_NEWNS | CLONE_FS)) { + tst_res(TFAIL | TERRNO, "unshare failed"); + exit (1); + } + + SAFE_MOUNT("none", "/", NULL, MS_REC|MS_PRIVATE, NULL); + SAFE_MKDIR(chroot_dir, 0777); + SAFE_MOUNT("none", chroot_dir, "tmpfs", 0, 0); + SAFE_CHROOT(chroot_dir); + SAFE_MKDIR(new_root, 0777); + SAFE_MOUNT("none", new_root, "tmpfs", 0, 0); + SAFE_MKDIR(put_old, 0777); + + // EPERM + // The calling process does not have the CAP_SYS_ADMIN capability. + cap_value_t cap_value[] = { CAP_SYS_ADMIN }; + cap_t cap = cap_get_proc(); + if (!cap) { + tst_res(TFAIL | TERRNO, "cap_get_proc failed"); + exit (1); + } + + if (cap_set_flag(cap, CAP_EFFECTIVE, 1, cap_value, CAP_CLEAR)) { + tst_res(TFAIL | TERRNO, "cap_set_flag failed"); + exit (1); + } + + if (cap_set_proc(cap)) { + tst_res(TFAIL | TERRNO, "cap_set_proc failed"); + exit (1); + } + + if (syscall(__NR_pivot_root, new_root, put_old) == 0) { + tst_res(TFAIL, "pivot_root succeeded unexpectedly"); + exit (1); + } + + if (errno != EPERM) { + tst_res(TFAIL | TERRNO, + "pivot_root failed with wrong errno"); + exit (1); + } + + tst_res(TPASS, "pivot_root failed with EPERM as expected"); + exit(0); + } + + tst_reap_children(); +} + +#else +static void run(void) +{ + tst_brk(TCONF, NULL, "unshare is undefined."); +} +#endif + +static struct tst_test test = { + .test_all = run, + .needs_tmpdir = 1, + .needs_root = 1, + .forks_child = 1, +};