1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 10:58:12 +00:00

Kernel: Utilize AK::Userspace<T> in the ioctl interface

It's easy to forget the responsibility of validating and safely copying
kernel parameters in code that is far away from syscalls. ioctl's are
one such example, and bugs there are just as dangerous as at the root
syscall level.

To avoid this case, utilize the AK::Userspace<T> template in the ioctl
kernel interface so that implementors have no choice but to properly
validate and copy ioctl pointer arguments.
This commit is contained in:
Brian Gianforcaro 2021-07-26 02:47:00 -07:00 committed by Ali Mohammad Pur
parent 0bb3d83a48
commit 9a04f53a0f
16 changed files with 99 additions and 93 deletions

View file

@ -311,31 +311,34 @@ KResultOr<size_t> KeyboardDevice::write(FileDescription&, u64, const UserOrKerne
return 0;
}
int KeyboardDevice::ioctl(FileDescription&, unsigned request, FlatPtr arg)
int KeyboardDevice::ioctl(FileDescription&, unsigned request, Userspace<void*> arg)
{
switch (request) {
case KEYBOARD_IOCTL_GET_NUM_LOCK: {
auto* output = (bool*)arg;
auto output = static_ptr_cast<bool*>(arg);
if (!copy_to_user(output, &m_num_lock_on))
return -EFAULT;
return 0;
}
case KEYBOARD_IOCTL_SET_NUM_LOCK: {
if (arg != 0 && arg != 1)
// In this case we expect the value to be a boolean and not a pointer.
auto num_lock_value = static_cast<u8>(arg.ptr());
if (num_lock_value != 0 && num_lock_value != 1)
return -EINVAL;
m_num_lock_on = arg;
m_num_lock_on = !!num_lock_value;
return 0;
}
case KEYBOARD_IOCTL_GET_CAPS_LOCK: {
auto* output = (bool*)arg;
auto output = static_ptr_cast<bool*>(arg);
if (!copy_to_user(output, &m_caps_lock_on))
return -EFAULT;
return 0;
}
case KEYBOARD_IOCTL_SET_CAPS_LOCK: {
if (arg != 0 && arg != 1)
auto caps_lock_value = static_cast<u8>(arg.ptr());
if (caps_lock_value != 0 && caps_lock_value != 1)
return -EINVAL;
m_caps_lock_on = arg;
m_caps_lock_on = !!caps_lock_value;
return 0;
}
default: