diff --git a/gui/game_run.pas b/gui/game_run.pas index 3050519c..bd255c40 100644 --- a/gui/game_run.pas +++ b/gui/game_run.pas @@ -248,13 +248,13 @@ begin err:=vfs_mount_mkdir('ufs','/savedata0' ,'savedata',nil,0); //fs guest host - err:=vfs_mount_mkdir('ufs','/app0' ,pchar(Item.FMountList.app0 ),nil,0); + err:=vfs_mount_mkdir('ufs','/app0' ,pchar(Item.FMountList.app0 ),nil,MNT_RDONLY); if (err<>0) then begin print_error_td('error mount "'+Item.FMountList.app0+'" to "/app0" code='+IntToStr(err)); end; - err:=vfs_mount_mkdir('ufs','/system',pchar(Item.FMountList.system),nil,0); + err:=vfs_mount_mkdir('ufs','/system',pchar(Item.FMountList.system),nil,MNT_RDONLY); if (err<>0) then begin print_error_td('error mount "'+Item.FMountList.system+'" to "/system" code='+IntToStr(err)); diff --git a/sys/fs/devfs/devfs_vnops.pas b/sys/fs/devfs/devfs_vnops.pas index 1638b08d..14c46fec 100644 --- a/sys/fs/devfs/devfs_vnops.pas +++ b/sys/fs/devfs/devfs_vnops.pas @@ -1122,7 +1122,7 @@ begin if (cnp^.cn_namelen=1) and (pname^='.') then begin - if ((flags and ISLASTCN) and nameiop<>LOOKUP) then + if ((flags and ISLASTCN)<>0) and (nameiop<>LOOKUP) then begin Exit(EINVAL); end; diff --git a/sys/fs/nullfs/null_vnops.pas b/sys/fs/nullfs/null_vnops.pas index 44fc9737..7f035770 100644 --- a/sys/fs/nullfs/null_vnops.pas +++ b/sys/fs/nullfs/null_vnops.pas @@ -345,14 +345,15 @@ begin vp:=ap^.a_vp; vap:=ap^.a_vap; - if ((vap^.va_flags <>VNOVAL) or + if ((p_mount(vp^.v_mount)^.mnt_flag and MNT_RDONLY)<>0) and + ( + (vap^.va_flags <>VNOVAL) or (vap^.va_uid <>VNOVAL) or (vap^.va_gid <>VNOVAL) or (vap^.va_atime.tv_sec<>VNOVAL) or (vap^.va_mtime.tv_sec<>VNOVAL) or (vap^.va_mode <>VNOVAL) - ) and - ((p_mount(vp^.v_mount)^.mnt_flag and MNT_RDONLY)<>0) then + ) then begin Exit(EROFS); end; @@ -370,7 +371,9 @@ begin VFIFO: begin if (vap^.va_flags<>VNOVAL) then + begin Exit(EOPNOTSUPP); + end; Exit(0); end; else @@ -380,7 +383,9 @@ begin * mounted read-only. } if ((p_mount(vp^.v_mount)^.mnt_flag and MNT_RDONLY)<>0) then + begin Exit(EROFS); + end; end; end; end; @@ -434,7 +439,9 @@ begin VREG: begin if ((p_mount(vp^.v_mount)^.mnt_flag and MNT_RDONLY)<>0) then + begin Exit(EROFS); + end; end; else; end; diff --git a/sys/fs/ufs/ufs_vnops.pas b/sys/fs/ufs/ufs_vnops.pas index a56969dc..fd65497d 100644 --- a/sys/fs/ufs/ufs_vnops.pas +++ b/sys/fs/ufs/ufs_vnops.pas @@ -461,6 +461,14 @@ begin Exit(ENOTDIR); end; + //If read-only and op is not LOOKUP, will return EROFS. + if ((flags and ISLASTCN)<>0) and + ((p_mount(dvp^.v_mount)^.mnt_flag and MNT_RDONLY)<>0) and + (nameiop <> LOOKUP) then + begin + Exit(EROFS); + end; + if (((flags and ISDOTDOT)<>0) and ((dvp^.v_vflag and VV_ROOT)<>0)) then begin Exit(EIO); @@ -474,7 +482,7 @@ begin if (cnp^.cn_namelen=1) and (pname^='.') then begin - if ((flags and ISLASTCN) and nameiop<>LOOKUP) then + if ((flags and ISLASTCN)<>0) and (nameiop<>LOOKUP) then begin Exit(EINVAL); end; @@ -571,13 +579,28 @@ function ufs_access(ap:p_vop_access_args):Integer; var vp:p_vnode; de:p_ufs_dirent; + accmode:accmode_t; error:Integer; begin vp:=ap^.a_vp; de:=vp^.v_data; - error:=vaccess(vp^.v_type, de^.ufs_mode, de^.ufs_uid, de^.ufs_gid, ap^.a_accmode, nil); + accmode:=ap^.a_accmode; + + if ((accmode and VWRITE)<>0) and + ((p_mount(vp^.v_mount)^.mnt_flag and MNT_RDONLY)<>0) then + begin + case vp^.v_type of + VREG, + VDIR, + VLNK: + Exit(EROFS); + else; + end; + end; + + error:=vaccess(vp^.v_type, de^.ufs_mode, de^.ufs_uid, de^.ufs_gid, accmode, nil); if (error=0) then begin @@ -659,6 +682,19 @@ begin vap:=ap^.a_vap; vp:=ap^.a_vp; + if ((p_mount(vp^.v_mount)^.mnt_flag and MNT_RDONLY)<>0) and + ( + (vap^.va_flags <>VNOVAL) or + (vap^.va_uid <>VNOVAL) or + (vap^.va_gid <>VNOVAL) or + (vap^.va_atime.tv_sec<>VNOVAL) or + (vap^.va_mtime.tv_sec<>VNOVAL) or + (vap^.va_mode <>VNOVAL) + ) then + begin + Exit(EROFS); + end; + if (vap^.va_type <>VNON) or (vap^.va_nlink <>VNOVAL) or (vap^.va_fsid <>VNOVAL) or diff --git a/sys/md/md_vnops.pas b/sys/md/md_vnops.pas index ae997531..65d0b66b 100644 --- a/sys/md/md_vnops.pas +++ b/sys/md/md_vnops.pas @@ -1162,6 +1162,14 @@ begin Exit(ENOTDIR); end; + //If read-only and op is not LOOKUP, will return EROFS. + if ((flags and ISLASTCN)<>0) and + ((p_mount(dvp^.v_mount)^.mnt_flag and MNT_RDONLY)<>0) and + (nameiop <> LOOKUP) then + begin + Exit(EROFS); + end; + if (((flags and ISDOTDOT)<>0) and ((dvp^.v_vflag and VV_ROOT)<>0)) then begin Exit(EIO); @@ -1175,7 +1183,7 @@ begin if (cnp^.cn_namelen=1) and (pname^='.') then begin - if ((flags and ISLASTCN) and nameiop<>LOOKUP) then + if ((flags and ISLASTCN)<>0) and (nameiop<>LOOKUP) then begin Exit(EINVAL); end; @@ -2175,6 +2183,19 @@ begin vap:=ap^.a_vap; vp:=ap^.a_vp; + if ((p_mount(vp^.v_mount)^.mnt_flag and MNT_RDONLY)<>0) and + ( + (vap^.va_flags <>VNOVAL) or + (vap^.va_uid <>VNOVAL) or + (vap^.va_gid <>VNOVAL) or + (vap^.va_atime.tv_sec<>VNOVAL) or + (vap^.va_mtime.tv_sec<>VNOVAL) or + (vap^.va_mode <>VNOVAL) + ) then + begin + Exit(EROFS); + end; + if (vap^.va_type <>VNON) or (vap^.va_nlink <>VNOVAL) or (vap^.va_fsid <>VNOVAL) or diff --git a/sys/vfs/vfs_mountroot.pas b/sys/vfs/vfs_mountroot.pas index 9e7209f1..7b528b22 100644 --- a/sys/vfs/vfs_mountroot.pas +++ b/sys/vfs/vfs_mountroot.pas @@ -9,6 +9,9 @@ uses mqueue, vmount; +const + MNT_RDONLY=vmount.MNT_RDONLY; + procedure vfs_mountroot(); function vfs_mount_path (fstype,fspath,from,opts:PChar;flags:QWORD):Integer; function vfs_mount_mkdir (fstype,fspath,from,opts:PChar;flags:QWORD):Integer;