mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 14:28:12 +00:00
Kernel: Handle promise violations in the syscall handler
Previously we would crash the process immediately when a promise violation was found during a syscall. This is error prone, as we don't unwind the stack. This means that in certain cases we can leak resources, like an OwnPtr / RefPtr tracked on the stack. Or even leak a lock acquired in a ScopeLockLocker. To remedy this situation we move the promise violation handling to the syscall handler, right before we return to user space. This allows the code to follow the normal unwind path, and grantees there is no longer any cleanup that needs to occur. The Process::require_promise() and Process::require_no_promises() functions were modified to return ErrorOr<void> so we enforce that the errors are always propagated by the caller.
This commit is contained in:
parent
c444a3fc9e
commit
54b9a4ec1e
66 changed files with 156 additions and 148 deletions
|
@ -11,7 +11,7 @@ namespace Kernel {
|
|||
ErrorOr<FlatPtr> Process::sys$seteuid(UserID new_euid)
|
||||
{
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||
require_promise(Pledge::id);
|
||||
TRY(require_promise(Pledge::id));
|
||||
|
||||
if (new_euid == (uid_t)-1)
|
||||
return EINVAL;
|
||||
|
@ -31,7 +31,7 @@ ErrorOr<FlatPtr> Process::sys$seteuid(UserID new_euid)
|
|||
ErrorOr<FlatPtr> Process::sys$setegid(GroupID new_egid)
|
||||
{
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||
require_promise(Pledge::id);
|
||||
TRY(require_promise(Pledge::id));
|
||||
|
||||
if (new_egid == (uid_t)-1)
|
||||
return EINVAL;
|
||||
|
@ -50,7 +50,7 @@ ErrorOr<FlatPtr> Process::sys$setegid(GroupID new_egid)
|
|||
ErrorOr<FlatPtr> Process::sys$setuid(UserID new_uid)
|
||||
{
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||
require_promise(Pledge::id);
|
||||
TRY(require_promise(Pledge::id));
|
||||
|
||||
if (new_uid == (uid_t)-1)
|
||||
return EINVAL;
|
||||
|
@ -71,7 +71,7 @@ ErrorOr<FlatPtr> Process::sys$setuid(UserID new_uid)
|
|||
ErrorOr<FlatPtr> Process::sys$setgid(GroupID new_gid)
|
||||
{
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||
require_promise(Pledge::id);
|
||||
TRY(require_promise(Pledge::id));
|
||||
|
||||
if (new_gid == (uid_t)-1)
|
||||
return EINVAL;
|
||||
|
@ -92,7 +92,7 @@ ErrorOr<FlatPtr> Process::sys$setgid(GroupID new_gid)
|
|||
ErrorOr<FlatPtr> Process::sys$setreuid(UserID new_ruid, UserID new_euid)
|
||||
{
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||
require_promise(Pledge::id);
|
||||
TRY(require_promise(Pledge::id));
|
||||
|
||||
if (new_ruid == (uid_t)-1)
|
||||
new_ruid = uid();
|
||||
|
@ -118,7 +118,7 @@ ErrorOr<FlatPtr> Process::sys$setreuid(UserID new_ruid, UserID new_euid)
|
|||
ErrorOr<FlatPtr> Process::sys$setresuid(UserID new_ruid, UserID new_euid, UserID new_suid)
|
||||
{
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||
require_promise(Pledge::id);
|
||||
TRY(require_promise(Pledge::id));
|
||||
|
||||
if (new_ruid == (uid_t)-1)
|
||||
new_ruid = uid();
|
||||
|
@ -144,7 +144,7 @@ ErrorOr<FlatPtr> Process::sys$setresuid(UserID new_ruid, UserID new_euid, UserID
|
|||
ErrorOr<FlatPtr> Process::sys$setresgid(GroupID new_rgid, GroupID new_egid, GroupID new_sgid)
|
||||
{
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||
require_promise(Pledge::id);
|
||||
TRY(require_promise(Pledge::id));
|
||||
|
||||
if (new_rgid == (gid_t)-1)
|
||||
new_rgid = gid();
|
||||
|
@ -170,7 +170,7 @@ ErrorOr<FlatPtr> Process::sys$setresgid(GroupID new_rgid, GroupID new_egid, Grou
|
|||
ErrorOr<FlatPtr> Process::sys$setgroups(size_t count, Userspace<const gid_t*> user_gids)
|
||||
{
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||
require_promise(Pledge::id);
|
||||
TRY(require_promise(Pledge::id));
|
||||
if (!is_superuser())
|
||||
return EPERM;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue