mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-29 16:21:29 +00:00
Kernel: Add unveil('b')
This is a new "browse" permission that lets you open (and subsequently list contents of) directories underneath the path, but not regular files or any other types of files.
This commit is contained in:
parent
23dc3ff0c2
commit
098070b767
Notes:
sideshowbarker
2024-07-19 01:17:40 +09:00
Author: https://github.com/bugaevc Commit: https://github.com/SerenityOS/serenity/commit/098070b767d Pull-request: https://github.com/SerenityOS/serenity/pull/4130 Reviewed-by: https://github.com/alimpfard Reviewed-by: https://github.com/awesomekling
|
@ -28,6 +28,7 @@ include the following characters:
|
|||
* `w`: May write to a file at this path
|
||||
* `x`: May execute a program image at this path
|
||||
* `c`: May create or remove a file at this path
|
||||
* `b`: May browse directories at this path
|
||||
|
||||
A single `unveil()` call may specify multiple permission characters at once.
|
||||
Subsequent `unveil()` calls may take away permissions from the ones allowed
|
||||
|
@ -78,6 +79,9 @@ unveil("/etc/WindowServer/WindowServer.ini", "rwc");
|
|||
// Allow the process to execute Calendar:
|
||||
unveil("/bin/Calendar", "x");
|
||||
|
||||
// Allow the process to browse files from /usr/share:
|
||||
unveil("/usr/share", "b");
|
||||
|
||||
// Disallow any further veil manipulation:
|
||||
unveil(nullptr, nullptr);
|
||||
```
|
||||
|
|
|
@ -644,6 +644,8 @@ static Optional<KBuffer> procfs$pid_unveil(InodeIdentifier identifier)
|
|||
permissions_builder.append('x');
|
||||
if (unveiled_path.permissions & UnveiledPath::Access::CreateOrRemove)
|
||||
permissions_builder.append('c');
|
||||
if (unveiled_path.permissions & UnveiledPath::Access::Browse)
|
||||
permissions_builder.append('b');
|
||||
obj.add("permissions", permissions_builder.to_string());
|
||||
}
|
||||
array.finish();
|
||||
|
|
|
@ -825,7 +825,13 @@ const UnveiledPath* VFS::find_matching_unveiled_path(StringView path)
|
|||
for (auto& unveiled_path : Process::current()->unveiled_paths()) {
|
||||
if (path == unveiled_path.path)
|
||||
return &unveiled_path;
|
||||
if (path.starts_with(unveiled_path.path) && path.length() > unveiled_path.path.length() && path[unveiled_path.path.length()] == '/')
|
||||
if (!path.starts_with(unveiled_path.path))
|
||||
continue;
|
||||
// /foo/ and /foo/bar
|
||||
if (unveiled_path.path.ends_with('/'))
|
||||
return &unveiled_path;
|
||||
// /foo and /foo/bar
|
||||
if (path.length() > unveiled_path.path.length() && path[unveiled_path.path.length()] == '/')
|
||||
return &unveiled_path;
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -863,10 +869,18 @@ KResult VFS::validate_path_against_process_veil(StringView path, int options)
|
|||
return KSuccess;
|
||||
}
|
||||
if (options & O_RDONLY) {
|
||||
if (!(unveiled_path->permissions & UnveiledPath::Access::Read)) {
|
||||
dbg() << "Rejecting path '" << path << "' since it hasn't been unveiled with 'r' permission.";
|
||||
dump_backtrace();
|
||||
return KResult(-EACCES);
|
||||
if (options & O_DIRECTORY) {
|
||||
if (!(unveiled_path->permissions & (UnveiledPath::Access::Read | UnveiledPath::Access::Browse))) {
|
||||
dbg() << "Rejecting path '" << path << "' since it hasn't been unveiled with 'r' or 'b' permissions.";
|
||||
dump_backtrace();
|
||||
return KResult(-EACCES);
|
||||
}
|
||||
} else {
|
||||
if (!(unveiled_path->permissions & UnveiledPath::Access::Read)) {
|
||||
dbg() << "Rejecting path '" << path << "' since it hasn't been unveiled with 'r' permission.";
|
||||
dump_backtrace();
|
||||
return KResult(-EACCES);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (options & O_WRONLY) {
|
||||
|
|
|
@ -101,6 +101,7 @@ struct UnveiledPath {
|
|||
Write = 2,
|
||||
Execute = 4,
|
||||
CreateOrRemove = 8,
|
||||
Browse = 16,
|
||||
};
|
||||
|
||||
String path;
|
||||
|
|
|
@ -49,7 +49,7 @@ int Process::sys$unveil(Userspace<const Syscall::SC_unveil_params*> user_params)
|
|||
if (!params.path.characters || !params.permissions.characters)
|
||||
return -EINVAL;
|
||||
|
||||
if (params.permissions.length > 4)
|
||||
if (params.permissions.length > 5)
|
||||
return -EINVAL;
|
||||
|
||||
auto path = get_syscall_path_argument(params.path);
|
||||
|
@ -79,6 +79,9 @@ int Process::sys$unveil(Userspace<const Syscall::SC_unveil_params*> user_params)
|
|||
case 'c':
|
||||
new_permissions |= UnveiledPath::Access::CreateOrRemove;
|
||||
break;
|
||||
case 'b':
|
||||
new_permissions |= UnveiledPath::Access::Browse;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue