Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F146090199
D21391.1779193573.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D21391.1779193573.diff
View Options
Index: lib/libc/sys/fcntl.2
===================================================================
--- lib/libc/sys/fcntl.2
+++ lib/libc/sys/fcntl.2
@@ -28,7 +28,7 @@
.\" @(#)fcntl.2 8.2 (Berkeley) 1/12/94
.\" $FreeBSD$
.\"
-.Dd Nov 15, 2018
+.Dd August 24, 2019
.Dt FCNTL 2
.Os
.Sh NAME
@@ -180,6 +180,13 @@
A zero value in
.Fa arg
turns off read ahead.
+.It Dv F_ADD_SEALS
+Add seals to the descriptor
+.Fa fd ,
+as described below.
+.It Dv F_GET_SEALS
+Get seals associated with descriptor
+.Fa fd .
.El
.Pp
The flags for the
@@ -217,6 +224,30 @@
upon availability of data to be read.
.El
.Pp
+The seals that may be applied with
+.Dv F_ADD_SEALS
+are as follows:
+.Bl -tag -width F_SEAL_SHRINK
+.It Dv F_SEAL_SEAL
+Prevent any further seals from being applied to
+.Fa fd .
+.It Dv F_SEAL_SHRINK
+Prevent
+.Fa fd
+from being shrunk with
+.Xr ftruncate 2 .
+.It Dv F_SEAL_GROW
+Prevent
+.Fa fd
+from being enlarged with
+.Xr ftruncate 2 .
+.It Dv F_SEAL_WRITE
+Prevent any further
+.Xr write 2
+calls to
+.Fa fd .
+.El
+.Pp
Several commands are available for doing advisory file locking;
they all operate on the following structure:
.Bd -literal
Index: sys/kern/kern_descrip.c
===================================================================
--- sys/kern/kern_descrip.c
+++ sys/kern/kern_descrip.c
@@ -46,6 +46,7 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/caprights.h>
#include <sys/capsicum.h>
#include <sys/conf.h>
#include <sys/fcntl.h>
@@ -483,6 +484,7 @@
int
kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg)
{
+ cap_rights_t rights;
struct filedesc *fdp;
struct flock *flp;
struct file *fp, *fp2;
@@ -492,6 +494,7 @@
int error, flg, tmp;
uint64_t bsize;
off_t foffset;
+ bool setcaps;
error = 0;
flg = F_POSIX;
@@ -756,6 +759,61 @@
fdrop(fp, td);
break;
+ case F_ADD_SEALS:
+ error = fget_unlocked(fdp, fd, &cap_no_rights, &fp, NULL);
+ if (error != 0)
+ break;
+ if ((fp->f_flag & (FWRITE | FSEALABLE)) != (FWRITE | FSEALABLE))
+ error = EINVAL;
+ else if ((fp->f_seals & F_SEAL_SEAL) != 0)
+ error = EPERM;
+ if (error != 0) {
+ fdrop(fp, td);
+ break;
+ }
+
+ tmp = (arg & ~fp->f_seals);
+ /* No new bits? break out, no harm no foul. */
+ if (tmp == 0) {
+ fdrop(fp, td);
+ break;
+ }
+
+ /* fp->f_seals can never be cleared */
+ atomic_set_int(&fp->f_seals, arg);
+ rights = *cap_rights(fdp, fd);
+ setcaps = false;
+
+ /* F_SEAL_WRITE translates to revoking CAP_WRITE */
+ if ((tmp & F_SEAL_WRITE) != 0) {
+ cap_rights_clear(&rights, CAP_WRITE);
+ setcaps = true;
+ }
+
+ /* We can revoke truncate completely */
+ if ((tmp & F_SEAL_TRUNCATE) != 0 &&
+ (fp->f_seals & F_SEAL_TRUNCATE) == F_SEAL_TRUNCATE) {
+ cap_rights_clear(&rights, CAP_FTRUNCATE);
+ setcaps = true;
+ }
+
+ if (setcaps)
+ kern_cap_rights_limit(td, fd, &rights);
+
+ fdrop(fp, td);
+ break;
+
+ case F_GET_SEALS:
+ error = fget_unlocked(fdp, fd, &cap_no_rights, &fp, NULL);
+ if (error != 0)
+ break;
+ if ((fp->f_flag & FSEALABLE) == 0)
+ error = EINVAL;
+ else
+ td->td_retval[0] = fp->f_seals;
+ fdrop(fp, td);
+ break;
+
case F_RDAHEAD:
arg = arg ? 128 * 1024: 0;
/* FALLTHROUGH */
Index: sys/kern/sys_generic.c
===================================================================
--- sys/kern/sys_generic.c
+++ sys/kern/sys_generic.c
@@ -63,6 +63,7 @@
#include <sys/resourcevar.h>
#include <sys/selinfo.h>
#include <sys/sleepqueue.h>
+#include <sys/stat.h>
#include <sys/syscallsubr.h>
#include <sys/sysctl.h>
#include <sys/sysent.h>
@@ -595,6 +596,7 @@
int
kern_ftruncate(struct thread *td, int fd, off_t length)
{
+ struct stat sb;
struct file *fp;
int error;
@@ -606,10 +608,30 @@
return (error);
AUDIT_ARG_FILE(td->td_proc, fp);
if (!(fp->f_flag & FWRITE)) {
- fdrop(fp, td);
- return (EINVAL);
+ error = EINVAL;
+ goto out;
+ }
+ /*
+ * ftruncate being completely sealed is already handled by revoking the
+ * ftruncate capability completely. Here we only have to handle the
+ * case of either restricted shrink or restricted growth, but not both.
+ */
+ if ((fp->f_seals & F_SEAL_TRUNCATE) != 0) {
+ error = fo_stat(fp, &sb, td->td_ucred, td);
+ if (error == 0) {
+ if (length < sb.st_size &&
+ (fp->f_seals & F_SEAL_SHRINK) != 0) {
+ error = ENOTCAPABLE;
+ goto out;
+ } else if (length > sb.st_size &&
+ (fp->f_seals & F_SEAL_GROW) != 0) {
+ error = ENOTCAPABLE;
+ goto out;
+ }
+ }
}
error = fo_truncate(fp, length, td->td_ucred, td);
+out:
fdrop(fp, td);
return (error);
}
Index: sys/sys/fcntl.h
===================================================================
--- sys/sys/fcntl.h
+++ sys/sys/fcntl.h
@@ -196,6 +196,10 @@
#define FRDAHEAD O_CREAT
#endif
+#ifdef _KERNEL
+#define FSEALABLE O_TRUNC
+#endif
+
#if __POSIX_VISIBLE >= 200809
/*
* Magic value that specify the use of the current working directory
@@ -248,8 +252,22 @@
#endif
#if __BSD_VISIBLE
#define F_DUP2FD_CLOEXEC 18 /* Like F_DUP2FD, but FD_CLOEXEC is set */
+#define F_ADD_SEALS 19
+#define F_GET_SEALS 20
#endif
+/* Seals (F_ADD_SEALS, F_GET_SEALS */
+#if __BSD_VISIBLE
+#define F_SEAL_SEAL 0x0001 /* Prevent adding sealings */
+#define F_SEAL_SHRINK 0x0002 /* May not shrink */
+#define F_SEAL_GROW 0x0004 /* May not grow */
+#define F_SEAL_WRITE 0x0008 /* May not write */
+
+#ifdef _KERNEL
+#define F_SEAL_TRUNCATE (F_SEAL_SHRINK | F_SEAL_GROW)
+#endif /* _KERNEL */
+#endif /* __BSD_VISIBLE */
+
/* file descriptor flags (F_GETFD, F_SETFD) */
#define FD_CLOEXEC 1 /* close-on-exec flag */
Index: sys/sys/file.h
===================================================================
--- sys/sys/file.h
+++ sys/sys/file.h
@@ -197,6 +197,10 @@
* Mandatory Access control information.
*/
void *f_label; /* Place-holder for MAC label. */
+ /*
+ * Current seals on the fd
+ */
+ uint32_t f_seals;
};
#define f_cdevpriv f_vnun.fvn_cdevpriv
Index: sys/sys/param.h
===================================================================
--- sys/sys/param.h
+++ sys/sys/param.h
@@ -60,7 +60,7 @@
* in the range 5 to 9.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 1300040 /* Master, propagated to newvers */
+#define __FreeBSD_version 1300041 /* Master, propagated to newvers */
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, May 19, 12:26 PM (5 h, 30 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28745080
Default Alt Text
D21391.1779193573.diff (6 KB)
Attached To
Mode
D21391: [1/3] Add mostly Linux-compatible file sealing support
Attached
Detach File
Event Timeline
Log In to Comment