Author: pjd Date: Thu Mar 21 22:59:01 2013 New Revision: 248599 URL: http://svnweb.freebsd.org/changeset/base/248599
Log: Implement chflagsat(2) system call, similar to fchmodat(2), but operates on file flags. Reviewed by: kib, jilles Sponsored by: The FreeBSD Foundation Modified: head/contrib/openbsm/etc/audit_event head/lib/libc/sys/Symbol.map head/sys/bsm/audit_kevents.h head/sys/compat/freebsd32/syscalls.master head/sys/kern/capabilities.conf head/sys/kern/syscalls.master head/sys/kern/vfs_syscalls.c head/sys/sys/capability.h head/sys/sys/stat.h Modified: head/contrib/openbsm/etc/audit_event ============================================================================== --- head/contrib/openbsm/etc/audit_event Thu Mar 21 22:47:03 2013 (r248598) +++ head/contrib/openbsm/etc/audit_event Thu Mar 21 22:59:01 2013 (r248599) @@ -570,6 +570,7 @@ 43206:AUE_CAP_FCNTLS_GET:cap_fcntls_get(2):fm 43207:AUE_BINDAT:bindat(2):nt 43208:AUE_CONNECTAT:connectat(2):nt +43209:AUE_CHFLAGSAT:chflagsat(2):fm # # Solaris userspace events. # Modified: head/lib/libc/sys/Symbol.map ============================================================================== --- head/lib/libc/sys/Symbol.map Thu Mar 21 22:47:03 2013 (r248598) +++ head/lib/libc/sys/Symbol.map Thu Mar 21 22:59:01 2013 (r248599) @@ -386,6 +386,7 @@ FBSD_1.3 { cap_rights_get; cap_rights_limit; cap_sandboxed; + chflagsat; clock_getcpuclockid2; connectat; ffclock_getcounter; Modified: head/sys/bsm/audit_kevents.h ============================================================================== --- head/sys/bsm/audit_kevents.h Thu Mar 21 22:47:03 2013 (r248598) +++ head/sys/bsm/audit_kevents.h Thu Mar 21 22:59:01 2013 (r248599) @@ -610,6 +610,7 @@ #define AUE_CAP_FCNTLS_GET 43206 /* TrustedBSD. */ #define AUE_BINDAT 43207 /* TrustedBSD. */ #define AUE_CONNECTAT 43208 /* TrustedBSD. */ +#define AUE_CHFLAGSAT 43209 /* FreeBSD-specific. */ /* * Darwin BSM uses a number of AUE_O_* definitions, which are aliased to the Modified: head/sys/compat/freebsd32/syscalls.master ============================================================================== --- head/sys/compat/freebsd32/syscalls.master Thu Mar 21 22:47:03 2013 (r248598) +++ head/sys/compat/freebsd32/syscalls.master Thu Mar 21 22:59:01 2013 (r248599) @@ -1020,3 +1020,5 @@ int namelen); } 539 AUE_CONNECTAT NOPROTO { int connectat(int fd, int s, caddr_t name, \ int namelen); } +540 AUE_CHFLAGSAT NOPROTO { int chflagsat(int fd, const char *path, \ + u_long flags, int atflag); } Modified: head/sys/kern/capabilities.conf ============================================================================== --- head/sys/kern/capabilities.conf Thu Mar 21 22:47:03 2013 (r248598) +++ head/sys/kern/capabilities.conf Thu Mar 21 22:59:01 2013 (r248599) @@ -445,6 +445,7 @@ olio_listio ## ## Operations relative to directory capabilities. ## +chflagsat faccessat fchmodat fchownat Modified: head/sys/kern/syscalls.master ============================================================================== --- head/sys/kern/syscalls.master Thu Mar 21 22:47:03 2013 (r248598) +++ head/sys/kern/syscalls.master Thu Mar 21 22:59:01 2013 (r248599) @@ -970,5 +970,7 @@ int namelen); } 539 AUE_CONNECTAT STD { int connectat(int fd, int s, caddr_t name, \ int namelen); } +540 AUE_CHFLAGSAT STD { int chflagsat(int fd, const char *path, \ + u_long flags, int atflag); } ; Please copy any additions and changes to the following compatability tables: ; sys/compat/freebsd32/syscalls.master Modified: head/sys/kern/vfs_syscalls.c ============================================================================== --- head/sys/kern/vfs_syscalls.c Thu Mar 21 22:47:03 2013 (r248598) +++ head/sys/kern/vfs_syscalls.c Thu Mar 21 22:59:01 2013 (r248599) @@ -101,6 +101,10 @@ SDT_PROBE_ARGTYPE(vfs, , stat, reg, 1, " static int chroot_refuse_vdir_fds(struct filedesc *fdp); static int getutimes(const struct timeval *, enum uio_seg, struct timespec *); +static int kern_chflags(struct thread *td, const char *path, + enum uio_seg pathseg, u_long flags); +static int kern_chflagsat(struct thread *td, int fd, const char *path, + enum uio_seg pathseg, u_long flags, int atflag); static int setfflags(struct thread *td, struct vnode *, u_long); static int setutimes(struct thread *td, struct vnode *, const struct timespec *, int, int); @@ -2669,17 +2673,38 @@ sys_chflags(td, uap) u_long flags; } */ *uap; { - int error; - struct nameidata nd; - AUDIT_ARG_FFLAGS(uap->flags); - NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE1, UIO_USERSPACE, uap->path, td); - if ((error = namei(&nd)) != 0) - return (error); - NDFREE(&nd, NDF_ONLY_PNBUF); - error = setfflags(td, nd.ni_vp, uap->flags); - vrele(nd.ni_vp); - return (error); + return (kern_chflags(td, uap->path, UIO_USERSPACE, uap->flags)); +} + +#ifndef _SYS_SYSPROTO_H_ +struct chflagsat_args { + int fd; + const char *path; + u_long flags; + int atflag; +} +#endif +int +sys_chflagsat(struct thread *td, struct chflagsat_args *uap) +{ + int fd = uap->fd; + char *path = uap->path; + u_long flags = uap->flags; + int atflag = uap->atflag; + + if (atflag & ~AT_SYMLINK_NOFOLLOW) + return (EINVAL); + + return (kern_chflagsat(td, fd, path, UIO_USERSPACE, flags, atflag)); +} + +static int +kern_chflags(struct thread *td, const char *path, enum uio_seg pathseg, + u_long flags) +{ + + return (kern_chflagsat(td, AT_FDCWD, path, pathseg, flags, 0)); } /* @@ -2693,16 +2718,26 @@ sys_lchflags(td, uap) u_long flags; } */ *uap; { - int error; + + return (kern_chflagsat(td, AT_FDCWD, uap->path, UIO_USERSPACE, + uap->flags, AT_SYMLINK_NOFOLLOW)); +} + +static int +kern_chflagsat(struct thread *td, int fd, const char *path, + enum uio_seg pathseg, u_long flags, int atflag) +{ struct nameidata nd; + int error, follow; - AUDIT_ARG_FFLAGS(uap->flags); - NDINIT(&nd, LOOKUP, NOFOLLOW | AUDITVNODE1, UIO_USERSPACE, uap->path, - td); + AUDIT_ARG_FFLAGS(flags); + follow = (atflag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW; + NDINIT_ATRIGHTS(&nd, LOOKUP, follow | AUDITVNODE1, pathseg, path, fd, + CAP_FCHFLAGS, td); if ((error = namei(&nd)) != 0) return (error); NDFREE(&nd, NDF_ONLY_PNBUF); - error = setfflags(td, nd.ni_vp, uap->flags); + error = setfflags(td, nd.ni_vp, flags); vrele(nd.ni_vp); return (error); } Modified: head/sys/sys/capability.h ============================================================================== --- head/sys/sys/capability.h Thu Mar 21 22:47:03 2013 (r248598) +++ head/sys/sys/capability.h Thu Mar 21 22:59:01 2013 (r248599) @@ -102,6 +102,7 @@ /* VFS methods. */ #define CAP_FCHDIR 0x0000000000000200ULL #define CAP_FCHFLAGS 0x0000000000000100ULL +#define CAP_CHFLAGSAT CAP_FCHFLAGS #define CAP_FCHMOD 0x0000000000000400ULL #define CAP_FCHMODAT CAP_FCHMOD #define CAP_FCHOWN 0x0000000000000800ULL Modified: head/sys/sys/stat.h ============================================================================== --- head/sys/sys/stat.h Thu Mar 21 22:47:03 2013 (r248598) +++ head/sys/sys/stat.h Thu Mar 21 22:59:01 2013 (r248599) @@ -293,6 +293,7 @@ struct nstat { __BEGIN_DECLS #if __BSD_VISIBLE int chflags(const char *, unsigned long); +int chflagsat(int, const char *, unsigned long, int); #endif int chmod(const char *, mode_t); #if __BSD_VISIBLE _______________________________________________ svn-src-head@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"