Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces a KernelSU API version (decoupled from KernelSU version) and adds a way to retrieve the kernel commit hash from both the kernel ioctl interface and LKM module metadata, then wires that through ksud/ksuinit and the Android manager UI.
Changes:
- Extend
GET_INFOioctl to reportapiandcommit(with legacy fallback). - Record
ksu_version,ksu_api, andksu_commitin the LKM viaMODULE_INFO, and print these at init. - Update ksud/ksuinit/manager to consume the new ioctl fields and display/log them.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| userspace/ksuinit/src/init.rs | Updates KernelSU presence detection to use new/legacy GET_INFO ioctls. |
| userspace/ksud/src/ksucalls.rs | Adds new GET_INFO struct + caches richer kernel info (api/commit). |
| userspace/ksud/src/cli.rs | Adds a debug subcommand to print kernel info. |
| manager/app/src/main/res/values/strings.xml | Adds UI strings for API version and commit. |
| manager/app/src/main/res/values-zh-rCN/strings.xml | Adds Chinese UI strings for API version and commit. |
| manager/app/src/main/java/me/weishu/kernelsu/ui/util/LogEvent.kt | Includes API/commit in bugreport output. |
| manager/app/src/main/java/me/weishu/kernelsu/ui/screen/home/HomeUtils.kt | Adds API/commit fields to SystemInfo. |
| manager/app/src/main/java/me/weishu/kernelsu/ui/screen/home/HomeMiuix.kt | Displays API/commit on MIUIX home UI. |
| manager/app/src/main/java/me/weishu/kernelsu/ui/screen/home/HomeMaterial.kt | Displays API/commit on Material home UI. |
| manager/app/src/main/java/me/weishu/kernelsu/ui/component/KsuValidCheck.kt | Switches validity logic to use new API-version-based helper. |
| manager/app/src/main/java/me/weishu/kernelsu/Natives.kt | Exposes API version + commit via JNI; adjusts compatibility checks. |
| manager/app/src/main/cpp/ksu.h | Extends native ioctl structs and declarations for API/commit. |
| manager/app/src/main/cpp/ksu.cc | Implements new GET_INFO ioctl flow and exposes API version. |
| manager/app/src/main/cpp/jni.cc | Adds JNI getters for API version and commit. |
| kernel/supercalls.h | Extends kernel ioctl structs and defines new/legacy ioctl numbers. |
| kernel/supercalls.c | Implements new/legacy GET_INFO handlers with commit buffer copyout. |
| kernel/ksu.h | Defines KERNEL_SU_API_VERSION. |
| kernel/ksu.c | Prints version/api/commit and records MODULE_INFO metadata. |
| kernel/Kbuild | Derives and defines KSU_COMMIT from git HEAD. |
| .github/workflows/build-manager.yml | Expands CI trigger path conditions. |
Comments suppressed due to low confidence (1)
manager/app/src/main/java/me/weishu/kernelsu/ui/component/KsuValidCheck.kt:15
KsuIsValidnow setsksuVersionto a Boolean (Natives.ksuValid()), but then checksksuVersion != null. Since a Boolean is never null whenisManageris true, this will always rendercontent()even whenksuValid()is false. Change this to check the boolean value (e.g.,if (isManager && Natives.ksuValid())) and consider renaming the local variable to reflect that it’s a validity flag, not a version.
val isManager = Natives.isManager
val ksuVersion = if (isManager) Natives.ksuValid() else null
if (ksuVersion != null) {
content()
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| fun ksuValid(): Boolean = apiVersion > MINIMAL_SUPPORTED_API | ||
|
|
||
| fun requireNewKernel(): Boolean { | ||
| return version != -1 && version < MINIMAL_SUPPORTED_KERNEL | ||
| val api = apiVersion | ||
| if (api > 0) { | ||
| return api < MINIMAL_SUPPORTED_API | ||
| } else { | ||
| return version != -1 && version < MINIMAL_SUPPORTED_KERNEL | ||
| } |
There was a problem hiding this comment.
ksuValid() uses apiVersion > MINIMAL_SUPPORTED_API, which makes API version 1 (the first valid API per the comment) evaluate to invalid. This is also inconsistent with requireNewKernel() which treats api < MINIMAL_SUPPORTED_API as the cutoff. Adjust the comparison so API version 1 is considered valid (and keep the semantics consistent between these helpers).
| let mut cmd = std::mem::MaybeUninit::<GetInfoCmd>::uninit(); | ||
| let ptr = cmd.as_mut_ptr(); | ||
| let mut buf = std::mem::MaybeUninit::<[u8; 256]>::uninit(); | ||
| unsafe { | ||
| (&raw mut (*ptr).len).write(256); | ||
| (&raw mut (*ptr).commit).write(buf.as_mut_ptr() as u64); | ||
| } | ||
| if ksuctl(KSU_IOCTL_GET_INFO, ptr).is_ok() { | ||
| let cmd = unsafe { cmd.assume_init() }; | ||
| let buf = unsafe { buf.assume_init() }; | ||
| let commit = String::from_utf8_lossy(&buf[..cmd.len as usize]).to_string(); |
There was a problem hiding this comment.
get_info() uses MaybeUninit::<GetInfoCmd>::uninit() and only writes commit/len before calling into the kernel. The kernel copies back len, and this code then slices buf[..cmd.len as usize] without clamping to the buffer size; a buggy/mismatched kernel could return a larger len and cause a panic. Consider zero-initializing the struct (or at least all fields/padding) before the ioctl and clamping cmd.len to buf.len() before slicing to make this robust.
| let mut cmd = std::mem::MaybeUninit::<GetInfoCmd>::uninit(); | |
| let ptr = cmd.as_mut_ptr(); | |
| let mut buf = std::mem::MaybeUninit::<[u8; 256]>::uninit(); | |
| unsafe { | |
| (&raw mut (*ptr).len).write(256); | |
| (&raw mut (*ptr).commit).write(buf.as_mut_ptr() as u64); | |
| } | |
| if ksuctl(KSU_IOCTL_GET_INFO, ptr).is_ok() { | |
| let cmd = unsafe { cmd.assume_init() }; | |
| let buf = unsafe { buf.assume_init() }; | |
| let commit = String::from_utf8_lossy(&buf[..cmd.len as usize]).to_string(); | |
| let mut cmd = GetInfoCmd::default(); | |
| let mut buf = std::mem::MaybeUninit::<[u8; 256]>::uninit(); | |
| let buf_cap = 256usize; | |
| unsafe { | |
| cmd.len = buf_cap as u32; | |
| cmd.commit = buf.as_mut_ptr() as u64; | |
| } | |
| let ptr = &mut cmd as *mut GetInfoCmd; | |
| if ksuctl(KSU_IOCTL_GET_INFO, ptr).is_ok() { | |
| let cmd_len = std::cmp::min(cmd.len as usize, buf_cap); | |
| let buf = unsafe { buf.assume_init() }; | |
| let commit = String::from_utf8_lossy(&buf[..cmd_len]).to_string(); |
Added an API version number, independent of the kernelsu version, for easier management.
Used
MODULE_INFOto record lkm version information and commit hash, allowing direct retrieval of necessary information from ko files.Changed the kernel API to support reporting API versions and kernel commit hashes.
Adapted the manager, ksud, and ksuinit to the new kernel API.
Fixed the inconsistency between the
ksu_get_info_cmd(_legacy)structure in ksud and ksuinit and the kernel.Added more paths to CI trigger conditions.