Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F108248368
D34424.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D34424.diff
View Options
diff --git a/lib/libc/sys/closefrom.2 b/lib/libc/sys/closefrom.2
--- a/lib/libc/sys/closefrom.2
+++ b/lib/libc/sys/closefrom.2
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd April 12, 2020
+.Dd March 3, 2022
.Dt CLOSEFROM 2
.Os
.Sh NAME
@@ -56,8 +56,12 @@
.Fa highfd
inclusive, clamped to the range of open file descriptors.
Any errors encountered while closing file descriptors are ignored.
-There are currently no defined
-.Fa flags .
+Supported
+.Fa flags :
+.Bl -tag -width ".Dv CLOSE_RANGE_CLOEXEC"
+.It Dv CLOSE_RANGE_CLOEXEC
+Set the close-on-exec flag on descriptors in the range instead of closing them.
+.El
.Sh RETURN VALUES
Upon successful completion,
.Fn close_range
diff --git a/lib/libsysdecode/flags.c b/lib/libsysdecode/flags.c
--- a/lib/libsysdecode/flags.c
+++ b/lib/libsysdecode/flags.c
@@ -400,6 +400,13 @@
return (print_mask_int(fp, capfcntl, rights, rem));
}
+bool
+sysdecode_close_range_flags(FILE *fp, int flags, int *rem)
+{
+
+ return (print_mask_int(fp, closerangeflags, flags, rem));
+}
+
const char *
sysdecode_extattrnamespace(int namespace)
{
diff --git a/lib/libsysdecode/mktables b/lib/libsysdecode/mktables
--- a/lib/libsysdecode/mktables
+++ b/lib/libsysdecode/mktables
@@ -94,6 +94,7 @@
gen_table "acltype" "ACL_TYPE_[A-Z4_]+[[:space:]]+0x[0-9]+" "sys/acl.h"
gen_table "atflags" "AT_[A-Z_]+[[:space:]]+0x[0-9]+" "sys/fcntl.h"
gen_table "capfcntl" "CAP_FCNTL_[A-Z]+[[:space:]]+\(1" "sys/capsicum.h"
+gen_table "closerangeflags" "CLOSE_RANGE_[A-Z]+[[:space:]]+\([0-9]+<<[0-9]+\)" "sys/unistd.h"
gen_table "extattrns" "EXTATTR_NAMESPACE_[A-Z]+[[:space:]]+0x[0-9]+" "sys/extattr.h"
gen_table "fadvisebehav" "POSIX_FADV_[A-Z]+[[:space:]]+[0-9]+" "sys/fcntl.h"
gen_table "openflags" "O_[A-Z]+[[:space:]]+0x[0-9A-Fa-f]+" "sys/fcntl.h" "O_RDONLY|O_RDWR|O_WRONLY"
diff --git a/lib/libsysdecode/sysdecode.h b/lib/libsysdecode/sysdecode.h
--- a/lib/libsysdecode/sysdecode.h
+++ b/lib/libsysdecode/sysdecode.h
@@ -43,6 +43,7 @@
bool sysdecode_atflags(FILE *_fp, int _flags, int *_rem);
bool sysdecode_cap_fcntlrights(FILE *_fp, uint32_t _rights, uint32_t *_rem);
void sysdecode_cap_rights(FILE *_fp, cap_rights_t *_rightsp);
+bool sysdecode_close_range_flags(FILE *_fp, int _flags, int *_rem);
const char *sysdecode_cmsg_type(int _cmsg_level, int _cmsg_type);
const char *sysdecode_extattrnamespace(int _namespace);
const char *sysdecode_fadvice(int _advice);
diff --git a/lib/libsysdecode/sysdecode_mask.3 b/lib/libsysdecode/sysdecode_mask.3
--- a/lib/libsysdecode/sysdecode_mask.3
+++ b/lib/libsysdecode/sysdecode_mask.3
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd January 16, 2018
+.Dd March 3, 2022
.Dt sysdecode_mask 3
.Os
.Sh NAME
@@ -32,6 +32,7 @@
.Nm sysdecode_accessmode ,
.Nm sysdecode_atflags ,
.Nm sysdecode_capfcntlrights ,
+.Nm sysdecode_close_range_flags ,
.Nm sysdecode_fcntl_fileflags ,
.Nm sysdecode_fileflags ,
.Nm sysdecode_filemode ,
@@ -74,6 +75,8 @@
.Ft bool
.Fn sysdecode_cap_fcntlrights "FILE *fp" "uint32_t rights" "uint32_t *rem"
.Ft bool
+.Fn sysdecode_close_range_flags "FILE *fp" "int flags" "int *rem"
+.Ft bool
.Fn sysdecode_fcntl_fileflags "FILE *fp" "int flags" "int *rem"
.Ft bool
.Fn sysdecode_fileflags "FILE *fp" "fflags_t flags" "fflags_t *rem"
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -1393,23 +1393,39 @@
return (closefp(fdp, fd, fp, td, true, true));
}
-int
-kern_close_range(struct thread *td, u_int lowfd, u_int highfd)
+static int
+close_range_cloexec(struct thread *td, u_int lowfd, u_int highfd)
{
struct filedesc *fdp;
- const struct fdescenttbl *fdt;
- struct file *fp;
+ struct fdescenttbl *fdt;
+ struct filedescent *fde;
int fd;
- /*
- * Check this prior to clamping; closefrom(3) with only fd 0, 1, and 2
- * open should not be a usage error. From a close_range() perspective,
- * close_range(3, ~0U, 0) in the same scenario should also likely not
- * be a usage error as all fd above 3 are in-fact already closed.
- */
- if (highfd < lowfd) {
- return (EINVAL);
+ fdp = td->td_proc->p_fd;
+ FILEDESC_XLOCK(fdp);
+ fdt = atomic_load_ptr(&fdp->fd_files);
+ highfd = MIN(highfd, fdt->fdt_nfiles - 1);
+ fd = lowfd;
+ if (__predict_false(fd > highfd)) {
+ goto out_locked;
+ }
+ for (; fd <= highfd; fd++) {
+ fde = &fdt->fdt_ofiles[fd];
+ if (fde->fde_file != NULL)
+ fde->fde_flags |= UF_EXCLOSE;
}
+out_locked:
+ FILEDESC_XUNLOCK(fdp);
+ return (0);
+}
+
+static int
+close_range_impl(struct thread *td, u_int lowfd, u_int highfd)
+{
+ struct filedesc *fdp;
+ const struct fdescenttbl *fdt;
+ struct file *fp;
+ int fd;
fdp = td->td_proc->p_fd;
FILEDESC_XLOCK(fdp);
@@ -1440,6 +1456,26 @@
return (0);
}
+int
+kern_close_range(struct thread *td, int flags, u_int lowfd, u_int highfd)
+{
+
+ /*
+ * Check this prior to clamping; closefrom(3) with only fd 0, 1, and 2
+ * open should not be a usage error. From a close_range() perspective,
+ * close_range(3, ~0U, 0) in the same scenario should also likely not
+ * be a usage error as all fd above 3 are in-fact already closed.
+ */
+ if (highfd < lowfd) {
+ return (EINVAL);
+ }
+
+ if ((flags & CLOSE_RANGE_CLOEXEC) != 0)
+ return (close_range_cloexec(td, lowfd, highfd));
+
+ return (close_range_impl(td, lowfd, highfd));
+}
+
#ifndef _SYS_SYSPROTO_H_
struct close_range_args {
u_int lowfd;
@@ -1455,10 +1491,9 @@
AUDIT_ARG_CMD(uap->highfd);
AUDIT_ARG_FFLAGS(uap->flags);
- /* No flags currently defined */
- if (uap->flags != 0)
+ if ((uap->flags & ~(CLOSE_RANGE_CLOEXEC)) != 0)
return (EINVAL);
- return (kern_close_range(td, uap->lowfd, uap->highfd));
+ return (kern_close_range(td, uap->flags, uap->lowfd, uap->highfd));
}
#ifdef COMPAT_FREEBSD12
@@ -1483,7 +1518,7 @@
* closefrom(0) which closes all files.
*/
lowfd = MAX(0, uap->lowfd);
- return (kern_close_range(td, lowfd, ~0U));
+ return (kern_close_range(td, 0, lowfd, ~0U));
}
#endif /* COMPAT_FREEBSD12 */
diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h
--- a/sys/sys/syscallsubr.h
+++ b/sys/sys/syscallsubr.h
@@ -111,7 +111,7 @@
struct timespec *ats);
void kern_thread_cputime(struct thread *targettd, struct timespec *ats);
void kern_process_cputime(struct proc *targetp, struct timespec *ats);
-int kern_close_range(struct thread *td, u_int lowfd, u_int highfd);
+int kern_close_range(struct thread *td, int flags, u_int lowfd, u_int highfd);
int kern_close(struct thread *td, int fd);
int kern_connectat(struct thread *td, int dirfd, int fd,
struct sockaddr *sa);
diff --git a/sys/sys/unistd.h b/sys/sys/unistd.h
--- a/sys/sys/unistd.h
+++ b/sys/sys/unistd.h
@@ -200,6 +200,11 @@
#define SWAPOFF_FORCE 0x00000001
+/*
+ * close_range() options.
+ */
+#define CLOSE_RANGE_CLOEXEC (1<<2)
+
#endif /* __BSD_VISIBLE */
#endif /* !_SYS_UNISTD_H_ */
diff --git a/tests/sys/file/closefrom_test.c b/tests/sys/file/closefrom_test.c
--- a/tests/sys/file/closefrom_test.c
+++ b/tests/sys/file/closefrom_test.c
@@ -144,7 +144,7 @@
{
struct shared_info *info;
pid_t pid;
- int fd, i, start;
+ int fd, flags, i, start;
printf("1..20\n");
@@ -325,5 +325,38 @@
fail(info->tag, "%s", info->message);
ok(info->tag);
+ /* test CLOSE_RANGE_CLOEXEC */
+ for (i = 0; i < 8; i++)
+ (void)devnull();
+ fd = highest_fd();
+ start = fd - 8;
+ if (close_range(start + 1, start + 4, CLOSE_RANGE_CLOEXEC) < 0)
+ fail_err("close_range(..., CLOSE_RANGE_CLOEXEC)");
+ flags = fcntl(start, F_GETFD);
+ if (flags < 0)
+ fail_err("fcntl(.., F_GETFD)");
+ if ((flags & FD_CLOEXEC) != 0)
+ fail("close_range", "CLOSE_RANGE_CLOEXEC set close-on-exec "
+ "when it should not have on fd %d", start);
+ for (i = start + 1; i <= start + 4; i++) {
+ flags = fcntl(i, F_GETFD);
+ if (flags < 0)
+ fail_err("fcntl(.., F_GETFD)");
+ if ((flags & FD_CLOEXEC) == 0)
+ fail("close_range", "CLOSE_RANGE_CLOEXEC did not set "
+ "close-on-exec on fd %d", i);
+ }
+ for (; i < start + 8; i++) {
+ flags = fcntl(i, F_GETFD);
+ if (flags < 0)
+ fail_err("fcntl(.., F_GETFD)");
+ if ((flags & FD_CLOEXEC) != 0)
+ fail("close_range", "CLOSE_RANGE_CLOEXEC set close-on-exec "
+ "when it should not have on fd %d", i);
+ }
+ if (close_range(start, start + 8, 0) < 0)
+ fail_err("close_range");
+ ok("close_range(..., CLOSE_RANGE_CLOEXEC)");
+
return (0);
}
diff --git a/usr.bin/kdump/kdump.c b/usr.bin/kdump/kdump.c
--- a/usr.bin/kdump/kdump.c
+++ b/usr.bin/kdump/kdump.c
@@ -864,6 +864,14 @@
ip++;
narg--;
break;
+ case SYS_close_range:
+ print_number(ip, narg, c);
+ print_number(ip, narg, c);
+ putchar(',');
+ print_mask_arg(sysdecode_close_range_flags, *ip);
+ ip += 3;
+ narg -= 3;
+ break;
case SYS_open:
case SYS_openat:
print_number(ip, narg, c);
diff --git a/usr.bin/truss/syscall.h b/usr.bin/truss/syscall.h
--- a/usr.bin/truss/syscall.h
+++ b/usr.bin/truss/syscall.h
@@ -91,6 +91,7 @@
Atfd,
Atflags,
CapFcntlRights,
+ Closerangeflags,
Extattrnamespace,
Fadvice,
Fcntl,
diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c
--- a/usr.bin/truss/syscalls.c
+++ b/usr.bin/truss/syscalls.c
@@ -183,6 +183,8 @@
.args = { { Int, 0 } } },
{ .name = "closefrom", .ret_type = 1, .nargs = 1,
.args = { { Int, 0 } } },
+ { .name = "close_range", .ret_type = 1, .nargs = 3,
+ .args = { { Int, 0 }, { Int, 1 }, { Closerangeflags, 2 } } },
{ .name = "compat11.fstat", .ret_type = 1, .nargs = 2,
.args = { { Int, 0 }, { Stat11 | OUT, 1 } } },
{ .name = "compat11.fstatat", .ret_type = 1, .nargs = 4,
@@ -1983,6 +1985,9 @@
case Fcntl:
print_integer_arg(sysdecode_fcntl_cmd, fp, args[sc->offset]);
break;
+ case Closerangeflags:
+ print_mask_arg(sysdecode_close_range_flags, fp, args[sc->offset]);
+ break;
case Mprot:
print_mask_arg(sysdecode_mmap_prot, fp, args[sc->offset]);
break;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jan 24, 2:31 AM (21 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16071956
Default Alt Text
D34424.diff (9 KB)
Attached To
Mode
D34424: fd: add close_range(..., CLOSE_RANGE_CLOEXEC)
Attached
Detach File
Event Timeline
Log In to Comment