Page MenuHomeFreeBSD

D14567.id43502.diff
No OneTemporary

D14567.id43502.diff

Index: include/unistd.h
===================================================================
--- include/unistd.h
+++ include/unistd.h
@@ -583,6 +583,7 @@
int undelete(const char *);
int unwhiteout(const char *);
void *valloc(size_t); /* obsoleted by malloc() */
+int fdunlinkat(int, int, const char *, int);
#ifndef _OPTRESET_DECLARED
#define _OPTRESET_DECLARED
Index: lib/libc/sys/Makefile.inc
===================================================================
--- lib/libc/sys/Makefile.inc
+++ lib/libc/sys/Makefile.inc
@@ -478,6 +478,7 @@
MLINKS+=thr_kill.2 thr_kill2.2
MLINKS+=truncate.2 ftruncate.2
MLINKS+=unlink.2 unlinkat.2
+MLINKS+=unlink.2 fdunlinkat.2
MLINKS+=utimensat.2 futimens.2
MLINKS+=utimes.2 futimes.2 \
utimes.2 futimesat.2 \
Index: lib/libc/sys/Symbol.map
===================================================================
--- lib/libc/sys/Symbol.map
+++ lib/libc/sys/Symbol.map
@@ -400,6 +400,7 @@
statfs;
cpuset_getdomain;
cpuset_setdomain;
+ fdunlinkat;
};
FBSDprivate_1.0 {
Index: lib/libc/sys/unlink.2
===================================================================
--- lib/libc/sys/unlink.2
+++ lib/libc/sys/unlink.2
@@ -28,7 +28,7 @@
.\" @(#)unlink.2 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
-.Dd December 1, 2017
+.Dd June 9, 2018
.Dt UNLINK 2
.Os
.Sh NAME
@@ -42,7 +42,9 @@
.Ft int
.Fn unlink "const char *path"
.Ft int
-.Fn unlinkat "int fd" "const char *path" "int flag"
+.Fn unlinkat "int dfd" "const char *path" "int flag"
+.Ft int
+.Fn fdunlinkat "int dfd" "int fd" "const char *path" "int flag"
.Sh DESCRIPTION
The
.Fn unlink
@@ -74,7 +76,7 @@
specifies a relative path.
In this case the directory entry to be removed is determined
relative to the directory associated with the file descriptor
-.Fa fd
+.Fa dfd
instead of the current working directory.
.Pp
The values for
@@ -105,6 +107,17 @@
respectively, depending on whether or not the
.Dv AT_REMOVEDIR
bit is set in flag.
+.Pp
+The
+.Fn fdunlinkat
+system call is equivalent to
+.Fn unlinkat
+except in the case where
+.Fa fd
+specified file descriptor which corespondent to the
+.Fa name
+file.
+If those two arguments are corresponding file will be removed.
.Sh RETURN VALUES
.Rv -std unlink
.Sh ERRORS
@@ -201,6 +214,16 @@
.Dv AT_FDCWD
nor a file descriptor associated with a directory.
.El
+.Pp
+In addition to the errors returned by the
+.Fn unlinkat ,
+the
+.Fn fdunlinkat
+may fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The file descriptor is not associated with the path.
+.El
.Sh SEE ALSO
.Xr chflags 2 ,
.Xr close 2 ,
@@ -220,6 +243,10 @@
.Fn unlinkat
system call appeared in
.Fx 8.0 .
+The
+.Fn fdunlinkat
+system call appeared in
+.Fx 12.0 .
.Pp
The
.Fn unlink
Index: sys/amd64/conf/CAPSICUM
===================================================================
--- sys/amd64/conf/CAPSICUM
+++ /dev/null
@@ -1,91 +0,0 @@
-
-
-
-
-cpu HAMMER
-ident CAPSICUM
-
-makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
-makeoptions WITH_CTF=1 # Run ctfconvert(1) for DTrace support
-
-options SCHED_ULE # ULE scheduler
-options PREEMPTION # Enable kernel thread preemption
-options INET # InterNETworking
-options INET6 # IPv6 communications protocols
-options TCP_OFFLOAD # TCP offload
-options SCTP # Stream Control Transmission Protocol
-options NFSCL # New Network Filesystem client
-options NFS_ROOT # NFS usable as /, requires NFSCL
-options COMPAT_FREEBSD32 # Compatible with i386 binaries
-options COMPAT_FREEBSD4 # Compatible with FreeBSD4
-options COMPAT_FREEBSD5 # Compatible with FreeBSD5
-options COMPAT_FREEBSD6 # Compatible with FreeBSD6
-options COMPAT_FREEBSD7 # Compatible with FreeBSD7
-options KTRACE # ktrace(1) support
-options STACK # stack(9) support
-options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
-options PRINTF_BUFR_SIZE=128 # Prevent printf output being interspersed.
-options KBD_INSTALL_CDEV # install a CDEV entry in /dev
-options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4)
-options AUDIT # Security event auditing
-options CAPABILITY_MODE # Capsicum capability mode
-options CAPABILITIES # Capsicum capabilities
-options MAC # TrustedBSD MAC Framework
-options KDTRACE_FRAME # Ensure frames are compiled in
-options KDTRACE_HOOKS # Kernel DTrace hooks
-options DDB_CTF # Kernel ELF linker loads CTF data
-
-# Debugging support. Always need this:
-options KDB # Enable kernel debugger support.
-# For minimum debugger support (stable branch) use:
-#options KDB_TRACE # Print a stack trace for a panic.
-# For full debugger support use this instead:
-options DDB # Support DDB.
-options INVARIANTS # Enable calls of extra sanity checking
-options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
-options WITNESS # Enable checks to detect deadlocks and cycles
-options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
-options MALLOC_DEBUG_MAXZONES=8 # Separate malloc(9) zones
-
-# Bus support.
-device acpi
-device pci
-
-# atkbdc0 controls both the keyboard and the PS/2 mouse
-device atkbdc # AT keyboard controller
-device atkbd # AT keyboard
-
-device kbdmux # keyboard multiplexer
-
-device vga # VGA video card driver
-options VESA # Add support for VESA BIOS Extensions (VBE)
-
-# syscons is the default console driver, resembling an SCO console
-device sc
-options SC_PIXEL_MODE # add support for the raster text mode
-
-# Serial (COM) ports
-device uart # Generic UART driver
-
-# Pseudo devices.
-device loop # Network loopback
-device random # Entropy device
-device ether # Ethernet support
-
-# The `bpf' device enables the Berkeley Packet Filter.
-# Be aware of the administrative consequences of enabling this!
-# Note that 'bpf' is required for DHCP.
-device bpf # Berkeley packet filter
-
-device le
-
-
-# VirtIO support
-device virtio # Generic VirtIO bus (required)
-device virtio_pci # VirtIO PCI device
-device vtnet # VirtIO Ethernet device
-device virtio_blk # VirtIO Block device
-device virtio_scsi # VirtIO SCSI device
-device virtio_balloon # VirtIO Memory Balloon device
-device virtio_scsi # VirtIO SCSI device
-device virtio_balloon # VirtIO Memory Balloon device
Index: sys/compat/cloudabi/cloudabi_file.c
===================================================================
--- sys/compat/cloudabi/cloudabi_file.c
+++ sys/compat/cloudabi/cloudabi_file.c
@@ -750,9 +750,9 @@
return (error);
if (uap->flags & CLOUDABI_UNLINK_REMOVEDIR)
- error = kern_rmdirat(td, uap->fd, path, UIO_SYSSPACE);
+ error = kern_fdrmdirat(td, uap->fd, -1, path, UIO_SYSSPACE);
else
- error = kern_unlinkat(td, uap->fd, path, UIO_SYSSPACE, 0);
+ error = kern_fdunlinkat(td, uap->fd, -1, path, UIO_SYSSPACE, 0);
cloudabi_freestr(path);
return (error);
}
Index: sys/compat/freebsd32/syscalls.master
===================================================================
--- sys/compat/freebsd32/syscalls.master
+++ sys/compat/freebsd32/syscalls.master
@@ -1123,5 +1123,7 @@
cpuwhich_t which, uint32_t id1, uint32_t id2, \
size_t domainsetsize, domainset_t *mask, \
int policy); }
+563 AUE_OPENAT_RWTC STD { int fdunlinkat(int dfd, int fd, const char *path, \
+ int flag, mode_t mode); }
; vim: syntax=off
Index: sys/compat/linux/linux_file.c
===================================================================
--- sys/compat/linux/linux_file.c
+++ sys/compat/linux/linux_file.c
@@ -612,7 +612,7 @@
#endif
if (args->flag & LINUX_AT_REMOVEDIR)
- error = kern_rmdirat(td, dfd, path, UIO_SYSSPACE);
+ error = kern_fdrmdirat(td, dfd, -1, path, UIO_SYSSPACE);
else
error = kern_unlinkat(td, dfd, path, UIO_SYSSPACE, 0);
if (error == EPERM && !(args->flag & LINUX_AT_REMOVEDIR)) {
@@ -725,7 +725,7 @@
if (ldebug(rmdir))
printf(ARGS(rmdir, "%s"), path);
#endif
- error = kern_rmdirat(td, AT_FDCWD, path, UIO_SYSSPACE);
+ error = kern_fdrmdirat(td, AT_FDCWD, -1, path, UIO_SYSSPACE);
LFREEPATH(path);
return (error);
}
Index: sys/i386/ibcs2/ibcs2_misc.c
===================================================================
--- sys/i386/ibcs2/ibcs2_misc.c
+++ sys/i386/ibcs2/ibcs2_misc.c
@@ -1120,7 +1120,7 @@
int error;
CHECKALTEXIST(td, uap->path, &path);
- error = kern_rmdirat(td, AT_FDCWD, path, UIO_SYSSPACE);
+ error = kern_fdrmdirat(td, AT_FDCWD, -1, path, UIO_SYSSPACE);
free(path, M_TEMP);
return (error);
}
Index: sys/kern/capabilities.conf
===================================================================
--- sys/kern/capabilities.conf
+++ sys/kern/capabilities.conf
@@ -462,7 +462,7 @@
readlinkat
renameat
symlinkat
-unlinkat
+unlinkfdat
utimensat
##
Index: sys/kern/syscalls.master
===================================================================
--- sys/kern/syscalls.master
+++ sys/kern/syscalls.master
@@ -1027,6 +1027,8 @@
cpuwhich_t which, id_t id, \
size_t domainsetsize, domainset_t *mask, \
int policy); }
+563 AUE_OPENAT_RWTC STD { int fdunlinkat(int dfd, int fd, const char *path, \
+ int flag, mode_t mode); }
; Please copy any additions and changes to the following compatability tables:
; sys/compat/freebsd32/syscalls.master
Index: sys/kern/vfs_mountroot.c
===================================================================
--- sys/kern/vfs_mountroot.c
+++ sys/kern/vfs_mountroot.c
@@ -388,7 +388,7 @@
if (mporoot == mpdevfs) {
vfs_unbusy(mpdevfs);
/* Unlink the no longer needed /dev/dev -> / symlink */
- error = kern_unlinkat(td, AT_FDCWD, "/dev/dev",
+ error = kern_fdunlinkat(td, AT_FDCWD, -1, "/dev/dev",
UIO_SYSSPACE, 0);
if (error)
printf("mountroot: unable to unlink /dev/dev "
Index: sys/kern/vfs_syscalls.c
===================================================================
--- sys/kern/vfs_syscalls.c
+++ sys/kern/vfs_syscalls.c
@@ -1737,7 +1737,21 @@
sys_unlink(struct thread *td, struct unlink_args *uap)
{
- return (kern_unlinkat(td, AT_FDCWD, uap->path, UIO_USERSPACE, 0));
+ return (kern_fdunlinkat(td, AT_FDCWD, -1, uap->path, UIO_USERSPACE, 0));
+}
+
+static int
+kern_fdunlinkat_ex(struct thread *td, int dfd, int fd, const char *path,
+ int flag, enum uio_seg pathseg, ino_t oldinum)
+{
+
+ if (flag & ~AT_REMOVEDIR)
+ return (EINVAL);
+
+ if (flag & AT_REMOVEDIR)
+ return (kern_fdrmdirat(td, dfd, fd, path, UIO_USERSPACE));
+
+ return (kern_fdunlinkat(td, dfd, fd, path, UIO_USERSPACE, 0));
}
#ifndef _SYS_SYSPROTO_H_
@@ -1750,43 +1764,65 @@
int
sys_unlinkat(struct thread *td, struct unlinkat_args *uap)
{
- int flag = uap->flag;
- int fd = uap->fd;
- char *path = uap->path;
- if (flag & ~AT_REMOVEDIR)
- return (EINVAL);
+ return (kern_fdunlinkat_ex(td, uap->fd, -1, uap->path, uap->flag,
+ UIO_USERSPACE, 0));
+}
- if (flag & AT_REMOVEDIR)
- return (kern_rmdirat(td, fd, path, UIO_USERSPACE));
- else
- return (kern_unlinkat(td, fd, path, UIO_USERSPACE, 0));
+#ifndef _SYS_SYSPROTO_H_
+struct fdunlinkat_args {
+ int dfd;
+ int fd;
+ const char *path;
+ int flag;
+};
+#endif
+int
+sys_fdunlinkat(struct thread *td, struct fdunlinkat_args *uap)
+{
+
+ return (kern_fdunlinkat_ex(td, uap->dfd, uap->fd, uap->path, uap->flag,
+ UIO_USERSPACE, 0));
}
int
-kern_unlinkat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
- ino_t oldinum)
+kern_fdunlinkat(struct thread *td, int dfd, int fd, const char *path,
+ enum uio_seg pathseg, ino_t oldinum)
{
struct mount *mp;
- struct vnode *vp;
+ struct file *fp;
+ struct vnode *vp, *vfdp;
struct nameidata nd;
struct stat sb;
cap_rights_t rights;
int error;
+ vfdp = NULL;
+ if (fd != -1) {
+ error = getvnode(td, fd, cap_rights_init(&rights, CAP_UNLINKFD),
+ &fp);
+ if (error != 0)
+ return (error);
+ vfdp = fp->f_vnode;
+ }
+
restart:
bwillwrite();
NDINIT_ATRIGHTS(&nd, DELETE, LOCKPARENT | LOCKLEAF | AUDITVNODE1,
- pathseg, path, fd, cap_rights_init(&rights, CAP_UNLINKAT), td);
- if ((error = namei(&nd)) != 0)
- return (error == EINVAL ? EPERM : error);
+ pathseg, path, dfd, cap_rights_init(&rights, CAP_UNLINKAT), td);
+ if ((error = namei(&nd)) != 0) {
+ error = (error == EINVAL ? EPERM : error);
+ goto fdout;
+ }
vp = nd.ni_vp;
if (vp->v_type == VDIR && oldinum == 0) {
error = EPERM; /* POSIX */
} else if (oldinum != 0 &&
((error = vn_stat(vp, &sb, td->td_ucred, NOCRED, td)) == 0) &&
sb.st_ino != oldinum) {
- error = EIDRM; /* Identifier removed */
+ error = EIDRM; /* Identifier removed */
+ } else if (vfdp != NULL && vfdp != vp) {
+ error = EINVAL;
} else {
/*
* The root of a mounted filesystem cannot be deleted.
@@ -1805,8 +1841,9 @@
else
vput(vp);
if ((error = vn_start_write(NULL, &mp,
- V_XSLEEP | PCATCH)) != 0)
- return (error);
+ V_XSLEEP | PCATCH)) != 0) {
+ goto fdout;
+ }
goto restart;
}
#ifdef MAC
@@ -1828,6 +1865,9 @@
vrele(vp);
else
vput(vp);
+fdout:
+ if (fd != -1)
+ fdrop(fp, td);
return (error);
}
@@ -3675,24 +3715,35 @@
sys_rmdir(struct thread *td, struct rmdir_args *uap)
{
- return (kern_rmdirat(td, AT_FDCWD, uap->path, UIO_USERSPACE));
+ return (kern_fdrmdirat(td, AT_FDCWD, -1, uap->path, UIO_USERSPACE));
}
int
-kern_rmdirat(struct thread *td, int fd, char *path, enum uio_seg pathseg)
+kern_fdrmdirat(struct thread *td, int dfd, int fd, const char *path,
+ enum uio_seg pathseg)
{
struct mount *mp;
- struct vnode *vp;
+ struct vnode *vp, *vfdp;
+ struct file *fp;
struct nameidata nd;
cap_rights_t rights;
int error;
+ vfdp = NULL;
+ if (fd != -1) {
+ error = getvnode(td, fd, cap_rights_init(&rights, CAP_UNLINKFD),
+ &fp);
+ if (error != 0)
+ return (error);
+ vfdp = fp->f_vnode;
+ }
+
restart:
bwillwrite();
NDINIT_ATRIGHTS(&nd, DELETE, LOCKPARENT | LOCKLEAF | AUDITVNODE1,
- pathseg, path, fd, cap_rights_init(&rights, CAP_UNLINKAT), td);
+ pathseg, path, dfd, cap_rights_init(&rights, CAP_UNLINKAT), td);
if ((error = namei(&nd)) != 0)
- return (error);
+ goto fdout;
vp = nd.ni_vp;
if (vp->v_type != VDIR) {
error = ENOTDIR;
@@ -3712,6 +3763,12 @@
error = EBUSY;
goto out;
}
+
+ if (vfdp != NULL && vfdp != vp) {
+ error = EINVAL;
+ goto out;
+ }
+
#ifdef MAC
error = mac_vnode_check_unlink(td->td_ucred, nd.ni_dvp, vp,
&nd.ni_cnd);
@@ -3726,7 +3783,7 @@
else
vput(nd.ni_dvp);
if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
- return (error);
+ goto fdout;
goto restart;
}
vfs_notify_upper(vp, VFS_NOTIFY_UPPER_UNLINK);
@@ -3739,6 +3796,9 @@
vrele(nd.ni_dvp);
else
vput(nd.ni_dvp);
+fdout:
+ if (fd != -1)
+ fdrop(fp, td);
return (error);
}
Index: sys/sys/syscallsubr.h
===================================================================
--- sys/sys/syscallsubr.h
+++ sys/sys/syscallsubr.h
@@ -216,7 +216,7 @@
enum uio_seg fromseg, struct mbuf **controlp);
int kern_renameat(struct thread *td, int oldfd, char *old, int newfd,
char *new, enum uio_seg pathseg);
-int kern_rmdirat(struct thread *td, int fd, char *path,
+int kern_fdrmdirat(struct thread *td, int dfd, int fd, const char *path,
enum uio_seg pathseg);
int kern_sched_getparam(struct thread *td, struct thread *targettd,
struct sched_param *param);
@@ -285,6 +285,8 @@
off_t length);
int kern_unlinkat(struct thread *td, int fd, char *path,
enum uio_seg pathseg, ino_t oldinum);
+int kern_fdunlinkat(struct thread *td, int dfd, int fd, const char *path,
+ enum uio_seg pathseg, ino_t oldinum);
int kern_utimesat(struct thread *td, int fd, char *path,
enum uio_seg pathseg, struct timeval *tptr, enum uio_seg tptrseg);
int kern_utimensat(struct thread *td, int fd, char *path,

File Metadata

Mime Type
text/plain
Expires
Thu, May 21, 8:07 AM (11 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33380956
Default Alt Text
D14567.id43502.diff (15 KB)

Event Timeline