Skip to content
GoogleGHSA-m7j5-797w-vmrh

Linux Kernel: Spectre-v1 gadgets

MediumCVE-2023-0458 · Published Apr 18, 2023 · updated Apr 27, 2023

### Summary Detected a few exploitable gadgets that could leak secret memory through a side-channel such as MDS as well as insufficient hardening of the usercopy functions against spectre-v1. ### Severity Moderate - These vulnerabilities could be exploited to leak secret memory. ### Proof of Concept The gadget is in the ```do_prlimit``` function, which is invoked by a number of syscalls, including the ```getrlimit``` syscall. The code has been commented to better illustrate how we would exploit this weakness; you can see the commented code below. #### Half Spectre-v1 Gadget prlimit CVE-2023-0458 #### ``` c++ /* make sure you are allowed to change @tsk limits before calling this */ static int do_prlimit(struct task_struct *tsk, unsigned int resource, <------ resource is a syscall argument struct rlimit *new_rlim, struct rlimit *old_rlim) { struct rlimit *rlim; int retval = 0; if (resource >= RLIM_NLIMITS) <------ we speculatively bypass this branch NOT taken. return -EINVAL; if (new_rlim) { if (new_rlim->rlim_cur > new_rlim->rlim_max) return -EINVAL; if (resource == RLIMIT_NOFILE && new_rlim->rlim_max > sysctl_nr_open) return -EPERM; } /* Holding ...

GitHub advisory

Affected versions

PackageAffectedFixed in
Kernel
Product
< SeeAdditionalInfoSeeAdditionalInfo
Details and references

### Summary Detected a few exploitable gadgets that could leak secret memory through a side-channel such as MDS as well as insufficient hardening of the usercopy functions against spectre-v1. ### Severity Moderate - These vulnerabilities could be exploited to leak secret memory. ### Proof of Concept The gadget is in the ```do_prlimit``` function, which is invoked by a number of syscalls, including the ```getrlimit``` syscall. The code has been commented to better illustrate how we would exploit this weakness; you can see the commented code below. #### Half Spectre-v1 Gadget prlimit CVE-2023-0458 #### ``` c++ /* make sure you are allowed to change @tsk limits before calling this */ static int do_prlimit(struct task_struct *tsk, unsigned int resource, <------ resource is a syscall argument struct rlimit *new_rlim, struct rlimit *old_rlim) { struct rlimit *rlim; int retval = 0; if (resource >= RLIM_NLIMITS) <------ we speculatively bypass this branch NOT taken. return -EINVAL; if (new_rlim) { if (new_rlim->rlim_cur > new_rlim->rlim_max) return -EINVAL; if (resource == RLIMIT_NOFILE && new_rlim->rlim_max > sysctl_nr_open) return -EPERM; } /* Holding a refcount on tsk protects tsk->signal from disappearing. */ rlim = tsk->signal->rlim + resource; <------ resource gets added to a pointer, we now control an arbitrary offset of 0-4294967295 from tsk->signal->rlim task_lock(tsk->group_leader); if (new_rlim) { /* * Keep the capable check against init_user_ns until cgroups can * contain all limits. */ if (new_rlim->rlim_max > rlim->rlim_max && !capable(CAP_SYS_RESOURCE)) retval = -EPERM; if (!retval) retval = security_task_setrlimit(tsk, resource, new_rlim); } if (!retval) { if (old_rlim) *old_rlim = *rlim; <------ pointer gets dereferenced and the secret value has been loaded in the internal buffers of the CPU if (new_rlim) *rlim = *new_rlim; } ``` By combining this issue with a side-channel, such as Microarchitectural Data Sampling (MDS), we can leak secret kernel memory because the value of the arbitrary pointer is loaded into internal CPU buffers once it is dereferenced. We verified that the speculation window is large enough by making a duplicate of the code and sending a cache-signal to a userspace argument "probe" after the pointer dereference. In this manner, we can validate that the speculation window reaches the pointer-dereference of `rlim` when the CPU misspeculates the boundary check on the `resource` variable. As a result, we observe a cache-hit on our `probe` pointer. A copy of our kernel module to verify this has been added as an attachment. [Recent research](https://download.vusec.net/papers/kasper_ndss22.pdf) shows that an MDS gadget is exploitable with the default mitigation enabled i.e. `mds=full`. The XI.C section describes an experiment with two co-located threads, one that triggers the vulnerability through a syscall and one that reads the signal using MDS. They claim that they “verified that a signal exists if the loads are happening approximately at the same time in both threads, leaking the secret from a kernel buffer to user space”. After the bounds check on the `resource` parameter, we recommend adding a call to `barrier_nospec` to address this concern. #### Spectre-v1 Usercopy Hardening CVE-2023-0459 #### Another concern regarding spectre-v1 was detected in the usercopy functions, specifically on x86_64. In the past there has been some hardening to functions that deal with memory from user-space. For example, the mitigation for `copy_from_user` on 32-bits calls `__uaccess_begin_nospec` which is essentially the same as `barrier_nospec`. On 64-bits, however, we were unable to locate a comparable mitigation, so the `copy_(to|from)_user` methods do not implement a barrier on 64-bits. Calls to `__uaccess_begin_nospec` were previously present, but they seem to have bee

Severity from
GitHub (reviewed advisory)

More Google advisories

All Google
Advisory
Apple: Airpods Pro Device Link without Key
HighJun 15, 2023
NPM: Ignore Script Bypass
MediumMay 22, 2023
Jose4j: Chosen Ciphertext Attack in Jose4j
MediumApr 27, 2023
Facebook: Critical bugs in Facebook/Polygon Winterfell library
HighApr 12, 2023
Linux Kernel: Spectre v2 SMT mitigations problem
MediumApr 12, 2023
CISCO: ClamAV Heap Buffer Overflow
HighFeb 21, 2023

Critical advisories by email

Wednesdays: the week’s critical and high advisories in the AI and data stack, with the fixed versions. Only in weeks that have some.

Double opt-in. Unsubscribe any time.