Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F135540154
D14567.id39889.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D14567.id39889.diff
View Options
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;
+ unlinkfd;
};
FBSDprivate_1.0 {
Index: sys/compat/freebsd32/syscalls.master
===================================================================
--- sys/compat/freebsd32/syscalls.master
+++ sys/compat/freebsd32/syscalls.master
@@ -1123,5 +1123,6 @@
cpuwhich_t which, uint32_t id1, uint32_t id2, \
size_t domainsetsize, domainset_t *mask, \
int policy); }
+563 AUE_NULL STD { int unlinkfd(int fd, char *path); }
; vim: syntax=off
Index: sys/kern/capabilities.conf
===================================================================
--- sys/kern/capabilities.conf
+++ sys/kern/capabilities.conf
@@ -463,6 +463,7 @@
renameat
symlinkat
unlinkat
+unlinkfd
utimensat
##
Index: sys/kern/syscalls.master
===================================================================
--- sys/kern/syscalls.master
+++ sys/kern/syscalls.master
@@ -1027,6 +1027,7 @@
cpuwhich_t which, id_t id, \
size_t domainsetsize, domainset_t *mask, \
int policy); }
+563 AUE_NULL STD { int unlinkfd(int fd, char *path); }
; Please copy any additions and changes to the following compatability tables:
; sys/compat/freebsd32/syscalls.master
Index: sys/kern/vfs_syscalls.c
===================================================================
--- sys/kern/vfs_syscalls.c
+++ sys/kern/vfs_syscalls.c
@@ -1763,11 +1763,53 @@
return (kern_unlinkat(td, fd, path, UIO_USERSPACE, 0));
}
+static int
+unlink_vnode(struct thread *td, struct nameidata *nd, struct vnode *vp)
+{
+ int error;
+ struct mount *mp;
+
+ /*
+ * The root of a mounted filesystem cannot be deleted.
+ *
+ * XXX: can this only be a VDIR case?
+ */
+ if (vp->v_vflag & VV_ROOT) {
+ error = EBUSY;
+ } else {
+ if (vn_start_write(nd->ni_dvp, &mp, V_NOWAIT) != 0) {
+ NDFREE(nd, NDF_ONLY_PNBUF);
+ vput(nd->ni_dvp);
+ if (vp == nd->ni_dvp)
+ vrele(vp);
+ else
+ vput(vp);
+ if ((error = vn_start_write(NULL, &mp,
+ V_XSLEEP | PCATCH)) != 0)
+ return (error);
+ return (EINTR);
+ }
+#ifdef MAC
+ error = mac_vnode_check_unlink(td->td_ucred, nd->ni_dvp, vp,
+ &nd->ni_cnd);
+ if (error != 0)
+ goto out;
+#endif
+ vfs_notify_upper(vp, VFS_NOTIFY_UPPER_UNLINK);
+ error = VOP_REMOVE(nd->ni_dvp, vp, &nd->ni_cnd);
+#ifdef MAC
+out:
+#endif
+ vn_finished_write(mp);
+ }
+
+ return (error);
+}
+
int
kern_unlinkat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
ino_t oldinum)
{
- struct mount *mp;
struct vnode *vp;
struct nameidata nd;
struct stat sb;
@@ -1787,41 +1829,14 @@
((error = vn_stat(vp, &sb, td->td_ucred, NOCRED, td)) == 0) &&
sb.st_ino != oldinum) {
error = EIDRM; /* Identifier removed */
- } else {
- /*
- * The root of a mounted filesystem cannot be deleted.
- *
- * XXX: can this only be a VDIR case?
- */
- if (vp->v_vflag & VV_ROOT)
- error = EBUSY;
}
+
if (error == 0) {
- if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
- NDFREE(&nd, NDF_ONLY_PNBUF);
- vput(nd.ni_dvp);
- if (vp == nd.ni_dvp)
- vrele(vp);
- else
- vput(vp);
- if ((error = vn_start_write(NULL, &mp,
- V_XSLEEP | PCATCH)) != 0)
- return (error);
+ error = unlink_vnode(td, &nd, vp);
+ if (error == EINTR)
goto restart;
- }
-#ifdef MAC
- error = mac_vnode_check_unlink(td->td_ucred, nd.ni_dvp, vp,
- &nd.ni_cnd);
- if (error != 0)
- goto out;
-#endif
- vfs_notify_upper(vp, VFS_NOTIFY_UPPER_UNLINK);
- error = VOP_REMOVE(nd.ni_dvp, vp, &nd.ni_cnd);
-#ifdef MAC
-out:
-#endif
- vn_finished_write(mp);
}
+
NDFREE(&nd, NDF_ONLY_PNBUF);
vput(nd.ni_dvp);
if (vp == nd.ni_dvp)
@@ -1831,6 +1846,68 @@
return (error);
}
+#ifndef _SYS_SYSPROTO_H_
+struct unlinkfd_args {
+ int fd;
+ char *path;
+};
+#endif
+int
+sys_unlinkfd(struct thread *td, struct unlinkfd_args *uap)
+{
+ int fd = uap->fd;
+ char *path = uap->path;
+
+ return (kern_unlinkfd(td, fd, path));
+}
+
+int
+kern_unlinkfd(struct thread *td, int fd, char *path)
+{
+ struct nameidata nd;
+ struct file *fp;
+ struct vnode *vfdp, *vp;
+ cap_rights_t rights;
+ int error;
+
+ error = getvnode(td, fd, cap_rights_init(&rights, CAP_UNLINKFD), &fp);
+ if (error != 0)
+ return (error);
+ vfdp = fp->f_vnode;
+
+ if (vfdp->v_type == VDIR) {
+ error = EPERM;
+ goto out;
+ }
+
+restart:
+ bwillwrite();
+ NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF | AUDITVNODE1, UIO_USERSPACE,
+ path, td);
+ error = namei(&nd);
+ if (error != 0) {
+ if (error == EINVAL)
+ error = EPERM;
+ goto out;
+ }
+ vp = nd.ni_vp;
+ if (error == 0) {
+ if (vfdp == vp) {
+ error = unlink_vnode(td, &nd, vp);
+ if (error == EINTR)
+ goto restart;
+ } else {
+ error = EINVAL;
+ }
+ }
+ NDFREE(&nd, NDF_ONLY_PNBUF);
+ vput(nd.ni_dvp);
+ vput(vp);
+out:
+ fdrop(fp, td);
+ return (error);
+}
+
/*
* Reposition read/write file offset.
*/
Index: sys/sys/capsicum.h
===================================================================
--- sys/sys/capsicum.h
+++ sys/sys/capsicum.h
@@ -169,6 +169,8 @@
* will be removed.
*/
#define CAP_UNLINKAT (CAP_LOOKUP | 0x0000000010000000ULL)
+/* Allows unlinkfd. */
+#define CAP_UNLINKFD (CAP_LOOKUP | 0x0000080000000000ULL)
/* Socket operations. */
/* Allows for accept(2) and accept4(2). */
@@ -213,10 +215,10 @@
CAP_SETSOCKOPT | CAP_SHUTDOWN)
/* All used bits for index 0. */
-#define CAP_ALL0 CAPRIGHT(0, 0x000007FFFFFFFFFFULL)
+#define CAP_ALL0 CAPRIGHT(0, 0x00000FFFFFFFFFFFULL)
/* Available bits for index 0. */
-#define CAP_UNUSED0_44 CAPRIGHT(0, 0x0000080000000000ULL)
+#define CAP_UNUSED0_45 CAPRIGHT(0, 0x0000100000000000ULL)
/* ... */
#define CAP_UNUSED0_57 CAPRIGHT(0, 0x0100000000000000ULL)
Index: sys/sys/syscallsubr.h
===================================================================
--- sys/sys/syscallsubr.h
+++ sys/sys/syscallsubr.h
@@ -285,6 +285,7 @@
off_t length);
int kern_unlinkat(struct thread *td, int fd, char *path,
enum uio_seg pathseg, ino_t oldinum);
+int kern_unlinkfd(struct thread *td, int fd, char *path);
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
Details
Attached
Mime Type
text/plain
Expires
Tue, Nov 11, 4:03 PM (1 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25123062
Default Alt Text
D14567.id39889.diff (6 KB)
Attached To
Mode
D14567: Introduce funlinkat.
Attached
Detach File
Event Timeline
Log In to Comment