chroot_kernel() - new syscall to set rootnch/rootvn
authorAlex Hornung <ahornung@gmail.com>
Sat, 26 Jun 2010 21:34:28 +0000 (22:34 +0100)
committerAlex Hornung <ahornung@gmail.com>
Sun, 27 Jun 2010 01:05:51 +0000 (02:05 +0100)
* This new syscall can be used to override the default rootnch and
  rootvnode which are used for path lookups outside of a process context
  (i.e. in kernel-only context)

include/unistd.h
sys/kern/init_sysent.c
sys/kern/syscalls.c
sys/kern/syscalls.master
sys/kern/vfs_syscalls.c
sys/sys/syscall-hide.h
sys/sys/syscall.h
sys/sys/syscall.mk
sys/sys/sysproto.h
sys/sys/sysunion.h

index db7ae7e..d864fb7 100644 (file)
@@ -469,6 +469,7 @@ void         sync(void);
 #if (__XSI_VISIBLE && __XSI_VISIBLE <= 500) || __BSD_VISIBLE
 int     brk(const void *);
 int     chroot(const char *);
+int     chroot_kernel(const char *);
 int     getdtablesize(void);
 int     getpagesize(void) __pure2;
 char   *getpass(const char *);
index 089c558..f186de1 100644 (file)
@@ -555,4 +555,5 @@ struct sysent sysent[] = {
        { AS(mq_timedreceive_args), (sy_call_t *)sys_mq_timedreceive }, /* 519 = mq_timedreceive */
        { AS(ioprio_set_args), (sy_call_t *)sys_ioprio_set },   /* 520 = ioprio_set */
        { AS(ioprio_get_args), (sy_call_t *)sys_ioprio_get },   /* 521 = ioprio_get */
+       { AS(chroot_kernel_args), (sy_call_t *)sys_chroot_kernel },     /* 522 = chroot_kernel */
 };
index a2bbb29..42d6c83 100644 (file)
@@ -529,4 +529,5 @@ const char *syscallnames[] = {
        "mq_timedreceive",                      /* 519 = mq_timedreceive */
        "ioprio_set",                   /* 520 = ioprio_set */
        "ioprio_get",                   /* 521 = ioprio_get */
+       "chroot_kernel",                        /* 522 = chroot_kernel */
 };
index 4977a5f..591bcef 100644 (file)
                                  const struct timespec *abs_timeout); }
 520    STD     BSD     { int ioprio_set(int which, int who, int prio); }
 521    STD     BSD     { int ioprio_get(int which, int who); }
+522    STD     BSD     { int chroot_kernel(char *path); }
index 20807c7..05733c7 100644 (file)
@@ -1752,6 +1752,48 @@ sys_chroot(struct chroot_args *uap)
        return(error);
 }
 
+int
+sys_chroot_kernel(struct chroot_kernel_args *uap)
+{
+       struct thread *td = curthread;
+       struct nlookupdata nd;
+       struct nchandle *nch;
+       struct vnode *vp;
+       int error;
+
+       get_mplock();
+       error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW);
+       if (error)
+               goto error_nond;
+
+       error = nlookup(&nd);
+       if (error)
+               goto error_out;
+
+       nch = &nd.nl_nch;
+
+       error = priv_check_cred(td->td_ucred, PRIV_VFS_CHROOT, 0);
+       if (error)
+               goto error_out;
+
+       if ((vp = nch->ncp->nc_vp) == NULL) {
+               error = ENOENT;
+               goto error_out;
+       }
+
+       if ((error = cache_vref(nch, nd.nl_cred, &vp)) != 0)
+               goto error_out;
+
+       kprintf("chroot_kernel: set new rootnch/rootvnode to %s\n", uap->path);
+       vfs_cache_setroot(vp, cache_hold(nch));
+
+error_out:
+       nlookup_done(&nd);
+error_nond:
+       rel_mplock();
+       return(error);
+}
+
 /*
  * Common routine for chroot and chdir.  Given a locked, referenced vnode,
  * determine whether it is legal to chdir to the vnode.  The vnode's state
index a0ec77d..0607195 100644 (file)
@@ -352,3 +352,4 @@ HIDE_POSIX(mq_timedsend)
 HIDE_POSIX(mq_timedreceive)
 HIDE_BSD(ioprio_set)
 HIDE_BSD(ioprio_get)
+HIDE_BSD(chroot_kernel)
index ce21144..b121f6e 100644 (file)
 #define        SYS_mq_timedreceive     519
 #define        SYS_ioprio_set  520
 #define        SYS_ioprio_get  521
-#define        SYS_MAXSYSCALL  522
+#define        SYS_chroot_kernel       522
+#define        SYS_MAXSYSCALL  523
index a06739b..4103f66 100644 (file)
@@ -300,4 +300,5 @@ MIASM =  \
        mq_timedsend.o \
        mq_timedreceive.o \
        ioprio_set.o \
-       ioprio_get.o
+       ioprio_get.o \
+       chroot_kernel.o
index 4c3f31f..6b365af 100644 (file)
@@ -2295,6 +2295,12 @@ struct   ioprio_get_args {
        int     which;  char which_[PAD_(int)];
        int     who;    char who_[PAD_(int)];
 };
+struct chroot_kernel_args {
+#ifdef _KERNEL
+       struct sysmsg sysmsg;
+#endif
+       char *  path;   char path_[PAD_(char *)];
+};
 
 #ifdef COMPAT_43
 
@@ -2903,6 +2909,7 @@ int       sys_mq_timedsend (struct mq_timedsend_args *);
 int    sys_mq_timedreceive (struct mq_timedreceive_args *);
 int    sys_ioprio_set (struct ioprio_set_args *);
 int    sys_ioprio_get (struct ioprio_get_args *);
+int    sys_chroot_kernel (struct chroot_kernel_args *);
 
 #endif /* !_SYS_SYSPROTO_H_ */
 #undef PAD_
index af303c1..374ee3c 100644 (file)
@@ -408,4 +408,5 @@ union sysunion {
        struct  mq_timedreceive_args mq_timedreceive;
        struct  ioprio_set_args ioprio_set;
        struct  ioprio_get_args ioprio_get;
+       struct  chroot_kernel_args chroot_kernel;
 };