From 246693acf8309ec9b86116ad739d385afccdcdaa Mon Sep 17 00:00:00 2001 From: Antonio Huete Jimenez Date: Mon, 25 Oct 2010 17:04:37 +0200 Subject: [PATCH] nullfs - Add 'noexec' flag support. * 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 | 4 +++- sys/kern/kern_exec.c | 8 +++++--- sys/sys/imgact.h | 4 +++- sys/vfs/nullfs/null_vfsops.c | 2 ++ 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index 6146fd2b26..d56f1f96b0 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -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; diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 0236c05d51..4bbb198269 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -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); diff --git a/sys/sys/imgact.h b/sys/sys/imgact.h index 2d1eb855a4..e70c9a0f07 100644 --- a/sys/sys/imgact.h +++ b/sys/sys/imgact.h @@ -37,6 +37,8 @@ #ifndef _SYS_IMGACT_H_ #define _SYS_IMGACT_H_ +#include + #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, diff --git a/sys/vfs/nullfs/null_vfsops.c b/sys/vfs/nullfs/null_vfsops.c index 08100eeed6..57901dfc88 100644 --- a/sys/vfs/nullfs/null_vfsops.c +++ b/sys/vfs/nullfs/null_vfsops.c @@ -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; } -- 2.41.0