summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorLiav A <liavalb@gmail.com>2022-11-11 14:55:28 +0200
committerAndrew Kaster <andrewdkaster@gmail.com>2022-12-03 05:47:58 -0700
commit2e55956784ac0c61fe877c316867074e0f432452 (patch)
tree39daf35279978401fc80768fc4c42a61bf5b51c7 /Kernel
parent1aa07d7328a4f1eaee0ac773429090e1963d22fd (diff)
downloadserenity-2e55956784ac0c61fe877c316867074e0f432452.zip
Kernel: Forbid access to /sys/kernel/power_state for Jailed processes
There's simply no benefit in allowing sandboxed programs to change the power state of the machine, so disallow writes to the mentioned node to prevent malicious programs to request that.
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/FileSystem/SysFS/Subsystems/Kernel/PowerStateSwitch.cpp21
1 files changed, 14 insertions, 7 deletions
diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/PowerStateSwitch.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/PowerStateSwitch.cpp
index 747f2af126..5362a824c1 100644
--- a/Kernel/FileSystem/SysFS/Subsystems/Kernel/PowerStateSwitch.cpp
+++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/PowerStateSwitch.cpp
@@ -16,6 +16,7 @@
#include <Kernel/Process.h>
#include <Kernel/Sections.h>
#include <Kernel/TTY/ConsoleManagement.h>
+#include <Kernel/WorkQueue.h>
namespace Kernel {
@@ -45,18 +46,25 @@ ErrorOr<void> SysFSPowerStateSwitchNode::truncate(u64 size)
ErrorOr<size_t> SysFSPowerStateSwitchNode::write_bytes(off_t offset, size_t count, UserOrKernelBuffer const& data, OpenFileDescription*)
{
+ TRY(Process::current().jail().with([&](auto const& my_jail) -> ErrorOr<void> {
+ // Note: If we are in a jail, don't let the current process to change the power state.
+ if (my_jail)
+ return Error::from_errno(EPERM);
+ return {};
+ }));
if (Checked<off_t>::addition_would_overflow(offset, count))
- return EOVERFLOW;
+ return Error::from_errno(EOVERFLOW);
if (offset > 0)
- return EINVAL;
+ return Error::from_errno(EINVAL);
if (count > 1)
- return EINVAL;
-
+ return Error::from_errno(EINVAL);
char buf[1];
TRY(data.read(buf, 1));
+ if (buf[0] == '0')
+ return Error::from_errno(EINVAL);
switch (buf[0]) {
case '0':
- return EINVAL;
+ VERIFY_NOT_REACHED();
case '1':
reboot();
VERIFY_NOT_REACHED();
@@ -64,9 +72,8 @@ ErrorOr<size_t> SysFSPowerStateSwitchNode::write_bytes(off_t offset, size_t coun
poweroff();
VERIFY_NOT_REACHED();
default:
- return EINVAL;
+ VERIFY_NOT_REACHED();
}
- VERIFY_NOT_REACHED();
}
void SysFSPowerStateSwitchNode::reboot()