This series converts the Qualcomm Socinfo driver to Rust to improve its robustness.
The previous driver suffered from CVE-2024-58007, which would have been prevented by the enforced bounds-checking present in Rust. It's taken a while to get all the interfaces in place, but at this point, the only place it needs `unsafe` is to define an abstraction over the qcom-smem driver. Feedback on v1 of the patch showed how Rust can help to identify assumptions being made about APIs by requiring that reasoning be attached to `unsafe` blocks. Specifically, this identified: 1. The regions being returned by `qcom_smem_get` are not memory regions, they are IO mapped memory. 2. These regions will be unmapped if the `smem` device is unloaded. 3. For versions in particular, the behavior of re-reading the version info from the IO region when displaying outputs is load-bearing, not an implementation detail - these regions are *expected* to change. The previous driver accessed IO mapped regions through regular C memory accesses. This was possible without warning because the `qcom_smem_get` API exposes pointers stripped of their `__iomem` annotation. This is unlikely to cause trouble in practice, but goes against the recommendation of kernel documentation [1]. The previous driver did not have a direct mechanism to ensure it was being probed as a child of a `qcom-smem` device. While it was only ever probed correctly (from the `qcom-smem` device), the new implementation is robust to being probed improperly by other devices. Since we are now using the IO subsystem, it's now much clearer when we are intentionally choosing to do an IO read during a DebugFS implementation. I have tested this on a SM8650-HDK by diffing the contents of the exported DebugFS and examining the files under /sys/bus/soc/devices/soc0 While I believe I have everything correctly exported via DebugFS, I have not checked equivalence across a large swath of devices, only the one. This driver is currently quirk-compatible in DebugFS-exported values. If the maintainers do not believe that maintaining the exact formats is a benefit, we could simplify the code further by dropping some of the custom formatting functions used to match the output. I didn't touch MAINTAINERS because the existing socinfo.c is covered by a blanket directory maintainer, which would automatically cover the new Rust implementation. If it would be helpful, I would be willing to assist with this particular driver in the future. Since it was a surprise in the previous series, I will explicitly call out that this series is built on driver-core-next plus my patches to load randomness [2] and derive FromBytes / AsBytes [3]. If you use b4, this series should have appropriate metadata to recreate the tree for you. [1]: https://docs.kernel.org/driver-api/device-io.html#accessing-the-device [2]: https://lore.kernel.org/all/[email protected]/ [3]: https://lore.kernel.org/all/[email protected]/ Signed-off-by: Matthew Maurer <[email protected]> --- Changes in v2: - Rebase onto updated deps - Use sparse_array! macro to define PMIC_MODELS - Migrate to using auxdev - Add `qcom_smem_get_aux` to help enforce that we are a child device - Access IO mapped regions through the IO subsystem - Leverage `Devres` to ensure that the smem device is still present when accessing IO regions. - Switch to new kernel import style - Switch to c"foo" literals where possible - Link to v1: https://lore.kernel.org/r/[email protected] --- Matthew Maurer (6): rust: Add sparse_array! helper macro rust: io: Support copying arrays and slices rust: device: Support testing devices for equality rust: auxiliary: Support accessing raw aux pointer rust: debugfs: Allow access to device in Devres-wrapped scopes soc: qcom: socinfo: Convert to Rust drivers/soc/qcom/Kconfig | 1 + drivers/soc/qcom/Makefile | 2 +- drivers/soc/qcom/smem.c | 42 +- drivers/soc/qcom/socinfo.c | 931 ----------------------------------- drivers/soc/qcom/socinfo/Makefile | 2 + drivers/soc/qcom/socinfo/bindings.rs | 123 +++++ drivers/soc/qcom/socinfo/data.rs | 438 ++++++++++++++++ drivers/soc/qcom/socinfo/socinfo.rs | 446 +++++++++++++++++ include/linux/soc/qcom/smem.h | 4 + rust/bindgen_parameters | 1 + rust/bindings/bindings_helper.h | 6 + rust/kernel/auxiliary.rs | 6 +- rust/kernel/debugfs.rs | 40 ++ rust/kernel/device.rs | 8 + rust/kernel/devres.rs | 2 +- rust/kernel/drm/driver.rs | 2 +- rust/kernel/io.rs | 72 ++- rust/kernel/pwm.rs | 2 +- rust/kernel/slice.rs | 37 ++ 19 files changed, 1220 insertions(+), 945 deletions(-) --- base-commit: 559ac491542c00e2389f8cfc49661527b3b0d8a0 change-id: 20251029-qcom-socinfo-d8387c7fdb1c prerequisite-change-id: 20251029-add-entropy-f57e12ebe110:v5 prerequisite-patch-id: f1e8f8f557aa3df7510bd90beb1edf62faa117da prerequisite-change-id: 20251212-transmute-8ab6076700a8:v3 prerequisite-patch-id: 4f5f7cb002d02d232083ab5c3ce6b3cb90650bd6 prerequisite-patch-id: fcdcb6cfedd70cdc41d2d27244ea2a588ed40eb9 prerequisite-patch-id: f6bc9ae84b31e2400749c0db10e6aa4216b3858b prerequisite-patch-id: 95a7f946b6533ec4ccafee355626bb24a9be8f70 Best regards, -- Matthew Maurer <[email protected]>
