Qualcomm Incorporated · NASDAQ:QCOM

Qualcomm — Investor Presentation

49 slides from Qualcomm's investor presentation

  1. Slide 1: The Qualcomm DSP Driver

    The Qualcomm DSP Driver Unexpectedly Excavating an ITW Exploit Seth Jenkins - Google Project Zero

  2. Slide 2: Storytime On December 17 2023, a Serbian environmental activist named Ivan Bjelic is arrested

    Storytime On December 17 2023, a Serbian environmental activist named Ivan Bjelic is arrested His phone is confiscated and authorities compel him to provide the PIN code Forensic analysis by Amnesty International revealed that Cellebrite UFED was utilized against his device They determine that an exp

  3. Slide 3: Storytime

    Storytime December 17th 2023

  4. Slide 4: Storytime Exploit artifacts are turned over to Google Threat Analysis Group Including a tranche

    Storytime Exploit artifacts are turned over to Google Threat Analysis Group Including a tranche of kernel logs from when the exploit crashed…but not the exploit itself It’s apparent from the logs that the exploit triggered a bug in the adsprpc Android driver…but it’s unclear what exactly the bug is

  5. Slide 5: Whoami

    Whoami ● Seth Jenkins aka @__sethJenkins ● Security Researcher at Google Project Zero ● Primarily Linux and Android kernel research ● Focusing on LPE’s (get to root without a password!)

  6. Slide 6: Agenda ● Kernel log analysis ● The Bughunt Begins

    Agenda ● Kernel log analysis ● The Bughunt Begins ● Excavating an Exploit ● Conclusions

  7. Slide 7: Kernel log #1

    Kernel log #1 [ 47 .223480] Jadsprpc:] fastrpc_init_process: untrusted app trying to attach to privileged DSP PD [ 47.254494] adsprpc: mapping not found to unmap fd Oxffffffff, va OxfffffffTfTfTTTTT, len Oxffffff ff [ 47.254512] adsprpc: falcon: fastrpc_internal_mmap: ERROR: adding user allocated pa

  8. Slide 8: Kernel log #2

    [ [ Kernel log #2 37.458199] adsproc: fastrpc_init_process: untrusted app trying to attach to privileged DSP PD 97.492741] adsprpe: mapping not found to unnap fd OxFtFTFFTE, va OxtFFTFFIFFITFTEFE, len oxtftitt ff L 37.482759] adsproc: falcon: fastrpe_internal_mnap: ERROR: adding user allocated pages

  9. Slide 9: Kernel log #3

    Kernel log #3 [ 2244.639158] adsprpc: ERROR: fastrpc_internal_mmap: user application falcon trying to map withou t initialization [ 2244.641272] adsprpc: falcon: fastrpc_init_process: ERROR: donated memory allocated in userspace [ 2244.683779] adsprpc: mapping not found to unmap fd Oxffffffff, va Ox

  10. Slide 10: Kernel log #4

    Kernel log #4 [| 67.167518] adsprpc: fastrpc_init_process: untrusted app trying to attach to privileged DSP PD 67.262061] adsprpc: mapping not found to unmap fd OxfffFTTTT, va OXfffTTTTfrtftfttr, len oxffffft iff 67.202084] adsprpc: falcon: fastrpc_internal_mmap: ERROR: adding user allocated pages i

  11. Slide 11: Log Analysis

    Log Analysis fastrpc_init_process fastrpc_internal_munmap_fd fastrpc_internal_mmap fastrpc_mmap_free The exploit triggers very early function bailouts…why?

  12. Slide 12: Log Analysis

    Log Analysis fastrpc_mmap_free fastrpc_mmap structures seem important somehow… But this doesn’t seem like enough to figure out what the bug is I give up…for now

  13. Slide 13: The Bughunt Begins

    The Bughunt Begins

  14. Slide 14: adsprpc

    adsprpc Application Digital Signal Processor Remote Procedure Call driver Reachable through /dev/adsprpc-smd in untrusted_app contexts Acts as a liaison between the AP and the DSP Marshals data and manages memory mappings and buffers Complexity is pretty high

  15. Slide 15: CVE-2024-21455

    #define K_COPY_FROM_USER(err,| kernel] dst, src, size) \ do {\ if (!(kernel))\ err = copy_from_user((dst), \ (void const __user *)(src),\ (size));\ else\ memmove((dst), (src), (size));\ } while (@) int fastrpc_internal_invoke2(struct fastrpc_file *fl, struct fastrpc_ioctl_invoke2 *inv2) { switch (in

  16. Slide 16: long compat_fastrpc_device_ioctl(struct file *filp, unsigned int cmd,

    long compat_fastrpc_device_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { int err = @; struct fastrpc_file *fl = (struct fastrpc_file *)filp->private_data; if (!filp->f_op || !filp->f_op->unlocked_ioct1l) return -ENOTTY; ifl->is_compat = true;

  17. Slide 17: Ss ee

    Ss ee [49468.514358] Unable to handle kernel paging request at virtual address ffffffff41414141 T > T os [49468.514418] ESR = @x960@0005 [49468.514426] EC = 6x25: DABT (current EL), IL = 32 bits [49468.514433] SET = @, FnV = 8 [49468.516577] Call trace: [49468.516582] __memcpy+@x9@/8x250 [49468.5165

  18. Slide 18: struct fastrpc_mmap

    Maps can be stored on several struct fastrpc_mmap different lists Global (gfa) list fd-local (fl) list fl-local (ctx) array(s) Two different refcounts refs is used for all references ctx_refs is used for references by ctx objects/arrays Maps can be referenced by a context as either a buffer or a han

  19. Slide 19: fastrpc_mmap_create

    fastrpc_mmap_create fastrpc_mmap_create is a slight misnomer It first tries to find an existing map that fulfills the request If it succeeds it will take a reference on the existing map and return it Only if the map does not exist does it create a new map If the map is newly created it is immediatel

  20. Slide 20: CVE-2024-33060

    —" static int fastrpc_mmap_remove(struct fastrpc_file *fl, uintptr_t va, Bee : int size_t len, struct fastrpc_mmap **ppmap) statid { ) { struct fastrpc_mmap *match = NULL, *map; struct hlist_node *n; struct fastrpc_apps *me = &gfa; spin_lock(&me->hlock) ; hlist_for_each_entry_safe(map, n, &me->maps,

  21. Slide 21: CVE-2024-33060

    CVE-2024-33060 <-fastrpc_internal_mem_unmap Normally this race would be prevented by fl->internal_map_mutex But because we’re operating on the global gfa maps list, we can just have two separate fl structs concurrently accessing the same list

  22. Slide 22: { 2890.558370] [@: poc:22189] Unable to handle kernel paging request at

    { 2890.558370] [@: poc:22189] Unable to handle kernel paging request at virtual address @@6b6b6b6b6b6b83 { 2890.558411] [@: poc:22189] PC Code: 95ca6fb3 aa1703e0 2a1f03e1 97ffdbcc 2a1f@3f6 14000008 f940Gae8 (f8418d09) f90002e9 b4e00049 f9000537 f9000117 f90006e8 aal4@3e0 95ca66a2 aa1303e8 95ca66a8 d

  23. Slide 23: CVE-2024-49848

    static int fastrpc_mmap_remove(struct fastrpc_file *fl, int fd, uintptr_t va, size_t len, struct fastrpc_mmap **ppmap) { z : struct fastrpc_mmap *match = NULL, *map; int fastrpc_internal_me genase NLSt.node ane struct fastrpc_apps *me = &gfa; { unsigned long irq_flags Q; int err = 0; struct fastrpc_

  24. Slide 24: int fastrpc_internal_munmap_fd(struct fastrpc_file *fl,

    int fastrpc_internal_munmap_fd(struct fastrpc_file *fl, struct fastrpc_ioctl_munmap_fd *ud) { int err = 0; struct fastrpc_mmap *map = NULL; mutex_lock(&f1->internal_map_mutex) ; mutex_lock(&f1->map mutex) - err =|fastrpc_mmap_find(fl, ud->fd, NULL, ud->va, ud->len, 0, @, &map); if (err) ¢ mutex_unlo

  25. Slide 25: isn’t explicitly disallowed in the other two cases…

    FASTRPC_ATTR_KEEP_MAP isn’t explicitly disallowed in the other two cases…

  26. Slide 26: I can create a map with only 1 reference that can have a reference

    I can create a map with only 1 reference that can have a reference dropped with fastrpc_internal_munmap_fd This doesn’t provide these guarantees that the other unmapping functions provide If I can achieve this layout, I can cause a crash

  27. Slide 27: Created via fastrpc_internal_mem_map

    Created via fastrpc_internal_mem_map

  28. Slide 28: Created via fastrpc_internal_mem_map

    Created via fastrpc_internal_mem_map

  29. Slide 29: Created via fastrpc_internal_mem_map

    Created via fastrpc_internal_mem_map

  30. Slide 30: Created via fastrpc_internal_mem_map

    Created via fastrpc_internal_mem_map

  31. Slide 31: I can only create FASTRPC_ATTR_KEEP_MAP && FASTRPC_MAP_FD_NOMAP mappings with fastrpc_internal_mem_map Normally creat…

    I can only create FASTRPC_ATTR_KEEP_MAP && FASTRPC_MAP_FD_NOMAP mappings with fastrpc_internal_mem_map Normally creating a map where the only reference is a context requires map creation to be done during context creation…aka not fastrpc_internal_mem_map

  32. Slide 32: int fastrpc_internal_mem_map(struct fastrpc_file *f1,

    int fastrpc_internal_mem_map(struct fastrpc_file *f1, struct fastrpc_ioctl_mem_map *ud) { int err = 0; struct fastrpc_mmap *map = NULL; mutex_lock(&f1->internal_map_mutex) ; mutex_lock(&f1->map preees> VERIFY(err, !(err fastrpc_mmap_create]fl, ud->m.fd, NULL, ud->m.attrs ud= "Ir " static if ud->m.fl

  33. Slide 33: Hey doesn’t this look kinda familiar? Works only against a newer kernel version than

    Hey doesn’t this look kinda familiar? Works only against a newer kernel version than the ITW exploit…but I suspect I’m getting warm

  34. Slide 34: The ITW exploit ● Crashes in a fastrpc_mmap_free call ● The ITW exploit causes

    The ITW exploit ● Crashes in a fastrpc_mmap_free call ● The ITW exploit causes a wild value for map->fl->cid (memory corruption) The ITW exploit is probably causing a fastrpc_mmap UAF I have two fastrpc_mmap UAF bugs Neither of them seem right… Let’s keep looking

  35. Slide 35: CVE-2024-43047

    CVE-2024-43047 A context can reference a map in two different ways Buffer reference acquired here

  36. Slide 36: CVE-2024-43047

    CVE-2024-43047 A context can reference a map in two different ways Buffer reference dropped here

  37. Slide 37: CVE-2024-43047

    CVE-2024-43047 Handle reference acquired here

  38. Slide 38: CVE-2024-43047

    CVE-2024-43047 Handle reference dropped here DSP populates fdlist fastrpc_mmap_find finds a map in the fl list with the associated fd This is very different from how buffer references are acquired and dropped How do we know the map we find is the same map we acquired a reference on earlier?

  39. Slide 39: Create map A Take reference to map A as a handle from a context

    Create map A Take reference to map A as a handle from a context X Create map B that collides with map A Take reference to map B as a buffer from a context Y Finish using context X map B dropped instead of map A

  40. Slide 40: Another map UAF issue It doesn’t look exactly the same… But that’s to be

    Another map UAF issue It doesn’t look exactly the same… But that’s to be expected This bug would have worked on the same kernel version the ITW exploit used Of all the bugs I found, this one is the most promising vulnerability that the ITW exploit might have used

  41. Slide 41: Excavating an exploit Can I exploit this issue? No info leak :(

    Excavating an exploit Can I exploit this issue? No info leak :( Need to find some compatible heap spray object… Turns out to be harder than I expected The “wild space value” is a timestamp…. Could this be from whatever object the exploit heap sprayed??

  42. Slide 42: Excavating an exploit Now I’m looking for an object with a timestamp at a

    Excavating an exploit Now I’m looking for an object with a timestamp at a very specific location Can I find some sprayable object where at *(object+16)+104 I find a timestamp? Wait a second…

  43. Slide 43: Kernel log #3

    Kernel log #3 [ 2244.639158] adsprpc: ERROR: fastrpc_internal_mmap: user application falcon trying to map withou t initialization [ 2244.641272] adsprpc: falcon: fastrpc_init_process: ERROR: donated memory allocated in userspace [ 2244.683779] adsprpc: mapping not found to unmap fd Oxffffffff, va Ox

  44. Slide 44: Excavating an exploit We had a crash in kmalloc for an inotify object at

    Excavating an exploit We had a crash in kmalloc for an inotify object at just the right time when the exploit would be heap spraying. Maybe that’s the object that fits the bill? object +16 -> + 104

  45. Slide 45: Excavating an exploit

    Excavating an exploit agham.github.io Upon searching for previous research on usable linux structures, | found this great talk talking about elastic objects in the linux kernel, specifically a chart of objects, where | found the suitable inotify_event_info, The idea here being corrupting the length

  46. Slide 46: Kernel log #4

    Kernel log #4 Plausible reallocation with pipe buffers Would give them full control of the underlying fastrpc_mmap object

  47. Slide 47: Unsolved Questions Why does the exploit generate those first simple errors? How does the

    Unsolved Questions Why does the exploit generate those first simple errors? How does the exploit crash at the inotify allocation? How did the exploit crash during fl->maps list-traversal? Generating many invalid channel id messages - why? Multiple seconds between invalid channel id messages - why?

  48. Slide 48: Patch Timelines

    Patch Timelines CVE-2024-21455: Reported June 11, 2024; Fixed Oct 7, 2024 (118 days) ASB: November 4, 2024 (146 days) CVE-2024-33060: Reported June 25, 2024; Fixed Sep 3, 2024 (70 days) Duplicate, fix was written by May 27, 2024 (99+ days from patch written to release) CVE-2024-49848: Reported July

  49. Slide 49: Conclusion

    Conclusion Cybersecurity is only as strong as its weakest link

Qualcomm — Investor Presentation on 6ix