diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index 6146fd2..63dd544 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -522,7 +522,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, NULL); if (error) { vn_unlock(imgp->vp); goto fail; diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 0236c05..e2a75e4 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -186,6 +186,7 @@ kern_execve(struct nlookupdata *nd, struct image_args *args) int error, len, i; struct image_params image_params, *imgp; struct vattr attr; + struct mount *m_toplevel; int (*img_first) (struct image_params *); if (debug_execve_args) { @@ -237,9 +238,11 @@ 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); + m_toplevel = nd->nl_nch.mount; + error = exec_check_permissions(imgp, m_toplevel); if (error) { vn_unlock(imgp->vp); goto exec_fail_dealloc; @@ -981,7 +984,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 *m_toplevel) { struct proc *p = imgp->proc; struct vnode *vp = imgp->vp; @@ -1002,6 +1005,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) || + ((m_toplevel != NULL) && (m_toplevel->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 2d1eb85..e70c9a0 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 08100ee..57901df 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; }