Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F142329015
D41967.id127769.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D41967.id127769.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D41967: copy_file_range: fix capabilities premissions
Attached
Detach File
Event Timeline
Log In to Comment