nullfs - Add 'noexec' flag support.
authorAntonio Huete Jimenez <tuxillo@quantumachine.net>
Mon, 25 Oct 2010 15:04:37 +0000 (17:04 +0200)
committerMatthew Dillon <dillon@apollo.backplane.com>
Thu, 28 Oct 2010 23:06:07 +0000 (16:06 -0700)
* Make possible to mount a null-mount with 'noexec' option.

* If the underlying filesystem is mounted as 'noexec' and no options
were given at mount-time, the null mount will automatically
have 'noexec'.

Pointed-out-by: @dillon
sys/kern/imgact_elf.c
sys/kern/kern_exec.c
sys/sys/imgact.h
sys/vfs/nullfs/null_vfsops.c

index 6146fd2..d56f1f9 100644 (file)
@@ -491,6 +491,7 @@ elf_load_file(struct proc *p, const char *file, u_long *addr, u_long *entry)
        struct vmspace *vmspace = p->p_vmspace;
        struct vattr *attr;
        struct image_params *imgp;
+       struct mount *topmnt;
        vm_prot_t prot;
        u_long rbase;
        u_long base_addr = 0;
@@ -515,6 +516,7 @@ elf_load_file(struct proc *p, const char *file, u_long *addr, u_long *entry)
                error = nlookup(nd);
        if (error == 0)
                error = cache_vget(&nd->nl_nch, nd->nl_cred, LK_EXCLUSIVE, &imgp->vp);
+       topmnt = nd->nl_nch.mount;
        nlookup_done(nd);
        if (error)
                goto fail;
@@ -522,7 +524,7 @@ elf_load_file(struct proc *p, const char *file, u_long *addr, u_long *entry)
        /*
         * Check permissions, modes, uid, etc on the file, and "open" it.
         */
-       error = exec_check_permissions(imgp);
+       error = exec_check_permissions(imgp, topmnt);
        if (error) {
                vn_unlock(imgp->vp);
                goto fail;
index 0236c05..4bbb198 100644 (file)
@@ -237,9 +237,10 @@ interpret:
                goto exec_fail;
 
        /*
-        * Check file permissions (also 'opens' file)
+        * Check file permissions (also 'opens' file).
+        * Include also the top level mount in the check.
         */
-       error = exec_check_permissions(imgp);
+       error = exec_check_permissions(imgp, nd->nl_nch.mount);
        if (error) {
                vn_unlock(imgp->vp);
                goto exec_fail_dealloc;
@@ -981,7 +982,7 @@ exec_copyout_strings(struct image_params *imgp)
  *     Return 0 for success or error code on failure.
  */
 int
-exec_check_permissions(struct image_params *imgp)
+exec_check_permissions(struct image_params *imgp, struct mount *topmnt)
 {
        struct proc *p = imgp->proc;
        struct vnode *vp = imgp->vp;
@@ -1002,6 +1003,7 @@ exec_check_permissions(struct image_params *imgp)
         * 3) Insure that the file is a regular file.
         */
        if ((vp->v_mount->mnt_flag & MNT_NOEXEC) ||
+           ((topmnt != NULL) && (topmnt->mnt_flag & MNT_NOEXEC)) ||
            ((attr->va_mode & 0111) == 0) ||
            (attr->va_type != VREG)) {
                return (EACCES);
index 2d1eb85..e70c9a0 100644 (file)
@@ -37,6 +37,8 @@
 #ifndef _SYS_IMGACT_H_
 #define        _SYS_IMGACT_H_
 
+#include <sys/mount.h>
+
 #define MAXSHELLCMDLEN 128
 
 struct image_args {
@@ -71,7 +73,7 @@ enum  exec_path_segflg {PATH_SYSSPACE, PATH_USERSPACE};
 
 struct vmspace;
 int    exec_resident_imgact (struct image_params *);
-int    exec_check_permissions (struct image_params *);
+int    exec_check_permissions (struct image_params *, struct mount *);
 int    exec_new_vmspace (struct image_params *, struct vmspace *vmres);
 int    exec_shell_imgact (struct image_params *);
 int    exec_copyin_args(struct image_args *, char *, enum exec_path_segflg,
index 08100ee..57901df 100644 (file)
@@ -140,6 +140,8 @@ nullfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
        if (xmp->nullm_vfs != rootvp->v_mount) {
                if (xmp->nullm_vfs->mnt_flag & MNT_RDONLY)
                        mp->mnt_flag |= MNT_RDONLY;
+               if (xmp->nullm_vfs->mnt_flag & MNT_NOEXEC)
+                       mp->mnt_flag |= MNT_NOEXEC;
                xmp->nullm_vfs = rootvp->v_mount;
        }