diff --git a/sys/vfs/vfs_lookup.pas b/sys/vfs/vfs_lookup.pas index 9f0135a9..516fb5cd 100644 --- a/sys/vfs/vfs_lookup.pas +++ b/sys/vfs/vfs_lookup.pas @@ -661,20 +661,23 @@ dirloop: ((cnp^.cn_flags and NOCROSSMOUNT)<>0)) then begin ndp^.ni_dvp:=dp; - ndp^.ni_vp:=dp; + ndp^.ni_vp :=dp; vfslocked:=VFS_LOCK_GIANT(dp^.v_mount); VREF(dp); goto nextname; end; + if ((dp^.v_vflag and VV_ROOT)=0) then begin break; end; + if ((dp^.v_iflag and VI_DOOMED)<>0) then { forced unmount } begin error:=ENOENT; goto bad; end; + tdp:=dp; dp:=p_mount(dp^.v_mount)^.mnt_vnodecovered; tvfslocked:=dvfslocked; diff --git a/sys/vfs/vfs_mountroot.pas b/sys/vfs/vfs_mountroot.pas index 7b528b22..29e31213 100644 --- a/sys/vfs/vfs_mountroot.pas +++ b/sys/vfs/vfs_mountroot.pas @@ -117,20 +117,26 @@ end; procedure set_rootvnode(); begin if (VFS_ROOT(TAILQ_FIRST(@mountlist), LK_EXCLUSIVE, @rootvnode)<>0) then + begin Assert(False,'Cannot find root vnode'); + end; VOP_UNLOCK(rootvnode, 0); FILEDESC_XLOCK(@fd_table); if (fd_table.fd_cdir<>nil) then + begin vrele(fd_table.fd_cdir); + end; fd_table.fd_cdir:=rootvnode; VREF(rootvnode); if (fd_table.fd_rdir<>nil) then + begin vrele(fd_table.fd_rdir); + end; fd_table.fd_rdir:=rootvnode; VREF(rootvnode); diff --git a/sys/vfs/vfs_syscalls.pas b/sys/vfs/vfs_syscalls.pas index 0e99cbf8..8aa14053 100644 --- a/sys/vfs/vfs_syscalls.pas +++ b/sys/vfs/vfs_syscalls.pas @@ -754,6 +754,7 @@ var begin VFS_ASSERT_GIANT(vp^.v_mount); FILEDESC_XLOCK(@fd_table); + if (chroot_allow_open_directories=0) or ((chroot_allow_open_directories=1) and (fd_table.fd_rdir<>rootvnode)) then begin @@ -764,14 +765,17 @@ begin Exit(error); end; end; + oldvp:=fd_table.fd_rdir; fd_table.fd_rdir:=vp; VREF(fd_table.fd_rdir); + if (fd_table.fd_jdir=nil) then begin fd_table.fd_jdir:=vp; VREF(fd_table.fd_jdir); end; + FILEDESC_XUNLOCK(@fd_table); vfslocked:=VFS_LOCK_GIANT(oldvp^.v_mount); vrele(oldvp); @@ -808,13 +812,19 @@ begin end; if ((flags and O_CREAT)<>0) then + begin rights:=rights or CAP_CREATE; + end; if ((flags and O_TRUNC)<>0) then + begin rights:=rights or CAP_FTRUNCATE; + end; if ((flags and O_EXLOCK)<>0) or ((flags and O_SHLOCK)<>0) then + begin rights:=rights or CAP_FLOCK; + end; Exit(rights); end;