From nobody Thu Sep 28 14:07:39 2023 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4RxFfz4T74z4tpnW; Thu, 28 Sep 2023 14:07:39 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4RxFfz2yrXz3SNL; Thu, 28 Sep 2023 14:07:39 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1695910059; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=OeQ6v2RsRDKadogavUFqgXC+M3bXof0Jf7ktJTu5NGM=; b=CX08/VLqUxQvLnnCXxAtKFws7mvcWTQkgFHn+lE0sNLv8DDYD8ilv80Tjg0ISbS+rTK6Rt XKGZsrhp5jR1kQJQn3oo+YZhfu1ZDJUIaZ9GYxP4sCAazfxVMAqqEWJXSKbd8bhG4c259j 2UKRrcoKWaUoZufQ5KWxu3weOGk4oppakFYbxjL+4hc5JhbSWshZPPGcGUsd1LHNg+1RXP xqSoQNa5yHUwAB1ycrguEoVx+/FSf6nifTEsPQsePGT8EsITbB3xGboF2Mdy8l0ke/yGeK mcKVz/OQlvvmqSiZKSMGKrbQ5xEc2MeMt8syA4morOE2nBPEJtJKJTCY7O5ffg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1695910059; a=rsa-sha256; cv=none; b=KKs1H9/32V57+xVXUR5K1Af3/rPZMiLF7700JJ2mR00hbAyAFostyTBsJRucC1gKD53V7T x4ruJYTBvef1EUWpqgXCZ0fIH/FRqDTW/dgPMGXLWo0bXXOm57E3EqJtc3zRVtUM+T43KB KOLI1z94SUH2/n7h6jfUEv6P40YTLm/6jvJQWID23GkA3UJEKB+l0OkXf0s2au687aKRVB 3h3vEhZPyrL058nCSwGsQ2/c1mHGe2Fa+TohosQWPJSxamIyTUPcpVMB+S5H9yrbrHw07U IJgXGzRbWo1XLbqLkXMy6EgPNWYu6QIa6rM1Mm7uqWR4CRo0kSymW9yKRRnm1Q== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1695910059; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=OeQ6v2RsRDKadogavUFqgXC+M3bXof0Jf7ktJTu5NGM=; b=dyn9br5JEdFpqQMJlwGX/SVHm1s062+wyl5pJFtBsAHGtAMHP79/YH0ZcRrDayUGAOANAN rp4xLJ9rNShiJS2Jkl9NQUDOQIobutZe+2yuCDcJMEd7Ij2/g+wXimT2Gj6TYQr3dRG7EY iakyjAoIs8zxEq4JEBg2qWWHtiXpUSq5UkxwvMjn8G8qLwYQDFiQNCjoDq48xjGhIux1cP BjTAzUd3U8Gz7TfLGH5NICsVjZpsE7gwL+Jo5/YgqdUFkw+GbeDnx8aBZ5XwRLJSLpsGxx ww9VfW0pnml3VIi8BfXtcd26fhHmCr8C70aXwtJvW2Qvvm+iKLNyUhg+Bt8JSQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4RxFfz20mqz978; Thu, 28 Sep 2023 14:07:39 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 38SE7dbg039281; Thu, 28 Sep 2023 14:07:39 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 38SE7dAR039278; Thu, 28 Sep 2023 14:07:39 GMT (envelope-from git) Date: Thu, 28 Sep 2023 14:07:39 GMT Message-Id: <202309281407.38SE7dAR039278@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Mariusz Zaborski Subject: git: 62d3f57c22ee - main - capsicum: add tests for copy_file_range List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: oshogbo X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 62d3f57c22eea353dcc3c4a2f70ef72a42a8cd83 Auto-Submitted: auto-generated The branch main has been updated by oshogbo: URL: https://cgit.FreeBSD.org/src/commit/?id=62d3f57c22eea353dcc3c4a2f70ef72a42a8cd83 commit 62d3f57c22eea353dcc3c4a2f70ef72a42a8cd83 Author: Mariusz Zaborski AuthorDate: 2023-09-28 13:27:27 +0000 Commit: Mariusz Zaborski CommitDate: 2023-09-28 13:48:32 +0000 capsicum: add tests for copy_file_range Reviewed by: emaste, theraven, kib, markj (all previous version) Differential Revision: https://reviews.freebsd.org/D41967 --- contrib/capsicum-test/copy_file_range.cc | 228 +++++++++++++++++++++++++++++++ contrib/capsicum-test/makefile | 2 +- tests/sys/capsicum/Makefile | 1 + 3 files changed, 230 insertions(+), 1 deletion(-) diff --git a/contrib/capsicum-test/copy_file_range.cc b/contrib/capsicum-test/copy_file_range.cc new file mode 100644 index 000000000000..b785eb7f1e97 --- /dev/null +++ b/contrib/capsicum-test/copy_file_range.cc @@ -0,0 +1,228 @@ +#include +#include + +#include + +#include "capsicum.h" +#include "capsicum-test.h" +#include "syscalls.h" + +#define TOPDIR "cap_copy_file_range" +#define INFILE "infile" +#define OUTFILE "outfile" + +/* Test that copy_file_range() checks capabilities correctly. + * When used without offset arguments, copy_file_range() should + * require only CAP_READ on the source and CAP_WRITE on the destination + * file descriptors, respectively. + * When used with offset arguments, copy_file_range() should + * additionally require CAP_SEEK. + */ +class CopyFileRangeTest : public ::testing::Test { + public: + CopyFileRangeTest() { + int rc = mkdir(TmpFile(TOPDIR), 0755); + EXPECT_OK(rc); + if (rc < 0) { + EXPECT_EQ(EEXIST, errno); + } + wd_ = open(TmpFile(TOPDIR), O_DIRECTORY); + EXPECT_OK(wd_); + CreateFile(TmpFile(TOPDIR "/" INFILE)); + CreateFile(TmpFile(TOPDIR "/" OUTFILE)); + } + ~CopyFileRangeTest() { + close(wd_); + unlink(TmpFile(TOPDIR "/" INFILE)); + unlink(TmpFile(TOPDIR "/" OUTFILE)); + rmdir(TmpFile(TOPDIR)); + } + + private: + void CreateFile(const char *filename) { + int fd = open(filename, O_CREAT|O_RDWR, 0644); + const char *contents = "lorem ipsum dolor sit amet"; + EXPECT_OK(fd); + for (int i = 0; i < 100; i++) { + EXPECT_OK(write(fd, contents, strlen(contents))); + } + close(fd); + } + + protected: + int wd_; + + int openInFile(cap_rights_t *rights) { + int fd = openat(wd_, INFILE, O_RDONLY); + EXPECT_OK(fd); + EXPECT_OK(cap_rights_limit(fd, rights)); + return fd; + } + int openOutFile(cap_rights_t *rights) { + int fd = openat(wd_, OUTFILE, O_WRONLY); + EXPECT_OK(fd); + EXPECT_OK(cap_rights_limit(fd, rights)); + return fd; + } +}; + +TEST_F(CopyFileRangeTest, WriteReadNeg) { + cap_rights_t rights_in, rights_out; + + cap_rights_init(&rights_in, CAP_WRITE); + cap_rights_init(&rights_out, CAP_READ); + + int fd_in = openInFile(&rights_in); + int fd_out = openOutFile(&rights_out); + off_t off_in = 0, off_out = 0; + + EXPECT_NOTCAPABLE(copy_file_range(fd_in, NULL, fd_out, NULL, 8, 0)); + EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, NULL, 8, 0)); + EXPECT_NOTCAPABLE(copy_file_range(fd_in, NULL, fd_out, &off_out, 8, 0)); + EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, &off_out, 8, 0)); + off_in = 20; + off_out = 20; + EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, NULL, 8, 0)); + EXPECT_NOTCAPABLE(copy_file_range(fd_in, NULL, fd_out, &off_out, 8, 0)); + EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, &off_out, 8, 0)); + close(fd_in); + close(fd_out); +} + +TEST_F(CopyFileRangeTest, ReadReadNeg) { + cap_rights_t rights_in, rights_out; + + cap_rights_init(&rights_in, CAP_READ); + cap_rights_init(&rights_out, CAP_READ); + + int fd_in = openInFile(&rights_in); + int fd_out = openOutFile(&rights_out); + off_t off_in = 0, off_out = 0; + + EXPECT_NOTCAPABLE(copy_file_range(fd_in, NULL, fd_out, NULL, 8, 0)); + EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, NULL, 8, 0)); + EXPECT_NOTCAPABLE(copy_file_range(fd_in, NULL, fd_out, &off_out, 8, 0)); + EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, &off_out, 8, 0)); + off_in = 20; + off_out = 20; + EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, NULL, 8, 0)); + EXPECT_NOTCAPABLE(copy_file_range(fd_in, NULL, fd_out, &off_out, 8, 0)); + EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, &off_out, 8, 0)); + close(fd_in); + close(fd_out); +} + +TEST_F(CopyFileRangeTest, WriteWriteNeg) { + cap_rights_t rights_in, rights_out; + + cap_rights_init(&rights_in, CAP_WRITE); + cap_rights_init(&rights_out, CAP_WRITE); + + int fd_in = openInFile(&rights_in); + int fd_out = openOutFile(&rights_out); + off_t off_in = 0, off_out = 0; + + EXPECT_NOTCAPABLE(copy_file_range(fd_in, NULL, fd_out, NULL, 8, 0)); + EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, NULL, 8, 0)); + EXPECT_NOTCAPABLE(copy_file_range(fd_in, NULL, fd_out, &off_out, 8, 0)); + EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, &off_out, 8, 0)); + off_in = 20; + off_out = 20; + EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, NULL, 8, 0)); + EXPECT_NOTCAPABLE(copy_file_range(fd_in, NULL, fd_out, &off_out, 8, 0)); + EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, &off_out, 8, 0)); + close(fd_in); + close(fd_out); +} + +TEST_F(CopyFileRangeTest, ReadWrite) { + cap_rights_t rights_in, rights_out; + + cap_rights_init(&rights_in, CAP_READ); + cap_rights_init(&rights_out, CAP_WRITE); + + int fd_in = openInFile(&rights_in); + int fd_out = openOutFile(&rights_out); + off_t off_in = 0, off_out = 0; + + EXPECT_OK(copy_file_range(fd_in, NULL, fd_out, NULL, 8, 0)); + EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, NULL, 8, 0)); + EXPECT_NOTCAPABLE(copy_file_range(fd_in, NULL, fd_out, &off_out, 8, 0)); + EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, &off_out, 8, 0)); + off_in = 20; + off_out = 20; + EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, NULL, 8, 0)); + EXPECT_NOTCAPABLE(copy_file_range(fd_in, NULL, fd_out, &off_out, 8, 0)); + EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, &off_out, 8, 0)); + close(fd_in); + close(fd_out); +} + +TEST_F(CopyFileRangeTest, ReadSeekWrite) { + cap_rights_t rights_in, rights_out; + + cap_rights_init(&rights_in, CAP_READ, CAP_SEEK); + cap_rights_init(&rights_out, CAP_WRITE); + + int fd_in = openInFile(&rights_in); + int fd_out = openOutFile(&rights_out); + off_t off_in = 0, off_out = 0; + + EXPECT_OK(copy_file_range(fd_in, NULL, fd_out, NULL, 8, 0)); + EXPECT_OK(copy_file_range(fd_in, &off_in, fd_out, NULL, 8, 0)); + EXPECT_NOTCAPABLE(copy_file_range(fd_in, NULL, fd_out, &off_out, 8, 0)); + EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, &off_out, 8, 0)); + off_in = 20; + off_out = 20; + EXPECT_OK(copy_file_range(fd_in, &off_in, fd_out, NULL, 8, 0)); + EXPECT_NOTCAPABLE(copy_file_range(fd_in, NULL, fd_out, &off_out, 8, 0)); + EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, &off_out, 8, 0)); + close(fd_in); + close(fd_out); +} + +TEST_F(CopyFileRangeTest, ReadWriteSeek) { + cap_rights_t rights_in, rights_out; + + cap_rights_init(&rights_in, CAP_READ); + cap_rights_init(&rights_out, CAP_WRITE, CAP_SEEK); + + int fd_in = openInFile(&rights_in); + int fd_out = openOutFile(&rights_out); + off_t off_in = 0, off_out = 0; + + EXPECT_OK(copy_file_range(fd_in, NULL, fd_out, NULL, 8, 0)); + EXPECT_OK(copy_file_range(fd_in, NULL, fd_out, &off_out, 8, 0)); + EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, NULL, 8, 0)); + EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, &off_out, 8, 0)); + off_in = 20; + off_out = 20; + EXPECT_OK(copy_file_range(fd_in, NULL, fd_out, &off_out, 8, 0)); + EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, NULL, 8, 0)); + EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, &off_out, 8, 0)); + close(fd_in); + close(fd_out); +} + +TEST_F(CopyFileRangeTest, ReadSeekWriteSeek) { + cap_rights_t rights_in, rights_out; + + cap_rights_init(&rights_in, CAP_READ, CAP_SEEK); + cap_rights_init(&rights_out, CAP_WRITE, CAP_SEEK); + + int fd_in = openInFile(&rights_in); + int fd_out = openOutFile(&rights_out); + off_t off_in = 0, off_out = 0; + + EXPECT_OK(copy_file_range(fd_in, NULL, fd_out, NULL, 8, 0)); + EXPECT_OK(copy_file_range(fd_in, &off_in, fd_out, NULL, 8, 0)); + EXPECT_OK(copy_file_range(fd_in, NULL, fd_out, &off_out, 8, 0)); + EXPECT_OK(copy_file_range(fd_in, &off_in, fd_out, &off_out, 8, 0)); + off_in = 20; + off_out = 20; + EXPECT_OK(copy_file_range(fd_in, NULL, fd_out, &off_out, 8, 0)); + EXPECT_OK(copy_file_range(fd_in, &off_in, fd_out, NULL, 8, 0)); + EXPECT_OK(copy_file_range(fd_in, &off_in, fd_out, &off_out, 8, 0)); + close(fd_in); + close(fd_out); +} diff --git a/contrib/capsicum-test/makefile b/contrib/capsicum-test/makefile index ad697f160e2e..e55393bbf131 100644 --- a/contrib/capsicum-test/makefile +++ b/contrib/capsicum-test/makefile @@ -1,5 +1,5 @@ all: capsicum-test smoketest mini-me mini-me.noexec mini-me.setuid $(EXTRA_PROGS) -OBJECTS=capsicum-test-main.o capsicum-test.o capability-fd.o fexecve.o procdesc.o capmode.o fcntl.o ioctl.o openat.o sysctl.o select.o mqueue.o socket.o sctp.o capability-fd-pair.o linux.o overhead.o rename.o +OBJECTS=capsicum-test-main.o capsicum-test.o capability-fd.o copy_file_range.o fexecve.o procdesc.o capmode.o fcntl.o ioctl.o openat.o sysctl.o select.o mqueue.o socket.o sctp.o capability-fd-pair.o linux.o overhead.o rename.o GTEST_DIR=gtest-1.10.0 GTEST_INCS=-I$(GTEST_DIR)/include -I$(GTEST_DIR) diff --git a/tests/sys/capsicum/Makefile b/tests/sys/capsicum/Makefile index 542c6720521c..81cb4fa1ceee 100644 --- a/tests/sys/capsicum/Makefile +++ b/tests/sys/capsicum/Makefile @@ -19,6 +19,7 @@ SRCS.capsicum-test+= \ capsicum-test-main.cc \ capsicum-test.cc \ capability-fd.cc \ + copy_file_range.cc \ fexecve.cc \ procdesc.cc \ capmode.cc \