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-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to