mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-11-06 13:30:00 +00:00
Merge pull request #12556 from babyhuey/fix/sched-efault
fix(libkernel): return EFAULT from rtprio_thread and sched_rr_get_interval for a bad pointer
This commit is contained in:
4 files changed
+30
-6
No files matched your search
@@ -126,15 +126,19 @@ int APS5_VABI rtprio_thread_nid_postfix(int function, int lwpid, GuestRtPrio* pr
|
||||
int schedPriority = self->priority.load(std::memory_order_relaxed);
|
||||
const bool other = lwpid != 0 && static_cast<std::int64_t>(lwpid) != static_cast<std::int64_t>(self->tid);
|
||||
if (other && !GetLiveGuestThreadSched_nid_no_patch(lwpid, policy, schedPriority)) return fail(GuestEsrch);
|
||||
GuestRtPrio requested{};
|
||||
if (function == Set && !GuestCopyIn_nid_no_patch(&requested, priority, sizeof(requested))) return fail(GuestEfault);
|
||||
const bool realTime = policy == GuestSchedFifo || policy == GuestSchedRr;
|
||||
if (function == Lookup) {
|
||||
priority->type = realTime ? (policy == GuestSchedFifo ? Fifo : Realtime) : Normal;
|
||||
priority->prio = realTime ? static_cast<std::uint16_t>(schedPriority) : 0;
|
||||
GuestRtPrio current{};
|
||||
current.type = realTime ? (policy == GuestSchedFifo ? Fifo : Realtime) : Normal;
|
||||
current.prio = realTime ? static_cast<std::uint16_t>(schedPriority) : 0;
|
||||
if (!GuestCopyOut_nid_no_patch(priority, ¤t, sizeof(current))) return fail(GuestEfault);
|
||||
return 0;
|
||||
}
|
||||
if (other) NotImplemented_nid_no_patch("rtprio_thread: a thread other than the calling one");
|
||||
if (realTime) NotImplemented_nid_no_patch("rtprio_thread: a guest thread's real-time class");
|
||||
if (priority->type == Normal && priority->prio == 0) return 0;
|
||||
if (requested.type == Normal && requested.prio == 0) return 0;
|
||||
NotImplemented_nid_no_patch("rtprio_thread: a real-time priority change");
|
||||
}
|
||||
|
||||
|
||||
@@ -986,9 +986,8 @@ int APS5_VABI sched_rr_get_interval_nid_postfix(int pid, KernelTimespec* interva
|
||||
constexpr int GuestEsrch = 3;
|
||||
const int self = getpid_nid_postfix();
|
||||
if (pid != 0 && pid != self) return static_cast<int>(Fail(GuestEsrch));
|
||||
if (interval == nullptr) return static_cast<int>(Fail(GuestEfault));
|
||||
interval->tv_sec = 0;
|
||||
interval->tv_nsec = 94000000;
|
||||
const KernelTimespec quantum{0, 94000000};
|
||||
if (interval == nullptr || !GuestCopyOut_nid_no_patch(interval, &quantum, sizeof(quantum))) return static_cast<int>(Fail(GuestEfault));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -92,6 +92,17 @@ int main() {
|
||||
CheckThread(GUEST_SCHED_FIFO, 256, RTP_PRIO_FIFO);
|
||||
Require(LookupError(2, 0, &self) == GUEST_ESRCH);
|
||||
Require(LookupError(RTP_LOOKUP, 0, nullptr) == GUEST_EFAULT);
|
||||
auto* unmapped = reinterpret_cast<GuestRtPrio*>(std::uintptr_t{0x10});
|
||||
Require(LookupError(RTP_LOOKUP, 0, unmapped) == GUEST_EFAULT);
|
||||
Require(LookupError(RTP_SET, 0, unmapped) == GUEST_EFAULT);
|
||||
Require(LookupError(RTP_SET, 999999, unmapped) == GUEST_ESRCH);
|
||||
void* page = nullptr;
|
||||
Require(sceKernelMapFlexibleMemory(&page, 0x4000, 3, 0) == 0 && page != nullptr);
|
||||
auto* readOnly = static_cast<GuestRtPrio*>(page);
|
||||
*readOnly = {7, 7};
|
||||
Require(sceKernelMprotect(page, 0x4000, 1) == 0);
|
||||
Require(LookupError(RTP_LOOKUP, 0, readOnly) == GUEST_EFAULT);
|
||||
Require(readOnly->type == 7 && readOnly->prio == 7);
|
||||
Require(LookupError(RTP_LOOKUP, 1, &self) == GUEST_ESRCH);
|
||||
Require(LookupError(RTP_LOOKUP, 999999, &self) == GUEST_ESRCH);
|
||||
bool threw = false;
|
||||
|
||||
@@ -54,6 +54,16 @@ int main() {
|
||||
Require(sched_rr_get_interval_nid_postfix(self + 1, &interval) == -1 && *__error_nid_postfix() == 3);
|
||||
*__error_nid_postfix() = 0;
|
||||
Require(sched_rr_get_interval_nid_postfix(0, nullptr) == -1 && *__error_nid_postfix() == 14);
|
||||
*__error_nid_postfix() = 0;
|
||||
Require(sched_rr_get_interval_nid_postfix(0, reinterpret_cast<KernelTimespec*>(std::uintptr_t{0x10})) == -1 && *__error_nid_postfix() == 14);
|
||||
*__error_nid_postfix() = 0;
|
||||
Require(sched_rr_get_interval_nid_postfix(-1, reinterpret_cast<KernelTimespec*>(std::uintptr_t{0x10})) == -1 && *__error_nid_postfix() == 3);
|
||||
void* page = nullptr;
|
||||
Require(sceKernelMapFlexibleMemory(&page, 0x4000, 3, 0) == 0 && page != nullptr);
|
||||
Require(sceKernelMprotect(page, 0x4000, 1) == 0);
|
||||
*__error_nid_postfix() = 0;
|
||||
Require(sched_rr_get_interval_nid_postfix(0, static_cast<KernelTimespec*>(page)) == -1 && *__error_nid_postfix() == 14);
|
||||
Require(static_cast<KernelTimespec*>(page)->tv_nsec == 0);
|
||||
for (int policy : {1, 3}) {
|
||||
Require(sched_get_priority_max_nid_postfix(policy) == 767);
|
||||
Require(sched_get_priority_min_nid_postfix(policy) == 256);
|
||||
|
||||
Reference in new issue
Block a user