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 ...
Affected versions
| Package | Affected | Fixed in |
|---|---|---|
| Kernel Product | < SeeAdditionalInfo | SeeAdditionalInfo |
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| Date | Advisory | Severity | Fixed in |
|---|---|---|---|
| Jun 152023 | Apple: Airpods Pro Device Link without Key | High | No fix yet |
| May 222023 | NPM: Ignore Script Bypass | Medium | Nopatchedversionsatthistime |
| Apr 272023 | Jose4j: Chosen Ciphertext Attack in Jose4j | Medium | No fix yet |
| Apr 122023 | Facebook: Critical bugs in Facebook/Polygon Winterfell library | High | No fix yet |
| Apr 122023 | Linux Kernel: Spectre v2 SMT mitigations problem | Medium | 6.3 |
| Feb 212023 | CISCO: ClamAV Heap Buffer Overflow | High | No fix yet |