Everywhere: Fix incorrect usages of AK::Checked

Specifically, explicitly specify the checked type, use the resulting
value instead of doing the same calculation twice, and break down
calculations to discrete operations to ensure no intermediary overflows
are missed.
This commit is contained in:
Idan Horowitz 2021-07-04 20:23:26 +03:00 committed by Linus Groh
parent 3f70efed9c
commit 301c1a3a58
Notes: sideshowbarker 2024-07-18 10:27:40 +09:00
6 changed files with 16 additions and 15 deletions

View file

@ -131,42 +131,42 @@ template<typename T>
[[nodiscard]] inline bool copy_n_from_user(T* dest, const T* src, size_t count)
{
static_assert(IsTriviallyCopyable<T>);
Checked size = sizeof(T);
Checked<size_t> size = sizeof(T);
size *= count;
if (size.has_overflow())
return false;
return copy_from_user(dest, src, sizeof(T) * count);
return copy_from_user(dest, src, size.value());
}
template<typename T>
[[nodiscard]] inline bool copy_n_to_user(T* dest, const T* src, size_t count)
{
static_assert(IsTriviallyCopyable<T>);
Checked size = sizeof(T);
Checked<size_t> size = sizeof(T);
size *= count;
if (size.has_overflow())
return false;
return copy_to_user(dest, src, sizeof(T) * count);
return copy_to_user(dest, src, size.value());
}
template<typename T>
[[nodiscard]] inline bool copy_n_from_user(T* dest, Userspace<const T*> src, size_t count)
{
static_assert(IsTriviallyCopyable<T>);
Checked size = sizeof(T);
Checked<size_t> size = sizeof(T);
size *= count;
if (size.has_overflow())
return false;
return copy_from_user(dest, src.unsafe_userspace_ptr(), sizeof(T) * count);
return copy_from_user(dest, src.unsafe_userspace_ptr(), size.value());
}
template<typename T>
[[nodiscard]] inline bool copy_n_to_user(Userspace<T*> dest, const T* src, size_t count)
{
static_assert(IsTriviallyCopyable<T>);
Checked size = sizeof(T);
Checked<size_t> size = sizeof(T);
size *= count;
if (size.has_overflow())
return false;
return copy_to_user(dest.unsafe_userspace_ptr(), src, sizeof(T) * count);
return copy_to_user(dest.unsafe_userspace_ptr(), src, size.value());
}

View file

@ -942,14 +942,14 @@ KResultOr<FlatPtr> Process::sys$execve(Userspace<const Syscall::SC_execve_params
auto copy_user_strings = [](const auto& list, auto& output) {
if (!list.length)
return true;
Checked size = sizeof(*list.strings);
Checked<size_t> size = sizeof(*list.strings);
size *= list.length;
if (size.has_overflow())
return false;
Vector<Syscall::StringArgument, 32> strings;
if (!strings.try_resize(list.length))
return false;
if (!copy_from_user(strings.data(), list.strings, list.length * sizeof(*list.strings)))
if (!copy_from_user(strings.data(), list.strings, size.value()))
return false;
for (size_t i = 0; i < list.length; ++i) {
auto string = copy_string_from_user(strings[i]);

View file

@ -152,7 +152,7 @@ KResultOr<FlatPtr> Process::sys$poll(Userspace<const Syscall::SC_poll_params*> u
Vector<pollfd, FD_SETSIZE> fds_copy;
if (params.nfds > 0) {
Checked nfds_checked = sizeof(pollfd);
Checked<size_t> nfds_checked = sizeof(pollfd);
nfds_checked *= params.nfds;
if (nfds_checked.has_overflow())
return EFAULT;

View file

@ -97,7 +97,8 @@ static void initialize_typed_array_from_typed_array(GlobalObject& global_object,
auto element_length = src_array.array_length();
auto element_size = dest_array.element_size();
Checked byte_length = element_size * element_length;
Checked<size_t> byte_length = element_size;
byte_length *= element_length;
if (byte_length.has_overflow()) {
vm.throw_exception<RangeError>(global_object, ErrorType::InvalidLength, "typed array");
return;

View file

@ -362,7 +362,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::set)
return {};
}
Checked checked { source_length };
Checked<size_t> checked = source_length;
checked += static_cast<u32>(target_offset);
if (checked.has_overflow() || checked.value() > target_length) {
vm.throw_exception<JS::RangeError>(global_object, "Overflow or out of bounds in target length");
@ -436,7 +436,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::set)
return {};
}
Checked checked { source_length };
Checked<size_t> checked = source_length;
checked += static_cast<u32>(target_offset);
if (checked.has_overflow() || checked.value() > target_length) {
vm.throw_exception<JS::RangeError>(global_object, "Overflow or out of bounds in target length");

View file

@ -191,7 +191,7 @@ void BytecodeInterpreter::call_address(Configuration& configuration, FunctionAdd
TRAP_IF_NOT(rhs.has_value()); \
dbgln_if(WASM_TRACE_DEBUG, "{} {} {} = ??", ulhs.value(), #operator, rhs.value()); \
__VA_ARGS__; \
Checked lhs = ulhs.value(); \
Checked<type> lhs = ulhs.value(); \
lhs operator##= rhs.value(); \
TRAP_IF_NOT(!lhs.has_overflow()); \
auto result = lhs.value(); \