Page MenuHomeFreeBSD

D41967.id127769.diff
No OneTemporary

D41967.id127769.diff

Index: bin/cat/cat.c
===================================================================
--- bin/cat/cat.c
+++ bin/cat/cat.c
@@ -155,7 +155,7 @@
err(EXIT_FAILURE, "unable to create Casper");
fa = fileargs_cinit(casper, argc, argv, O_RDONLY, 0,
- cap_rights_init(&rights, CAP_READ | CAP_FSTAT | CAP_FCNTL),
+ cap_rights_init(&rights, CAP_READ | CAP_FSTAT | CAP_FCNTL | CAP_SEEK),
FA_OPEN | FA_REALPATH);
if (fa == NULL)
err(EXIT_FAILURE, "unable to create fileargs");
Index: contrib/capsicum-test/copy_file_range.cc
===================================================================
--- /dev/null
+++ contrib/capsicum-test/copy_file_range.cc
@@ -0,0 +1,159 @@
+#include <sys/types.h>
+#include <fcntl.h>
+
+#include <string>
+
+#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, 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);
+}
Index: contrib/capsicum-test/makefile
===================================================================
--- contrib/capsicum-test/makefile
+++ 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)
Index: sys/kern/vfs_syscalls.c
===================================================================
--- sys/kern/vfs_syscalls.c
+++ sys/kern/vfs_syscalls.c
@@ -4899,7 +4899,8 @@
len = SSIZE_MAX;
/* Get the file structures for the file descriptors. */
- error = fget_read(td, infd, &cap_read_rights, &infp);
+ error = fget_read(td, infd,
+ (inoffp != NULL ? &cap_pread_rights : &cap_read_rights), &infp);
if (error != 0)
goto out;
if (infp->f_ops == &badfileops) {
@@ -4910,7 +4911,8 @@
error = EINVAL;
goto out;
}
- error = fget_write(td, outfd, &cap_write_rights, &outfp);
+ error = fget_write(td, outfd,
+ (outoffp != NULL ? &cap_pwrite_rights : &cap_write_rights), &outfp);
if (error != 0)
goto out;
if (outfp->f_ops == &badfileops) {

File Metadata

Mime Type
text/plain
Expires
Mon, Jan 19, 3:43 PM (7 h, 12 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27748811
Default Alt Text
D41967.id127769.diff (7 KB)

Event Timeline