Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 01 Apr 2019 18:16:51 +0200
From:      "Kristof Provost" <kp@FreeBSD.org>
To:        rgrimes@freebsd.org
Cc:        "Andrey V. Elsukov" <bu7cher@yandex.ru>, "Mateusz Guzik" <mjguzik@gmail.com>, src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   Re: svn commit: r345760 - in head: contrib/pf sys/netpfil/pf sbin/pfctl
Message-ID:  <FA6F7C1D-7B2D-4B74-A6E9-8C1112DAEEAD@FreeBSD.org>
In-Reply-To: <201904011348.x31Dm86D015297@gndrsh.dnsmgr.net>
References:  <201904011348.x31Dm86D015297@gndrsh.dnsmgr.net>

next in thread | previous in thread | raw e-mail | index | archive | help
On 1 Apr 2019, at 15:48, Rodney W. Grimes wrote:
> [ Charset UTF-8 unsupported, converting... ]
>> On 01.04.2019 16:30, Rodney W. Grimes wrote:
>> It seems it is too late:
>> 	https://marc.info/?l=openbsd-tech&m=155409489427092&w=2
>
> I am wondering on the above as it has a date of:
> Date:       2019-04-01 5:01:03
>
> which would be in line with Kristof's joke.
>
Yes, OpenBSD are clearly joking as well.

>> 	http://mail-index.netbsd.org/tech-kern/2019/03/29/msg024883.html
> This is inline with what is being proposed here, NetBSD has
> old rotted code that needs updated.

[Disclaimer: I do not speak for NetBSD, and based this on my reading of 
that thread]

NetBSD however are serious.
Their situation is slightly different, in that their primary reason is 
that they don’t have a maintainer for their pf version and it’s 
suffering from significant bitrot.

Our situation is somewhat better. Our pf is maintained and does get bug 
fixes and improvements. Not as many as I’d like, but there’s 
something.

> Rather than do that work
> twice, do it 1.5 times (implementing the same technology in
> 2 OS's should be less work than doing it twice.)
>
> I believe there is grant money avaliable from a non Foundation
> source that could be used to do this work.
>
I’m not at all opposed to updating our pf, but there are a few 
obstacles (technical: performance, syntax and vimage. Practical: this is 
a lot of work). If people are interested in that discussion I’d 
propose someone start a new thread on freebsd-pf@, and I’ll expand on 
what I think the problems are and what needs to be done.

I’d also be interested in knowing what people are looking for from an 
updated pf in FreeBSD. What are the improvements in OpenBSD that you’d 
really like to see in FreeBSD?

Regards,
Kristof
From owner-svn-src-projects@freebsd.org  Mon Apr  1 16:36:05 2019
Return-Path: <owner-svn-src-projects@freebsd.org>
Delivered-To: svn-src-projects@mailman.ysv.freebsd.org
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1])
 by mailman.ysv.freebsd.org (Postfix) with ESMTP id 889831568DEC
 for <svn-src-projects@mailman.ysv.freebsd.org>;
 Mon,  1 Apr 2019 16:36:05 +0000 (UTC)
 (envelope-from asomers@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)
 server-signature RSA-PSS (4096 bits)
 client-signature RSA-PSS (4096 bits) client-digest SHA256)
 (Client CN "mxrelay.nyi.freebsd.org",
 Issuer "Let's Encrypt Authority X3" (verified OK))
 by mx1.freebsd.org (Postfix) with ESMTPS id 2BCF076A93;
 Mon,  1 Apr 2019 16:36:05 +0000 (UTC)
 (envelope-from asomers@FreeBSD.org)
Received: from repo.freebsd.org (repo.freebsd.org
 [IPv6:2610:1c1:1:6068::e6a:0])
 (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
 (Client did not present a certificate)
 by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 09AF8190FC;
 Mon,  1 Apr 2019 16:36:05 +0000 (UTC)
 (envelope-from asomers@FreeBSD.org)
Received: from repo.freebsd.org ([127.0.1.37])
 by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x31Ga4cD014758;
 Mon, 1 Apr 2019 16:36:04 GMT (envelope-from asomers@FreeBSD.org)
Received: (from asomers@localhost)
 by repo.freebsd.org (8.15.2/8.15.2/Submit) id x31Ga3Rv014748;
 Mon, 1 Apr 2019 16:36:03 GMT (envelope-from asomers@FreeBSD.org)
Message-Id: <201904011636.x31Ga3Rv014748@repo.freebsd.org>
X-Authentication-Warning: repo.freebsd.org: asomers set sender to
 asomers@FreeBSD.org using -f
From: Alan Somers <asomers@FreeBSD.org>
Date: Mon, 1 Apr 2019 16:36:03 +0000 (UTC)
To: src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject: svn commit: r345768 - in projects/fuse2: sys/fs/fuse
 tests/sys/fs/fusefs
X-SVN-Group: projects
X-SVN-Commit-Author: asomers
X-SVN-Commit-Paths: in projects/fuse2: sys/fs/fuse tests/sys/fs/fusefs
X-SVN-Commit-Revision: 345768
X-SVN-Commit-Repository: base
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
X-Rspamd-Queue-Id: 2BCF076A93
X-Spamd-Bar: --
Authentication-Results: mx1.freebsd.org
X-Spamd-Result: default: False [-2.97 / 15.00];
 local_wl_from(0.00)[FreeBSD.org];
 NEURAL_HAM_MEDIUM(-1.00)[-0.999,0];
 NEURAL_HAM_SHORT(-0.97)[-0.975,0];
 NEURAL_HAM_LONG(-1.00)[-1.000,0];
 ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US]
X-BeenThere: svn-src-projects@freebsd.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: "SVN commit messages for the src &quot; projects&quot;
 tree" <svn-src-projects.freebsd.org>
List-Unsubscribe: <https://lists.freebsd.org/mailman/options/svn-src-projects>, 
 <mailto:svn-src-projects-request@freebsd.org?subject=unsubscribe>
List-Archive: <http://lists.freebsd.org/pipermail/svn-src-projects/>;
List-Post: <mailto:svn-src-projects@freebsd.org>
List-Help: <mailto:svn-src-projects-request@freebsd.org?subject=help>
List-Subscribe: <https://lists.freebsd.org/mailman/listinfo/svn-src-projects>, 
 <mailto:svn-src-projects-request@freebsd.org?subject=subscribe>
X-List-Received-Date: Mon, 01 Apr 2019 16:36:05 -0000

Author: asomers
Date: Mon Apr  1 16:36:02 2019
New Revision: 345768
URL: https://svnweb.freebsd.org/changeset/base/345768

Log:
  fusefs: allow opening files O_EXEC
  
  O_EXEC is useful for fexecve(2) and fchdir(2).  Treat it as another fufh
  type alongside the existing RDONLY, WRONLY, and RDWR.  Prior to r345742 this
  would've caused a memory and performance penalty.
  
  PR:		236329
  Sponsored by:	The FreeBSD Foundation

Modified:
  projects/fuse2/sys/fs/fuse/fuse_file.c
  projects/fuse2/sys/fs/fuse/fuse_file.h
  projects/fuse2/sys/fs/fuse/fuse_vnops.c
  projects/fuse2/tests/sys/fs/fusefs/mockfs.cc
  projects/fuse2/tests/sys/fs/fusefs/open.cc
  projects/fuse2/tests/sys/fs/fusefs/opendir.cc
  projects/fuse2/tests/sys/fs/fusefs/readdir.cc
  projects/fuse2/tests/sys/fs/fusefs/releasedir.cc
  projects/fuse2/tests/sys/fs/fusefs/utils.cc

Modified: projects/fuse2/sys/fs/fuse/fuse_file.c
==============================================================================
--- projects/fuse2/sys/fs/fuse/fuse_file.c	Mon Apr  1 16:15:29 2019	(r345767)
+++ projects/fuse2/sys/fs/fuse/fuse_file.c	Mon Apr  1 16:36:02 2019	(r345768)
@@ -121,12 +121,8 @@ fuse_filehandle_open(struct vnode *vp, fufh_type_t fuf
 
 	if (vnode_isdir(vp)) {
 		op = FUSE_OPENDIR;
-		if (fufh_type != FUFH_RDONLY) {
-			SDT_PROBE2(fuse, , file, trace, 1,
-				"non-rdonly fh requested for a directory?");
-			printf("FUSE:non-rdonly fh requested for a directory?\n");
-			fufh_type = FUFH_RDONLY;
-		}
+		/* vn_open_vnode already rejects FWRITE on directories */
+		MPASS(fufh_type == FUFH_RDONLY || fufh_type == FUFH_EXEC);
 	}
 	fdisp_init(&fdi, sizeof(*foi));
 	fdisp_make_vp(&fdi, op, vp, td, cred);

Modified: projects/fuse2/sys/fs/fuse/fuse_file.h
==============================================================================
--- projects/fuse2/sys/fs/fuse/fuse_file.h	Mon Apr  1 16:15:29 2019	(r345767)
+++ projects/fuse2/sys/fs/fuse/fuse_file.h	Mon Apr  1 16:36:02 2019	(r345768)
@@ -72,14 +72,11 @@
  */
 typedef enum fufh_type {
 	FUFH_INVALID = -1,
-	FUFH_RDONLY  = 0,
-	FUFH_WRONLY  = 1,
-	FUFH_RDWR    = 2,
-	/* TODO: add FUFH_EXEC */
+	FUFH_RDONLY  = O_RDONLY,
+	FUFH_WRONLY  = O_WRONLY,
+	FUFH_RDWR    = O_RDWR,
+	FUFH_EXEC    = O_EXEC,
 } fufh_type_t;
-_Static_assert(FUFH_RDONLY == O_RDONLY, "RDONLY");
-_Static_assert(FUFH_WRONLY == O_WRONLY, "WRONLY");
-_Static_assert(FUFH_RDWR == O_RDWR, "RDWR");
 
 struct fuse_filehandle {
 	LIST_ENTRY(fuse_filehandle) next;
@@ -110,6 +107,8 @@ fuse_filehandle_xlate_from_fflags(int fflags)
 		return FUFH_WRONLY;
 	else if (fflags & (FREAD))
 		return FUFH_RDONLY;
+	else if (fflags & (FEXEC))
+		return FUFH_EXEC;
 	else
 		panic("FUSE: What kind of a flag is this (%x)?", fflags);
 }
@@ -123,6 +122,7 @@ fuse_filehandle_xlate_to_oflags(fufh_type_t type)
 	case FUFH_RDONLY:
 	case FUFH_WRONLY:
 	case FUFH_RDWR:
+	case FUFH_EXEC:
 		oflags = type;
 		break;
 	default:

Modified: projects/fuse2/sys/fs/fuse/fuse_vnops.c
==============================================================================
--- projects/fuse2/sys/fs/fuse/fuse_vnops.c	Mon Apr  1 16:15:29 2019	(r345767)
+++ projects/fuse2/sys/fs/fuse/fuse_vnops.c	Mon Apr  1 16:36:02 2019	(r345768)
@@ -285,7 +285,8 @@ fuse_vnop_close(struct vop_close_args *ap)
 	if (vnode_isdir(vp)) {
 		struct fuse_filehandle *fufh;
 
-		if (fuse_filehandle_get(vp, O_RDONLY, &fufh) == 0)
+		if ((fuse_filehandle_get(vp, O_RDONLY, &fufh) == 0) ||
+		    (fuse_filehandle_get(vp, O_EXEC, &fufh) == 0))
 			fuse_filehandle_close(vp, fufh, NULL, cred);
 		return 0;
 	}
@@ -1201,16 +1202,12 @@ fuse_vnop_open(struct vop_open_args *ap)
 		return ENXIO;
 	if (vp->v_type == VCHR || vp->v_type == VBLK || vp->v_type == VFIFO)
 		return (EOPNOTSUPP);
-	if ((mode & (FREAD | FWRITE)) == 0)
+	if ((mode & (FREAD | FWRITE | FEXEC)) == 0)
 		return EINVAL;
 
 	fvdat = VTOFUD(vp);
 
-	if (vnode_isdir(vp)) {
-		fufh_type = FUFH_RDONLY;
-	} else {
-		fufh_type = fuse_filehandle_xlate_from_fflags(mode);
-	}
+	fufh_type = fuse_filehandle_xlate_from_fflags(mode);
 
 	if (fuse_filehandle_validrw(vp, fufh_type) != FUFH_INVALID) {
 		fuse_vnode_open(vp, 0, td);
@@ -1303,7 +1300,7 @@ fuse_vnop_readdir(struct vop_readdir_args *ap)
 		return EINVAL;
 	}
 
-	if ((err = fuse_filehandle_get(vp, O_RDONLY, &fufh)) != 0) {
+	if ((err = fuse_filehandle_get(vp, FUFH_RDONLY, &fufh)) != 0) {
 		SDT_PROBE2(fuse, , vnops, trace, 1,
 			"calling readdir() before open()");
 		err = fuse_filehandle_open(vp, O_RDONLY, &fufh, NULL, cred);

Modified: projects/fuse2/tests/sys/fs/fusefs/mockfs.cc
==============================================================================
--- projects/fuse2/tests/sys/fs/fusefs/mockfs.cc	Mon Apr  1 16:15:29 2019	(r345767)
+++ projects/fuse2/tests/sys/fs/fusefs/mockfs.cc	Mon Apr  1 16:36:02 2019	(r345768)
@@ -200,7 +200,8 @@ void debug_fuseop(const mockfs_buf_in *in)
 				in->body.read.size);
 			break;
 		case FUSE_READDIR:
-			printf(" offset=%lu size=%u", in->body.readdir.offset,
+			printf(" fh=%#lx offset=%lu size=%u",
+				in->body.readdir.fh, in->body.readdir.offset,
 				in->body.readdir.size);
 			break;
 		case FUSE_RELEASE:

Modified: projects/fuse2/tests/sys/fs/fusefs/open.cc
==============================================================================
--- projects/fuse2/tests/sys/fs/fusefs/open.cc	Mon Apr  1 16:15:29 2019	(r345767)
+++ projects/fuse2/tests/sys/fs/fusefs/open.cc	Mon Apr  1 16:36:02 2019	(r345768)
@@ -250,8 +250,7 @@ TEST_F(Open, o_excl)
 	test_ok(O_WRONLY | O_EXCL, O_WRONLY);
 }
 
-/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236329 */
-TEST_F(Open, DISABLED_o_exec)
+TEST_F(Open, o_exec)
 {
 	test_ok(O_EXEC, O_EXEC);
 }

Modified: projects/fuse2/tests/sys/fs/fusefs/opendir.cc
==============================================================================
--- projects/fuse2/tests/sys/fs/fusefs/opendir.cc	Mon Apr  1 16:15:29 2019	(r345767)
+++ projects/fuse2/tests/sys/fs/fusefs/opendir.cc	Mon Apr  1 16:36:02 2019	(r345768)
@@ -44,6 +44,29 @@ void expect_lookup(const char *relpath, uint64_t ino)
 {
 	FuseTest::expect_lookup(relpath, ino, S_IFDIR | 0755, 0, 1);
 }
+
+void expect_opendir(uint64_t ino, uint32_t flags, ProcessMockerT r)
+{
+	/* opendir(3) calls fstatfs */
+	EXPECT_CALL(*m_mock, process(
+		ResultOf([](auto in) {
+			return (in->header.opcode == FUSE_STATFS);
+		}, Eq(true)),
+		_)
+	).WillRepeatedly(Invoke(ReturnImmediate([=](auto i __unused, auto out) {
+		SET_OUT_HEADER_LEN(out, statfs);
+	})));
+
+	EXPECT_CALL(*m_mock, process(
+		ResultOf([=](auto in) {
+			return (in->header.opcode == FUSE_OPENDIR &&
+				in->header.nodeid == ino &&
+				in->body.opendir.flags == flags);
+		}, Eq(true)),
+		_)
+	).WillOnce(Invoke(r));
+}
+
 };
 
 
@@ -59,14 +82,8 @@ TEST_F(Opendir, enoent)
 	uint64_t ino = 42;
 
 	expect_lookup(RELPATH, ino);
+	expect_opendir(ino, O_RDONLY, ReturnErrno(ENOENT));
 
-	EXPECT_CALL(*m_mock, process(
-		ResultOf([=](auto in) {
-			return (in->header.opcode == FUSE_OPENDIR &&
-				in->header.nodeid == ino);
-		}, Eq(true)),
-		_)
-	).WillOnce(Invoke(ReturnErrno(ENOENT)));
 	EXPECT_NE(0, open(FULLPATH, O_DIRECTORY));
 	EXPECT_EQ(ENOENT, errno);
 }
@@ -82,15 +99,8 @@ TEST_F(Opendir, eperm)
 	uint64_t ino = 42;
 
 	expect_lookup(RELPATH, ino);
+	expect_opendir(ino, O_RDONLY, ReturnErrno(EPERM));
 
-	EXPECT_CALL(*m_mock, process(
-		ResultOf([=](auto in) {
-			return (in->header.opcode == FUSE_OPENDIR &&
-				in->header.nodeid == ino);
-		}, Eq(true)),
-		_)
-	).WillOnce(Invoke(ReturnErrno(EPERM)));
-
 	EXPECT_NE(0, open(FULLPATH, O_DIRECTORY));
 	EXPECT_EQ(EPERM, errno);
 }
@@ -102,45 +112,43 @@ TEST_F(Opendir, open)
 	uint64_t ino = 42;
 
 	expect_lookup(RELPATH, ino);
-
-	EXPECT_CALL(*m_mock, process(
-		ResultOf([=](auto in) {
-			return (in->header.opcode == FUSE_OPENDIR &&
-				in->header.nodeid == ino);
-		}, Eq(true)),
-		_)
-	).WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto out) {
+	expect_opendir(ino, O_RDONLY,
+	ReturnImmediate([=](auto in __unused, auto out) {
 		SET_OUT_HEADER_LEN(out, open);
-	})));
+	}));
 
 	EXPECT_LE(0, open(FULLPATH, O_DIRECTORY)) << strerror(errno);
 }
 
-TEST_F(Opendir, opendir)
+/* Directories can be opened O_EXEC for stuff like fchdir(2) */
+TEST_F(Opendir, open_exec)
 {
 	const char FULLPATH[] = "mountpoint/some_dir";
 	const char RELPATH[] = "some_dir";
 	uint64_t ino = 42;
+	int fd;
 
 	expect_lookup(RELPATH, ino);
-	EXPECT_CALL(*m_mock, process(
-		ResultOf([](auto in) {
-			return (in->header.opcode == FUSE_STATFS);
-		}, Eq(true)),
-		_)
-	).WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto out) {
-		SET_OUT_HEADER_LEN(out, statfs);
-	})));
+	expect_opendir(ino, O_EXEC,
+	ReturnImmediate([=](auto in __unused, auto out) {
+		SET_OUT_HEADER_LEN(out, open);
+	}));
 
-	EXPECT_CALL(*m_mock, process(
-		ResultOf([=](auto in) {
-			return (in->header.opcode == FUSE_OPENDIR &&
-				in->header.nodeid == ino);
-		}, Eq(true)),
-		_)
-	).WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto out) {
+	fd = open(FULLPATH, O_EXEC | O_DIRECTORY);
+	ASSERT_LE(0, fd) << strerror(errno);
+}
+
+TEST_F(Opendir, opendir)
+{
+	const char FULLPATH[] = "mountpoint/some_dir";
+	const char RELPATH[] = "some_dir";
+	uint64_t ino = 42;
+
+	expect_lookup(RELPATH, ino);
+	expect_opendir(ino, O_RDONLY,
+	ReturnImmediate([=](auto in __unused, auto out) {
 		SET_OUT_HEADER_LEN(out, open);
-	})));
+	}));
 
 	errno = 0;
 	EXPECT_NE(NULL, opendir(FULLPATH)) << strerror(errno);

Modified: projects/fuse2/tests/sys/fs/fusefs/readdir.cc
==============================================================================
--- projects/fuse2/tests/sys/fs/fusefs/readdir.cc	Mon Apr  1 16:15:29 2019	(r345767)
+++ projects/fuse2/tests/sys/fs/fusefs/readdir.cc	Mon Apr  1 16:36:02 2019	(r345768)
@@ -52,6 +52,7 @@ void expect_readdir(uint64_t ino, uint64_t off, vector
 		ResultOf([=](auto in) {
 			return (in->header.opcode == FUSE_READDIR &&
 				in->header.nodeid == ino &&
+				in->body.readdir.fh == FH &&
 				in->body.readdir.offset == off);
 		}, Eq(true)),
 		_)

Modified: projects/fuse2/tests/sys/fs/fusefs/releasedir.cc
==============================================================================
--- projects/fuse2/tests/sys/fs/fusefs/releasedir.cc	Mon Apr  1 16:15:29 2019	(r345767)
+++ projects/fuse2/tests/sys/fs/fusefs/releasedir.cc	Mon Apr  1 16:36:02 2019	(r345768)
@@ -30,6 +30,7 @@
 
 extern "C" {
 #include <dirent.h>
+#include <fcntl.h>
 }
 
 #include "mockfs.hh"
@@ -106,4 +107,22 @@ TEST_F(ReleaseDir, ok)
 	ASSERT_NE(NULL, dir) << strerror(errno);
 
 	ASSERT_EQ(0, closedir(dir)) << strerror(errno);
+}
+
+/* Directories opened O_EXEC should be properly released, too */
+TEST_F(ReleaseDir, o_exec)
+{
+	const char FULLPATH[] = "mountpoint/some_dir";
+	const char RELPATH[] = "some_dir";
+	uint64_t ino = 42;
+	int fd;
+
+	expect_lookup(RELPATH, ino);
+	expect_opendir(ino);
+	expect_releasedir(ino, ReturnErrno(0));
+	
+	fd = open(FULLPATH, O_EXEC | O_DIRECTORY);
+	EXPECT_LE(0, fd) << strerror(errno);
+
+	ASSERT_EQ(0, close(fd)) << strerror(errno);
 }

Modified: projects/fuse2/tests/sys/fs/fusefs/utils.cc
==============================================================================
--- projects/fuse2/tests/sys/fs/fusefs/utils.cc	Mon Apr  1 16:15:29 2019	(r345767)
+++ projects/fuse2/tests/sys/fs/fusefs/utils.cc	Mon Apr  1 16:36:02 2019	(r345768)
@@ -166,6 +166,7 @@ void FuseTest::expect_open(uint64_t ino, uint32_t flag
 
 void FuseTest::expect_opendir(uint64_t ino)
 {
+	/* opendir(3) calls fstatfs */
 	EXPECT_CALL(*m_mock, process(
 		ResultOf([](auto in) {
 			return (in->header.opcode == FUSE_STATFS);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?FA6F7C1D-7B2D-4B74-A6E9-8C1112DAEEAD>