1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 13:57:35 +00:00

Kernel/SysFS: Don't refresh/set-values inside the Jail spinlock scope

Only do so after a brief check if we are in a Jail or not. This fixes
SMP, because apparently it is crashing when calling try_generate()
from the SysFSGlobalInformation::refresh_data method, so the fix for
this is to simply not do that inside the Process' Jail spinlock scope,
because otherwise we will simply have a possible flow of taking
multiple conflicting Spinlocks (in the wrong order multiple times), for
the SysFSOverallProcesses generation code:
Process::current().jail(), and then Process::for_each_in_same_jail being
called, we take Process::all_instances(), and Process::current().jail()
again.
Therefore, we should at the very least eliminate the first taking of the
Process::current().jail() spinlock, in the refresh_data method of the
SysFSGlobalInformation class.
This commit is contained in:
Liav A 2023-01-03 22:45:42 +02:00 committed by Jelle Raaijmakers
parent 76b9d06b19
commit a9839d7ac5
3 changed files with 18 additions and 15 deletions

View file

@ -23,20 +23,22 @@ ErrorOr<size_t> SysFSSystemBooleanVariable::write_bytes(off_t, size_t count, Use
char value = 0;
TRY(buffer.read(&value, 1));
return Process::current().jail().with([&](auto& my_jail) -> ErrorOr<size_t> {
TRY(Process::current().jail().with([&](auto& my_jail) -> ErrorOr<void> {
// Note: If we are in a jail, don't let the current process to change the variable.
if (my_jail)
return Error::from_errno(EPERM);
if (count != 1)
return Error::from_errno(EINVAL);
if (value == '0')
set_value(false);
else if (value == '1')
set_value(true);
else
return Error::from_errno(EINVAL);
return {};
}));
if (count != 1)
return Error::from_errno(EINVAL);
if (value == '0') {
set_value(false);
return 1;
});
} else if (value == '1') {
set_value(true);
return 1;
}
return Error::from_errno(EINVAL);
}
ErrorOr<void> SysFSSystemBooleanVariable::truncate(u64 size)

View file

@ -25,13 +25,14 @@ ErrorOr<size_t> SysFSSystemStringVariable::write_bytes(off_t, size_t count, User
auto new_value = TRY(KString::try_create_uninitialized(count, value));
TRY(buffer.read(value, count));
auto new_value_without_possible_newlines = TRY(KString::try_create(new_value->view().trim("\n"sv)));
return Process::current().jail().with([&](auto& my_jail) -> ErrorOr<size_t> {
TRY(Process::current().jail().with([&](auto& my_jail) -> ErrorOr<void> {
// Note: If we are in a jail, don't let the current process to change the variable.
if (my_jail)
return Error::from_errno(EPERM);
set_value(move(new_value_without_possible_newlines));
return count;
});
return {};
}));
set_value(move(new_value_without_possible_newlines));
return count;
}
ErrorOr<void> SysFSSystemStringVariable::truncate(u64 size)