* 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
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;
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;
/*
* 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;
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;
* 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;
* 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);
#ifndef _SYS_IMGACT_H_
#define _SYS_IMGACT_H_
+#include <sys/mount.h>
+
#define MAXSHELLCMDLEN 128
struct image_args {
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,
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;
}