From 551633bbb8502fe979b274786f4dcb44084df267 Mon Sep 17 00:00:00 2001 From: ketikai Date: Thu, 28 May 2026 01:09:22 +0800 Subject: [PATCH 01/79] revert(ksu): "'kernelsu: Add KernelSU v0.9.5' to 'Revert "kernelsu: defconfig: grus: Enable KernelSU"'" b09a17bc22f1e87897e66abeb43ff7679115ddff^..8f5409aef50e0cb885508b814b8ee953e2072437 This reverts commit b09a17bc22f1e87897e66abeb43ff7679115ddff. Signed-off-by: ketikai --- drivers/Kconfig | 1 - drivers/Makefile | 2 - drivers/input/input.c | 8 - drivers/kernelsu/Kconfig | 19 - drivers/kernelsu/LICENSE | 339 --------- drivers/kernelsu/Makefile | 69 -- drivers/kernelsu/allowlist.c | 529 ------------- drivers/kernelsu/allowlist.h | 27 - drivers/kernelsu/apk_sign.c | 320 -------- drivers/kernelsu/apk_sign.h | 8 - drivers/kernelsu/arch.h | 92 --- drivers/kernelsu/core_hook.c | 856 --------------------- drivers/kernelsu/core_hook.h | 9 - drivers/kernelsu/embed_ksud.c | 5 - drivers/kernelsu/export_symbol.txt | 2 - drivers/kernelsu/include/ksu_hook.h | 28 - drivers/kernelsu/kernel_compat.c | 176 ----- drivers/kernelsu/kernel_compat.h | 39 - drivers/kernelsu/klog.h | 11 - drivers/kernelsu/ksu.c | 100 --- drivers/kernelsu/ksu.h | 99 --- drivers/kernelsu/ksud.c | 666 ----------------- drivers/kernelsu/ksud.h | 14 - drivers/kernelsu/manager.h | 36 - drivers/kernelsu/selinux/Makefile | 16 - drivers/kernelsu/selinux/rules.c | 476 ------------ drivers/kernelsu/selinux/selinux.c | 145 ---- drivers/kernelsu/selinux/selinux.h | 25 - drivers/kernelsu/selinux/sepolicy.c | 1070 --------------------------- drivers/kernelsu/selinux/sepolicy.h | 46 -- drivers/kernelsu/sucompat.c | 367 --------- drivers/kernelsu/throne_tracker.c | 382 ---------- drivers/kernelsu/throne_tracker.h | 10 - fs/devpts/inode.c | 7 - fs/exec.c | 9 - fs/namespace.c | 34 - fs/open.c | 9 - fs/read_write.c | 9 - fs/stat.c | 8 - security/selinux/hooks.c | 19 - 40 files changed, 6087 deletions(-) delete mode 100644 drivers/kernelsu/Kconfig delete mode 100644 drivers/kernelsu/LICENSE delete mode 100644 drivers/kernelsu/Makefile delete mode 100644 drivers/kernelsu/allowlist.c delete mode 100644 drivers/kernelsu/allowlist.h delete mode 100644 drivers/kernelsu/apk_sign.c delete mode 100644 drivers/kernelsu/apk_sign.h delete mode 100644 drivers/kernelsu/arch.h delete mode 100644 drivers/kernelsu/core_hook.c delete mode 100644 drivers/kernelsu/core_hook.h delete mode 100644 drivers/kernelsu/embed_ksud.c delete mode 100644 drivers/kernelsu/export_symbol.txt delete mode 100644 drivers/kernelsu/include/ksu_hook.h delete mode 100644 drivers/kernelsu/kernel_compat.c delete mode 100644 drivers/kernelsu/kernel_compat.h delete mode 100644 drivers/kernelsu/klog.h delete mode 100644 drivers/kernelsu/ksu.c delete mode 100644 drivers/kernelsu/ksu.h delete mode 100644 drivers/kernelsu/ksud.c delete mode 100644 drivers/kernelsu/ksud.h delete mode 100644 drivers/kernelsu/manager.h delete mode 100644 drivers/kernelsu/selinux/Makefile delete mode 100644 drivers/kernelsu/selinux/rules.c delete mode 100644 drivers/kernelsu/selinux/selinux.c delete mode 100644 drivers/kernelsu/selinux/selinux.h delete mode 100644 drivers/kernelsu/selinux/sepolicy.c delete mode 100644 drivers/kernelsu/selinux/sepolicy.h delete mode 100644 drivers/kernelsu/sucompat.c delete mode 100644 drivers/kernelsu/throne_tracker.c delete mode 100644 drivers/kernelsu/throne_tracker.h diff --git a/drivers/Kconfig b/drivers/Kconfig index a58d9ab6a21a..59608162435d 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -212,5 +212,4 @@ source "drivers/sensors/Kconfig" source "drivers/tee/Kconfig" -source "drivers/kernelsu/Kconfig" endmenu diff --git a/drivers/Makefile b/drivers/Makefile index 5041d7566d34..557cba5af5c9 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -181,5 +181,3 @@ obj-$(CONFIG_ESOC) += esoc/ obj-$(CONFIG_FPGA) += fpga/ obj-$(CONFIG_SENSORS_SSC) += sensors/ obj-$(CONFIG_TEE) += tee/ - -obj-$(CONFIG_KSU) += kernelsu/ diff --git a/drivers/input/input.c b/drivers/input/input.c index cd9b89e2cbba..378717d1b3b4 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -377,19 +377,11 @@ static int input_get_disposition(struct input_dev *dev, return disposition; } -#ifdef CONFIG_KSU -extern int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code, int *value); -#endif - static void input_handle_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { int disposition = input_get_disposition(dev, type, code, &value); -#ifdef CONFIG_KSU - ksu_handle_input_handle_event(&type, &code, &value); -#endif - if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN) add_input_randomness(type, code, value); diff --git a/drivers/kernelsu/Kconfig b/drivers/kernelsu/Kconfig deleted file mode 100644 index cdf8b33826c2..000000000000 --- a/drivers/kernelsu/Kconfig +++ /dev/null @@ -1,19 +0,0 @@ -menu "KernelSU" - -config KSU - tristate "KernelSU function support" - depends on OVERLAY_FS - default n - help - Enable kernel-level root privileges on Android System. - To compile as a module, choose M here: the - module will be called kernelsu. - -config KSU_DEBUG - bool "KernelSU debug mode" - depends on KSU - default n - help - Enable KernelSU debug mode. - -endmenu diff --git a/drivers/kernelsu/LICENSE b/drivers/kernelsu/LICENSE deleted file mode 100644 index d159169d1050..000000000000 --- a/drivers/kernelsu/LICENSE +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/drivers/kernelsu/Makefile b/drivers/kernelsu/Makefile deleted file mode 100644 index 08f7f46d0fae..000000000000 --- a/drivers/kernelsu/Makefile +++ /dev/null @@ -1,69 +0,0 @@ -kernelsu-objs := ksu.o -kernelsu-objs += allowlist.o -kernelsu-objs += apk_sign.o -kernelsu-objs += sucompat.o -kernelsu-objs += throne_tracker.o -kernelsu-objs += core_hook.o -kernelsu-objs += ksud.o -kernelsu-objs += embed_ksud.o -kernelsu-objs += kernel_compat.o - -kernelsu-objs += selinux/selinux.o -kernelsu-objs += selinux/sepolicy.o -kernelsu-objs += selinux/rules.o -ccflags-y += -I$(srctree)/security/selinux -I$(srctree)/security/selinux/include -ccflags-y += -I$(objtree)/security/selinux -include $(srctree)/include/uapi/asm-generic/errno.h - -obj-$(CONFIG_KSU) += kernelsu.o - -# .git is a text file while the module is imported by 'git submodule add'. -ifeq ($(shell test -e $(srctree)/$(src)/../.git; echo $$?),0) -$(shell cd $(srctree)/$(src); /usr/bin/env PATH="$$PATH":/usr/bin:/usr/local/bin [ -f ../.git/shallow ] && git fetch --unshallow) -KSU_GIT_VERSION := $(shell cd $(srctree)/$(src); /usr/bin/env PATH="$$PATH":/usr/bin:/usr/local/bin git rev-list --count HEAD) -# ksu_version: major * 10000 + git version + 200 for historical reasons -$(eval KSU_VERSION=$(shell expr 10000 + $(KSU_GIT_VERSION) + 200)) -$(info -- KernelSU version: $(KSU_VERSION)) -ccflags-y += -DKSU_VERSION=$(KSU_VERSION) -else # If there is no .git file, the default version will be passed. -$(warning "KSU_GIT_VERSION not defined! It is better to make KernelSU a git submodule!") -ccflags-y += -DKSU_VERSION=11872 -endif - -ifeq ($(shell grep -q " current_sid(void)" $(srctree)/security/selinux/include/objsec.h; echo $$?),0) -ccflags-y += -DKSU_COMPAT_HAS_CURRENT_SID -endif - -ifeq ($(shell grep -q "struct selinux_state " $(srctree)/security/selinux/include/security.h; echo $$?),0) -ccflags-y += -DKSU_COMPAT_HAS_SELINUX_STATE -endif - -ifndef KSU_EXPECTED_SIZE -KSU_EXPECTED_SIZE := 0x033b -endif - -ifndef KSU_EXPECTED_HASH -KSU_EXPECTED_HASH := c371061b19d8c7d7d6133c6a9bafe198fa944e50c1b31c9d8daa8d7f1fc2d2d6 -endif - -ifdef KSU_MANAGER_PACKAGE -ccflags-y += -DKSU_MANAGER_PACKAGE=\"$(KSU_MANAGER_PACKAGE)\" -$(info -- KernelSU Manager package name: $(KSU_MANAGER_PACKAGE)) -endif - -$(info -- KernelSU Manager signature size: $(KSU_EXPECTED_SIZE)) -$(info -- KernelSU Manager signature hash: $(KSU_EXPECTED_HASH)) - -ccflags-y += -DEXPECTED_SIZE=$(KSU_EXPECTED_SIZE) -ccflags-y += -DEXPECTED_HASH=\"$(KSU_EXPECTED_HASH)\" - -ifeq ($(shell grep -q "int path_umount" $(srctree)/fs/namespace.c; echo $$?),0) -ccflags-y += -DKSU_UMOUNT -else -$(info -- Did you know you can backport path_umount to fs/namespace.c from 5.9?) -$(info -- Read: https://kernelsu.org/guide/how-to-integrate-for-non-gki.html#how-to-backport-path-umount) -endif - -ccflags-y += -Wno-implicit-function-declaration -Wno-strict-prototypes -Wno-int-conversion -Wno-gcc-compat -ccflags-y += -Wno-declaration-after-statement -Wno-unused-function - -# Keep a new line here!! Because someone may append config diff --git a/drivers/kernelsu/allowlist.c b/drivers/kernelsu/allowlist.c deleted file mode 100644 index 4fbba9355949..000000000000 --- a/drivers/kernelsu/allowlist.c +++ /dev/null @@ -1,529 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) -#include -#endif - -#include "ksu.h" -#include "klog.h" // IWYU pragma: keep -#include "selinux/selinux.h" -#include "kernel_compat.h" -#include "allowlist.h" -#include "manager.h" - -#define FILE_MAGIC 0x7f4b5355 // ' KSU', u32 -#define FILE_FORMAT_VERSION 3 // u32 - -#define KSU_APP_PROFILE_PRESERVE_UID 9999 // NOBODY_UID -#define KSU_DEFAULT_SELINUX_DOMAIN "u:r:su:s0" - -static DEFINE_MUTEX(allowlist_mutex); - -// default profiles, these may be used frequently, so we cache it -static struct root_profile default_root_profile; -static struct non_root_profile default_non_root_profile; - -static int allow_list_arr[PAGE_SIZE / sizeof(int)] __read_mostly __aligned(PAGE_SIZE); -static int allow_list_pointer __read_mostly = 0; - -static void remove_uid_from_arr(uid_t uid) -{ - int *temp_arr; - int i, j; - - if (allow_list_pointer == 0) - return; - - temp_arr = kmalloc(sizeof(allow_list_arr), GFP_KERNEL); - if (temp_arr == NULL) { - pr_err("%s: unable to allocate memory\n", __func__); - return; - } - - for (i = j = 0; i < allow_list_pointer; i++) { - if (allow_list_arr[i] == uid) - continue; - temp_arr[j++] = allow_list_arr[i]; - } - - allow_list_pointer = j; - - for (; j < ARRAY_SIZE(allow_list_arr); j++) - temp_arr[j] = -1; - - memcpy(&allow_list_arr, temp_arr, PAGE_SIZE); - kfree(temp_arr); -} - -static void init_default_profiles() -{ - default_root_profile.uid = 0; - default_root_profile.gid = 0; - default_root_profile.groups_count = 1; - default_root_profile.groups[0] = 0; - memset(&default_root_profile.capabilities, 0xff, - sizeof(default_root_profile.capabilities)); - default_root_profile.namespaces = 0; - strcpy(default_root_profile.selinux_domain, KSU_DEFAULT_SELINUX_DOMAIN); - - // This means that we will umount modules by default! - default_non_root_profile.umount_modules = true; -} - -struct perm_data { - struct list_head list; - struct app_profile profile; -}; - -static struct list_head allow_list; - -static uint8_t allow_list_bitmap[PAGE_SIZE] __read_mostly __aligned(PAGE_SIZE); -#define BITMAP_UID_MAX ((sizeof(allow_list_bitmap) * BITS_PER_BYTE) - 1) - -#define KERNEL_SU_ALLOWLIST "/data/adb/ksu/.allowlist" - -static struct work_struct ksu_save_work; -static struct work_struct ksu_load_work; - -bool persistent_allow_list(void); - -void ksu_show_allow_list(void) -{ - struct perm_data *p = NULL; - struct list_head *pos = NULL; - pr_info("ksu_show_allow_list\n"); - list_for_each (pos, &allow_list) { - p = list_entry(pos, struct perm_data, list); - pr_info("uid :%d, allow: %d\n", p->profile.current_uid, - p->profile.allow_su); - } -} - -#ifdef CONFIG_KSU_DEBUG -static void ksu_grant_root_to_shell() -{ - struct app_profile profile = { - .allow_su = true, - .current_uid = 2000, - }; - strcpy(profile.key, "com.android.shell"); - strcpy(profile.rp_config.profile.selinux_domain, KSU_DEFAULT_SELINUX_DOMAIN); - ksu_set_app_profile(&profile, false); -} -#endif - -bool ksu_get_app_profile(struct app_profile *profile) -{ - struct perm_data *p = NULL; - struct list_head *pos = NULL; - bool found = false; - - list_for_each (pos, &allow_list) { - p = list_entry(pos, struct perm_data, list); - bool uid_match = profile->current_uid == p->profile.current_uid; - if (uid_match) { - // found it, override it with ours - memcpy(profile, &p->profile, sizeof(*profile)); - found = true; - goto exit; - } - } - -exit: - return found; -} - -static inline bool forbid_system_uid(uid_t uid) { - #define SHELL_UID 2000 - #define SYSTEM_UID 1000 - return uid < SHELL_UID && uid != SYSTEM_UID; -} - -static bool profile_valid(struct app_profile *profile) -{ - if (!profile) { - return false; - } - - if (forbid_system_uid(profile->current_uid)) { - pr_err("uid lower than 2000 is unsupported: %d\n", profile->current_uid); - return false; - } - - if (profile->version < KSU_APP_PROFILE_VER) { - pr_info("Unsupported profile version: %d\n", profile->version); - return false; - } - - if (profile->allow_su) { - if (profile->rp_config.profile.groups_count > KSU_MAX_GROUPS) { - return false; - } - - if (strlen(profile->rp_config.profile.selinux_domain) == 0) { - return false; - } - } - - return true; -} - -bool ksu_set_app_profile(struct app_profile *profile, bool persist) -{ - struct perm_data *p = NULL; - struct list_head *pos = NULL; - bool result = false; - - if (!profile_valid(profile)) { - pr_err("Failed to set app profile: invalid profile!\n"); - return false; - } - - list_for_each (pos, &allow_list) { - p = list_entry(pos, struct perm_data, list); - // both uid and package must match, otherwise it will break multiple package with different user id - if (profile->current_uid == p->profile.current_uid && - !strcmp(profile->key, p->profile.key)) { - // found it, just override it all! - memcpy(&p->profile, profile, sizeof(*profile)); - result = true; - goto out; - } - } - - // not found, alloc a new node! - p = (struct perm_data *)kmalloc(sizeof(struct perm_data), GFP_KERNEL); - if (!p) { - pr_err("ksu_set_app_profile alloc failed\n"); - return false; - } - - memcpy(&p->profile, profile, sizeof(*profile)); - if (profile->allow_su) { - pr_info("set root profile, key: %s, uid: %d, gid: %d, context: %s\n", - profile->key, profile->current_uid, - profile->rp_config.profile.gid, - profile->rp_config.profile.selinux_domain); - } else { - pr_info("set app profile, key: %s, uid: %d, umount modules: %d\n", - profile->key, profile->current_uid, - profile->nrp_config.profile.umount_modules); - } - list_add_tail(&p->list, &allow_list); - -out: - if (profile->current_uid <= BITMAP_UID_MAX) { - if (profile->allow_su) - allow_list_bitmap[profile->current_uid / BITS_PER_BYTE] |= 1 << (profile->current_uid % BITS_PER_BYTE); - else - allow_list_bitmap[profile->current_uid / BITS_PER_BYTE] &= ~(1 << (profile->current_uid % BITS_PER_BYTE)); - } else { - if (profile->allow_su) { - /* - * 1024 apps with uid higher than BITMAP_UID_MAX - * registered to request superuser? - */ - if (allow_list_pointer >= ARRAY_SIZE(allow_list_arr)) { - pr_err("too many apps registered\n"); - WARN_ON(1); - return false; - } - allow_list_arr[allow_list_pointer++] = profile->current_uid; - } else { - remove_uid_from_arr(profile->current_uid); - } - } - result = true; - - // check if the default profiles is changed, cache it to a single struct to accelerate access. - if (unlikely(!strcmp(profile->key, "$"))) { - // set default non root profile - memcpy(&default_non_root_profile, &profile->nrp_config.profile, - sizeof(default_non_root_profile)); - } - - if (unlikely(!strcmp(profile->key, "#"))) { - // set default root profile - memcpy(&default_root_profile, &profile->rp_config.profile, - sizeof(default_root_profile)); - } - - if (persist) - persistent_allow_list(); - - return result; -} - -bool __ksu_is_allow_uid(uid_t uid) -{ - int i; - - if (unlikely(uid == 0)) { - // already root, but only allow our domain. - return is_ksu_domain(); - } - - if (forbid_system_uid(uid)) { - // do not bother going through the list if it's system - return false; - } - - if (likely(ksu_is_manager_uid_valid()) && unlikely(ksu_get_manager_uid() == uid)) { - // manager is always allowed! - return true; - } - - if (likely(uid <= BITMAP_UID_MAX)) { - return !!(allow_list_bitmap[uid / BITS_PER_BYTE] & (1 << (uid % BITS_PER_BYTE))); - } else { - for (i = 0; i < allow_list_pointer; i++) { - if (allow_list_arr[i] == uid) - return true; - } - } - - return false; -} - -bool ksu_uid_should_umount(uid_t uid) -{ - struct app_profile profile = { .current_uid = uid }; - if (likely(ksu_is_manager_uid_valid()) && unlikely(ksu_get_manager_uid() == uid)) { - // we should not umount on manager! - return false; - } - bool found = ksu_get_app_profile(&profile); - if (!found) { - // no app profile found, it must be non root app - return default_non_root_profile.umount_modules; - } - if (profile.allow_su) { - // if found and it is granted to su, we shouldn't umount for it - return false; - } else { - // found an app profile - if (profile.nrp_config.use_default) { - return default_non_root_profile.umount_modules; - } else { - return profile.nrp_config.profile.umount_modules; - } - } -} - -struct root_profile *ksu_get_root_profile(uid_t uid) -{ - struct perm_data *p = NULL; - struct list_head *pos = NULL; - - list_for_each (pos, &allow_list) { - p = list_entry(pos, struct perm_data, list); - if (uid == p->profile.current_uid && p->profile.allow_su) { - if (!p->profile.rp_config.use_default) { - return &p->profile.rp_config.profile; - } - } - } - - // use default profile - return &default_root_profile; -} - -bool ksu_get_allow_list(int *array, int *length, bool allow) -{ - struct perm_data *p = NULL; - struct list_head *pos = NULL; - int i = 0; - list_for_each (pos, &allow_list) { - p = list_entry(pos, struct perm_data, list); - // pr_info("get_allow_list uid: %d allow: %d\n", p->uid, p->allow); - if (p->profile.allow_su == allow) { - array[i++] = p->profile.current_uid; - } - } - *length = i; - - return true; -} - -void do_save_allow_list(struct work_struct *work) -{ - u32 magic = FILE_MAGIC; - u32 version = FILE_FORMAT_VERSION; - struct perm_data *p = NULL; - struct list_head *pos = NULL; - loff_t off = 0; - - struct file *fp = - ksu_filp_open_compat(KERNEL_SU_ALLOWLIST, O_WRONLY | O_CREAT | O_TRUNC, 0644); - if (IS_ERR(fp)) { - pr_err("save_allow_list create file failed: %ld\n", PTR_ERR(fp)); - return; - } - - // store magic and version - if (ksu_kernel_write_compat(fp, &magic, sizeof(magic), &off) != - sizeof(magic)) { - pr_err("save_allow_list write magic failed.\n"); - goto exit; - } - - if (ksu_kernel_write_compat(fp, &version, sizeof(version), &off) != - sizeof(version)) { - pr_err("save_allow_list write version failed.\n"); - goto exit; - } - - list_for_each (pos, &allow_list) { - p = list_entry(pos, struct perm_data, list); - pr_info("save allow list, name: %s uid :%d, allow: %d\n", - p->profile.key, p->profile.current_uid, - p->profile.allow_su); - - ksu_kernel_write_compat(fp, &p->profile, sizeof(p->profile), - &off); - } - -exit: - filp_close(fp, 0); -} - -void do_load_allow_list(struct work_struct *work) -{ - loff_t off = 0; - ssize_t ret = 0; - struct file *fp = NULL; - u32 magic; - u32 version; - -#ifdef CONFIG_KSU_DEBUG - // always allow adb shell by default - ksu_grant_root_to_shell(); -#endif - - // load allowlist now! - fp = ksu_filp_open_compat(KERNEL_SU_ALLOWLIST, O_RDONLY, 0); - if (IS_ERR(fp)) { - pr_err("load_allow_list open file failed: %ld\n", PTR_ERR(fp)); - return; - } - - // verify magic - if (ksu_kernel_read_compat(fp, &magic, sizeof(magic), &off) != - sizeof(magic) || - magic != FILE_MAGIC) { - pr_err("allowlist file invalid: %d!\n", magic); - goto exit; - } - - if (ksu_kernel_read_compat(fp, &version, sizeof(version), &off) != - sizeof(version)) { - pr_err("allowlist read version: %d failed\n", version); - goto exit; - } - - pr_info("allowlist version: %d\n", version); - - while (true) { - struct app_profile profile; - - ret = ksu_kernel_read_compat(fp, &profile, sizeof(profile), - &off); - - if (ret <= 0) { - pr_info("load_allow_list read err: %zd\n", ret); - break; - } - - pr_info("load_allow_uid, name: %s, uid: %d, allow: %d\n", - profile.key, profile.current_uid, profile.allow_su); - ksu_set_app_profile(&profile, false); - } - -exit: - ksu_show_allow_list(); - filp_close(fp, 0); -} - -void ksu_prune_allowlist(bool (*is_uid_valid)(uid_t, char *, void *), void *data) -{ - struct perm_data *np = NULL; - struct perm_data *n = NULL; - - bool modified = false; - // TODO: use RCU! - mutex_lock(&allowlist_mutex); - list_for_each_entry_safe (np, n, &allow_list, list) { - uid_t uid = np->profile.current_uid; - char *package = np->profile.key; - // we use this uid for special cases, don't prune it! - bool is_preserved_uid = uid == KSU_APP_PROFILE_PRESERVE_UID; - if (!is_preserved_uid && !is_uid_valid(uid, package, data)) { - modified = true; - pr_info("prune uid: %d, package: %s\n", uid, package); - list_del(&np->list); - if (likely(uid <= BITMAP_UID_MAX)) { - allow_list_bitmap[uid / BITS_PER_BYTE] &= ~(1 << (uid % BITS_PER_BYTE)); - } - remove_uid_from_arr(uid); - smp_mb(); - kfree(np); - } - } - mutex_unlock(&allowlist_mutex); - - if (modified) { - persistent_allow_list(); - } -} - -// make sure allow list works cross boot -bool persistent_allow_list(void) -{ - return ksu_queue_work(&ksu_save_work); -} - -bool ksu_load_allow_list(void) -{ - return ksu_queue_work(&ksu_load_work); -} - -void ksu_allowlist_init(void) -{ - int i; - - BUILD_BUG_ON(sizeof(allow_list_bitmap) != PAGE_SIZE); - BUILD_BUG_ON(sizeof(allow_list_arr) != PAGE_SIZE); - - for (i = 0; i < ARRAY_SIZE(allow_list_arr); i++) - allow_list_arr[i] = -1; - - INIT_LIST_HEAD(&allow_list); - - INIT_WORK(&ksu_save_work, do_save_allow_list); - INIT_WORK(&ksu_load_work, do_load_allow_list); - - init_default_profiles(); -} - -void ksu_allowlist_exit(void) -{ - struct perm_data *np = NULL; - struct perm_data *n = NULL; - - do_save_allow_list(NULL); - - // free allowlist - mutex_lock(&allowlist_mutex); - list_for_each_entry_safe (np, n, &allow_list, list) { - list_del(&np->list); - kfree(np); - } - mutex_unlock(&allowlist_mutex); -} diff --git a/drivers/kernelsu/allowlist.h b/drivers/kernelsu/allowlist.h deleted file mode 100644 index e89bf71fa10c..000000000000 --- a/drivers/kernelsu/allowlist.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef __KSU_H_ALLOWLIST -#define __KSU_H_ALLOWLIST - -#include -#include "ksu.h" - -void ksu_allowlist_init(void); - -void ksu_allowlist_exit(void); - -bool ksu_load_allow_list(void); - -void ksu_show_allow_list(void); - -bool __ksu_is_allow_uid(uid_t uid); -#define ksu_is_allow_uid(uid) unlikely(__ksu_is_allow_uid(uid)) - -bool ksu_get_allow_list(int *array, int *length, bool allow); - -void ksu_prune_allowlist(bool (*is_uid_exist)(uid_t, char *, void *), void *data); - -bool ksu_get_app_profile(struct app_profile *); -bool ksu_set_app_profile(struct app_profile *, bool persist); - -bool ksu_uid_should_umount(uid_t uid); -struct root_profile *ksu_get_root_profile(uid_t uid); -#endif diff --git a/drivers/kernelsu/apk_sign.c b/drivers/kernelsu/apk_sign.c deleted file mode 100644 index ba8b73f2eb2b..000000000000 --- a/drivers/kernelsu/apk_sign.c +++ /dev/null @@ -1,320 +0,0 @@ -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_KSU_DEBUG -#include -#endif -#include -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) -#include -#else -#include -#endif - -#include "apk_sign.h" -#include "klog.h" // IWYU pragma: keep -#include "kernel_compat.h" - - -struct sdesc { - struct shash_desc shash; - char ctx[]; -}; - -static struct sdesc *init_sdesc(struct crypto_shash *alg) -{ - struct sdesc *sdesc; - int size; - - size = sizeof(struct shash_desc) + crypto_shash_descsize(alg); - sdesc = kmalloc(size, GFP_KERNEL); - if (!sdesc) - return ERR_PTR(-ENOMEM); - sdesc->shash.tfm = alg; - return sdesc; -} - -static int calc_hash(struct crypto_shash *alg, const unsigned char *data, - unsigned int datalen, unsigned char *digest) -{ - struct sdesc *sdesc; - int ret; - - sdesc = init_sdesc(alg); - if (IS_ERR(sdesc)) { - pr_info("can't alloc sdesc\n"); - return PTR_ERR(sdesc); - } - - ret = crypto_shash_digest(&sdesc->shash, data, datalen, digest); - kfree(sdesc); - return ret; -} - -static int ksu_sha256(const unsigned char *data, unsigned int datalen, - unsigned char *digest) -{ - struct crypto_shash *alg; - char *hash_alg_name = "sha256"; - int ret; - - alg = crypto_alloc_shash(hash_alg_name, 0, 0); - if (IS_ERR(alg)) { - pr_info("can't alloc alg %s\n", hash_alg_name); - return PTR_ERR(alg); - } - ret = calc_hash(alg, data, datalen, digest); - crypto_free_shash(alg); - return ret; -} - -static bool check_block(struct file *fp, u32 *size4, loff_t *pos, u32 *offset, - unsigned expected_size, const char *expected_sha256) -{ - ksu_kernel_read_compat(fp, size4, 0x4, pos); // signer-sequence length - ksu_kernel_read_compat(fp, size4, 0x4, pos); // signer length - ksu_kernel_read_compat(fp, size4, 0x4, pos); // signed data length - - *offset += 0x4 * 3; - - ksu_kernel_read_compat(fp, size4, 0x4, pos); // digests-sequence length - - *pos += *size4; - *offset += 0x4 + *size4; - - ksu_kernel_read_compat(fp, size4, 0x4, pos); // certificates length - ksu_kernel_read_compat(fp, size4, 0x4, pos); // certificate length - *offset += 0x4 * 2; - - if (*size4 == expected_size) { - *offset += *size4; - -#define CERT_MAX_LENGTH 1024 - char cert[CERT_MAX_LENGTH]; - if (*size4 > CERT_MAX_LENGTH) { - pr_info("cert length overlimit\n"); - return false; - } - ksu_kernel_read_compat(fp, cert, *size4, pos); - unsigned char digest[SHA256_DIGEST_SIZE]; - if (IS_ERR(ksu_sha256(cert, *size4, digest))) { - pr_info("sha256 error\n"); - return false; - } - - char hash_str[SHA256_DIGEST_SIZE * 2 + 1]; - hash_str[SHA256_DIGEST_SIZE * 2] = '\0'; - - bin2hex(hash_str, digest, SHA256_DIGEST_SIZE); - pr_info("sha256: %s, expected: %s\n", hash_str, - expected_sha256); - if (strcmp(expected_sha256, hash_str) == 0) { - return true; - } - } - return false; -} - -struct zip_entry_header { - uint32_t signature; - uint16_t version; - uint16_t flags; - uint16_t compression; - uint16_t mod_time; - uint16_t mod_date; - uint32_t crc32; - uint32_t compressed_size; - uint32_t uncompressed_size; - uint16_t file_name_length; - uint16_t extra_field_length; -} __attribute__((packed)); - -// This is a necessary but not sufficient condition, but it is enough for us -static bool has_v1_signature_file(struct file *fp) -{ - struct zip_entry_header header; - const char MANIFEST[] = "META-INF/MANIFEST.MF"; - - loff_t pos = 0; - - while (ksu_kernel_read_compat(fp, &header, - sizeof(struct zip_entry_header), &pos) == - sizeof(struct zip_entry_header)) { - if (header.signature != 0x04034b50) { - // ZIP magic: 'PK' - return false; - } - // Read the entry file name - if (header.file_name_length == sizeof(MANIFEST) - 1) { - char fileName[sizeof(MANIFEST)]; - ksu_kernel_read_compat(fp, fileName, - header.file_name_length, &pos); - fileName[header.file_name_length] = '\0'; - - // Check if the entry matches META-INF/MANIFEST.MF - if (strncmp(MANIFEST, fileName, sizeof(MANIFEST) - 1) == - 0) { - return true; - } - } else { - // Skip the entry file name - pos += header.file_name_length; - } - - // Skip to the next entry - pos += header.extra_field_length + header.compressed_size; - } - - return false; -} - -static __always_inline bool check_v2_signature(char *path, - unsigned expected_size, - const char *expected_sha256) -{ - unsigned char buffer[0x11] = { 0 }; - u32 size4; - u64 size8, size_of_block; - - loff_t pos; - - bool v2_signing_valid = false; - int v2_signing_blocks = 0; - bool v3_signing_exist = false; - bool v3_1_signing_exist = false; - - int i; - struct file *fp = ksu_filp_open_compat(path, O_RDONLY, 0); - if (IS_ERR(fp)) { - pr_err("open %s error.\n", path); - return false; - } - - // disable inotify for this file - fp->f_mode |= FMODE_NONOTIFY; - - // https://en.wikipedia.org/wiki/Zip_(file_format)#End_of_central_directory_record_(EOCD) - for (i = 0;; ++i) { - unsigned short n; - pos = generic_file_llseek(fp, -i - 2, SEEK_END); - ksu_kernel_read_compat(fp, &n, 2, &pos); - if (n == i) { - pos -= 22; - ksu_kernel_read_compat(fp, &size4, 4, &pos); - if ((size4 ^ 0xcafebabeu) == 0xccfbf1eeu) { - break; - } - } - if (i == 0xffff) { - pr_info("error: cannot find eocd\n"); - goto clean; - } - } - - pos += 12; - // offset - ksu_kernel_read_compat(fp, &size4, 0x4, &pos); - pos = size4 - 0x18; - - ksu_kernel_read_compat(fp, &size8, 0x8, &pos); - ksu_kernel_read_compat(fp, buffer, 0x10, &pos); - if (strcmp((char *)buffer, "APK Sig Block 42")) { - goto clean; - } - - pos = size4 - (size8 + 0x8); - ksu_kernel_read_compat(fp, &size_of_block, 0x8, &pos); - if (size_of_block != size8) { - goto clean; - } - - int loop_count = 0; - while (loop_count++ < 10) { - uint32_t id; - uint32_t offset; - ksu_kernel_read_compat(fp, &size8, 0x8, - &pos); // sequence length - if (size8 == size_of_block) { - break; - } - ksu_kernel_read_compat(fp, &id, 0x4, &pos); // id - offset = 4; - if (id == 0x7109871au) { - v2_signing_blocks++; - v2_signing_valid = - check_block(fp, &size4, &pos, &offset, - expected_size, expected_sha256); - } else if (id == 0xf05368c0u) { - // http://aospxref.com/android-14.0.0_r2/xref/frameworks/base/core/java/android/util/apk/ApkSignatureSchemeV3Verifier.java#73 - v3_signing_exist = true; - } else if (id == 0x1b93ad61u) { - // http://aospxref.com/android-14.0.0_r2/xref/frameworks/base/core/java/android/util/apk/ApkSignatureSchemeV3Verifier.java#74 - v3_1_signing_exist = true; - } else { -#ifdef CONFIG_KSU_DEBUG - pr_info("Unknown id: 0x%08x\n", id); -#endif - } - pos += (size8 - offset); - } - - if (v2_signing_blocks != 1) { -#ifdef CONFIG_KSU_DEBUG - pr_err("Unexpected v2 signature count: %d\n", - v2_signing_blocks); -#endif - v2_signing_valid = false; - } - - if (v2_signing_valid) { - int has_v1_signing = has_v1_signature_file(fp); - if (has_v1_signing) { - pr_err("Unexpected v1 signature scheme found!\n"); - filp_close(fp, 0); - return false; - } - } -clean: - filp_close(fp, 0); - - if (v3_signing_exist || v3_1_signing_exist) { -#ifdef CONFIG_KSU_DEBUG - pr_err("Unexpected v3 signature scheme found!\n"); -#endif - return false; - } - - return v2_signing_valid; -} - -#ifdef CONFIG_KSU_DEBUG - -int ksu_debug_manager_uid = -1; - -#include "manager.h" - -static int set_expected_size(const char *val, const struct kernel_param *kp) -{ - int rv = param_set_uint(val, kp); - ksu_set_manager_uid(ksu_debug_manager_uid); - pr_info("ksu_manager_uid set to %d\n", ksu_debug_manager_uid); - return rv; -} - -static struct kernel_param_ops expected_size_ops = { - .set = set_expected_size, - .get = param_get_uint, -}; - -module_param_cb(ksu_debug_manager_uid, &expected_size_ops, - &ksu_debug_manager_uid, S_IRUSR | S_IWUSR); - -#endif - -bool is_manager_apk(char *path) -{ - return check_v2_signature(path, EXPECTED_SIZE, EXPECTED_HASH); -} \ No newline at end of file diff --git a/drivers/kernelsu/apk_sign.h b/drivers/kernelsu/apk_sign.h deleted file mode 100644 index bed501c49264..000000000000 --- a/drivers/kernelsu/apk_sign.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __KSU_H_APK_V2_SIGN -#define __KSU_H_APK_V2_SIGN - -#include - -bool is_manager_apk(char *path); - -#endif diff --git a/drivers/kernelsu/arch.h b/drivers/kernelsu/arch.h deleted file mode 100644 index f36ec5f509fa..000000000000 --- a/drivers/kernelsu/arch.h +++ /dev/null @@ -1,92 +0,0 @@ -#ifndef __KSU_H_ARCH -#define __KSU_H_ARCH - -#include - -#if defined(__aarch64__) - -#define __PT_PARM1_REG regs[0] -#define __PT_PARM2_REG regs[1] -#define __PT_PARM3_REG regs[2] -#define __PT_SYSCALL_PARM4_REG regs[3] -#define __PT_CCALL_PARM4_REG regs[3] -#define __PT_PARM5_REG regs[4] -#define __PT_PARM6_REG regs[5] -#define __PT_RET_REG regs[30] -#define __PT_FP_REG regs[29] /* Works only with CONFIG_FRAME_POINTER */ -#define __PT_RC_REG regs[0] -#define __PT_SP_REG sp -#define __PT_IP_REG pc - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0) -#define PRCTL_SYMBOL "__arm64_sys_prctl" -#define SYS_READ_SYMBOL "__arm64_sys_read" -#define SYS_NEWFSTATAT_SYMBOL "__arm64_sys_newfstatat" -#define SYS_FACCESSAT_SYMBOL "__arm64_sys_faccessat" -#define SYS_EXECVE_SYMBOL "__arm64_sys_execve" -#else -#define PRCTL_SYMBOL "sys_prctl" -#define SYS_READ_SYMBOL "sys_read" -#define SYS_NEWFSTATAT_SYMBOL "sys_newfstatat" -#define SYS_FACCESSAT_SYMBOL "sys_faccessat" -#define SYS_EXECVE_SYMBOL "sys_execve" -#endif - -#elif defined(__x86_64__) - -#define __PT_PARM1_REG di -#define __PT_PARM2_REG si -#define __PT_PARM3_REG dx -/* syscall uses r10 for PARM4 */ -#define __PT_SYSCALL_PARM4_REG r10 -#define __PT_CCALL_PARM4_REG cx -#define __PT_PARM5_REG r8 -#define __PT_PARM6_REG r9 -#define __PT_RET_REG sp -#define __PT_FP_REG bp -#define __PT_RC_REG ax -#define __PT_SP_REG sp -#define __PT_IP_REG ip -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0) -#define PRCTL_SYMBOL "__x64_sys_prctl" -#define SYS_READ_SYMBOL "__x64_sys_read" -#define SYS_NEWFSTATAT_SYMBOL "__x64_sys_newfstatat" -#define SYS_FACCESSAT_SYMBOL "__x64_sys_faccessat" -#define SYS_EXECVE_SYMBOL "__x64_sys_execve" -#else -#define PRCTL_SYMBOL "sys_prctl" -#define SYS_READ_SYMBOL "sys_read" -#define SYS_NEWFSTATAT_SYMBOL "sys_newfstatat" -#define SYS_FACCESSAT_SYMBOL "sys_faccessat" -#define SYS_EXECVE_SYMBOL "sys_execve" -#endif - -#else -#error "Unsupported arch" -#endif - -/* allow some architecutres to override `struct pt_regs` */ -#ifndef __PT_REGS_CAST -#define __PT_REGS_CAST(x) (x) -#endif - -#define PT_REGS_PARM1(x) (__PT_REGS_CAST(x)->__PT_PARM1_REG) -#define PT_REGS_PARM2(x) (__PT_REGS_CAST(x)->__PT_PARM2_REG) -#define PT_REGS_PARM3(x) (__PT_REGS_CAST(x)->__PT_PARM3_REG) -#define PT_REGS_SYSCALL_PARM4(x) (__PT_REGS_CAST(x)->__PT_SYSCALL_PARM4_REG) -#define PT_REGS_CCALL_PARM4(x) (__PT_REGS_CAST(x)->__PT_CCALL_PARM4_REG) -#define PT_REGS_PARM5(x) (__PT_REGS_CAST(x)->__PT_PARM5_REG) -#define PT_REGS_PARM6(x) (__PT_REGS_CAST(x)->__PT_PARM6_REG) -#define PT_REGS_RET(x) (__PT_REGS_CAST(x)->__PT_RET_REG) -#define PT_REGS_FP(x) (__PT_REGS_CAST(x)->__PT_FP_REG) -#define PT_REGS_RC(x) (__PT_REGS_CAST(x)->__PT_RC_REG) -#define PT_REGS_SP(x) (__PT_REGS_CAST(x)->__PT_SP_REG) -#define PT_REGS_IP(x) (__PT_REGS_CAST(x)->__PT_IP_REG) - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0) -#define PT_REAL_REGS(regs) ((struct pt_regs *)PT_REGS_PARM1(regs)) -#else -#define PT_REAL_REGS(regs) ((regs)) -#endif - -#endif diff --git a/drivers/kernelsu/core_hook.c b/drivers/kernelsu/core_hook.c deleted file mode 100644 index 429ba3306ea3..000000000000 --- a/drivers/kernelsu/core_hook.c +++ /dev/null @@ -1,856 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#ifdef MODULE -#include -#include -#include -#include -#include -#endif - -#include "allowlist.h" -#include "arch.h" -#include "core_hook.h" -#include "klog.h" // IWYU pragma: keep -#include "ksu.h" -#include "ksud.h" -#include "manager.h" -#include "selinux/selinux.h" -#include "throne_tracker.h" -#include "throne_tracker.h" -#include "kernel_compat.h" - -static bool ksu_module_mounted = false; - -extern int handle_sepolicy(unsigned long arg3, void __user *arg4); - -static inline bool is_allow_su() -{ - if (is_manager()) { - // we are manager, allow! - return true; - } - return ksu_is_allow_uid(current_uid().val); -} - -static inline bool is_unsupported_uid(uid_t uid) -{ -#define LAST_APPLICATION_UID 19999 - uid_t appid = uid % 100000; - return appid > LAST_APPLICATION_UID; -} - -static struct group_info root_groups = { .usage = ATOMIC_INIT(2) }; - -static void setup_groups(struct root_profile *profile, struct cred *cred) -{ - if (profile->groups_count > KSU_MAX_GROUPS) { - pr_warn("Failed to setgroups, too large group: %d!\n", - profile->uid); - return; - } - - if (profile->groups_count == 1 && profile->groups[0] == 0) { - // setgroup to root and return early. - if (cred->group_info) - put_group_info(cred->group_info); - cred->group_info = get_group_info(&root_groups); - return; - } - - u32 ngroups = profile->groups_count; - struct group_info *group_info = groups_alloc(ngroups); - if (!group_info) { - pr_warn("Failed to setgroups, ENOMEM for: %d\n", profile->uid); - return; - } - - int i; - for (i = 0; i < ngroups; i++) { - gid_t gid = profile->groups[i]; - kgid_t kgid = make_kgid(current_user_ns(), gid); - if (!gid_valid(kgid)) { - pr_warn("Failed to setgroups, invalid gid: %d\n", gid); - put_group_info(group_info); - return; - } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) - group_info->gid[i] = kgid; -#else - GROUP_AT(group_info, i) = kgid; -#endif - } - - groups_sort(group_info); - set_groups(cred, group_info); -} - -void escape_to_root(void) -{ - struct cred *cred; - - cred = (struct cred *)__task_cred(current); - - if (cred->euid.val == 0) { - pr_warn("Already root, don't escape!\n"); - return; - } - struct root_profile *profile = ksu_get_root_profile(cred->uid.val); - - cred->uid.val = profile->uid; - cred->suid.val = profile->uid; - cred->euid.val = profile->uid; - cred->fsuid.val = profile->uid; - - cred->gid.val = profile->gid; - cred->fsgid.val = profile->gid; - cred->sgid.val = profile->gid; - cred->egid.val = profile->gid; - - BUILD_BUG_ON(sizeof(profile->capabilities.effective) != - sizeof(kernel_cap_t)); - - // setup capabilities - // we need CAP_DAC_READ_SEARCH becuase `/data/adb/ksud` is not accessible for non root process - // we add it here but don't add it to cap_inhertiable, it would be dropped automaticly after exec! - u64 cap_for_ksud = - profile->capabilities.effective | CAP_DAC_READ_SEARCH; - memcpy(&cred->cap_effective, &cap_for_ksud, - sizeof(cred->cap_effective)); - memcpy(&cred->cap_inheritable, &profile->capabilities.effective, - sizeof(cred->cap_inheritable)); - memcpy(&cred->cap_permitted, &profile->capabilities.effective, - sizeof(cred->cap_permitted)); - memcpy(&cred->cap_bset, &profile->capabilities.effective, - sizeof(cred->cap_bset)); - memcpy(&cred->cap_ambient, &profile->capabilities.effective, - sizeof(cred->cap_ambient)); - - // disable seccomp -#if defined(CONFIG_GENERIC_ENTRY) && \ - LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) - current_thread_info()->syscall_work &= ~SYSCALL_WORK_SECCOMP; -#else - current_thread_info()->flags &= ~(TIF_SECCOMP | _TIF_SECCOMP); -#endif - -#ifdef CONFIG_SECCOMP - current->seccomp.mode = 0; - current->seccomp.filter = NULL; -#else -#endif - - setup_groups(profile, cred); - - setup_selinux(profile->selinux_domain); -} - -int ksu_handle_rename(struct dentry *old_dentry, struct dentry *new_dentry) -{ - if (!current->mm) { - // skip kernel threads - return 0; - } - - if (current_uid().val != 1000) { - // skip non system uid - return 0; - } - - if (!old_dentry || !new_dentry) { - return 0; - } - - // /data/system/packages.list.tmp -> /data/system/packages.list - if (strcmp(new_dentry->d_iname, "packages.list")) { - return 0; - } - - char path[128]; - char *buf = dentry_path_raw(new_dentry, path, sizeof(path)); - if (IS_ERR(buf)) { - pr_err("dentry_path_raw failed.\n"); - return 0; - } - - if (strcmp(buf, "/system/packages.list")) { - return 0; - } - pr_info("renameat: %s -> %s, new path: %s\n", old_dentry->d_iname, - new_dentry->d_iname, buf); - - track_throne(); - - return 0; -} - -int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3, - unsigned long arg4, unsigned long arg5) -{ - // if success, we modify the arg5 as result! - u32 *result = (u32 *)arg5; - u32 reply_ok = KERNEL_SU_OPTION; - - if (KERNEL_SU_OPTION != option) { - return 0; - } - - // TODO: find it in throne tracker! - uid_t current_uid_val = current_uid().val; - uid_t manager_uid = ksu_get_manager_uid(); - if (current_uid_val != manager_uid && - current_uid_val % 100000 == manager_uid) { - ksu_set_manager_uid(current_uid_val); - } - - bool from_root = 0 == current_uid().val; - bool from_manager = is_manager(); - - if (!from_root && !from_manager) { - // only root or manager can access this interface - return 0; - } - -#ifdef CONFIG_KSU_DEBUG - pr_info("option: 0x%x, cmd: %ld\n", option, arg2); -#endif - - if (arg2 == CMD_BECOME_MANAGER) { - if (from_manager) { - if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) { - pr_err("become_manager: prctl reply error\n"); - } - return 0; - } - return 0; - } - - if (arg2 == CMD_GRANT_ROOT) { - if (is_allow_su()) { - pr_info("allow root for: %d\n", current_uid().val); - escape_to_root(); - if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) { - pr_err("grant_root: prctl reply error\n"); - } - } - return 0; - } - - // Both root manager and root processes should be allowed to get version - if (arg2 == CMD_GET_VERSION) { - u32 version = KERNEL_SU_VERSION; - if (copy_to_user(arg3, &version, sizeof(version))) { - pr_err("prctl reply error, cmd: %lu\n", arg2); - } -#ifdef MODULE - u32 is_lkm = 0x1; -#else - u32 is_lkm = 0x0; -#endif - if (arg4 && copy_to_user(arg4, &is_lkm, sizeof(is_lkm))) { - pr_err("prctl reply error, cmd: %lu\n", arg2); - } - return 0; - } - - if (arg2 == CMD_REPORT_EVENT) { - if (!from_root) { - return 0; - } - switch (arg3) { - case EVENT_POST_FS_DATA: { - static bool post_fs_data_lock = false; - if (!post_fs_data_lock) { - post_fs_data_lock = true; - pr_info("post-fs-data triggered\n"); - on_post_fs_data(); - } - break; - } - case EVENT_BOOT_COMPLETED: { - static bool boot_complete_lock = false; - if (!boot_complete_lock) { - boot_complete_lock = true; - pr_info("boot_complete triggered\n"); - } - break; - } - case EVENT_MODULE_MOUNTED: { - ksu_module_mounted = true; - pr_info("module mounted!\n"); - break; - } - default: - break; - } - return 0; - } - - if (arg2 == CMD_SET_SEPOLICY) { - if (!from_root) { - return 0; - } - if (!handle_sepolicy(arg3, arg4)) { - if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) { - pr_err("sepolicy: prctl reply error\n"); - } - } - - return 0; - } - - if (arg2 == CMD_CHECK_SAFEMODE) { - if (ksu_is_safe_mode()) { - pr_warn("safemode enabled!\n"); - if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) { - pr_err("safemode: prctl reply error\n"); - } - } - return 0; - } - - if (arg2 == CMD_GET_ALLOW_LIST || arg2 == CMD_GET_DENY_LIST) { - u32 array[128]; - u32 array_length; - bool success = ksu_get_allow_list(array, &array_length, - arg2 == CMD_GET_ALLOW_LIST); - if (success) { - if (!copy_to_user(arg4, &array_length, - sizeof(array_length)) && - !copy_to_user(arg3, array, - sizeof(u32) * array_length)) { - if (copy_to_user(result, &reply_ok, - sizeof(reply_ok))) { - pr_err("prctl reply error, cmd: %lu\n", - arg2); - } - } else { - pr_err("prctl copy allowlist error\n"); - } - } - return 0; - } - - if (arg2 == CMD_UID_GRANTED_ROOT || arg2 == CMD_UID_SHOULD_UMOUNT) { - uid_t target_uid = (uid_t)arg3; - bool allow = false; - if (arg2 == CMD_UID_GRANTED_ROOT) { - allow = ksu_is_allow_uid(target_uid); - } else if (arg2 == CMD_UID_SHOULD_UMOUNT) { - allow = ksu_uid_should_umount(target_uid); - } else { - pr_err("unknown cmd: %lu\n", arg2); - } - if (!copy_to_user(arg4, &allow, sizeof(allow))) { - if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) { - pr_err("prctl reply error, cmd: %lu\n", arg2); - } - } else { - pr_err("prctl copy err, cmd: %lu\n", arg2); - } - return 0; - } - - // all other cmds are for 'root manager' - if (!from_manager) { - return 0; - } - - // we are already manager - if (arg2 == CMD_GET_APP_PROFILE) { - struct app_profile profile; - if (copy_from_user(&profile, arg3, sizeof(profile))) { - pr_err("copy profile failed\n"); - return 0; - } - - bool success = ksu_get_app_profile(&profile); - if (success) { - if (copy_to_user(arg3, &profile, sizeof(profile))) { - pr_err("copy profile failed\n"); - return 0; - } - if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) { - pr_err("prctl reply error, cmd: %lu\n", arg2); - } - } - return 0; - } - - if (arg2 == CMD_SET_APP_PROFILE) { - struct app_profile profile; - if (copy_from_user(&profile, arg3, sizeof(profile))) { - pr_err("copy profile failed\n"); - return 0; - } - - // todo: validate the params - if (ksu_set_app_profile(&profile, true)) { - if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) { - pr_err("prctl reply error, cmd: %lu\n", arg2); - } - } - return 0; - } - - return 0; -} - -static bool is_appuid(kuid_t uid) -{ -#define PER_USER_RANGE 100000 -#define FIRST_APPLICATION_UID 10000 -#define LAST_APPLICATION_UID 19999 - - uid_t appid = uid.val % PER_USER_RANGE; - return appid >= FIRST_APPLICATION_UID && appid <= LAST_APPLICATION_UID; -} - -static bool should_umount(struct path *path) -{ - if (!path) { - return false; - } - - if (current->nsproxy->mnt_ns == init_nsproxy.mnt_ns) { - pr_info("ignore global mnt namespace process: %d\n", - current_uid().val); - return false; - } - - if (path->mnt && path->mnt->mnt_sb && path->mnt->mnt_sb->s_type) { - const char *fstype = path->mnt->mnt_sb->s_type->name; - return strcmp(fstype, "overlay") == 0; - } - return false; -} - -static int ksu_umount_mnt(struct path *path, int flags) -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0) || defined(KSU_UMOUNT) - return path_umount(path, flags); -#else - // TODO: umount for non GKI kernel - return -ENOSYS; -#endif -} - -static void try_umount(const char *mnt, bool check_mnt, int flags) -{ - struct path path; - int err = kern_path(mnt, 0, &path); - if (err) { - return; - } - - if (path.dentry != path.mnt->mnt_root) { - // it is not root mountpoint, maybe umounted by others already. - return; - } - - // we are only interest in some specific mounts - if (check_mnt && !should_umount(&path)) { - return; - } - - err = ksu_umount_mnt(&path, flags); - if (err) { - pr_warn("umount %s failed: %d\n", mnt, err); - } -} - -int ksu_handle_setuid(struct cred *new, const struct cred *old) -{ - // this hook is used for umounting overlayfs for some uid, if there isn't any module mounted, just ignore it! - if (!ksu_module_mounted) { - return 0; - } - - if (!new || !old) { - return 0; - } - - kuid_t new_uid = new->uid; - kuid_t old_uid = old->uid; - - if (0 != old_uid.val) { - // old process is not root, ignore it. - return 0; - } - - if (!is_appuid(new_uid) || is_unsupported_uid(new_uid.val)) { - // pr_info("handle setuid ignore non application or isolated uid: %d\n", new_uid.val); - return 0; - } - - if (ksu_is_allow_uid(new_uid.val)) { - // pr_info("handle setuid ignore allowed application: %d\n", new_uid.val); - return 0; - } - - if (!ksu_uid_should_umount(new_uid.val)) { - return 0; - } else { -#ifdef CONFIG_KSU_DEBUG - pr_info("uid: %d should not umount!\n", current_uid().val); -#endif - } - - // check old process's selinux context, if it is not zygote, ignore it! - // because some su apps may setuid to untrusted_app but they are in global mount namespace - // when we umount for such process, that is a disaster! - bool is_zygote_child = is_zygote(old->security); - if (!is_zygote_child) { - pr_info("handle umount ignore non zygote child: %d\n", - current->pid); - return 0; - } -#ifdef CONFIG_KSU_DEBUG - // umount the target mnt - pr_info("handle umount for uid: %d, pid: %d\n", new_uid.val, - current->pid); -#endif - - // fixme: use `collect_mounts` and `iterate_mount` to iterate all mountpoint and - // filter the mountpoint whose target is `/data/adb` - try_umount("/system", true, 0); - try_umount("/vendor", true, 0); - try_umount("/product", true, 0); - try_umount("/data/adb/modules", false, MNT_DETACH); - - // try umount ksu temp path - try_umount("/debug_ramdisk", false, MNT_DETACH); - try_umount("/sbin", false, MNT_DETACH); - - return 0; -} - -// Init functons - -static int handler_pre(struct kprobe *p, struct pt_regs *regs) -{ - struct pt_regs *real_regs = PT_REAL_REGS(regs); - int option = (int)PT_REGS_PARM1(real_regs); - unsigned long arg2 = (unsigned long)PT_REGS_PARM2(real_regs); - unsigned long arg3 = (unsigned long)PT_REGS_PARM3(real_regs); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0) - // PRCTL_SYMBOL is the arch-specificed one, which receive raw pt_regs from syscall - unsigned long arg4 = (unsigned long)PT_REGS_SYSCALL_PARM4(real_regs); -#else - // PRCTL_SYMBOL is the common one, called by C convention in do_syscall_64 - // https://elixir.bootlin.com/linux/v4.15.18/source/arch/x86/entry/common.c#L287 - unsigned long arg4 = (unsigned long)PT_REGS_CCALL_PARM4(real_regs); -#endif - unsigned long arg5 = (unsigned long)PT_REGS_PARM5(real_regs); - - return ksu_handle_prctl(option, arg2, arg3, arg4, arg5); -} - -static struct kprobe prctl_kp = { - .symbol_name = PRCTL_SYMBOL, - .pre_handler = handler_pre, -}; - -static int renameat_handler_pre(struct kprobe *p, struct pt_regs *regs) -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0) - // https://elixir.bootlin.com/linux/v5.12-rc1/source/include/linux/fs.h - struct renamedata *rd = PT_REGS_PARM1(regs); - struct dentry *old_entry = rd->old_dentry; - struct dentry *new_entry = rd->new_dentry; -#else - struct dentry *old_entry = (struct dentry *)PT_REGS_PARM2(regs); - struct dentry *new_entry = (struct dentry *)PT_REGS_CCALL_PARM4(regs); -#endif - - return ksu_handle_rename(old_entry, new_entry); -} - -static struct kprobe renameat_kp = { - .symbol_name = "vfs_rename", - .pre_handler = renameat_handler_pre, -}; - -__maybe_unused int ksu_kprobe_init(void) -{ - int rc = 0; - rc = register_kprobe(&prctl_kp); - - if (rc) { - pr_info("prctl kprobe failed: %d.\n", rc); - return rc; - } - - rc = register_kprobe(&renameat_kp); - pr_info("renameat kp: %d\n", rc); - - return rc; -} - -__maybe_unused int ksu_kprobe_exit(void) -{ - unregister_kprobe(&prctl_kp); - unregister_kprobe(&renameat_kp); - return 0; -} - -static int ksu_task_prctl(int option, unsigned long arg2, unsigned long arg3, - unsigned long arg4, unsigned long arg5) -{ - ksu_handle_prctl(option, arg2, arg3, arg4, arg5); - return -ENOSYS; -} -// kernel 4.4 and 4.9 -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || defined(CONFIG_IS_HW_HISI) -static int ksu_key_permission(key_ref_t key_ref, const struct cred *cred, - unsigned perm) -{ - if (init_session_keyring != NULL) { - return 0; - } - if (strcmp(current->comm, "init")) { - // we are only interested in `init` process - return 0; - } - init_session_keyring = cred->session_keyring; - pr_info("kernel_compat: got init_session_keyring\n"); - return 0; -} -#endif -static int ksu_inode_rename(struct inode *old_inode, struct dentry *old_dentry, - struct inode *new_inode, struct dentry *new_dentry) -{ - return ksu_handle_rename(old_dentry, new_dentry); -} - -static int ksu_task_fix_setuid(struct cred *new, const struct cred *old, - int flags) -{ - return ksu_handle_setuid(new, old); -} - -#ifndef MODULE -static struct security_hook_list ksu_hooks[] = { - LSM_HOOK_INIT(task_prctl, ksu_task_prctl), - LSM_HOOK_INIT(inode_rename, ksu_inode_rename), - LSM_HOOK_INIT(task_fix_setuid, ksu_task_fix_setuid), -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || defined(CONFIG_IS_HW_HISI) - LSM_HOOK_INIT(key_permission, ksu_key_permission) -#endif -}; - -void __init ksu_lsm_hook_init(void) -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) - security_add_hooks(ksu_hooks, ARRAY_SIZE(ksu_hooks), "ksu"); -#else - // https://elixir.bootlin.com/linux/v4.10.17/source/include/linux/lsm_hooks.h#L1892 - security_add_hooks(ksu_hooks, ARRAY_SIZE(ksu_hooks)); -#endif -} - -#else -static int override_security_head(void *head, const void *new_head, size_t len) -{ - unsigned long base = (unsigned long)head & PAGE_MASK; - unsigned long offset = offset_in_page(head); - - // this is impossible for our case because the page alignment - // but be careful for other cases! - BUG_ON(offset + len > PAGE_SIZE); - struct page *page = phys_to_page(__pa(base)); - if (!page) { - return -EFAULT; - } - - void *addr = vmap(&page, 1, VM_MAP, PAGE_KERNEL); - if (!addr) { - return -ENOMEM; - } - local_irq_disable(); - memcpy(addr + offset, new_head, len); - local_irq_enable(); - vunmap(addr); - return 0; -} - -static void free_security_hook_list(struct hlist_head *head) -{ - struct hlist_node *temp; - struct security_hook_list *entry; - - if (!head) - return; - - hlist_for_each_entry_safe (entry, temp, head, list) { - hlist_del(&entry->list); - kfree(entry); - } - - kfree(head); -} - -struct hlist_head *copy_security_hlist(struct hlist_head *orig) -{ - struct hlist_head *new_head = kmalloc(sizeof(*new_head), GFP_KERNEL); - if (!new_head) - return NULL; - - INIT_HLIST_HEAD(new_head); - - struct security_hook_list *entry; - struct security_hook_list *new_entry; - - hlist_for_each_entry (entry, orig, list) { - new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL); - if (!new_entry) { - free_security_hook_list(new_head); - return NULL; - } - - *new_entry = *entry; - - hlist_add_tail_rcu(&new_entry->list, new_head); - } - - return new_head; -} - -#define LSM_SEARCH_MAX 180 // This should be enough to iterate -static void *find_head_addr(void *security_ptr, int *index) -{ - if (!security_ptr) { - return NULL; - } - struct hlist_head *head_start = - (struct hlist_head *)&security_hook_heads; - - for (int i = 0; i < LSM_SEARCH_MAX; i++) { - struct hlist_head *head = head_start + i; - struct security_hook_list *pos; - hlist_for_each_entry (pos, head, list) { - if (pos->hook.capget == security_ptr) { - if (index) { - *index = i; - } - return head; - } - } - } - - return NULL; -} - -#define GET_SYMBOL_ADDR(sym) \ - ({ \ - void *addr = kallsyms_lookup_name(#sym ".cfi_jt"); \ - if (!addr) { \ - addr = kallsyms_lookup_name(#sym); \ - } \ - addr; \ - }) - -#define KSU_LSM_HOOK_HACK_INIT(head_ptr, name, func) \ - do { \ - static struct security_hook_list hook = { \ - .hook = { .name = func } \ - }; \ - hook.head = head_ptr; \ - hook.lsm = "ksu"; \ - struct hlist_head *new_head = copy_security_hlist(hook.head); \ - if (!new_head) { \ - pr_err("Failed to copy security list: %s\n", #name); \ - break; \ - } \ - hlist_add_tail_rcu(&hook.list, new_head); \ - if (override_security_head(hook.head, new_head, \ - sizeof(*new_head))) { \ - free_security_hook_list(new_head); \ - pr_err("Failed to hack lsm for: %s\n", #name); \ - } \ - } while (0) - -void __init ksu_lsm_hook_init(void) -{ - void *cap_prctl = GET_SYMBOL_ADDR(cap_task_prctl); - void *prctl_head = find_head_addr(cap_prctl, NULL); - if (prctl_head) { - if (prctl_head != &security_hook_heads.task_prctl) { - pr_warn("prctl's address has shifted!\n"); - } - KSU_LSM_HOOK_HACK_INIT(prctl_head, task_prctl, ksu_task_prctl); - } else { - pr_warn("Failed to find task_prctl!\n"); - } - - int inode_killpriv_index = -1; - void *cap_killpriv = GET_SYMBOL_ADDR(cap_inode_killpriv); - find_head_addr(cap_killpriv, &inode_killpriv_index); - if (inode_killpriv_index < 0) { - pr_warn("Failed to find inode_rename, use kprobe instead!\n"); - register_kprobe(&renameat_kp); - } else { - int inode_rename_index = inode_killpriv_index + - &security_hook_heads.inode_rename - - &security_hook_heads.inode_killpriv; - struct hlist_head *head_start = - (struct hlist_head *)&security_hook_heads; - void *inode_rename_head = head_start + inode_rename_index; - if (inode_rename_head != &security_hook_heads.inode_rename) { - pr_warn("inode_rename's address has shifted!\n"); - } - KSU_LSM_HOOK_HACK_INIT(inode_rename_head, inode_rename, - ksu_inode_rename); - } - void *cap_setuid = GET_SYMBOL_ADDR(cap_task_fix_setuid); - void *setuid_head = find_head_addr(cap_setuid, NULL); - if (setuid_head) { - if (setuid_head != &security_hook_heads.task_fix_setuid) { - pr_warn("setuid's address has shifted!\n"); - } - KSU_LSM_HOOK_HACK_INIT(setuid_head, task_fix_setuid, - ksu_task_fix_setuid); - } else { - pr_warn("Failed to find task_fix_setuid!\n"); - } - smp_mb(); -} -#endif - -void __init ksu_core_init(void) -{ - ksu_lsm_hook_init(); -} - -void ksu_core_exit(void) -{ -#ifdef CONFIG_KPROBES - pr_info("ksu_core_kprobe_exit\n"); - // we dont use this now - // ksu_kprobe_exit(); -#endif -} diff --git a/drivers/kernelsu/core_hook.h b/drivers/kernelsu/core_hook.h deleted file mode 100644 index 616951e8db35..000000000000 --- a/drivers/kernelsu/core_hook.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __KSU_H_KSU_CORE -#define __KSU_H_KSU_CORE - -#include - -void __init ksu_core_init(void); -void ksu_core_exit(void); - -#endif diff --git a/drivers/kernelsu/embed_ksud.c b/drivers/kernelsu/embed_ksud.c deleted file mode 100644 index 24c401219c15..000000000000 --- a/drivers/kernelsu/embed_ksud.c +++ /dev/null @@ -1,5 +0,0 @@ -// WARNING: THIS IS A STUB FILE -// This file will be regenerated by CI - -unsigned int ksud_size = 0; -const char ksud[0] = {}; diff --git a/drivers/kernelsu/export_symbol.txt b/drivers/kernelsu/export_symbol.txt deleted file mode 100644 index 1abd805e8e6a..000000000000 --- a/drivers/kernelsu/export_symbol.txt +++ /dev/null @@ -1,2 +0,0 @@ -register_kprobe -unregister_kprobe diff --git a/drivers/kernelsu/include/ksu_hook.h b/drivers/kernelsu/include/ksu_hook.h deleted file mode 100644 index ea0b04d3e538..000000000000 --- a/drivers/kernelsu/include/ksu_hook.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef __KSU_H_KSHOOK -#define __KSU_H_KSHOOK - -#include -#include - -// For sucompat - -int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode, - int *flags); - -int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags); - -// For ksud - -int ksu_handle_vfs_read(struct file **file_ptr, char __user **buf_ptr, - size_t *count_ptr, loff_t **pos); - -// For ksud and sucompat - -int ksu_handle_execveat(int *fd, struct filename **filename_ptr, void *argv, - void *envp, int *flags); - -// For volume button -int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code, - int *value); - -#endif diff --git a/drivers/kernelsu/kernel_compat.c b/drivers/kernelsu/kernel_compat.c deleted file mode 100644 index b242bc637398..000000000000 --- a/drivers/kernelsu/kernel_compat.c +++ /dev/null @@ -1,176 +0,0 @@ -#include -#include -#include -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) -#include -#else -#include -#endif -#include -#include "klog.h" // IWYU pragma: keep -#include "kernel_compat.h" // Add check Huawei Device - -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || defined(CONFIG_IS_HW_HISI) -#include -#include -#include -struct key *init_session_keyring = NULL; - -static inline int install_session_keyring(struct key *keyring) -{ - struct cred *new; - int ret; - - new = prepare_creds(); - if (!new) - return -ENOMEM; - - ret = install_session_keyring_to_cred(new, keyring); - if (ret < 0) { - abort_creds(new); - return ret; - } - - return commit_creds(new); -} -#endif - -extern struct task_struct init_task; - -// mnt_ns context switch for environment that android_init->nsproxy->mnt_ns != init_task.nsproxy->mnt_ns, such as WSA -struct ksu_ns_fs_saved { - struct nsproxy *ns; - struct fs_struct *fs; -}; - -static void ksu_save_ns_fs(struct ksu_ns_fs_saved *ns_fs_saved) -{ - ns_fs_saved->ns = current->nsproxy; - ns_fs_saved->fs = current->fs; -} - -static void ksu_load_ns_fs(struct ksu_ns_fs_saved *ns_fs_saved) -{ - current->nsproxy = ns_fs_saved->ns; - current->fs = ns_fs_saved->fs; -} - -static bool android_context_saved_checked = false; -static bool android_context_saved_enabled = false; -static struct ksu_ns_fs_saved android_context_saved; - -void ksu_android_ns_fs_check() -{ - if (android_context_saved_checked) - return; - android_context_saved_checked = true; - task_lock(current); - if (current->nsproxy && current->fs && - current->nsproxy->mnt_ns != init_task.nsproxy->mnt_ns) { - android_context_saved_enabled = true; - pr_info("android context saved enabled due to init mnt_ns(%p) != android mnt_ns(%p)\n", - current->nsproxy->mnt_ns, init_task.nsproxy->mnt_ns); - ksu_save_ns_fs(&android_context_saved); - } else { - pr_info("android context saved disabled\n"); - } - task_unlock(current); -} - -struct file *ksu_filp_open_compat(const char *filename, int flags, umode_t mode) -{ -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || defined(CONFIG_IS_HW_HISI) - if (init_session_keyring != NULL && !current_cred()->session_keyring && - (current->flags & PF_WQ_WORKER)) { - pr_info("installing init session keyring for older kernel\n"); - install_session_keyring(init_session_keyring); - } -#endif - // switch mnt_ns even if current is not wq_worker, to ensure what we open is the correct file in android mnt_ns, rather than user created mnt_ns - struct ksu_ns_fs_saved saved; - if (android_context_saved_enabled) { - pr_info("start switch current nsproxy and fs to android context\n"); - task_lock(current); - ksu_save_ns_fs(&saved); - ksu_load_ns_fs(&android_context_saved); - task_unlock(current); - } - struct file *fp = filp_open(filename, flags, mode); - if (android_context_saved_enabled) { - task_lock(current); - ksu_load_ns_fs(&saved); - task_unlock(current); - pr_info("switch current nsproxy and fs back to saved successfully\n"); - } - return fp; -} - -ssize_t ksu_kernel_read_compat(struct file *p, void *buf, size_t count, - loff_t *pos) -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) - return kernel_read(p, buf, count, pos); -#else - loff_t offset = pos ? *pos : 0; - ssize_t result = kernel_read(p, offset, (char *)buf, count); - if (pos && result > 0) { - *pos = offset + result; - } - return result; -#endif -} - -ssize_t ksu_kernel_write_compat(struct file *p, const void *buf, size_t count, - loff_t *pos) -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) - return kernel_write(p, buf, count, pos); -#else - loff_t offset = pos ? *pos : 0; - ssize_t result = kernel_write(p, buf, count, offset); - if (pos && result > 0) { - *pos = offset + result; - } - return result; -#endif -} - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0) -long ksu_strncpy_from_user_nofault(char *dst, const void __user *unsafe_addr, - long count) -{ - return strncpy_from_user_nofault(dst, unsafe_addr, count); -} -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0) -long ksu_strncpy_from_user_nofault(char *dst, const void __user *unsafe_addr, - long count) -{ - return strncpy_from_unsafe_user(dst, unsafe_addr, count); -} -#else -// Copied from: https://elixir.bootlin.com/linux/v4.9.337/source/mm/maccess.c#L201 -long ksu_strncpy_from_user_nofault(char *dst, const void __user *unsafe_addr, - long count) -{ - mm_segment_t old_fs = get_fs(); - long ret; - - if (unlikely(count <= 0)) - return 0; - - set_fs(USER_DS); - pagefault_disable(); - ret = strncpy_from_user(dst, unsafe_addr, count); - pagefault_enable(); - set_fs(old_fs); - - if (ret >= count) { - ret = count; - dst[ret - 1] = '\0'; - } else if (ret > 0) { - ret++; - } - - return ret; -} -#endif diff --git a/drivers/kernelsu/kernel_compat.h b/drivers/kernelsu/kernel_compat.h deleted file mode 100644 index ba9981857fd1..000000000000 --- a/drivers/kernelsu/kernel_compat.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef __KSU_H_KERNEL_COMPAT -#define __KSU_H_KERNEL_COMPAT - -#include -#include -#include "ss/policydb.h" -#include "linux/key.h" - -/* - * Adapt to Huawei HISI kernel without affecting other kernels , - * Huawei Hisi Kernel EBITMAP Enable or Disable Flag , - * From ss/ebitmap.h - */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) && \ - (LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0)) || \ - (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) && \ - (LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)) -#ifdef HISI_SELINUX_EBITMAP_RO -#define CONFIG_IS_HW_HISI -#endif -#endif - -extern long ksu_strncpy_from_user_nofault(char *dst, - const void __user *unsafe_addr, - long count); - -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || defined(CONFIG_IS_HW_HISI) -extern struct key *init_session_keyring; -#endif - -extern void ksu_android_ns_fs_check(); -extern struct file *ksu_filp_open_compat(const char *filename, int flags, - umode_t mode); -extern ssize_t ksu_kernel_read_compat(struct file *p, void *buf, size_t count, - loff_t *pos); -extern ssize_t ksu_kernel_write_compat(struct file *p, const void *buf, - size_t count, loff_t *pos); - -#endif diff --git a/drivers/kernelsu/klog.h b/drivers/kernelsu/klog.h deleted file mode 100644 index a934027fbeeb..000000000000 --- a/drivers/kernelsu/klog.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef __KSU_H_KLOG -#define __KSU_H_KLOG - -#include - -#ifdef pr_fmt -#undef pr_fmt -#define pr_fmt(fmt) "KernelSU: " fmt -#endif - -#endif diff --git a/drivers/kernelsu/ksu.c b/drivers/kernelsu/ksu.c deleted file mode 100644 index 3639edc21503..000000000000 --- a/drivers/kernelsu/ksu.c +++ /dev/null @@ -1,100 +0,0 @@ -#include -#include -#include -#include -#include - -#include "allowlist.h" -#include "arch.h" -#include "core_hook.h" -#include "klog.h" // IWYU pragma: keep -#include "ksu.h" -#include "throne_tracker.h" - -static struct workqueue_struct *ksu_workqueue; - -bool ksu_queue_work(struct work_struct *work) -{ - return queue_work(ksu_workqueue, work); -} - -extern int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr, - void *argv, void *envp, int *flags); - -extern int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr, - void *argv, void *envp, int *flags); - -int ksu_handle_execveat(int *fd, struct filename **filename_ptr, void *argv, - void *envp, int *flags) -{ - ksu_handle_execveat_ksud(fd, filename_ptr, argv, envp, flags); - return ksu_handle_execveat_sucompat(fd, filename_ptr, argv, envp, - flags); -} - -extern void ksu_sucompat_init(); -extern void ksu_sucompat_exit(); -extern void ksu_ksud_init(); -extern void ksu_ksud_exit(); - -int __init kernelsu_init(void) -{ -#ifdef CONFIG_KSU_DEBUG - pr_alert("*************************************************************"); - pr_alert("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **"); - pr_alert("** **"); - pr_alert("** You are running KernelSU in DEBUG mode **"); - pr_alert("** **"); - pr_alert("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **"); - pr_alert("*************************************************************"); -#endif - - ksu_core_init(); - - ksu_workqueue = alloc_ordered_workqueue("kernelsu_work_queue", 0); - - ksu_allowlist_init(); - - ksu_throne_tracker_init(); - -#ifdef CONFIG_KPROBES - ksu_sucompat_init(); - ksu_ksud_init(); -#else - pr_alert("KPROBES is disabled, KernelSU may not work, please check https://kernelsu.org/guide/how-to-integrate-for-non-gki.html"); -#endif - -#ifdef MODULE -#ifndef CONFIG_KSU_DEBUG - kobject_del(&THIS_MODULE->mkobj.kobj); -#endif -#endif - return 0; -} - -void kernelsu_exit(void) -{ - ksu_allowlist_exit(); - - ksu_throne_tracker_exit(); - - destroy_workqueue(ksu_workqueue); - -#ifdef CONFIG_KPROBES - ksu_ksud_exit(); - ksu_sucompat_exit(); -#endif - - ksu_core_exit(); -} - -module_init(kernelsu_init); -module_exit(kernelsu_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("weishu"); -MODULE_DESCRIPTION("Android KernelSU"); - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0) -MODULE_IMPORT_NS(VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver); -#endif diff --git a/drivers/kernelsu/ksu.h b/drivers/kernelsu/ksu.h deleted file mode 100644 index 35d1b14dbb7c..000000000000 --- a/drivers/kernelsu/ksu.h +++ /dev/null @@ -1,99 +0,0 @@ -#ifndef __KSU_H_KSU -#define __KSU_H_KSU - -#include -#include - -#define KERNEL_SU_VERSION KSU_VERSION -#define KERNEL_SU_OPTION 0xDEADBEEF - -#define CMD_GRANT_ROOT 0 -#define CMD_BECOME_MANAGER 1 -#define CMD_GET_VERSION 2 -#define CMD_ALLOW_SU 3 -#define CMD_DENY_SU 4 -#define CMD_GET_ALLOW_LIST 5 -#define CMD_GET_DENY_LIST 6 -#define CMD_REPORT_EVENT 7 -#define CMD_SET_SEPOLICY 8 -#define CMD_CHECK_SAFEMODE 9 -#define CMD_GET_APP_PROFILE 10 -#define CMD_SET_APP_PROFILE 11 -#define CMD_UID_GRANTED_ROOT 12 -#define CMD_UID_SHOULD_UMOUNT 13 - -#define EVENT_POST_FS_DATA 1 -#define EVENT_BOOT_COMPLETED 2 -#define EVENT_MODULE_MOUNTED 3 - -#define KSU_APP_PROFILE_VER 2 -#define KSU_MAX_PACKAGE_NAME 256 -// NGROUPS_MAX for Linux is 65535 generally, but we only supports 32 groups. -#define KSU_MAX_GROUPS 32 -#define KSU_SELINUX_DOMAIN 64 - -struct root_profile { - int32_t uid; - int32_t gid; - - int32_t groups_count; - int32_t groups[KSU_MAX_GROUPS]; - - // kernel_cap_t is u32[2] for capabilities v3 - struct { - u64 effective; - u64 permitted; - u64 inheritable; - } capabilities; - - char selinux_domain[KSU_SELINUX_DOMAIN]; - - int32_t namespaces; -}; - -struct non_root_profile { - bool umount_modules; -}; - -struct app_profile { - // It may be utilized for backward compatibility, although we have never explicitly made any promises regarding this. - u32 version; - - // this is usually the package of the app, but can be other value for special apps - char key[KSU_MAX_PACKAGE_NAME]; - int32_t current_uid; - bool allow_su; - - union { - struct { - bool use_default; - char template_name[KSU_MAX_PACKAGE_NAME]; - - struct root_profile profile; - } rp_config; - - struct { - bool use_default; - - struct non_root_profile profile; - } nrp_config; - }; -}; - -bool ksu_queue_work(struct work_struct *work); - -static inline int startswith(char *s, char *prefix) -{ - return strncmp(s, prefix, strlen(prefix)); -} - -static inline int endswith(const char *s, const char *t) -{ - size_t slen = strlen(s); - size_t tlen = strlen(t); - if (tlen > slen) - return 1; - return strcmp(s + slen - tlen, t); -} - -#endif diff --git a/drivers/kernelsu/ksud.c b/drivers/kernelsu/ksud.c deleted file mode 100644 index 68e473524284..000000000000 --- a/drivers/kernelsu/ksud.c +++ /dev/null @@ -1,666 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) -#include -#else -#include -#endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0) -#include -#endif -#include -#include -#include -#include -#include - -#include "allowlist.h" -#include "arch.h" -#include "klog.h" // IWYU pragma: keep -#include "ksud.h" -#include "kernel_compat.h" -#include "selinux/selinux.h" - -static const char KERNEL_SU_RC[] = - "\n" - - "on post-fs-data\n" - " start logd\n" - // We should wait for the post-fs-data finish - " exec u:r:su:s0 root -- " KSUD_PATH " post-fs-data\n" - "\n" - - "on nonencrypted\n" - " exec u:r:su:s0 root -- " KSUD_PATH " services\n" - "\n" - - "on property:vold.decrypt=trigger_restart_framework\n" - " exec u:r:su:s0 root -- " KSUD_PATH " services\n" - "\n" - - "on property:sys.boot_completed=1\n" - " exec u:r:su:s0 root -- " KSUD_PATH " boot-completed\n" - "\n" - - "\n"; - -static void stop_vfs_read_hook(); -static void stop_execve_hook(); -static void stop_input_hook(); - -#ifdef CONFIG_KPROBES -static struct work_struct stop_vfs_read_work; -static struct work_struct stop_execve_hook_work; -static struct work_struct stop_input_hook_work; -#else -bool ksu_vfs_read_hook __read_mostly = true; -bool ksu_execveat_hook __read_mostly = true; -bool ksu_input_hook __read_mostly = true; -#endif - -u32 ksu_devpts_sid; - -void on_post_fs_data(void) -{ - static bool done = false; - if (done) { - pr_info("on_post_fs_data already done\n"); - return; - } - done = true; - pr_info("on_post_fs_data!\n"); - ksu_load_allow_list(); - // sanity check, this may influence the performance - stop_input_hook(); - - ksu_devpts_sid = ksu_get_devpts_sid(); - pr_info("devpts sid: %d\n", ksu_devpts_sid); -} - -#define MAX_ARG_STRINGS 0x7FFFFFFF -struct user_arg_ptr { -#ifdef CONFIG_COMPAT - bool is_compat; -#endif - union { - const char __user *const __user *native; -#ifdef CONFIG_COMPAT - const compat_uptr_t __user *compat; -#endif - } ptr; -}; - -static const char __user *get_user_arg_ptr(struct user_arg_ptr argv, int nr) -{ - const char __user *native; - -#ifdef CONFIG_COMPAT - if (unlikely(argv.is_compat)) { - compat_uptr_t compat; - - if (get_user(compat, argv.ptr.compat + nr)) - return ERR_PTR(-EFAULT); - - return compat_ptr(compat); - } -#endif - - if (get_user(native, argv.ptr.native + nr)) - return ERR_PTR(-EFAULT); - - return native; -} - -/* - * count() counts the number of strings in array ARGV. - */ - -/* - * Make sure old GCC compiler can use __maybe_unused, - * Test passed in 4.4.x ~ 4.9.x when use GCC. - */ - -static int __maybe_unused count(struct user_arg_ptr argv, int max) -{ - int i = 0; - - if (argv.ptr.native != NULL) { - for (;;) { - const char __user *p = get_user_arg_ptr(argv, i); - - if (!p) - break; - - if (IS_ERR(p)) - return -EFAULT; - - if (i >= max) - return -E2BIG; - ++i; - - if (fatal_signal_pending(current)) - return -ERESTARTNOHAND; - cond_resched(); - } - } - return i; -} - -// IMPORTANT NOTE: the call from execve_handler_pre WON'T provided correct value for envp and flags in GKI version -int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr, - struct user_arg_ptr *argv, - struct user_arg_ptr *envp, int *flags) -{ -#ifndef CONFIG_KPROBES - if (!ksu_execveat_hook) { - return 0; - } -#endif - struct filename *filename; - - static const char app_process[] = "/system/bin/app_process"; - static bool first_app_process = true; - - /* This applies to versions Android 10+ */ - static const char system_bin_init[] = "/system/bin/init"; - /* This applies to versions between Android 6 ~ 9 */ - static const char old_system_init[] = "/init"; - static bool init_second_stage_executed = false; - - if (!filename_ptr) - return 0; - - filename = *filename_ptr; - if (IS_ERR(filename)) { - return 0; - } - - if (unlikely(!memcmp(filename->name, system_bin_init, - sizeof(system_bin_init) - 1) && - argv)) { - // /system/bin/init executed - int argc = count(*argv, MAX_ARG_STRINGS); - pr_info("/system/bin/init argc: %d\n", argc); - if (argc > 1 && !init_second_stage_executed) { - const char __user *p = get_user_arg_ptr(*argv, 1); - if (p && !IS_ERR(p)) { - char first_arg[16]; - ksu_strncpy_from_user_nofault( - first_arg, p, sizeof(first_arg)); - pr_info("/system/bin/init first arg: %s\n", - first_arg); - if (!strcmp(first_arg, "second_stage")) { - pr_info("/system/bin/init second_stage executed\n"); - apply_kernelsu_rules(); - init_second_stage_executed = true; - ksu_android_ns_fs_check(); - } - } else { - pr_err("/system/bin/init parse args err!\n"); - } - } - } else if (unlikely(!memcmp(filename->name, old_system_init, - sizeof(old_system_init) - 1) && - argv)) { - // /init executed - int argc = count(*argv, MAX_ARG_STRINGS); - pr_info("/init argc: %d\n", argc); - if (argc > 1 && !init_second_stage_executed) { - /* This applies to versions between Android 6 ~ 7 */ - const char __user *p = get_user_arg_ptr(*argv, 1); - if (p && !IS_ERR(p)) { - char first_arg[16]; - ksu_strncpy_from_user_nofault( - first_arg, p, sizeof(first_arg)); - pr_info("/init first arg: %s\n", first_arg); - if (!strcmp(first_arg, "--second-stage")) { - pr_info("/init second_stage executed\n"); - apply_kernelsu_rules(); - init_second_stage_executed = true; - ksu_android_ns_fs_check(); - } - } else { - pr_err("/init parse args err!\n"); - } - } else if (argc == 1 && !init_second_stage_executed && envp) { - /* This applies to versions between Android 8 ~ 9 */ - int envc = count(*envp, MAX_ARG_STRINGS); - if (envc > 0) { - int n; - for (n = 1; n <= envc; n++) { - const char __user *p = - get_user_arg_ptr(*envp, n); - if (!p || IS_ERR(p)) { - continue; - } - char env[256]; - // Reading environment variable strings from user space - if (ksu_strncpy_from_user_nofault( - env, p, sizeof(env)) < 0) - continue; - // Parsing environment variable names and values - char *env_name = env; - char *env_value = strchr(env, '='); - if (env_value == NULL) - continue; - // Replace equal sign with string terminator - *env_value = '\0'; - env_value++; - // Check if the environment variable name and value are matching - if (!strcmp(env_name, - "INIT_SECOND_STAGE") && - (!strcmp(env_value, "1") || - !strcmp(env_value, "true"))) { - pr_info("/init second_stage executed\n"); - apply_kernelsu_rules(); - init_second_stage_executed = - true; - ksu_android_ns_fs_check(); - } - } - } - } - } - - if (unlikely(first_app_process && !memcmp(filename->name, app_process, - sizeof(app_process) - 1))) { - first_app_process = false; - pr_info("exec app_process, /data prepared, second_stage: %d\n", - init_second_stage_executed); - on_post_fs_data(); // we keep this for old ksud - stop_execve_hook(); - } - - return 0; -} - -static ssize_t (*orig_read)(struct file *, char __user *, size_t, loff_t *); -static ssize_t (*orig_read_iter)(struct kiocb *, struct iov_iter *); -static struct file_operations fops_proxy; -static ssize_t read_count_append = 0; - -static ssize_t read_proxy(struct file *file, char __user *buf, size_t count, - loff_t *pos) -{ - bool first_read = file->f_pos == 0; - ssize_t ret = orig_read(file, buf, count, pos); - if (first_read) { - pr_info("read_proxy append %ld + %ld\n", ret, - read_count_append); - ret += read_count_append; - } - return ret; -} - -static ssize_t read_iter_proxy(struct kiocb *iocb, struct iov_iter *to) -{ - bool first_read = iocb->ki_pos == 0; - ssize_t ret = orig_read_iter(iocb, to); - if (first_read) { - pr_info("read_iter_proxy append %ld + %ld\n", ret, - read_count_append); - ret += read_count_append; - } - return ret; -} - -int ksu_handle_vfs_read(struct file **file_ptr, char __user **buf_ptr, - size_t *count_ptr, loff_t **pos) -{ -#ifndef CONFIG_KPROBES - if (!ksu_vfs_read_hook) { - return 0; - } -#endif - struct file *file; - char __user *buf; - size_t count; - - if (strcmp(current->comm, "init")) { - // we are only interest in `init` process - return 0; - } - - file = *file_ptr; - if (IS_ERR(file)) { - return 0; - } - - if (!d_is_reg(file->f_path.dentry)) { - return 0; - } - - const char *short_name = file->f_path.dentry->d_name.name; - if (strcmp(short_name, "atrace.rc")) { - // we are only interest `atrace.rc` file name file - return 0; - } - char path[256]; - char *dpath = d_path(&file->f_path, path, sizeof(path)); - - if (IS_ERR(dpath)) { - return 0; - } - - if (strcmp(dpath, "/system/etc/init/atrace.rc")) { - return 0; - } - - // we only process the first read - static bool rc_inserted = false; - if (rc_inserted) { - // we don't need this kprobe, unregister it! - stop_vfs_read_hook(); - return 0; - } - rc_inserted = true; - - // now we can sure that the init process is reading - // `/system/etc/init/atrace.rc` - buf = *buf_ptr; - count = *count_ptr; - - size_t rc_count = strlen(KERNEL_SU_RC); - - pr_info("vfs_read: %s, comm: %s, count: %zu, rc_count: %zu\n", dpath, - current->comm, count, rc_count); - - if (count < rc_count) { - pr_err("count: %zu < rc_count: %zu\n", count, rc_count); - return 0; - } - - size_t ret = copy_to_user(buf, KERNEL_SU_RC, rc_count); - if (ret) { - pr_err("copy ksud.rc failed: %zu\n", ret); - return 0; - } - - // we've succeed to insert ksud.rc, now we need to proxy the read and modify the result! - // But, we can not modify the file_operations directly, because it's in read-only memory. - // We just replace the whole file_operations with a proxy one. - memcpy(&fops_proxy, file->f_op, sizeof(struct file_operations)); - orig_read = file->f_op->read; - if (orig_read) { - fops_proxy.read = read_proxy; - } - orig_read_iter = file->f_op->read_iter; - if (orig_read_iter) { - fops_proxy.read_iter = read_iter_proxy; - } - // replace the file_operations - file->f_op = &fops_proxy; - read_count_append = rc_count; - - *buf_ptr = buf + rc_count; - *count_ptr = count - rc_count; - - return 0; -} - -int ksu_handle_sys_read(unsigned int fd, char __user **buf_ptr, - size_t *count_ptr) -{ - struct file *file = fget(fd); - if (!file) { - return 0; - } - int result = ksu_handle_vfs_read(&file, buf_ptr, count_ptr, NULL); - fput(file); - return result; -} - -static unsigned int volumedown_pressed_count = 0; - -static bool is_volumedown_enough(unsigned int count) -{ - return count >= 3; -} - -int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code, - int *value) -{ -#ifndef CONFIG_KPROBES - if (!ksu_input_hook) { - return 0; - } -#endif - if (*type == EV_KEY && *code == KEY_VOLUMEDOWN) { - int val = *value; - pr_info("KEY_VOLUMEDOWN val: %d\n", val); - if (val) { - // key pressed, count it - volumedown_pressed_count += 1; - if (is_volumedown_enough(volumedown_pressed_count)) { - stop_input_hook(); - } - } - } - - return 0; -} - -bool ksu_is_safe_mode() -{ - static bool safe_mode = false; - if (safe_mode) { - // don't need to check again, userspace may call multiple times - return true; - } - - // stop hook first! - stop_input_hook(); - - pr_info("volumedown_pressed_count: %d\n", volumedown_pressed_count); - if (is_volumedown_enough(volumedown_pressed_count)) { - // pressed over 3 times - pr_info("KEY_VOLUMEDOWN pressed max times, safe mode detected!\n"); - safe_mode = true; - return true; - } - - return false; -} - -#ifdef CONFIG_KPROBES - -// https://elixir.bootlin.com/linux/v5.10.158/source/fs/exec.c#L1864 -static int execve_handler_pre(struct kprobe *p, struct pt_regs *regs) -{ - int *fd = (int *)&PT_REGS_PARM1(regs); - struct filename **filename_ptr = - (struct filename **)&PT_REGS_PARM2(regs); - struct user_arg_ptr argv; -#ifdef CONFIG_COMPAT - argv.is_compat = PT_REGS_PARM3(regs); - if (unlikely(argv.is_compat)) { - argv.ptr.compat = PT_REGS_CCALL_PARM4(regs); - } else { - argv.ptr.native = PT_REGS_CCALL_PARM4(regs); - } -#else - argv.ptr.native = PT_REGS_PARM3(regs); -#endif - - return ksu_handle_execveat_ksud(fd, filename_ptr, &argv, NULL, NULL); -} - -static int sys_execve_handler_pre(struct kprobe *p, struct pt_regs *regs) -{ - struct pt_regs *real_regs = PT_REAL_REGS(regs); - const char __user **filename_user = - (const char **)&PT_REGS_PARM1(real_regs); - const char __user *const __user *__argv = - (const char __user *const __user *)PT_REGS_PARM2(real_regs); - struct user_arg_ptr argv = { .ptr.native = __argv }; - struct filename filename_in, *filename_p; - char path[32]; - - if (!filename_user) - return 0; - - memset(path, 0, sizeof(path)); - ksu_strncpy_from_user_nofault(path, *filename_user, 32); - filename_in.name = path; - - filename_p = &filename_in; - return ksu_handle_execveat_ksud(AT_FDCWD, &filename_p, &argv, NULL, - NULL); -} - -// remove this later! -__maybe_unused static int vfs_read_handler_pre(struct kprobe *p, - struct pt_regs *regs) -{ - struct file **file_ptr = (struct file **)&PT_REGS_PARM1(regs); - char __user **buf_ptr = (char **)&PT_REGS_PARM2(regs); - size_t *count_ptr = (size_t *)&PT_REGS_PARM3(regs); - loff_t **pos_ptr = (loff_t **)&PT_REGS_CCALL_PARM4(regs); - - return ksu_handle_vfs_read(file_ptr, buf_ptr, count_ptr, pos_ptr); -} - -static int sys_read_handler_pre(struct kprobe *p, struct pt_regs *regs) -{ - struct pt_regs *real_regs = PT_REAL_REGS(regs); - unsigned int fd = PT_REGS_PARM1(real_regs); - char __user **buf_ptr = (char __user **)&PT_REGS_PARM2(real_regs); - size_t count_ptr = (size_t *)&PT_REGS_PARM3(real_regs); - - return ksu_handle_sys_read(fd, buf_ptr, count_ptr); -} - -static int input_handle_event_handler_pre(struct kprobe *p, - struct pt_regs *regs) -{ - unsigned int *type = (unsigned int *)&PT_REGS_PARM2(regs); - unsigned int *code = (unsigned int *)&PT_REGS_PARM3(regs); - int *value = (int *)&PT_REGS_CCALL_PARM4(regs); - return ksu_handle_input_handle_event(type, code, value); -} - -#if 1 -static struct kprobe execve_kp = { - .symbol_name = SYS_EXECVE_SYMBOL, - .pre_handler = sys_execve_handler_pre, -}; -#else -static struct kprobe execve_kp = { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0) - .symbol_name = "do_execveat_common", -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) - .symbol_name = "__do_execve_file", -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) - .symbol_name = "do_execveat_common", -#endif - .pre_handler = execve_handler_pre, -}; -#endif - -#if 1 -static struct kprobe vfs_read_kp = { - .symbol_name = SYS_READ_SYMBOL, - .pre_handler = sys_read_handler_pre, -}; -#else -static struct kprobe vfs_read_kp = { - .symbol_name = "vfs_read", - .pre_handler = vfs_read_handler_pre, -}; -#endif - -static struct kprobe input_event_kp = { - .symbol_name = "input_event", - .pre_handler = input_handle_event_handler_pre, -}; - -static void do_stop_vfs_read_hook(struct work_struct *work) -{ - unregister_kprobe(&vfs_read_kp); -} - -static void do_stop_execve_hook(struct work_struct *work) -{ - unregister_kprobe(&execve_kp); -} - -static void do_stop_input_hook(struct work_struct *work) -{ - unregister_kprobe(&input_event_kp); -} -#endif - -static void stop_vfs_read_hook() -{ -#ifdef CONFIG_KPROBES - bool ret = schedule_work(&stop_vfs_read_work); - pr_info("unregister vfs_read kprobe: %d!\n", ret); -#else - ksu_vfs_read_hook = false; - pr_info("stop vfs_read_hook\n"); -#endif -} - -static void stop_execve_hook() -{ -#ifdef CONFIG_KPROBES - bool ret = schedule_work(&stop_execve_hook_work); - pr_info("unregister execve kprobe: %d!\n", ret); -#else - ksu_execveat_hook = false; - pr_info("stop execve_hook\n"); -#endif -} - -static void stop_input_hook() -{ - static bool input_hook_stopped = false; - if (input_hook_stopped) { - return; - } - input_hook_stopped = true; -#ifdef CONFIG_KPROBES - bool ret = schedule_work(&stop_input_hook_work); - pr_info("unregister input kprobe: %d!\n", ret); -#else - ksu_input_hook = false; - pr_info("stop input_hook\n"); -#endif -} - -// ksud: module support -void ksu_ksud_init() -{ -#ifdef CONFIG_KPROBES - int ret; - - ret = register_kprobe(&execve_kp); - pr_info("ksud: execve_kp: %d\n", ret); - - ret = register_kprobe(&vfs_read_kp); - pr_info("ksud: vfs_read_kp: %d\n", ret); - - ret = register_kprobe(&input_event_kp); - pr_info("ksud: input_event_kp: %d\n", ret); - - INIT_WORK(&stop_vfs_read_work, do_stop_vfs_read_hook); - INIT_WORK(&stop_execve_hook_work, do_stop_execve_hook); - INIT_WORK(&stop_input_hook_work, do_stop_input_hook); -#endif -} - -void ksu_ksud_exit() -{ -#ifdef CONFIG_KPROBES - unregister_kprobe(&execve_kp); - // this should be done before unregister vfs_read_kp - // unregister_kprobe(&vfs_read_kp); - unregister_kprobe(&input_event_kp); -#endif -} \ No newline at end of file diff --git a/drivers/kernelsu/ksud.h b/drivers/kernelsu/ksud.h deleted file mode 100644 index cc2df243a8f0..000000000000 --- a/drivers/kernelsu/ksud.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __KSU_H_KSUD -#define __KSU_H_KSUD - -#include - -#define KSUD_PATH "/data/adb/ksud" - -void on_post_fs_data(void); - -bool ksu_is_safe_mode(void); - -extern u32 ksu_devpts_sid; - -#endif diff --git a/drivers/kernelsu/manager.h b/drivers/kernelsu/manager.h deleted file mode 100644 index be5bbced6f73..000000000000 --- a/drivers/kernelsu/manager.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef __KSU_H_KSU_MANAGER -#define __KSU_H_KSU_MANAGER - -#include -#include - -#define KSU_INVALID_UID -1 - -extern uid_t ksu_manager_uid; // DO NOT DIRECT USE - -static inline bool ksu_is_manager_uid_valid() -{ - return ksu_manager_uid != KSU_INVALID_UID; -} - -static inline bool is_manager() -{ - return unlikely(ksu_manager_uid == current_uid().val); -} - -static inline uid_t ksu_get_manager_uid() -{ - return ksu_manager_uid; -} - -static inline void ksu_set_manager_uid(uid_t uid) -{ - ksu_manager_uid = uid; -} - -static inline void ksu_invalidate_manager_uid() -{ - ksu_manager_uid = KSU_INVALID_UID; -} - -#endif diff --git a/drivers/kernelsu/selinux/Makefile b/drivers/kernelsu/selinux/Makefile deleted file mode 100644 index 870750be2ed6..000000000000 --- a/drivers/kernelsu/selinux/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -obj-y += selinux.o -obj-y += sepolicy.o -obj-y += rules.o - -ifeq ($(shell grep -q " current_sid(void)" $(srctree)/security/selinux/include/objsec.h; echo $$?),0) -ccflags-y += -DKSU_COMPAT_HAS_CURRENT_SID -endif - -ifeq ($(shell grep -q "struct selinux_state " $(srctree)/security/selinux/include/security.h; echo $$?),0) -ccflags-y += -DKSU_COMPAT_HAS_SELINUX_STATE -endif - -ccflags-y += -Wno-implicit-function-declaration -Wno-strict-prototypes -Wno-int-conversion -ccflags-y += -Wno-declaration-after-statement -Wno-unused-function -ccflags-y += -I$(srctree)/security/selinux -I$(srctree)/security/selinux/include -ccflags-y += -I$(objtree)/security/selinux -include $(srctree)/include/uapi/asm-generic/errno.h diff --git a/drivers/kernelsu/selinux/rules.c b/drivers/kernelsu/selinux/rules.c deleted file mode 100644 index 1ba6d853f2a9..000000000000 --- a/drivers/kernelsu/selinux/rules.c +++ /dev/null @@ -1,476 +0,0 @@ -#include -#include -#include - -#include "../klog.h" // IWYU pragma: keep -#include "selinux.h" -#include "sepolicy.h" -#include "ss/services.h" -#include "linux/lsm_audit.h" -#include "xfrm.h" - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) -#define SELINUX_POLICY_INSTEAD_SELINUX_SS -#endif - -#define KERNEL_SU_DOMAIN "su" -#define KERNEL_SU_FILE "ksu_file" -#define KERNEL_EXEC_TYPE "ksu_exec" -#define ALL NULL - -static struct policydb *get_policydb(void) -{ - struct policydb *db; -// selinux_state does not exists before 4.19 -#ifdef KSU_COMPAT_USE_SELINUX_STATE -#ifdef SELINUX_POLICY_INSTEAD_SELINUX_SS - struct selinux_policy *policy = rcu_dereference(selinux_state.policy); - db = &policy->policydb; -#else - struct selinux_ss *ss = rcu_dereference(selinux_state.ss); - db = &ss->policydb; -#endif -#else - db = &policydb; -#endif - return db; -} - -void apply_kernelsu_rules() -{ - if (!getenforce()) { - pr_info("SELinux permissive or disabled, apply rules!\n"); - } - - rcu_read_lock(); - struct policydb *db = get_policydb(); - - ksu_permissive(db, KERNEL_SU_DOMAIN); - ksu_typeattribute(db, KERNEL_SU_DOMAIN, "mlstrustedsubject"); - ksu_typeattribute(db, KERNEL_SU_DOMAIN, "netdomain"); - ksu_typeattribute(db, KERNEL_SU_DOMAIN, "bluetoothdomain"); - - // Create unconstrained file type - ksu_type(db, KERNEL_SU_FILE, "file_type"); - ksu_typeattribute(db, KERNEL_SU_FILE, "mlstrustedobject"); - ksu_allow(db, ALL, KERNEL_SU_FILE, ALL, ALL); - - // allow all! - ksu_allow(db, KERNEL_SU_DOMAIN, ALL, ALL, ALL); - - // allow us do any ioctl - if (db->policyvers >= POLICYDB_VERSION_XPERMS_IOCTL) { - ksu_allowxperm(db, KERNEL_SU_DOMAIN, ALL, "blk_file", ALL); - ksu_allowxperm(db, KERNEL_SU_DOMAIN, ALL, "fifo_file", ALL); - ksu_allowxperm(db, KERNEL_SU_DOMAIN, ALL, "chr_file", ALL); - ksu_allowxperm(db, KERNEL_SU_DOMAIN, ALL, "file", ALL); - } - - // we need to save allowlist in /data/adb/ksu - ksu_allow(db, "kernel", "adb_data_file", "dir", ALL); - ksu_allow(db, "kernel", "adb_data_file", "file", ALL); - // we need to search /data/app - ksu_allow(db, "kernel", "apk_data_file", "file", "open"); - ksu_allow(db, "kernel", "apk_data_file", "dir", "open"); - ksu_allow(db, "kernel", "apk_data_file", "dir", "read"); - ksu_allow(db, "kernel", "apk_data_file", "dir", "search"); - // we may need to do mount on shell - ksu_allow(db, "kernel", "shell_data_file", "file", ALL); - // we need to read /data/system/packages.list - ksu_allow(db, "kernel", "kernel", "capability", "dac_override"); - // Android 10+: - // http://aospxref.com/android-12.0.0_r3/xref/system/sepolicy/private/file_contexts#512 - ksu_allow(db, "kernel", "packages_list_file", "file", ALL); - // Kernel 4.4 - ksu_allow(db, "kernel", "packages_list_file", "dir", ALL); - // Android 9-: - // http://aospxref.com/android-9.0.0_r61/xref/system/sepolicy/private/file_contexts#360 - ksu_allow(db, "kernel", "system_data_file", "file", ALL); - ksu_allow(db, "kernel", "system_data_file", "dir", ALL); - // our ksud triggered by init - ksu_allow(db, "init", "adb_data_file", "file", ALL); - ksu_allow(db, "init", "adb_data_file", "dir", ALL); // #1289 - ksu_allow(db, "init", KERNEL_SU_DOMAIN, ALL, ALL); - // we need to umount modules in zygote - ksu_allow(db, "zygote", "adb_data_file", "dir", "search"); - - // copied from Magisk rules - // suRights - ksu_allow(db, "servicemanager", KERNEL_SU_DOMAIN, "dir", "search"); - ksu_allow(db, "servicemanager", KERNEL_SU_DOMAIN, "dir", "read"); - ksu_allow(db, "servicemanager", KERNEL_SU_DOMAIN, "file", "open"); - ksu_allow(db, "servicemanager", KERNEL_SU_DOMAIN, "file", "read"); - ksu_allow(db, "servicemanager", KERNEL_SU_DOMAIN, "process", "getattr"); - ksu_allow(db, ALL, KERNEL_SU_DOMAIN, "process", "sigchld"); - - // allowLog - ksu_allow(db, "logd", KERNEL_SU_DOMAIN, "dir", "search"); - ksu_allow(db, "logd", KERNEL_SU_DOMAIN, "file", "read"); - ksu_allow(db, "logd", KERNEL_SU_DOMAIN, "file", "open"); - ksu_allow(db, "logd", KERNEL_SU_DOMAIN, "file", "getattr"); - - // dumpsys - ksu_allow(db, ALL, KERNEL_SU_DOMAIN, "fd", "use"); - ksu_allow(db, ALL, KERNEL_SU_DOMAIN, "fifo_file", "write"); - ksu_allow(db, ALL, KERNEL_SU_DOMAIN, "fifo_file", "read"); - ksu_allow(db, ALL, KERNEL_SU_DOMAIN, "fifo_file", "open"); - ksu_allow(db, ALL, KERNEL_SU_DOMAIN, "fifo_file", "getattr"); - - // bootctl - ksu_allow(db, "hwservicemanager", KERNEL_SU_DOMAIN, "dir", "search"); - ksu_allow(db, "hwservicemanager", KERNEL_SU_DOMAIN, "file", "read"); - ksu_allow(db, "hwservicemanager", KERNEL_SU_DOMAIN, "file", "open"); - ksu_allow(db, "hwservicemanager", KERNEL_SU_DOMAIN, "process", - "getattr"); - - // For mounting loop devices, mirrors, tmpfs - ksu_allow(db, "kernel", ALL, "file", "read"); - ksu_allow(db, "kernel", ALL, "file", "write"); - - // Allow all binder transactions - ksu_allow(db, ALL, KERNEL_SU_DOMAIN, "binder", ALL); - - // Allow system server kill su process - ksu_allow(db, "system_server", KERNEL_SU_DOMAIN, "process", "getpgid"); - ksu_allow(db, "system_server", KERNEL_SU_DOMAIN, "process", "sigkill"); - - rcu_read_unlock(); -} - -#define MAX_SEPOL_LEN 128 - -#define CMD_NORMAL_PERM 1 -#define CMD_XPERM 2 -#define CMD_TYPE_STATE 3 -#define CMD_TYPE 4 -#define CMD_TYPE_ATTR 5 -#define CMD_ATTR 6 -#define CMD_TYPE_TRANSITION 7 -#define CMD_TYPE_CHANGE 8 -#define CMD_GENFSCON 9 - -struct sepol_data { - u32 cmd; - u32 subcmd; - char __user *sepol1; - char __user *sepol2; - char __user *sepol3; - char __user *sepol4; - char __user *sepol5; - char __user *sepol6; - char __user *sepol7; -}; - -static int get_object(char *buf, char __user *user_object, size_t buf_sz, - char **object) -{ - if (!user_object) { - *object = ALL; - return 0; - } - - if (strncpy_from_user(buf, user_object, buf_sz) < 0) { - return -1; - } - - *object = buf; - - return 0; -} - -// reset avc cache table, otherwise the new rules will not take effect if already denied -static void reset_avc_cache() -{ -#if ((!defined(KSU_COMPAT_USE_SELINUX_STATE)) || \ - LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0)) - avc_ss_reset(0); - selnl_notify_policyload(0); - selinux_status_update_policyload(0); -#else - struct selinux_avc *avc = selinux_state.avc; - avc_ss_reset(avc, 0); - selnl_notify_policyload(0); - selinux_status_update_policyload(&selinux_state, 0); -#endif - selinux_xfrm_notify_policyload(); -} - -int handle_sepolicy(unsigned long arg3, void __user *arg4) -{ - if (!arg4) { - return -1; - } - - if (!getenforce()) { - pr_info("SELinux permissive or disabled when handle policy!\n"); - } - - struct sepol_data data; - if (copy_from_user(&data, arg4, sizeof(struct sepol_data))) { - pr_err("sepol: copy sepol_data failed.\n"); - return -1; - } - - u32 cmd = data.cmd; - u32 subcmd = data.subcmd; - - rcu_read_lock(); - - struct policydb *db = get_policydb(); - - int ret = -1; - if (cmd == CMD_NORMAL_PERM) { - char src_buf[MAX_SEPOL_LEN]; - char tgt_buf[MAX_SEPOL_LEN]; - char cls_buf[MAX_SEPOL_LEN]; - char perm_buf[MAX_SEPOL_LEN]; - - char *s, *t, *c, *p; - if (get_object(src_buf, data.sepol1, sizeof(src_buf), &s) < 0) { - pr_err("sepol: copy src failed.\n"); - goto exit; - } - - if (get_object(tgt_buf, data.sepol2, sizeof(tgt_buf), &t) < 0) { - pr_err("sepol: copy tgt failed.\n"); - goto exit; - } - - if (get_object(cls_buf, data.sepol3, sizeof(cls_buf), &c) < 0) { - pr_err("sepol: copy cls failed.\n"); - goto exit; - } - - if (get_object(perm_buf, data.sepol4, sizeof(perm_buf), &p) < - 0) { - pr_err("sepol: copy perm failed.\n"); - goto exit; - } - - bool success = false; - if (subcmd == 1) { - success = ksu_allow(db, s, t, c, p); - } else if (subcmd == 2) { - success = ksu_deny(db, s, t, c, p); - } else if (subcmd == 3) { - success = ksu_auditallow(db, s, t, c, p); - } else if (subcmd == 4) { - success = ksu_dontaudit(db, s, t, c, p); - } else { - pr_err("sepol: unknown subcmd: %d\n", subcmd); - } - ret = success ? 0 : -1; - - } else if (cmd == CMD_XPERM) { - char src_buf[MAX_SEPOL_LEN]; - char tgt_buf[MAX_SEPOL_LEN]; - char cls_buf[MAX_SEPOL_LEN]; - - char __maybe_unused - operation[MAX_SEPOL_LEN]; // it is always ioctl now! - char perm_set[MAX_SEPOL_LEN]; - - char *s, *t, *c; - if (get_object(src_buf, data.sepol1, sizeof(src_buf), &s) < 0) { - pr_err("sepol: copy src failed.\n"); - goto exit; - } - if (get_object(tgt_buf, data.sepol2, sizeof(tgt_buf), &t) < 0) { - pr_err("sepol: copy tgt failed.\n"); - goto exit; - } - if (get_object(cls_buf, data.sepol3, sizeof(cls_buf), &c) < 0) { - pr_err("sepol: copy cls failed.\n"); - goto exit; - } - if (strncpy_from_user(operation, data.sepol4, - sizeof(operation)) < 0) { - pr_err("sepol: copy operation failed.\n"); - goto exit; - } - if (strncpy_from_user(perm_set, data.sepol5, sizeof(perm_set)) < - 0) { - pr_err("sepol: copy perm_set failed.\n"); - goto exit; - } - - bool success = false; - if (subcmd == 1) { - success = ksu_allowxperm(db, s, t, c, perm_set); - } else if (subcmd == 2) { - success = ksu_auditallowxperm(db, s, t, c, perm_set); - } else if (subcmd == 3) { - success = ksu_dontauditxperm(db, s, t, c, perm_set); - } else { - pr_err("sepol: unknown subcmd: %d\n", subcmd); - } - ret = success ? 0 : -1; - } else if (cmd == CMD_TYPE_STATE) { - char src[MAX_SEPOL_LEN]; - - if (strncpy_from_user(src, data.sepol1, sizeof(src)) < 0) { - pr_err("sepol: copy src failed.\n"); - goto exit; - } - - bool success = false; - if (subcmd == 1) { - success = ksu_permissive(db, src); - } else if (subcmd == 2) { - success = ksu_enforce(db, src); - } else { - pr_err("sepol: unknown subcmd: %d\n", subcmd); - } - if (success) - ret = 0; - - } else if (cmd == CMD_TYPE || cmd == CMD_TYPE_ATTR) { - char type[MAX_SEPOL_LEN]; - char attr[MAX_SEPOL_LEN]; - - if (strncpy_from_user(type, data.sepol1, sizeof(type)) < 0) { - pr_err("sepol: copy type failed.\n"); - goto exit; - } - if (strncpy_from_user(attr, data.sepol2, sizeof(attr)) < 0) { - pr_err("sepol: copy attr failed.\n"); - goto exit; - } - - bool success = false; - if (cmd == CMD_TYPE) { - success = ksu_type(db, type, attr); - } else { - success = ksu_typeattribute(db, type, attr); - } - if (!success) { - pr_err("sepol: %d failed.\n", cmd); - goto exit; - } - ret = 0; - - } else if (cmd == CMD_ATTR) { - char attr[MAX_SEPOL_LEN]; - - if (strncpy_from_user(attr, data.sepol1, sizeof(attr)) < 0) { - pr_err("sepol: copy attr failed.\n"); - goto exit; - } - if (!ksu_attribute(db, attr)) { - pr_err("sepol: %d failed.\n", cmd); - goto exit; - } - ret = 0; - - } else if (cmd == CMD_TYPE_TRANSITION) { - char src[MAX_SEPOL_LEN]; - char tgt[MAX_SEPOL_LEN]; - char cls[MAX_SEPOL_LEN]; - char default_type[MAX_SEPOL_LEN]; - char object[MAX_SEPOL_LEN]; - - if (strncpy_from_user(src, data.sepol1, sizeof(src)) < 0) { - pr_err("sepol: copy src failed.\n"); - goto exit; - } - if (strncpy_from_user(tgt, data.sepol2, sizeof(tgt)) < 0) { - pr_err("sepol: copy tgt failed.\n"); - goto exit; - } - if (strncpy_from_user(cls, data.sepol3, sizeof(cls)) < 0) { - pr_err("sepol: copy cls failed.\n"); - goto exit; - } - if (strncpy_from_user(default_type, data.sepol4, - sizeof(default_type)) < 0) { - pr_err("sepol: copy default_type failed.\n"); - goto exit; - } - char *real_object; - if (data.sepol5 == NULL) { - real_object = NULL; - } else { - if (strncpy_from_user(object, data.sepol5, - sizeof(object)) < 0) { - pr_err("sepol: copy object failed.\n"); - goto exit; - } - real_object = object; - } - - bool success = ksu_type_transition(db, src, tgt, cls, - default_type, real_object); - if (success) - ret = 0; - - } else if (cmd == CMD_TYPE_CHANGE) { - char src[MAX_SEPOL_LEN]; - char tgt[MAX_SEPOL_LEN]; - char cls[MAX_SEPOL_LEN]; - char default_type[MAX_SEPOL_LEN]; - - if (strncpy_from_user(src, data.sepol1, sizeof(src)) < 0) { - pr_err("sepol: copy src failed.\n"); - goto exit; - } - if (strncpy_from_user(tgt, data.sepol2, sizeof(tgt)) < 0) { - pr_err("sepol: copy tgt failed.\n"); - goto exit; - } - if (strncpy_from_user(cls, data.sepol3, sizeof(cls)) < 0) { - pr_err("sepol: copy cls failed.\n"); - goto exit; - } - if (strncpy_from_user(default_type, data.sepol4, - sizeof(default_type)) < 0) { - pr_err("sepol: copy default_type failed.\n"); - goto exit; - } - bool success = false; - if (subcmd == 1) { - success = ksu_type_change(db, src, tgt, cls, - default_type); - } else if (subcmd == 2) { - success = ksu_type_member(db, src, tgt, cls, - default_type); - } else { - pr_err("sepol: unknown subcmd: %d\n", subcmd); - } - if (success) - ret = 0; - } else if (cmd == CMD_GENFSCON) { - char name[MAX_SEPOL_LEN]; - char path[MAX_SEPOL_LEN]; - char context[MAX_SEPOL_LEN]; - if (strncpy_from_user(name, data.sepol1, sizeof(name)) < 0) { - pr_err("sepol: copy name failed.\n"); - goto exit; - } - if (strncpy_from_user(path, data.sepol2, sizeof(path)) < 0) { - pr_err("sepol: copy path failed.\n"); - goto exit; - } - if (strncpy_from_user(context, data.sepol3, sizeof(context)) < - 0) { - pr_err("sepol: copy context failed.\n"); - goto exit; - } - - if (!ksu_genfscon(db, name, path, context)) { - pr_err("sepol: %d failed.\n", cmd); - goto exit; - } - ret = 0; - } else { - pr_err("sepol: unknown cmd: %d\n", cmd); - } - -exit: - rcu_read_unlock(); - - // only allow and xallow needs to reset avc cache, but we cannot do that because - // we are in atomic context. so we just reset it every time. - reset_avc_cache(); - - return ret; -} diff --git a/drivers/kernelsu/selinux/selinux.c b/drivers/kernelsu/selinux/selinux.c deleted file mode 100644 index 4ba20b0435c2..000000000000 --- a/drivers/kernelsu/selinux/selinux.c +++ /dev/null @@ -1,145 +0,0 @@ -#include "selinux.h" -#include "objsec.h" -#include "linux/version.h" -#include "../klog.h" // IWYU pragma: keep -#ifndef KSU_COMPAT_USE_SELINUX_STATE -#include "avc.h" -#endif - -#define KERNEL_SU_DOMAIN "u:r:su:s0" - -static int transive_to_domain(const char *domain) -{ - struct cred *cred; - struct task_security_struct *tsec; - u32 sid; - int error; - - cred = (struct cred *)__task_cred(current); - - tsec = cred->security; - if (!tsec) { - pr_err("tsec == NULL!\n"); - return -1; - } - - error = security_secctx_to_secid(domain, strlen(domain), &sid); - if (error) { - pr_info("security_secctx_to_secid %s -> sid: %d, error: %d\n", - domain, sid, error); - } - if (!error) { - tsec->sid = sid; - tsec->create_sid = 0; - tsec->keycreate_sid = 0; - tsec->sockcreate_sid = 0; - } - return error; -} - -void setup_selinux(const char *domain) -{ - if (transive_to_domain(domain)) { - pr_err("transive domain failed.\n"); - return; - } - - /* we didn't need this now, we have change selinux rules when boot! -if (!is_domain_permissive) { - if (set_domain_permissive() == 0) { - is_domain_permissive = true; - } -}*/ -} - -void setenforce(bool enforce) -{ -#ifdef CONFIG_SECURITY_SELINUX_DEVELOP -#ifdef KSU_COMPAT_USE_SELINUX_STATE - selinux_state.enforcing = enforce; -#else - selinux_enforcing = enforce; -#endif -#endif -} - -bool getenforce() -{ -#ifdef CONFIG_SECURITY_SELINUX_DISABLE -#ifdef KSU_COMPAT_USE_SELINUX_STATE - if (selinux_state.disabled) { -#else - if (selinux_disabled) { -#endif - return false; - } -#endif - -#ifdef CONFIG_SECURITY_SELINUX_DEVELOP -#ifdef KSU_COMPAT_USE_SELINUX_STATE - return selinux_state.enforcing; -#else - return selinux_enforcing; -#endif -#else - return true; -#endif -} - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) && \ - !defined(KSU_COMPAT_HAS_CURRENT_SID) -/* - * get the subjective security ID of the current task - */ -static inline u32 current_sid(void) -{ - const struct task_security_struct *tsec = current_security(); - - return tsec->sid; -} -#endif - -bool is_ksu_domain() -{ - char *domain; - u32 seclen; - bool result; - int err = security_secid_to_secctx(current_sid(), &domain, &seclen); - if (err) { - return false; - } - result = strncmp(KERNEL_SU_DOMAIN, domain, seclen) == 0; - security_release_secctx(domain, seclen); - return result; -} - -bool is_zygote(void *sec) -{ - struct task_security_struct *tsec = (struct task_security_struct *)sec; - if (!tsec) { - return false; - } - char *domain; - u32 seclen; - bool result; - int err = security_secid_to_secctx(tsec->sid, &domain, &seclen); - if (err) { - return false; - } - result = strncmp("u:r:zygote:s0", domain, seclen) == 0; - security_release_secctx(domain, seclen); - return result; -} - -#define DEVPTS_DOMAIN "u:object_r:ksu_file:s0" - -u32 ksu_get_devpts_sid() -{ - u32 devpts_sid = 0; - int err = security_secctx_to_secid(DEVPTS_DOMAIN, strlen(DEVPTS_DOMAIN), - &devpts_sid); - if (err) { - pr_info("get devpts sid err %d\n", err); - } - return devpts_sid; -} diff --git a/drivers/kernelsu/selinux/selinux.h b/drivers/kernelsu/selinux/selinux.h deleted file mode 100644 index 07120c253268..000000000000 --- a/drivers/kernelsu/selinux/selinux.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef __KSU_H_SELINUX -#define __KSU_H_SELINUX - -#include "linux/types.h" -#include "linux/version.h" - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)) || defined(KSU_COMPAT_HAS_SELINUX_STATE) -#define KSU_COMPAT_USE_SELINUX_STATE -#endif - -void setup_selinux(const char *); - -void setenforce(bool); - -bool getenforce(); - -bool is_ksu_domain(); - -bool is_zygote(void *cred); - -void apply_kernelsu_rules(); - -u32 ksu_get_devpts_sid(); - -#endif diff --git a/drivers/kernelsu/selinux/sepolicy.c b/drivers/kernelsu/selinux/sepolicy.c deleted file mode 100644 index acdc45ad81f7..000000000000 --- a/drivers/kernelsu/selinux/sepolicy.c +++ /dev/null @@ -1,1070 +0,0 @@ -#include -#include -#include -#include - -#include "sepolicy.h" -#include "../klog.h" // IWYU pragma: keep -#include "ss/symtab.h" -#include "../kernel_compat.h" // Add check Huawei Device - -#define KSU_SUPPORT_ADD_TYPE - -////////////////////////////////////////////////////// -// Declaration -////////////////////////////////////////////////////// - -static struct avtab_node *get_avtab_node(struct policydb *db, - struct avtab_key *key, - struct avtab_extended_perms *xperms); - -static bool add_rule(struct policydb *db, const char *s, const char *t, - const char *c, const char *p, int effect, bool invert); - -static void add_rule_raw(struct policydb *db, struct type_datum *src, - struct type_datum *tgt, struct class_datum *cls, - struct perm_datum *perm, int effect, bool invert); - -static void add_xperm_rule_raw(struct policydb *db, struct type_datum *src, - struct type_datum *tgt, struct class_datum *cls, - uint16_t low, uint16_t high, int effect, - bool invert); -static bool add_xperm_rule(struct policydb *db, const char *s, const char *t, - const char *c, const char *range, int effect, - bool invert); - -static bool add_type_rule(struct policydb *db, const char *s, const char *t, - const char *c, const char *d, int effect); - -static bool add_filename_trans(struct policydb *db, const char *s, - const char *t, const char *c, const char *d, - const char *o); - -static bool add_genfscon(struct policydb *db, const char *fs_name, - const char *path, const char *context); - -static bool add_type(struct policydb *db, const char *type_name, bool attr); - -static bool set_type_state(struct policydb *db, const char *type_name, - bool permissive); - -static void add_typeattribute_raw(struct policydb *db, struct type_datum *type, - struct type_datum *attr); - -static bool add_typeattribute(struct policydb *db, const char *type, - const char *attr); - -////////////////////////////////////////////////////// -// Implementation -////////////////////////////////////////////////////// - -// Invert is adding rules for auditdeny; in other cases, invert is removing -// rules -#define strip_av(effect, invert) ((effect == AVTAB_AUDITDENY) == !invert) - -#define ksu_hash_for_each(node_ptr, n_slot, cur) \ - int i; \ - for (i = 0; i < n_slot; ++i) \ - for (cur = node_ptr[i]; cur; cur = cur->next) - -// htable is a struct instead of pointer above 5.8.0: -// https://elixir.bootlin.com/linux/v5.8-rc1/source/security/selinux/ss/symtab.h -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0) -#define ksu_hashtab_for_each(htab, cur) \ - ksu_hash_for_each(htab.htable, htab.size, cur) -#else -#define ksu_hashtab_for_each(htab, cur) \ - ksu_hash_for_each(htab->htable, htab->size, cur) -#endif - -// symtab_search is introduced on 5.9.0: -// https://elixir.bootlin.com/linux/v5.9-rc1/source/security/selinux/ss/symtab.h -#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0) -#define symtab_search(s, name) hashtab_search((s)->table, name) -#define symtab_insert(s, name, datum) hashtab_insert((s)->table, name, datum) -#endif - -#define avtab_for_each(avtab, cur) \ - ksu_hash_for_each(avtab.htable, avtab.nslot, cur); - -static struct avtab_node *get_avtab_node(struct policydb *db, - struct avtab_key *key, - struct avtab_extended_perms *xperms) -{ - struct avtab_node *node; - - /* AVTAB_XPERMS entries are not necessarily unique */ - if (key->specified & AVTAB_XPERMS) { - bool match = false; - node = avtab_search_node(&db->te_avtab, key); - while (node) { - if ((node->datum.u.xperms->specified == - xperms->specified) && - (node->datum.u.xperms->driver == xperms->driver)) { - match = true; - break; - } - node = avtab_search_node_next(node, key->specified); - } - if (!match) - node = NULL; - } else { - node = avtab_search_node(&db->te_avtab, key); - } - - if (!node) { - struct avtab_datum avdatum = {}; - /* - * AUDITDENY, aka DONTAUDIT, are &= assigned, versus |= for - * others. Initialize the data accordingly. - */ - if (key->specified & AVTAB_XPERMS) { - avdatum.u.xperms = xperms; - } else { - avdatum.u.data = - key->specified == AVTAB_AUDITDENY ? ~0U : 0U; - } - /* this is used to get the node - insertion is actually unique */ - node = avtab_insert_nonunique(&db->te_avtab, key, &avdatum); - - int grow_size = sizeof(struct avtab_key); - grow_size += sizeof(struct avtab_datum); - if (key->specified & AVTAB_XPERMS) { - grow_size += sizeof(u8); - grow_size += sizeof(u8); - grow_size += sizeof(u32) * - ARRAY_SIZE(avdatum.u.xperms->perms.p); - } - db->len += grow_size; - } - - return node; -} - -static bool add_rule(struct policydb *db, const char *s, const char *t, - const char *c, const char *p, int effect, bool invert) -{ - struct type_datum *src = NULL, *tgt = NULL; - struct class_datum *cls = NULL; - struct perm_datum *perm = NULL; - - if (s) { - src = symtab_search(&db->p_types, s); - if (src == NULL) { - pr_info("source type %s does not exist\n", s); - return false; - } - } - - if (t) { - tgt = symtab_search(&db->p_types, t); - if (tgt == NULL) { - pr_info("target type %s does not exist\n", t); - return false; - } - } - - if (c) { - cls = symtab_search(&db->p_classes, c); - if (cls == NULL) { - pr_info("class %s does not exist\n", c); - return false; - } - } - - if (p) { - if (c == NULL) { - pr_info("No class is specified, cannot add perm [%s] \n", - p); - return false; - } - - perm = symtab_search(&cls->permissions, p); - if (perm == NULL && cls->comdatum != NULL) { - perm = symtab_search(&cls->comdatum->permissions, p); - } - if (perm == NULL) { - pr_info("perm %s does not exist in class %s\n", p, c); - return false; - } - } - add_rule_raw(db, src, tgt, cls, perm, effect, invert); - return true; -} - -static void add_rule_raw(struct policydb *db, struct type_datum *src, - struct type_datum *tgt, struct class_datum *cls, - struct perm_datum *perm, int effect, bool invert) -{ - if (src == NULL) { - struct hashtab_node *node; - if (strip_av(effect, invert)) { - ksu_hashtab_for_each(db->p_types.table, node) - { - add_rule_raw(db, - (struct type_datum *)node->datum, - tgt, cls, perm, effect, invert); - }; - } else { - ksu_hashtab_for_each(db->p_types.table, node) - { - struct type_datum *type = - (struct type_datum *)(node->datum); - if (type->attribute) { - add_rule_raw(db, type, tgt, cls, perm, - effect, invert); - } - }; - } - } else if (tgt == NULL) { - struct hashtab_node *node; - if (strip_av(effect, invert)) { - ksu_hashtab_for_each(db->p_types.table, node) - { - add_rule_raw(db, src, - (struct type_datum *)node->datum, - cls, perm, effect, invert); - }; - } else { - ksu_hashtab_for_each(db->p_types.table, node) - { - struct type_datum *type = - (struct type_datum *)(node->datum); - if (type->attribute) { - add_rule_raw(db, src, type, cls, perm, - effect, invert); - } - }; - } - } else if (cls == NULL) { - struct hashtab_node *node; - ksu_hashtab_for_each(db->p_classes.table, node) - { - add_rule_raw(db, src, tgt, - (struct class_datum *)node->datum, perm, - effect, invert); - } - } else { - struct avtab_key key; - key.source_type = src->value; - key.target_type = tgt->value; - key.target_class = cls->value; - key.specified = effect; - - struct avtab_node *node = get_avtab_node(db, &key, NULL); - if (invert) { - if (perm) - node->datum.u.data &= - ~(1U << (perm->value - 1)); - else - node->datum.u.data = 0U; - } else { - if (perm) - node->datum.u.data |= 1U << (perm->value - 1); - else - node->datum.u.data = ~0U; - } - } -} - -#define ioctl_driver(x) (x >> 8 & 0xFF) -#define ioctl_func(x) (x & 0xFF) - -#define xperm_test(x, p) (1 & (p[x >> 5] >> (x & 0x1f))) -#define xperm_set(x, p) (p[x >> 5] |= (1 << (x & 0x1f))) -#define xperm_clear(x, p) (p[x >> 5] &= ~(1 << (x & 0x1f))) - -static void add_xperm_rule_raw(struct policydb *db, struct type_datum *src, - struct type_datum *tgt, struct class_datum *cls, - uint16_t low, uint16_t high, int effect, - bool invert) -{ - if (src == NULL) { - struct hashtab_node *node; - ksu_hashtab_for_each(db->p_types.table, node) - { - struct type_datum *type = - (struct type_datum *)(node->datum); - if (type->attribute) { - add_xperm_rule_raw(db, type, tgt, cls, low, - high, effect, invert); - } - }; - } else if (tgt == NULL) { - struct hashtab_node *node; - ksu_hashtab_for_each(db->p_types.table, node) - { - struct type_datum *type = - (struct type_datum *)(node->datum); - if (type->attribute) { - add_xperm_rule_raw(db, src, type, cls, low, - high, effect, invert); - } - }; - } else if (cls == NULL) { - struct hashtab_node *node; - ksu_hashtab_for_each(db->p_classes.table, node) - { - add_xperm_rule_raw(db, src, tgt, - (struct class_datum *)(node->datum), - low, high, effect, invert); - }; - } else { - struct avtab_key key; - key.source_type = src->value; - key.target_type = tgt->value; - key.target_class = cls->value; - key.specified = effect; - - struct avtab_datum *datum; - struct avtab_node *node; - struct avtab_extended_perms xperms; - - memset(&xperms, 0, sizeof(xperms)); - if (ioctl_driver(low) != ioctl_driver(high)) { - xperms.specified = AVTAB_XPERMS_IOCTLDRIVER; - xperms.driver = 0; - } else { - xperms.specified = AVTAB_XPERMS_IOCTLFUNCTION; - xperms.driver = ioctl_driver(low); - } - int i; - if (xperms.specified == AVTAB_XPERMS_IOCTLDRIVER) { - for (i = ioctl_driver(low); i <= ioctl_driver(high); - ++i) { - if (invert) - xperm_clear(i, xperms.perms.p); - else - xperm_set(i, xperms.perms.p); - } - } else { - for (i = ioctl_func(low); i <= ioctl_func(high); ++i) { - if (invert) - xperm_clear(i, xperms.perms.p); - else - xperm_set(i, xperms.perms.p); - } - } - - node = get_avtab_node(db, &key, &xperms); - if (!node) { - pr_warn("add_xperm_rule_raw cannot found node!\n"); - return; - } - datum = &node->datum; - - if (datum->u.xperms == NULL) { - datum->u.xperms = - (struct avtab_extended_perms *)(kmalloc( - sizeof(xperms), GFP_KERNEL)); - if (!datum->u.xperms) { - pr_err("alloc xperms failed\n"); - return; - } - memcpy(datum->u.xperms, &xperms, sizeof(xperms)); - } - } -} - -static bool add_xperm_rule(struct policydb *db, const char *s, const char *t, - const char *c, const char *range, int effect, - bool invert) -{ - struct type_datum *src = NULL, *tgt = NULL; - struct class_datum *cls = NULL; - - if (s) { - src = symtab_search(&db->p_types, s); - if (src == NULL) { - pr_info("source type %s does not exist\n", s); - return false; - } - } - - if (t) { - tgt = symtab_search(&db->p_types, t); - if (tgt == NULL) { - pr_info("target type %s does not exist\n", t); - return false; - } - } - - if (c) { - cls = symtab_search(&db->p_classes, c); - if (cls == NULL) { - pr_info("class %s does not exist\n", c); - return false; - } - } - - u16 low, high; - - if (range) { - if (strchr(range, '-')) { - sscanf(range, "%hx-%hx", &low, &high); - } else { - sscanf(range, "%hx", &low); - high = low; - } - } else { - low = 0; - high = 0xFFFF; - } - - add_xperm_rule_raw(db, src, tgt, cls, low, high, effect, invert); - return true; -} - -static bool add_type_rule(struct policydb *db, const char *s, const char *t, - const char *c, const char *d, int effect) -{ - struct type_datum *src, *tgt, *def; - struct class_datum *cls; - - src = symtab_search(&db->p_types, s); - if (src == NULL) { - pr_info("source type %s does not exist\n", s); - return false; - } - tgt = symtab_search(&db->p_types, t); - if (tgt == NULL) { - pr_info("target type %s does not exist\n", t); - return false; - } - cls = symtab_search(&db->p_classes, c); - if (cls == NULL) { - pr_info("class %s does not exist\n", c); - return false; - } - def = symtab_search(&db->p_types, d); - if (def == NULL) { - pr_info("default type %s does not exist\n", d); - return false; - } - - struct avtab_key key; - key.source_type = src->value; - key.target_type = tgt->value; - key.target_class = cls->value; - key.specified = effect; - - struct avtab_node *node = get_avtab_node(db, &key, NULL); - node->datum.u.data = def->value; - - return true; -} - -// 5.9.0 : static inline int hashtab_insert(struct hashtab *h, void *key, void -// *datum, struct hashtab_key_params key_params) 5.8.0: int -// hashtab_insert(struct hashtab *h, void *k, void *d); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0) -static u32 filenametr_hash(const void *k) -{ - const struct filename_trans_key *ft = k; - unsigned long hash; - unsigned int byte_num; - unsigned char focus; - - hash = ft->ttype ^ ft->tclass; - - byte_num = 0; - while ((focus = ft->name[byte_num++])) - hash = partial_name_hash(focus, hash); - return hash; -} - -static int filenametr_cmp(const void *k1, const void *k2) -{ - const struct filename_trans_key *ft1 = k1; - const struct filename_trans_key *ft2 = k2; - int v; - - v = ft1->ttype - ft2->ttype; - if (v) - return v; - - v = ft1->tclass - ft2->tclass; - if (v) - return v; - - return strcmp(ft1->name, ft2->name); -} - -static const struct hashtab_key_params filenametr_key_params = { - .hash = filenametr_hash, - .cmp = filenametr_cmp, -}; -#endif - -static bool add_filename_trans(struct policydb *db, const char *s, - const char *t, const char *c, const char *d, - const char *o) -{ - struct type_datum *src, *tgt, *def; - struct class_datum *cls; - - src = symtab_search(&db->p_types, s); - if (src == NULL) { - pr_warn("source type %s does not exist\n", s); - return false; - } - tgt = symtab_search(&db->p_types, t); - if (tgt == NULL) { - pr_warn("target type %s does not exist\n", t); - return false; - } - cls = symtab_search(&db->p_classes, c); - if (cls == NULL) { - pr_warn("class %s does not exist\n", c); - return false; - } - def = symtab_search(&db->p_types, d); - if (def == NULL) { - pr_warn("default type %s does not exist\n", d); - return false; - } - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) - struct filename_trans_key key; - key.ttype = tgt->value; - key.tclass = cls->value; - key.name = (char *)o; - - struct filename_trans_datum *last = NULL; - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0) - struct filename_trans_datum *trans = - policydb_filenametr_search(db, &key); -#else - struct filename_trans_datum *trans = - hashtab_search(&db->filename_trans, &key); -#endif - while (trans) { - if (ebitmap_get_bit(&trans->stypes, src->value - 1)) { - // Duplicate, overwrite existing data and return - trans->otype = def->value; - return true; - } - if (trans->otype == def->value) - break; - last = trans; - trans = trans->next; - } - - if (trans == NULL) { - trans = (struct filename_trans_datum *)kcalloc(sizeof(*trans), - 1, GFP_ATOMIC); - struct filename_trans_key *new_key = - (struct filename_trans_key *)kmalloc(sizeof(*new_key), - GFP_ATOMIC); - *new_key = key; - new_key->name = kstrdup(key.name, GFP_ATOMIC); - trans->next = last; - trans->otype = def->value; - hashtab_insert(&db->filename_trans, new_key, trans, - filenametr_key_params); - } - - db->compat_filename_trans_count++; - return ebitmap_set_bit(&trans->stypes, src->value - 1, 1) == 0; -#else // < 5.7.0, has no filename_trans_key, but struct filename_trans - - struct filename_trans key; - key.ttype = tgt->value; - key.tclass = cls->value; - key.name = (char *)o; - - struct filename_trans_datum *trans = - hashtab_search(db->filename_trans, &key); - - if (trans == NULL) { - trans = (struct filename_trans_datum *)kcalloc(sizeof(*trans), - 1, GFP_ATOMIC); - if (!trans) { - pr_err("add_filename_trans: Failed to alloc datum\n"); - return false; - } - struct filename_trans *new_key = - (struct filename_trans *)kmalloc(sizeof(*new_key), - GFP_ATOMIC); - if (!new_key) { - pr_err("add_filename_trans: Failed to alloc new_key\n"); - return false; - } - *new_key = key; - new_key->name = kstrdup(key.name, GFP_ATOMIC); - trans->otype = def->value; - hashtab_insert(db->filename_trans, new_key, trans); - } - - return ebitmap_set_bit(&db->filename_trans_ttypes, src->value - 1, 1) == - 0; -#endif -} - -static bool add_genfscon(struct policydb *db, const char *fs_name, - const char *path, const char *context) -{ - return false; -} - -static void *ksu_realloc(void *old, size_t new_size, size_t old_size) -{ - // we can't use krealloc, because it may be read-only - void *new = kzalloc(new_size, GFP_ATOMIC); - if (!new) { - return NULL; - } - if (old_size) { - memcpy(new, old, old_size); - } - // we can't use kfree, because it may be read-only - // there maybe some leaks, maybe we can check ptr_write, but it's not a big deal - // kfree(old); - return new; -} - -static bool add_type(struct policydb *db, const char *type_name, bool attr) -{ -#ifdef KSU_SUPPORT_ADD_TYPE - struct type_datum *type = symtab_search(&db->p_types, type_name); - if (type) { - pr_warn("Type %s already exists\n", type_name); - return true; - } - - u32 value = ++db->p_types.nprim; - type = (struct type_datum *)kzalloc(sizeof(struct type_datum), - GFP_ATOMIC); - if (!type) { - pr_err("add_type: alloc type_datum failed.\n"); - return false; - } - - type->primary = 1; - type->value = value; - type->attribute = attr; - - char *key = kstrdup(type_name, GFP_ATOMIC); - if (!key) { - pr_err("add_type: alloc key failed.\n"); - return false; - } - - if (symtab_insert(&db->p_types, key, type)) { - pr_err("add_type: insert symtab failed.\n"); - return false; - } - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0) - struct ebitmap *new_type_attr_map_array = - ksu_realloc(db->type_attr_map_array, - value * sizeof(struct ebitmap), - (value - 1) * sizeof(struct ebitmap)); - - if (!new_type_attr_map_array) { - pr_err("add_type: alloc type_attr_map_array failed\n"); - return false; - } - - struct type_datum **new_type_val_to_struct = - ksu_realloc(db->type_val_to_struct, - sizeof(*db->type_val_to_struct) * value, - sizeof(*db->type_val_to_struct) * (value - 1)); - - if (!new_type_val_to_struct) { - pr_err("add_type: alloc type_val_to_struct failed\n"); - return false; - } - - char **new_val_to_name_types = - ksu_realloc(db->sym_val_to_name[SYM_TYPES], - sizeof(char *) * value, - sizeof(char *) * (value - 1)); - if (!new_val_to_name_types) { - pr_err("add_type: alloc val_to_name failed\n"); - return false; - } - - db->type_attr_map_array = new_type_attr_map_array; - ebitmap_init(&db->type_attr_map_array[value - 1]); - ebitmap_set_bit(&db->type_attr_map_array[value - 1], value - 1, 1); - - db->type_val_to_struct = new_type_val_to_struct; - db->type_val_to_struct[value - 1] = type; - - db->sym_val_to_name[SYM_TYPES] = new_val_to_name_types; - db->sym_val_to_name[SYM_TYPES][value - 1] = key; - - int i; - for (i = 0; i < db->p_roles.nprim; ++i) { - ebitmap_set_bit(&db->role_val_to_struct[i]->types, value - 1, - 1); - } - - return true; -#elif defined(CONFIG_IS_HW_HISI) - /* - * Huawei use type_attr_map and type_val_to_struct. - * And use ebitmap not flex_array. - */ - size_t new_size = sizeof(struct ebitmap) * db->p_types.nprim; - struct ebitmap *new_type_attr_map = - (krealloc(db->type_attr_map, new_size, GFP_ATOMIC)); - - struct type_datum **new_type_val_to_struct = - krealloc(db->type_val_to_struct, - sizeof(*db->type_val_to_struct) * db->p_types.nprim, - GFP_ATOMIC); - - if (!new_type_attr_map) { - pr_err("add_type: alloc type_attr_map failed\n"); - return false; - } - - if (!new_type_val_to_struct) { - pr_err("add_type: alloc type_val_to_struct failed\n"); - return false; - } - - char **new_val_to_name_types = - krealloc(db->sym_val_to_name[SYM_TYPES], - sizeof(char *) * db->symtab[SYM_TYPES].nprim, - GFP_KERNEL); - if (!new_val_to_name_types) { - pr_err("add_type: alloc val_to_name failed\n"); - return false; - } - - db->type_attr_map = new_type_attr_map; - ebitmap_init(&db->type_attr_map[value - 1], HISI_SELINUX_EBITMAP_RO); - ebitmap_set_bit(&db->type_attr_map[value - 1], value - 1, 1); - - db->type_val_to_struct = new_type_val_to_struct; - db->type_val_to_struct[value - 1] = type; - - db->sym_val_to_name[SYM_TYPES] = new_val_to_name_types; - db->sym_val_to_name[SYM_TYPES][value - 1] = key; - - int i; - for (i = 0; i < db->p_roles.nprim; ++i) { - ebitmap_set_bit(&db->role_val_to_struct[i]->types, value - 1, - 1); - } - - return true; -#else - // flex_array is not extensible, we need to create a new bigger one instead - struct flex_array *new_type_attr_map_array = - flex_array_alloc(sizeof(struct ebitmap), db->p_types.nprim, - GFP_ATOMIC | __GFP_ZERO); - - struct flex_array *new_type_val_to_struct = - flex_array_alloc(sizeof(struct type_datum *), db->p_types.nprim, - GFP_ATOMIC | __GFP_ZERO); - - struct flex_array *new_val_to_name_types = - flex_array_alloc(sizeof(char *), db->symtab[SYM_TYPES].nprim, - GFP_ATOMIC | __GFP_ZERO); - - if (!new_type_attr_map_array) { - pr_err("add_type: alloc type_attr_map_array failed\n"); - return false; - } - - if (!new_type_val_to_struct) { - pr_err("add_type: alloc type_val_to_struct failed\n"); - return false; - } - - if (!new_val_to_name_types) { - pr_err("add_type: alloc val_to_name failed\n"); - return false; - } - - // preallocate so we don't have to worry about the put ever failing - if (flex_array_prealloc(new_type_attr_map_array, 0, db->p_types.nprim, - GFP_ATOMIC | __GFP_ZERO)) { - pr_err("add_type: prealloc type_attr_map_array failed\n"); - return false; - } - - if (flex_array_prealloc(new_type_val_to_struct, 0, db->p_types.nprim, - GFP_ATOMIC | __GFP_ZERO)) { - pr_err("add_type: prealloc type_val_to_struct_array failed\n"); - return false; - } - - if (flex_array_prealloc(new_val_to_name_types, 0, - db->symtab[SYM_TYPES].nprim, - GFP_ATOMIC | __GFP_ZERO)) { - pr_err("add_type: prealloc val_to_name_types failed\n"); - return false; - } - - int j; - void *old_elem; - // copy the old data or pointers to new flex arrays - for (j = 0; j < db->type_attr_map_array->total_nr_elements; j++) { - old_elem = flex_array_get(db->type_attr_map_array, j); - if (old_elem) - flex_array_put(new_type_attr_map_array, j, old_elem, - GFP_ATOMIC | __GFP_ZERO); - } - - for (j = 0; j < db->type_val_to_struct_array->total_nr_elements; j++) { - old_elem = flex_array_get_ptr(db->type_val_to_struct_array, j); - if (old_elem) - flex_array_put_ptr(new_type_val_to_struct, j, old_elem, - GFP_ATOMIC | __GFP_ZERO); - } - - for (j = 0; j < db->symtab[SYM_TYPES].nprim; j++) { - old_elem = - flex_array_get_ptr(db->sym_val_to_name[SYM_TYPES], j); - if (old_elem) - flex_array_put_ptr(new_val_to_name_types, j, old_elem, - GFP_ATOMIC | __GFP_ZERO); - } - - // store the pointer of old flex arrays first, when assigning new ones we - // should free it - struct flex_array *old_fa; - - old_fa = db->type_attr_map_array; - db->type_attr_map_array = new_type_attr_map_array; - if (old_fa) { - flex_array_free(old_fa); - } - - ebitmap_init(flex_array_get(db->type_attr_map_array, value - 1)); - ebitmap_set_bit(flex_array_get(db->type_attr_map_array, value - 1), - value - 1, 1); - - old_fa = db->type_val_to_struct_array; - db->type_val_to_struct_array = new_type_val_to_struct; - if (old_fa) { - flex_array_free(old_fa); - } - flex_array_put_ptr(db->type_val_to_struct_array, value - 1, type, - GFP_ATOMIC | __GFP_ZERO); - - old_fa = db->sym_val_to_name[SYM_TYPES]; - db->sym_val_to_name[SYM_TYPES] = new_val_to_name_types; - if (old_fa) { - flex_array_free(old_fa); - } - flex_array_put_ptr(db->sym_val_to_name[SYM_TYPES], value - 1, key, - GFP_ATOMIC | __GFP_ZERO); - - int i; - for (i = 0; i < db->p_roles.nprim; ++i) { - ebitmap_set_bit(&db->role_val_to_struct[i]->types, value - 1, - 1); - } - return true; -#endif - -#else - return false; -#endif -} - -static bool set_type_state(struct policydb *db, const char *type_name, - bool permissive) -{ - struct type_datum *type; - if (type_name == NULL) { - struct hashtab_node *node; - ksu_hashtab_for_each(db->p_types.table, node) - { - type = (struct type_datum *)(node->datum); - if (ebitmap_set_bit(&db->permissive_map, type->value, - permissive)) - pr_info("Could not set bit in permissive map\n"); - }; - } else { - type = (struct type_datum *)symtab_search(&db->p_types, - type_name); - if (type == NULL) { - pr_info("type %s does not exist\n", type_name); - return false; - } - if (ebitmap_set_bit(&db->permissive_map, type->value, - permissive)) { - pr_info("Could not set bit in permissive map\n"); - return false; - } - } - return true; -} - -static void add_typeattribute_raw(struct policydb *db, struct type_datum *type, - struct type_datum *attr) -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0) - struct ebitmap *sattr = &db->type_attr_map_array[type->value - 1]; -#elif defined(CONFIG_IS_HW_HISI) - /* - * HISI_SELINUX_EBITMAP_RO is Huawei's unique features. - */ - struct ebitmap *sattr = &db->type_attr_map[type->value - 1], - HISI_SELINUX_EBITMAP_RO; -#else - struct ebitmap *sattr = - flex_array_get(db->type_attr_map_array, type->value - 1); -#endif - ebitmap_set_bit(sattr, attr->value - 1, 1); - - struct hashtab_node *node; - struct constraint_node *n; - struct constraint_expr *e; - ksu_hashtab_for_each(db->p_classes.table, node) - { - struct class_datum *cls = (struct class_datum *)(node->datum); - for (n = cls->constraints; n; n = n->next) { - for (e = n->expr; e; e = e->next) { - if (e->expr_type == CEXPR_NAMES && - ebitmap_get_bit(&e->type_names->types, - attr->value - 1)) { - ebitmap_set_bit(&e->names, - type->value - 1, 1); - } - } - } - }; -} - -static bool add_typeattribute(struct policydb *db, const char *type, - const char *attr) -{ - struct type_datum *type_d = symtab_search(&db->p_types, type); - if (type_d == NULL) { - pr_info("type %s does not exist\n", type); - return false; - } else if (type_d->attribute) { - pr_info("type %s is an attribute\n", attr); - return false; - } - - struct type_datum *attr_d = symtab_search(&db->p_types, attr); - if (attr_d == NULL) { - pr_info("attribute %s does not exist\n", type); - return false; - } else if (!attr_d->attribute) { - pr_info("type %s is not an attribute \n", attr); - return false; - } - - add_typeattribute_raw(db, type_d, attr_d); - return true; -} - -////////////////////////////////////////////////////////////////////////// - -// Operation on types -bool ksu_type(struct policydb *db, const char *name, const char *attr) -{ - return add_type(db, name, false) && add_typeattribute(db, name, attr); -} - -bool ksu_attribute(struct policydb *db, const char *name) -{ - return add_type(db, name, true); -} - -bool ksu_permissive(struct policydb *db, const char *type) -{ - return set_type_state(db, type, true); -} - -bool ksu_enforce(struct policydb *db, const char *type) -{ - return set_type_state(db, type, false); -} - -bool ksu_typeattribute(struct policydb *db, const char *type, const char *attr) -{ - return add_typeattribute(db, type, attr); -} - -bool ksu_exists(struct policydb *db, const char *type) -{ - return symtab_search(&db->p_types, type) != NULL; -} - -// Access vector rules -bool ksu_allow(struct policydb *db, const char *src, const char *tgt, - const char *cls, const char *perm) -{ - return add_rule(db, src, tgt, cls, perm, AVTAB_ALLOWED, false); -} - -bool ksu_deny(struct policydb *db, const char *src, const char *tgt, - const char *cls, const char *perm) -{ - return add_rule(db, src, tgt, cls, perm, AVTAB_ALLOWED, true); -} - -bool ksu_auditallow(struct policydb *db, const char *src, const char *tgt, - const char *cls, const char *perm) -{ - return add_rule(db, src, tgt, cls, perm, AVTAB_AUDITALLOW, false); -} -bool ksu_dontaudit(struct policydb *db, const char *src, const char *tgt, - const char *cls, const char *perm) -{ - return add_rule(db, src, tgt, cls, perm, AVTAB_AUDITDENY, true); -} - -// Extended permissions access vector rules -bool ksu_allowxperm(struct policydb *db, const char *src, const char *tgt, - const char *cls, const char *range) -{ - return add_xperm_rule(db, src, tgt, cls, range, AVTAB_XPERMS_ALLOWED, - false); -} - -bool ksu_auditallowxperm(struct policydb *db, const char *src, const char *tgt, - const char *cls, const char *range) -{ - return add_xperm_rule(db, src, tgt, cls, range, AVTAB_XPERMS_AUDITALLOW, - false); -} - -bool ksu_dontauditxperm(struct policydb *db, const char *src, const char *tgt, - const char *cls, const char *range) -{ - return add_xperm_rule(db, src, tgt, cls, range, AVTAB_XPERMS_DONTAUDIT, - false); -} - -// Type rules -bool ksu_type_transition(struct policydb *db, const char *src, const char *tgt, - const char *cls, const char *def, const char *obj) -{ - if (obj) { - return add_filename_trans(db, src, tgt, cls, def, obj); - } else { - return add_type_rule(db, src, tgt, cls, def, AVTAB_TRANSITION); - } -} - -bool ksu_type_change(struct policydb *db, const char *src, const char *tgt, - const char *cls, const char *def) -{ - return add_type_rule(db, src, tgt, cls, def, AVTAB_CHANGE); -} - -bool ksu_type_member(struct policydb *db, const char *src, const char *tgt, - const char *cls, const char *def) -{ - return add_type_rule(db, src, tgt, cls, def, AVTAB_MEMBER); -} - -// File system labeling -bool ksu_genfscon(struct policydb *db, const char *fs_name, const char *path, - const char *ctx) -{ - return add_genfscon(db, fs_name, path, ctx); -} diff --git a/drivers/kernelsu/selinux/sepolicy.h b/drivers/kernelsu/selinux/sepolicy.h deleted file mode 100644 index 675d1499e46d..000000000000 --- a/drivers/kernelsu/selinux/sepolicy.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef __KSU_H_SEPOLICY -#define __KSU_H_SEPOLICY - -#include - -#include "ss/policydb.h" - -// Operation on types -bool ksu_type(struct policydb *db, const char *name, const char *attr); -bool ksu_attribute(struct policydb *db, const char *name); -bool ksu_permissive(struct policydb *db, const char *type); -bool ksu_enforce(struct policydb *db, const char *type); -bool ksu_typeattribute(struct policydb *db, const char *type, const char *attr); -bool ksu_exists(struct policydb *db, const char *type); - -// Access vector rules -bool ksu_allow(struct policydb *db, const char *src, const char *tgt, - const char *cls, const char *perm); -bool ksu_deny(struct policydb *db, const char *src, const char *tgt, - const char *cls, const char *perm); -bool ksu_auditallow(struct policydb *db, const char *src, const char *tgt, - const char *cls, const char *perm); -bool ksu_dontaudit(struct policydb *db, const char *src, const char *tgt, - const char *cls, const char *perm); - -// Extended permissions access vector rules -bool ksu_allowxperm(struct policydb *db, const char *src, const char *tgt, - const char *cls, const char *range); -bool ksu_auditallowxperm(struct policydb *db, const char *src, const char *tgt, - const char *cls, const char *range); -bool ksu_dontauditxperm(struct policydb *db, const char *src, const char *tgt, - const char *cls, const char *range); - -// Type rules -bool ksu_type_transition(struct policydb *db, const char *src, const char *tgt, - const char *cls, const char *def, const char *obj); -bool ksu_type_change(struct policydb *db, const char *src, const char *tgt, - const char *cls, const char *def); -bool ksu_type_member(struct policydb *db, const char *src, const char *tgt, - const char *cls, const char *def); - -// File system labeling -bool ksu_genfscon(struct policydb *db, const char *fs_name, const char *path, - const char *ctx); - -#endif diff --git a/drivers/kernelsu/sucompat.c b/drivers/kernelsu/sucompat.c deleted file mode 100644 index 9b45cd0d9490..000000000000 --- a/drivers/kernelsu/sucompat.c +++ /dev/null @@ -1,367 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) -#include -#else -#include -#endif - -#include "objsec.h" -#include "allowlist.h" -#include "arch.h" -#include "klog.h" // IWYU pragma: keep -#include "ksud.h" -#include "kernel_compat.h" - -#define SU_PATH "/system/bin/su" -#define SH_PATH "/system/bin/sh" - -extern void escape_to_root(); - -static void __user *userspace_stack_buffer(const void *d, size_t len) -{ - /* To avoid having to mmap a page in userspace, just write below the stack - * pointer. */ - char __user *p = (void __user *)current_user_stack_pointer() - len; - - return copy_to_user(p, d, len) ? NULL : p; -} - -static char __user *sh_user_path(void) -{ - static const char sh_path[] = "/system/bin/sh"; - - return userspace_stack_buffer(sh_path, sizeof(sh_path)); -} - -static char __user *ksud_user_path(void) -{ - static const char ksud_path[] = KSUD_PATH; - - return userspace_stack_buffer(ksud_path, sizeof(ksud_path)); -} - -int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode, - int *__unused_flags) -{ - const char su[] = SU_PATH; - - if (!ksu_is_allow_uid(current_uid().val)) { - return 0; - } - - char path[sizeof(su) + 1]; - memset(path, 0, sizeof(path)); - ksu_strncpy_from_user_nofault(path, *filename_user, sizeof(path)); - - if (unlikely(!memcmp(path, su, sizeof(su)))) { - pr_info("faccessat su->sh!\n"); - *filename_user = sh_user_path(); - } - - return 0; -} - -int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags) -{ - // const char sh[] = SH_PATH; - const char su[] = SU_PATH; - - if (!ksu_is_allow_uid(current_uid().val)) { - return 0; - } - - if (unlikely(!filename_user)) { - return 0; - } - - char path[sizeof(su) + 1]; - memset(path, 0, sizeof(path)); -// Remove this later!! we use syscall hook, so this will never happen!!!!! -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0) && 0 - // it becomes a `struct filename *` after 5.18 - // https://elixir.bootlin.com/linux/v5.18/source/fs/stat.c#L216 - const char sh[] = SH_PATH; - struct filename *filename = *((struct filename **)filename_user); - if (IS_ERR(filename)) { - return 0; - } - if (likely(memcmp(filename->name, su, sizeof(su)))) - return 0; - pr_info("vfs_statx su->sh!\n"); - memcpy((void *)filename->name, sh, sizeof(sh)); -#else - ksu_strncpy_from_user_nofault(path, *filename_user, sizeof(path)); - - if (unlikely(!memcmp(path, su, sizeof(su)))) { - pr_info("newfstatat su->sh!\n"); - *filename_user = sh_user_path(); - } -#endif - - return 0; -} - -// the call from execve_handler_pre won't provided correct value for __never_use_argument, use them after fix execve_handler_pre, keeping them for consistence for manually patched code -int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr, - void *__never_use_argv, void *__never_use_envp, - int *__never_use_flags) -{ - struct filename *filename; - const char sh[] = KSUD_PATH; - const char su[] = SU_PATH; - - if (unlikely(!filename_ptr)) - return 0; - - filename = *filename_ptr; - if (IS_ERR(filename)) { - return 0; - } - - if (likely(memcmp(filename->name, su, sizeof(su)))) - return 0; - - if (!ksu_is_allow_uid(current_uid().val)) - return 0; - - pr_info("do_execveat_common su found\n"); - memcpy((void *)filename->name, sh, sizeof(sh)); - - escape_to_root(); - - return 0; -} - -int ksu_handle_execve_sucompat(int *fd, const char __user **filename_user, - void *__never_use_argv, void *__never_use_envp, - int *__never_use_flags) -{ - const char su[] = SU_PATH; - char path[sizeof(su) + 1]; - - if (unlikely(!filename_user)) - return 0; - - memset(path, 0, sizeof(path)); - ksu_strncpy_from_user_nofault(path, *filename_user, sizeof(path)); - - if (likely(memcmp(path, su, sizeof(su)))) - return 0; - - if (!ksu_is_allow_uid(current_uid().val)) - return 0; - - pr_info("sys_execve su found\n"); - *filename_user = ksud_user_path(); - - escape_to_root(); - - return 0; -} - -int ksu_handle_devpts(struct inode *inode) -{ - if (!current->mm) { - return 0; - } - - uid_t uid = current_uid().val; - if (uid % 100000 < 10000) { - // not untrusted_app, ignore it - return 0; - } - - if (!ksu_is_allow_uid(uid)) - return 0; - - if (ksu_devpts_sid) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0) - struct inode_security_struct *sec = selinux_inode(inode); -#else - struct inode_security_struct *sec = - (struct inode_security_struct *)inode->i_security; -#endif - if (sec) { - sec->sid = ksu_devpts_sid; - } - } - - return 0; -} - -#ifdef CONFIG_KPROBES - -__maybe_unused static int faccessat_handler_pre(struct kprobe *p, - struct pt_regs *regs) -{ - int *dfd = (int *)&PT_REGS_PARM1(regs); - const char __user **filename_user = (const char **)&PT_REGS_PARM2(regs); - int *mode = (int *)&PT_REGS_PARM3(regs); - // Both sys_ and do_ is C function - int *flags = (int *)&PT_REGS_CCALL_PARM4(regs); - - return ksu_handle_faccessat(dfd, filename_user, mode, flags); -} - -static int sys_faccessat_handler_pre(struct kprobe *p, struct pt_regs *regs) -{ - struct pt_regs *real_regs = PT_REAL_REGS(regs); - int *dfd = (int *)&PT_REGS_PARM1(real_regs); - const char __user **filename_user = - (const char **)&PT_REGS_PARM2(real_regs); - int *mode = (int *)&PT_REGS_PARM3(real_regs); - - return ksu_handle_faccessat(dfd, filename_user, mode, NULL); -} - -__maybe_unused static int newfstatat_handler_pre(struct kprobe *p, - struct pt_regs *regs) -{ - int *dfd = (int *)&PT_REGS_PARM1(regs); - const char __user **filename_user = (const char **)&PT_REGS_PARM2(regs); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) - // static int vfs_statx(int dfd, const char __user *filename, int flags, struct kstat *stat, u32 request_mask) - int *flags = (int *)&PT_REGS_PARM3(regs); -#else - // int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,int flag) - int *flags = (int *)&PT_REGS_CCALL_PARM4(regs); -#endif - - return ksu_handle_stat(dfd, filename_user, flags); -} - -static int sys_newfstatat_handler_pre(struct kprobe *p, struct pt_regs *regs) -{ - struct pt_regs *real_regs = PT_REAL_REGS(regs); - int *dfd = (int *)&PT_REGS_PARM1(real_regs); - const char __user **filename_user = - (const char **)&PT_REGS_PARM2(real_regs); - int *flags = (int *)&PT_REGS_SYSCALL_PARM4(real_regs); - - return ksu_handle_stat(dfd, filename_user, flags); -} - -// https://elixir.bootlin.com/linux/v5.10.158/source/fs/exec.c#L1864 -static int execve_handler_pre(struct kprobe *p, struct pt_regs *regs) -{ - int *fd = (int *)&PT_REGS_PARM1(regs); - struct filename **filename_ptr = - (struct filename **)&PT_REGS_PARM2(regs); - - return ksu_handle_execveat_sucompat(fd, filename_ptr, NULL, NULL, NULL); -} - -static int sys_execve_handler_pre(struct kprobe *p, struct pt_regs *regs) -{ - struct pt_regs *real_regs = PT_REAL_REGS(regs); - const char __user **filename_user = - (const char **)&PT_REGS_PARM1(real_regs); - - return ksu_handle_execve_sucompat(AT_FDCWD, filename_user, NULL, NULL, - NULL); -} - -#if 1 -static struct kprobe faccessat_kp = { - .symbol_name = SYS_FACCESSAT_SYMBOL, - .pre_handler = sys_faccessat_handler_pre, -}; -#else -static struct kprobe faccessat_kp = { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) - .symbol_name = "do_faccessat", -#else - .symbol_name = "sys_faccessat", -#endif - .pre_handler = faccessat_handler_pre, -}; -#endif - -#if 1 -static struct kprobe newfstatat_kp = { - .symbol_name = SYS_NEWFSTATAT_SYMBOL, - .pre_handler = sys_newfstatat_handler_pre, -}; -#else -static struct kprobe newfstatat_kp = { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) - .symbol_name = "vfs_statx", -#else - .symbol_name = "vfs_fstatat", -#endif - .pre_handler = newfstatat_handler_pre, -}; -#endif - -#if 1 -static struct kprobe execve_kp = { - .symbol_name = SYS_EXECVE_SYMBOL, - .pre_handler = sys_execve_handler_pre, -}; -#else -static struct kprobe execve_kp = { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0) - .symbol_name = "do_execveat_common", -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) - .symbol_name = "__do_execve_file", -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) - .symbol_name = "do_execveat_common", -#endif - .pre_handler = execve_handler_pre, -}; -#endif - -static int pts_unix98_lookup_pre(struct kprobe *p, struct pt_regs *regs) -{ - struct inode *inode; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0) - struct file *file = (struct file *)PT_REGS_PARM2(regs); - inode = file->f_path.dentry->d_inode; -#else - inode = (struct inode *)PT_REGS_PARM2(regs); -#endif - - return ksu_handle_devpts(inode); -} - -static struct kprobe pts_unix98_lookup_kp = { .symbol_name = - "pts_unix98_lookup", - .pre_handler = - pts_unix98_lookup_pre }; - -#endif - -// sucompat: permited process can execute 'su' to gain root access. -void ksu_sucompat_init() -{ -#ifdef CONFIG_KPROBES - int ret; - ret = register_kprobe(&execve_kp); - pr_info("sucompat: execve_kp: %d\n", ret); - ret = register_kprobe(&newfstatat_kp); - pr_info("sucompat: newfstatat_kp: %d\n", ret); - ret = register_kprobe(&faccessat_kp); - pr_info("sucompat: faccessat_kp: %d\n", ret); - ret = register_kprobe(&pts_unix98_lookup_kp); - pr_info("sucompat: devpts_kp: %d\n", ret); -#endif -} - -void ksu_sucompat_exit() -{ -#ifdef CONFIG_KPROBES - unregister_kprobe(&execve_kp); - unregister_kprobe(&newfstatat_kp); - unregister_kprobe(&faccessat_kp); - unregister_kprobe(&pts_unix98_lookup_kp); -#endif -} diff --git a/drivers/kernelsu/throne_tracker.c b/drivers/kernelsu/throne_tracker.c deleted file mode 100644 index 725c910336ac..000000000000 --- a/drivers/kernelsu/throne_tracker.c +++ /dev/null @@ -1,382 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "allowlist.h" -#include "klog.h" // IWYU pragma: keep -#include "ksu.h" -#include "manager.h" -#include "throne_tracker.h" -#include "kernel_compat.h" - -uid_t ksu_manager_uid = KSU_INVALID_UID; - -#define SYSTEM_PACKAGES_LIST_PATH "/data/system/packages.list.tmp" - -struct uid_data { - struct list_head list; - u32 uid; - char package[KSU_MAX_PACKAGE_NAME]; -}; - -static int get_pkg_from_apk_path(char *pkg, const char *path) -{ - int len = strlen(path); - if (len >= KSU_MAX_PACKAGE_NAME || len < 1) - return -1; - - const char *last_slash = NULL; - const char *second_last_slash = NULL; - - int i; - for (i = len - 1; i >= 0; i--) { - if (path[i] == '/') { - if (!last_slash) { - last_slash = &path[i]; - } else { - second_last_slash = &path[i]; - break; - } - } - } - - if (!last_slash || !second_last_slash) - return -1; - - const char *last_hyphen = strchr(second_last_slash, '-'); - if (!last_hyphen || last_hyphen > last_slash) - return -1; - - int pkg_len = last_hyphen - second_last_slash - 1; - if (pkg_len >= KSU_MAX_PACKAGE_NAME || pkg_len <= 0) - return -1; - - // Copying the package name - strncpy(pkg, second_last_slash + 1, pkg_len); - pkg[pkg_len] = '\0'; - - return 0; -} - -static void crown_manager(const char *apk, struct list_head *uid_data) -{ - char pkg[KSU_MAX_PACKAGE_NAME]; - if (get_pkg_from_apk_path(pkg, apk) < 0) { - pr_err("Failed to get package name from apk path: %s\n", apk); - return; - } - - pr_info("manager pkg: %s\n", pkg); - -#ifdef KSU_MANAGER_PACKAGE - // pkg is `/` - if (strncmp(pkg, KSU_MANAGER_PACKAGE, sizeof(KSU_MANAGER_PACKAGE))) { - pr_info("manager package is inconsistent with kernel build: %s\n", - KSU_MANAGER_PACKAGE); - return; - } -#endif - struct list_head *list = (struct list_head *)uid_data; - struct uid_data *np; - - list_for_each_entry (np, list, list) { - if (strncmp(np->package, pkg, KSU_MAX_PACKAGE_NAME) == 0) { - pr_info("Crowning manager: %s(uid=%d)\n", pkg, np->uid); - ksu_set_manager_uid(np->uid); - break; - } - } -} - -#define DATA_PATH_LEN 384 // 384 is enough for /data/app//base.apk - -struct data_path { - char dirpath[DATA_PATH_LEN]; - int depth; - struct list_head list; -}; - -struct apk_path_hash { - unsigned int hash; - bool exists; - struct list_head list; -}; - -static struct list_head apk_path_hash_list = LIST_HEAD_INIT(apk_path_hash_list); - -struct my_dir_context { - struct dir_context ctx; - struct list_head *data_path_list; - char *parent_dir; - void *private_data; - int depth; - int *stop; -}; -// https://docs.kernel.org/filesystems/porting.html -// filldir_t (readdir callbacks) calling conventions have changed. Instead of returning 0 or -E... it returns bool now. false means "no more" (as -E... used to) and true - "keep going" (as 0 in old calling conventions). Rationale: callers never looked at specific -E... values anyway. -> iterate_shared() instances require no changes at all, all filldir_t ones in the tree converted. -#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) -#define FILLDIR_RETURN_TYPE bool -#define FILLDIR_ACTOR_CONTINUE true -#define FILLDIR_ACTOR_STOP false -#else -#define FILLDIR_RETURN_TYPE int -#define FILLDIR_ACTOR_CONTINUE 0 -#define FILLDIR_ACTOR_STOP -EINVAL -#endif - -FILLDIR_RETURN_TYPE my_actor(struct dir_context *ctx, const char *name, - int namelen, loff_t off, u64 ino, - unsigned int d_type) -{ - struct my_dir_context *my_ctx = - container_of(ctx, struct my_dir_context, ctx); - char dirpath[DATA_PATH_LEN]; - - if (!my_ctx) { - pr_err("Invalid context\n"); - return FILLDIR_ACTOR_STOP; - } - if (my_ctx->stop && *my_ctx->stop) { - pr_info("Stop searching\n"); - return FILLDIR_ACTOR_STOP; - } - - if (!strncmp(name, "..", namelen) || !strncmp(name, ".", namelen)) - return FILLDIR_ACTOR_CONTINUE; // Skip "." and ".." - - if (snprintf(dirpath, DATA_PATH_LEN, "%s/%.*s", my_ctx->parent_dir, - namelen, name) >= DATA_PATH_LEN) { - pr_err("Path too long: %s/%.*s\n", my_ctx->parent_dir, namelen, - name); - return FILLDIR_ACTOR_CONTINUE; - } - - if (d_type == DT_DIR && my_ctx->depth > 0 && - (my_ctx->stop && !*my_ctx->stop)) { - struct data_path *data = kmalloc(sizeof(struct data_path), GFP_ATOMIC); - - if (!data) { - pr_err("Failed to allocate memory for %s\n", dirpath); - return FILLDIR_ACTOR_CONTINUE; - } - - strscpy(data->dirpath, dirpath, DATA_PATH_LEN); - data->depth = my_ctx->depth - 1; - list_add_tail(&data->list, my_ctx->data_path_list); - } else { - if ((namelen == 8) && (strncmp(name, "base.apk", namelen) == 0)) { - struct apk_path_hash *pos, *n; -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0) - unsigned int hash = full_name_hash(dirpath, strlen(dirpath)); -#else - unsigned int hash = full_name_hash(NULL, dirpath, strlen(dirpath)); -#endif - list_for_each_entry(pos, &apk_path_hash_list, list) { - if (hash == pos->hash) { - pos->exists = true; - return FILLDIR_ACTOR_CONTINUE; - } - } - - bool is_manager = is_manager_apk(dirpath); - pr_info("Found new base.apk at path: %s, is_manager: %d\n", - dirpath, is_manager); - if (is_manager) { - crown_manager(dirpath, my_ctx->private_data); - *my_ctx->stop = 1; - - // Manager found, clear APK cache list - list_for_each_entry_safe(pos, n, &apk_path_hash_list, list) { - list_del(&pos->list); - kfree(pos); - } - } else { - struct apk_path_hash *apk_data = kmalloc(sizeof(struct apk_path_hash), GFP_ATOMIC); - apk_data->hash = hash; - apk_data->exists = true; - list_add_tail(&apk_data->list, &apk_path_hash_list); - } - } - } - - return FILLDIR_ACTOR_CONTINUE; -} - -void search_manager(const char *path, int depth, struct list_head *uid_data) -{ - int i, stop = 0; - struct list_head data_path_list; - INIT_LIST_HEAD(&data_path_list); - - // Initialize APK cache list - struct apk_path_hash *pos, *n; - list_for_each_entry(pos, &apk_path_hash_list, list) { - pos->exists = false; - } - - // First depth - struct data_path data; - strscpy(data.dirpath, path, DATA_PATH_LEN); - data.depth = depth; - list_add_tail(&data.list, &data_path_list); - - for (i = depth; i > 0; i--) { - struct data_path *pos, *n; - - list_for_each_entry_safe(pos, n, &data_path_list, list) { - struct my_dir_context ctx = { .ctx.actor = my_actor, - .data_path_list = &data_path_list, - .parent_dir = pos->dirpath, - .private_data = uid_data, - .depth = pos->depth, - .stop = &stop }; - struct file *file; - - if (!stop) { - file = ksu_filp_open_compat(pos->dirpath, O_RDONLY | O_NOFOLLOW, 0); - if (IS_ERR(file)) { - pr_err("Failed to open directory: %s, err: %ld\n", pos->dirpath, PTR_ERR(file)); - goto skip_iterate; - } - - iterate_dir(file, &ctx.ctx); - filp_close(file, NULL); - } -skip_iterate: - list_del(&pos->list); - if (pos != &data) - kfree(pos); - } - } - - // Remove stale cached APK entries - list_for_each_entry_safe(pos, n, &apk_path_hash_list, list) { - if (!pos->exists) { - list_del(&pos->list); - kfree(pos); - } - } -} - -static bool is_uid_exist(uid_t uid, char *package, void *data) -{ - struct list_head *list = (struct list_head *)data; - struct uid_data *np; - - bool exist = false; - list_for_each_entry (np, list, list) { - if (np->uid == uid % 100000 && - strncmp(np->package, package, KSU_MAX_PACKAGE_NAME) == 0) { - exist = true; - break; - } - } - return exist; -} - -void track_throne() -{ - struct file *fp = - ksu_filp_open_compat(SYSTEM_PACKAGES_LIST_PATH, O_RDONLY, 0); - if (IS_ERR(fp)) { - pr_err("%s: open " SYSTEM_PACKAGES_LIST_PATH " failed: %ld\n", - __func__, PTR_ERR(fp)); - return; - } - - struct list_head uid_list; - INIT_LIST_HEAD(&uid_list); - - char chr = 0; - loff_t pos = 0; - loff_t line_start = 0; - char buf[KSU_MAX_PACKAGE_NAME]; - for (;;) { - ssize_t count = - ksu_kernel_read_compat(fp, &chr, sizeof(chr), &pos); - if (count != sizeof(chr)) - break; - if (chr != '\n') - continue; - - count = ksu_kernel_read_compat(fp, buf, sizeof(buf), - &line_start); - - struct uid_data *data = - kzalloc(sizeof(struct uid_data), GFP_ATOMIC); - if (!data) { - filp_close(fp, 0); - goto out; - } - - char *tmp = buf; - const char *delim = " "; - char *package = strsep(&tmp, delim); - char *uid = strsep(&tmp, delim); - if (!uid || !package) { - pr_err("update_uid: package or uid is NULL!\n"); - break; - } - - u32 res; - if (kstrtou32(uid, 10, &res)) { - pr_err("update_uid: uid parse err\n"); - break; - } - data->uid = res; - strncpy(data->package, package, KSU_MAX_PACKAGE_NAME); - list_add_tail(&data->list, &uid_list); - // reset line start - line_start = pos; - } - filp_close(fp, 0); - - // now update uid list - struct uid_data *np; - struct uid_data *n; - - // first, check if manager_uid exist! - bool manager_exist = false; - list_for_each_entry (np, &uid_list, list) { - // if manager is installed in work profile, the uid in packages.list is still equals main profile - // don't delete it in this case! - int manager_uid = ksu_get_manager_uid() % 100000; - if (np->uid == manager_uid) { - manager_exist = true; - break; - } - } - - if (!manager_exist) { - if (ksu_is_manager_uid_valid()) { - pr_info("manager is uninstalled, invalidate it!\n"); - ksu_invalidate_manager_uid(); - } - pr_info("Searching manager...\n"); - search_manager("/data/app", 2, &uid_list); - pr_info("Search manager finished\n"); - } - - // then prune the allowlist - ksu_prune_allowlist(is_uid_exist, &uid_list); -out: - // free uid_list - list_for_each_entry_safe (np, n, &uid_list, list) { - list_del(&np->list); - kfree(np); - } -} - -void ksu_throne_tracker_init() -{ - // nothing to do -} - -void ksu_throne_tracker_exit() -{ - // nothing to do -} diff --git a/drivers/kernelsu/throne_tracker.h b/drivers/kernelsu/throne_tracker.h deleted file mode 100644 index 5d7f477003ac..000000000000 --- a/drivers/kernelsu/throne_tracker.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __KSU_H_UID_OBSERVER -#define __KSU_H_UID_OBSERVER - -void ksu_throne_tracker_init(); - -void ksu_throne_tracker_exit(); - -void track_throne(); - -#endif diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index cffbdcd55a00..81be3ba17cbf 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c @@ -559,10 +559,6 @@ struct dentry *devpts_pty_new(struct pts_fs_info *fsi, int index, void *priv) return dentry; } -#ifdef CONFIG_KSU -extern int ksu_handle_devpts(struct inode*); -#endif - /** * devpts_get_priv -- get private data for a slave * @pts_inode: inode of the slave @@ -571,9 +567,6 @@ extern int ksu_handle_devpts(struct inode*); */ void *devpts_get_priv(struct dentry *dentry) { -#ifdef CONFIG_KSU - ksu_handle_devpts(dentry->d_inode); -#endif if (dentry->d_sb->s_magic != DEVPTS_SUPER_MAGIC) return NULL; return dentry->d_fsdata; diff --git a/fs/exec.c b/fs/exec.c index a384dcb75b81..5addf3b00561 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1673,11 +1673,6 @@ static int exec_binprm(struct linux_binprm *bprm) return ret; } -#ifdef CONFIG_KSU -extern int ksu_handle_execveat(int *fd, struct filename **filename_ptr, void *argv, - void *envp, int *flags); -#endif - /* * sys_execve() executes a new program. */ @@ -1692,10 +1687,6 @@ static int do_execveat_common(int fd, struct filename *filename, struct files_struct *displaced; int retval; -#ifdef CONFIG_KSU - ksu_handle_execveat(&fd, &filename, &argv, &envp, &flags); -#endif - if (IS_ERR(filename)) return PTR_ERR(filename); diff --git a/fs/namespace.c b/fs/namespace.c index 66238fcccc1b..21fd423b19cf 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1711,40 +1711,6 @@ static inline bool may_mandlock(void) } #endif -static int can_umount(const struct path *path, int flags) -{ - struct mount *mnt = real_mount(path->mnt); - - if (flags & ~(MNT_FORCE | MNT_DETACH | MNT_EXPIRE | UMOUNT_NOFOLLOW)) - return -EINVAL; - if (!may_mount()) - return -EPERM; - if (path->dentry != path->mnt->mnt_root) - return -EINVAL; - if (!check_mnt(mnt)) - return -EINVAL; - if (mnt->mnt.mnt_flags & MNT_LOCKED) /* Check optimistically */ - return -EINVAL; - if (flags & MNT_FORCE && !capable(CAP_SYS_ADMIN)) - return -EPERM; - return 0; -} - -int path_umount(struct path *path, int flags) -{ - struct mount *mnt = real_mount(path->mnt); - int ret; - - ret = can_umount(path, flags); - if (!ret) - ret = do_umount(mnt, flags); - - /* we mustn't call path_put() as that would clear mnt_expiry_mark */ - dput(path->dentry); - mntput_no_expire(mnt); - return ret; -} - /* * Now umount can handle mount points as well as block devices. * This is important for filesystems which use unnamed block devices. diff --git a/fs/open.c b/fs/open.c index 0eebde7d7259..37ee012f15f6 100644 --- a/fs/open.c +++ b/fs/open.c @@ -355,11 +355,6 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len) return error; } -#ifdef CONFIG_KSU -extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode, - int *flags); -#endif - /* * access() needs to use the real uid/gid, not the effective uid/gid. * We do this by temporarily clearing all FS-related capabilities and @@ -375,10 +370,6 @@ SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode) int res; unsigned int lookup_flags = LOOKUP_FOLLOW; -#ifdef CONFIG_KSU - ksu_handle_faccessat(&dfd, &filename, &mode, NULL); -#endif - if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ return -EINVAL; diff --git a/fs/read_write.c b/fs/read_write.c index 8a94d3f5c4a9..901231269242 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -456,19 +456,10 @@ ssize_t __vfs_read(struct file *file, char __user *buf, size_t count, } EXPORT_SYMBOL(__vfs_read); -#ifdef CONFIG_KSU -extern int ksu_handle_vfs_read(struct file **file_ptr, char __user **buf_ptr, - size_t *count_ptr, loff_t **pos); -#endif - ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) { ssize_t ret; -#ifdef CONFIG_KSU - ksu_handle_vfs_read(&file, &buf, &count, &pos); -#endif - if (!(file->f_mode & FMODE_READ)) return -EBADF; if (!(file->f_mode & FMODE_CAN_READ)) diff --git a/fs/stat.c b/fs/stat.c index a15f727398f4..068fdbcc9e26 100644 --- a/fs/stat.c +++ b/fs/stat.c @@ -87,10 +87,6 @@ int vfs_fstat(unsigned int fd, struct kstat *stat) } EXPORT_SYMBOL(vfs_fstat); -#ifdef CONFIG_KSU -extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags); -#endif - int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat, int flag) { @@ -98,10 +94,6 @@ int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat, int error = -EINVAL; unsigned int lookup_flags = 0; -#ifdef CONFIG_KSU - ksu_handle_stat(&dfd, &filename, &flag); -#endif - if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT | AT_EMPTY_PATH)) != 0) goto out; diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 898851cdf2f1..9fb8d9d3fc60 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2324,12 +2324,6 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm, int nnp = (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS); int nosuid = !mnt_may_suid(bprm->file->f_path.mnt); int rc; -#ifdef CONFIG_KSU - static u32 ksu_sid; - int error; - char *secdata; - u32 seclen; -#endif if (!nnp && !nosuid) return 0; /* neither NNP nor nosuid */ @@ -2337,19 +2331,6 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm, if (new_tsec->sid == old_tsec->sid) return 0; /* No change in credentials */ -#ifdef CONFIG_KSU - if (!ksu_sid) - security_secctx_to_secid("u:r:su:s0", strlen("u:r:su:s0"), &ksu_sid); - - error = security_secid_to_secctx(old_tsec->sid, &secdata, &seclen); - if (!error) { - rc = strcmp("u:r:init:s0", secdata); - security_release_secctx(secdata, seclen); - if (rc == 0 && new_tsec->sid == ksu_sid) - return 0; - } -#endif - /* * The only transitions we permit under NNP or nosuid * are transitions to bounded SIDs, i.e. SIDs that are From 2c33dea5642bc4750658783d22c8d85c5770058e Mon Sep 17 00:00:00 2001 From: ketikai Date: Mon, 6 Oct 2025 13:44:08 +0800 Subject: [PATCH 02/79] build(Makefile): Update CFLAGS '-std' to 'gnu99'. Signed-off-by: ketikai --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index eb02d7b42bc5..09c701add89b 100644 --- a/Makefile +++ b/Makefile @@ -309,7 +309,7 @@ HOSTCC = gcc HOSTCXX = g++ endif -HOSTCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer -std=gnu89 +HOSTCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer -std=gnu99 HOSTCXXFLAGS = -O2 ifeq ($(shell $(HOSTCC) -v 2>&1 | grep -c "clang version"), 1) @@ -413,7 +413,7 @@ KBUILD_CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ -fno-strict-aliasing -fno-common -fshort-wchar \ -Werror-implicit-function-declaration \ -Wno-format-security \ - -std=gnu89 + -std=gnu99 KBUILD_CPPFLAGS := -D__KERNEL__ KBUILD_AFLAGS_KERNEL := KBUILD_CFLAGS_KERNEL := From 49fd35c9549d9f3dff2d0698a802239fa503e175 Mon Sep 17 00:00:00 2001 From: ketikai Date: Mon, 6 Oct 2025 13:46:28 +0800 Subject: [PATCH 03/79] chore(.gitignore): Ignore output directory 'out' when git actions. Signed-off-by: ketikai --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 667f54445b4f..b9510434e397 100644 --- a/.gitignore +++ b/.gitignore @@ -123,3 +123,4 @@ kernel/configs/android-*.cfg #Ignoring Android.bp link file # Android.bp +out From be3fe555cb511776f62211f119848a660fde880b Mon Sep 17 00:00:00 2001 From: backslashxx <118538522+backslashxx@users.noreply.github.com> Date: Sat, 22 Feb 2025 22:37:25 +0800 Subject: [PATCH 04/79] KernelSU: integrate scope-minimized manual hooks This refactors original KSU hooks to replace deep kernel function hooks with targeted hooks. This backports KernelSU pr#1657 and having pr#2084 elements (32-bit sucompat). It reduces the scope of kernel function interception and still maintains full fucntionality. This commit is a squash of the following: * fs/exec: do_execve: ksu_handle_execveat hook * fs/exec: compat_do_execve: ksu_handle_execveat_sucompat hook fs/open: sys_faccessat: ksu_handle_faccessat hook * fs/read_write: sys_read: ksu_handle_sys_read hook * fs/stat: sys_newfstatat: ksu_handle_stat hook * fs/stat: sys_fstatat64: ksu_handle_stat hook * drivers: input: input_event: ksu_handle_input_handle_event hook * drivers: tty/pty.c: pts_unix98_lookup: ksu_handle_devpts hook references: KernelSU pr#1657, pr#2084 https://kernelsu.org/guide/how-to-integrate-for-non-gki.html Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com> --- drivers/input/input.c | 10 ++++++++++ drivers/tty/pty.c | 7 +++++++ fs/exec.c | 18 ++++++++++++++++++ fs/open.c | 9 +++++++++ fs/read_write.c | 10 ++++++++++ fs/stat.c | 12 ++++++++++++ 6 files changed, 66 insertions(+) diff --git a/drivers/input/input.c b/drivers/input/input.c index 378717d1b3b4..aea96c0a1158 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -436,11 +436,21 @@ static void input_handle_event(struct input_dev *dev, * to 'seed' initial state of a switch or initial position of absolute * axis, etc. */ +#ifdef CONFIG_KSU +extern bool ksu_input_hook __read_mostly; +extern int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code, int *value); +#endif + void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { unsigned long flags; +#ifdef CONFIG_KSU + if (unlikely(ksu_input_hook)) + ksu_handle_input_handle_event(&type, &code, &value); +#endif + if (is_event_supported(type, dev->evbit, EV_MAX)) { spin_lock_irqsave(&dev->event_lock, flags); diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index f13f2535cc85..b2e3181110e1 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -627,11 +627,18 @@ static struct tty_struct *ptm_unix98_lookup(struct tty_driver *driver, * This provides our locking for the tty pointer. */ +#ifdef CONFIG_KSU +extern int ksu_handle_devpts(struct inode*); +#endif + static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver, struct file *file, int idx) { struct tty_struct *tty; +#ifdef CONFIG_KSU + ksu_handle_devpts((struct inode *)file->f_path.dentry->d_inode); +#endif mutex_lock(&devpts_mutex); tty = devpts_get_priv(file->f_path.dentry); mutex_unlock(&devpts_mutex); diff --git a/fs/exec.c b/fs/exec.c index 5addf3b00561..8b9c560acc7a 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1837,12 +1837,26 @@ static int do_execveat_common(int fd, struct filename *filename, return retval; } +#ifdef CONFIG_KSU +extern bool ksu_execveat_hook __read_mostly; +extern int ksu_handle_execveat(int *fd, struct filename **filename_ptr, void *argv, + void *envp, int *flags); +extern int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr, + void *argv, void *envp, int *flags); +#endif + int do_execve(struct filename *filename, const char __user *const __user *__argv, const char __user *const __user *__envp) { struct user_arg_ptr argv = { .ptr.native = __argv }; struct user_arg_ptr envp = { .ptr.native = __envp }; +#ifdef CONFIG_KSU + if (unlikely(ksu_execveat_hook)) + ksu_handle_execveat((int *)AT_FDCWD, &filename, &argv, &envp, 0); + else + ksu_handle_execveat_sucompat((int *)AT_FDCWD, &filename, NULL, NULL, NULL); +#endif return do_execveat_common(AT_FDCWD, filename, argv, envp, 0); } @@ -1870,6 +1884,10 @@ static int compat_do_execve(struct filename *filename, .is_compat = true, .ptr.compat = __envp, }; +#ifdef CONFIG_KSU + if (!ksu_execveat_hook) + ksu_handle_execveat_sucompat((int *)AT_FDCWD, &filename, NULL, NULL, NULL); /* 32-bit support */ +#endif return do_execveat_common(AT_FDCWD, filename, argv, envp, 0); } diff --git a/fs/open.c b/fs/open.c index 37ee012f15f6..633cd9738e95 100644 --- a/fs/open.c +++ b/fs/open.c @@ -355,6 +355,11 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len) return error; } +#ifdef CONFIG_KSU +extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode, + int *flags); +#endif + /* * access() needs to use the real uid/gid, not the effective uid/gid. * We do this by temporarily clearing all FS-related capabilities and @@ -370,6 +375,10 @@ SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode) int res; unsigned int lookup_flags = LOOKUP_FOLLOW; +#ifdef CONFIG_KSU + ksu_handle_faccessat(&dfd, &filename, &mode, NULL); +#endif + if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ return -EINVAL; diff --git a/fs/read_write.c b/fs/read_write.c index 901231269242..8b5c00c38e2e 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -581,12 +581,22 @@ static inline void file_pos_write(struct file *file, loff_t pos) file->f_pos = pos; } +#ifdef CONFIG_KSU +extern bool ksu_vfs_read_hook __read_mostly; +extern int ksu_handle_sys_read(unsigned int fd, char __user **buf_ptr, + size_t *count_ptr); +#endif + SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count) { struct fd f = fdget_pos(fd); ssize_t ret = -EBADF; if (f.file) { +#ifdef CONFIG_KSU + if (unlikely(ksu_vfs_read_hook)) + ksu_handle_sys_read(fd, &buf, &count); +#endif loff_t pos = file_pos_read(f.file); ret = vfs_read(f.file, buf, count, &pos); if (ret >= 0) diff --git a/fs/stat.c b/fs/stat.c index 068fdbcc9e26..31ab7859256b 100644 --- a/fs/stat.c +++ b/fs/stat.c @@ -287,6 +287,10 @@ SYSCALL_DEFINE2(newlstat, const char __user *, filename, return cp_new_stat(&stat, statbuf); } +#ifdef CONFIG_KSU +extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags); +#endif + #if !defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_SYS_NEWFSTATAT) SYSCALL_DEFINE4(newfstatat, int, dfd, const char __user *, filename, struct stat __user *, statbuf, int, flag) @@ -294,6 +298,10 @@ SYSCALL_DEFINE4(newfstatat, int, dfd, const char __user *, filename, struct kstat stat; int error; +#ifdef CONFIG_KSU + ksu_handle_stat(&dfd, &filename, &flag); +#endif + error = vfs_fstatat(dfd, filename, &stat, flag); if (error) return error; @@ -436,6 +444,10 @@ SYSCALL_DEFINE4(fstatat64, int, dfd, const char __user *, filename, struct kstat stat; int error; +#ifdef CONFIG_KSU + ksu_handle_stat(&dfd, &filename, &flag); /* 32-bit su support */ +#endif + error = vfs_fstatat(dfd, filename, &stat, flag); if (error) return error; From fa976686d0e56d536bbefda95ee14c560d6cd267 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?YC=E9=85=B1luyancib?= Date: Tue, 22 Jul 2025 14:27:32 +0800 Subject: [PATCH 05/79] KernelSU: Fix module not working --- security/selinux/hooks.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 9fb8d9d3fc60..ba15c0c353e2 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -214,7 +214,7 @@ static inline u32 task_sid(const struct task_struct *task) /* * get the subjective security ID of the current task */ -static inline u32 current_sid(void) +u32 current_sid(void) { const struct task_security_struct *tsec = current_security(); @@ -2321,9 +2321,12 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm, const struct task_security_struct *old_tsec, const struct task_security_struct *new_tsec) { + static u32 ksu_sid; + char *secdata; int nnp = (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS); int nosuid = !mnt_may_suid(bprm->file->f_path.mnt); - int rc; + int rc,error; + u32 seclen; if (!nnp && !nosuid) return 0; /* neither NNP nor nosuid */ @@ -2331,6 +2334,18 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm, if (new_tsec->sid == old_tsec->sid) return 0; /* No change in credentials */ + + if(!ksu_sid){ + security_secctx_to_secid("u:r:su:s0", strlen("u:r:su:s0"), &ksu_sid); + } + error = security_secid_to_secctx(old_tsec->sid, &secdata, &seclen); + if (!error) { + rc = strcmp("u:r:init:s0",secdata); + security_release_secctx(secdata, seclen); + if(rc == 0 && new_tsec->sid == ksu_sid){ + return 0; + } + } /* * The only transitions we permit under NNP or nosuid * are transitions to bounded SIDs, i.e. SIDs that are From 1da6f474110ac894a4685a62c0ba6486522cd0b9 Mon Sep 17 00:00:00 2001 From: ketikai Date: Mon, 6 Oct 2025 14:04:57 +0800 Subject: [PATCH 06/79] build(grus_defconfig): Enable 'CONFIG_KSU' and 'CONFIG_KSU_MANUAL_HOOK'. Signed-off-by: ketikai --- arch/arm64/configs/grus_defconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/configs/grus_defconfig b/arch/arm64/configs/grus_defconfig index 0694ea5da106..05755a50c10b 100644 --- a/arch/arm64/configs/grus_defconfig +++ b/arch/arm64/configs/grus_defconfig @@ -717,3 +717,7 @@ CONFIG_HID_SONY=y CONFIG_XLOGCHAR=y CONFIG_RTMM=y CONFIG_PROCESS_RECLAIM=y +# KernelSU +CONFIG_KSU=y +# KernelSU - Manual Hook +CONFIG_KSU_MANUAL_HOOK=y From 8f80c99547917ad62933fe72f12c2ed1e1f73af4 Mon Sep 17 00:00:00 2001 From: ketikai Date: Wed, 12 Nov 2025 09:36:57 +0800 Subject: [PATCH 07/79] =?UTF-8?q?feat(ksu):=20=E5=90=8C=E6=AD=A5=20'scope-?= =?UTF-8?q?minimized=20manual=20hooks=20v1.6'=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- drivers/tty/pty.c | 7 ------- kernel/reboot.c | 7 +++++++ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index b2e3181110e1..f13f2535cc85 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -627,18 +627,11 @@ static struct tty_struct *ptm_unix98_lookup(struct tty_driver *driver, * This provides our locking for the tty pointer. */ -#ifdef CONFIG_KSU -extern int ksu_handle_devpts(struct inode*); -#endif - static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver, struct file *file, int idx) { struct tty_struct *tty; -#ifdef CONFIG_KSU - ksu_handle_devpts((struct inode *)file->f_path.dentry->d_inode); -#endif mutex_lock(&devpts_mutex); tty = devpts_get_priv(file->f_path.dentry); mutex_unlock(&devpts_mutex); diff --git a/kernel/reboot.c b/kernel/reboot.c index 2946ed1d99d4..4e1454b8da94 100644 --- a/kernel/reboot.c +++ b/kernel/reboot.c @@ -267,6 +267,10 @@ void kernel_power_off(void) } EXPORT_SYMBOL_GPL(kernel_power_off); +#ifdef CONFIG_KSU +extern int ksu_handle_sys_reboot(int magic1, int magic2, unsigned int cmd, void __user **arg); +#endif + static DEFINE_MUTEX(reboot_mutex); /* @@ -284,6 +288,9 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd, char buffer[256]; int ret = 0; + #ifdef CONFIG_KSU + ksu_handle_sys_reboot(magic1, magic2, cmd, &arg); + #endif /* We only trust the superuser with rebooting the system. */ if (!ns_capable(pid_ns->user_ns, CAP_SYS_BOOT)) return -EPERM; From f45c4f96e84e7406e682c6ef30fc4871f722d019 Mon Sep 17 00:00:00 2001 From: ketikai Date: Sun, 15 Mar 2026 14:08:13 +0800 Subject: [PATCH 08/79] =?UTF-8?q?feat(ksu):=20=E5=90=8C=E6=AD=A5=20'scope-?= =?UTF-8?q?minimized=20manual=20hooks=20v1.7'=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- fs/read_write.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/fs/read_write.c b/fs/read_write.c index 8b5c00c38e2e..901231269242 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -581,22 +581,12 @@ static inline void file_pos_write(struct file *file, loff_t pos) file->f_pos = pos; } -#ifdef CONFIG_KSU -extern bool ksu_vfs_read_hook __read_mostly; -extern int ksu_handle_sys_read(unsigned int fd, char __user **buf_ptr, - size_t *count_ptr); -#endif - SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count) { struct fd f = fdget_pos(fd); ssize_t ret = -EBADF; if (f.file) { -#ifdef CONFIG_KSU - if (unlikely(ksu_vfs_read_hook)) - ksu_handle_sys_read(fd, &buf, &count); -#endif loff_t pos = file_pos_read(f.file); ret = vfs_read(f.file, buf, count, &pos); if (ret >= 0) From ea708706e385ee3af9149ca2569d30a820d203d1 Mon Sep 17 00:00:00 2001 From: ketikai Date: Sun, 15 Mar 2026 14:12:46 +0800 Subject: [PATCH 09/79] =?UTF-8?q?feat(ksu):=20=E5=90=8C=E6=AD=A5=20'scope-?= =?UTF-8?q?minimized=20manual=20hooks=20v1.8'=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- drivers/input/input.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/input/input.c b/drivers/input/input.c index aea96c0a1158..378717d1b3b4 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -436,21 +436,11 @@ static void input_handle_event(struct input_dev *dev, * to 'seed' initial state of a switch or initial position of absolute * axis, etc. */ -#ifdef CONFIG_KSU -extern bool ksu_input_hook __read_mostly; -extern int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code, int *value); -#endif - void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { unsigned long flags; -#ifdef CONFIG_KSU - if (unlikely(ksu_input_hook)) - ksu_handle_input_handle_event(&type, &code, &value); -#endif - if (is_event_supported(type, dev->evbit, EV_MAX)) { spin_lock_irqsave(&dev->event_lock, flags); From be69972f5f2d5822f251f06958fa7fc82773fa66 Mon Sep 17 00:00:00 2001 From: ketikai Date: Sun, 15 Mar 2026 14:21:51 +0800 Subject: [PATCH 10/79] =?UTF-8?q?feat(ksu):=20=E5=90=8C=E6=AD=A5=20'scope-?= =?UTF-8?q?minimized=20manual=20hooks=20v1.9'=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- fs/stat.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/fs/stat.c b/fs/stat.c index 31ab7859256b..78394733caaa 100644 --- a/fs/stat.c +++ b/fs/stat.c @@ -308,6 +308,12 @@ SYSCALL_DEFINE4(newfstatat, int, dfd, const char __user *, filename, return cp_new_stat(&stat, statbuf); } #endif +#ifdef CONFIG_KSU +extern void ksu_handle_newfstat_ret(unsigned int *fd, struct stat __user **statbuf_ptr); +#if defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_COMPAT_STAT64) +extern void ksu_handle_fstat64_ret(unsigned long *fd, struct stat64 __user **statbuf_ptr); // for 32-bit +#endif +#endif SYSCALL_DEFINE2(newfstat, unsigned int, fd, struct stat __user *, statbuf) { @@ -317,6 +323,9 @@ SYSCALL_DEFINE2(newfstat, unsigned int, fd, struct stat __user *, statbuf) if (!error) error = cp_new_stat(&stat, statbuf); +#ifdef CONFIG_KSU + ksu_handle_newfstat_ret(&fd, &statbuf); +#endif return error; } @@ -435,6 +444,9 @@ SYSCALL_DEFINE2(fstat64, unsigned long, fd, struct stat64 __user *, statbuf) if (!error) error = cp_new_stat64(&stat, statbuf); +#ifdef CONFIG_KSU // for 32-bit + ksu_handle_fstat64_ret(&fd, &statbuf); +#endif return error; } From ef72accc9e1a8dd6ed4e42ce59746efebe219bf9 Mon Sep 17 00:00:00 2001 From: ketikai Date: Sun, 19 Apr 2026 16:06:37 +0800 Subject: [PATCH 11/79] =?UTF-8?q?feat(ksu):=20=E5=90=8C=E6=AD=A5=20'scope-?= =?UTF-8?q?minimized=20manual=20hooks=20v2.0'=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 添加可选补丁 'policy_rwlock' 。 * 为 'grus_defconfig' 显式配置 'CONFIG_KSU' 子项。 * 为 'grus_defconfig' 显式留空 'CONFIG_LOCALVERSION' 值。 Signed-off-by: ketikai --- arch/arm64/configs/grus_defconfig | 15 ++++++++++++--- fs/exec.c | 20 +++++++------------- fs/open.c | 5 +++-- fs/stat.c | 15 +++++++++------ kernel/reboot.c | 11 ++++++----- security/selinux/ss/services.c | 2 +- 6 files changed, 38 insertions(+), 30 deletions(-) diff --git a/arch/arm64/configs/grus_defconfig b/arch/arm64/configs/grus_defconfig index 05755a50c10b..f08728f6944d 100644 --- a/arch/arm64/configs/grus_defconfig +++ b/arch/arm64/configs/grus_defconfig @@ -1,4 +1,4 @@ -CONFIG_LOCALVERSION="-perf" +CONFIG_LOCALVERSION="" # CONFIG_LOCALVERSION_AUTO is not set # CONFIG_FHANDLE is not set CONFIG_AUDIT=y @@ -719,5 +719,14 @@ CONFIG_RTMM=y CONFIG_PROCESS_RECLAIM=y # KernelSU CONFIG_KSU=y -# KernelSU - Manual Hook -CONFIG_KSU_MANUAL_HOOK=y +# KernelSU - Scope-Minimized Manual Hooks +CONFIG_CFI=n +CONFIG_CFI_CLANG=n +CONFIG_KSU_EXTRAS=n +CONFIG_KSU_KPROBES_KSUD=n +CONFIG_KSU_FEATURE_ADBROOT=y +CONFIG_KSU_FEATURE_SULOG=y +CONFIG_KSU_TAMPER_SYSCALL_TABLE=n +CONFIG_KSU_DEBUG=n +CONFIG_KSU_THRONE_TRACKER_ALWAYS_THREADED=n +CONFIG_KSU_LSM_SECURITY_HOOKS=y diff --git a/fs/exec.c b/fs/exec.c index 8b9c560acc7a..579b081311fc 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1836,13 +1836,11 @@ static int do_execveat_common(int fd, struct filename *filename, putname(filename); return retval; } - + #ifdef CONFIG_KSU -extern bool ksu_execveat_hook __read_mostly; -extern int ksu_handle_execveat(int *fd, struct filename **filename_ptr, void *argv, - void *envp, int *flags); -extern int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr, - void *argv, void *envp, int *flags); +__attribute__((hot)) +extern int ksu_handle_execveat(int *fd, struct filename **filename_ptr, + void *argv, void *envp, int *flags); #endif int do_execve(struct filename *filename, @@ -1852,10 +1850,7 @@ int do_execve(struct filename *filename, struct user_arg_ptr argv = { .ptr.native = __argv }; struct user_arg_ptr envp = { .ptr.native = __envp }; #ifdef CONFIG_KSU - if (unlikely(ksu_execveat_hook)) - ksu_handle_execveat((int *)AT_FDCWD, &filename, &argv, &envp, 0); - else - ksu_handle_execveat_sucompat((int *)AT_FDCWD, &filename, NULL, NULL, NULL); + ksu_handle_execveat((int *)AT_FDCWD, &filename, &argv, &envp, 0); #endif return do_execveat_common(AT_FDCWD, filename, argv, envp, 0); } @@ -1884,9 +1879,8 @@ static int compat_do_execve(struct filename *filename, .is_compat = true, .ptr.compat = __envp, }; -#ifdef CONFIG_KSU - if (!ksu_execveat_hook) - ksu_handle_execveat_sucompat((int *)AT_FDCWD, &filename, NULL, NULL, NULL); /* 32-bit support */ +#ifdef CONFIG_KSU // 32-bit ksud and 32-on-64 support + ksu_handle_execveat((int *)AT_FDCWD, &filename, &argv, &envp, 0); #endif return do_execveat_common(AT_FDCWD, filename, argv, envp, 0); } diff --git a/fs/open.c b/fs/open.c index 633cd9738e95..760af4469c91 100644 --- a/fs/open.c +++ b/fs/open.c @@ -356,8 +356,9 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len) } #ifdef CONFIG_KSU -extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode, - int *flags); +__attribute__((hot)) +extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, + int *mode, int *flags); #endif /* diff --git a/fs/stat.c b/fs/stat.c index 78394733caaa..43295c07e27d 100644 --- a/fs/stat.c +++ b/fs/stat.c @@ -288,7 +288,9 @@ SYSCALL_DEFINE2(newlstat, const char __user *, filename, } #ifdef CONFIG_KSU -extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags); +__attribute__((hot)) +extern int ksu_handle_stat(int *dfd, const char __user **filename_user, + int *flags); #endif #if !defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_SYS_NEWFSTATAT) @@ -308,7 +310,8 @@ SYSCALL_DEFINE4(newfstatat, int, dfd, const char __user *, filename, return cp_new_stat(&stat, statbuf); } #endif -#ifdef CONFIG_KSU + +#if defined(CONFIG_KSU) && !defined(CONFIG_KSU_KPROBES_KSUD) extern void ksu_handle_newfstat_ret(unsigned int *fd, struct stat __user **statbuf_ptr); #if defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_COMPAT_STAT64) extern void ksu_handle_fstat64_ret(unsigned long *fd, struct stat64 __user **statbuf_ptr); // for 32-bit @@ -323,7 +326,7 @@ SYSCALL_DEFINE2(newfstat, unsigned int, fd, struct stat __user *, statbuf) if (!error) error = cp_new_stat(&stat, statbuf); -#ifdef CONFIG_KSU +#if defined(CONFIG_KSU) && !defined(CONFIG_KSU_KPROBES_KSUD) ksu_handle_newfstat_ret(&fd, &statbuf); #endif return error; @@ -444,7 +447,7 @@ SYSCALL_DEFINE2(fstat64, unsigned long, fd, struct stat64 __user *, statbuf) if (!error) error = cp_new_stat64(&stat, statbuf); -#ifdef CONFIG_KSU // for 32-bit +#if defined(CONFIG_KSU) && !defined(CONFIG_KSU_KPROBES_KSUD) // for 32-bit ksu_handle_fstat64_ret(&fd, &statbuf); #endif return error; @@ -456,8 +459,8 @@ SYSCALL_DEFINE4(fstatat64, int, dfd, const char __user *, filename, struct kstat stat; int error; -#ifdef CONFIG_KSU - ksu_handle_stat(&dfd, &filename, &flag); /* 32-bit su support */ +#ifdef CONFIG_KSU // 32-bit su + ksu_handle_stat(&dfd, &filename, &flag); #endif error = vfs_fstatat(dfd, filename, &stat, flag); diff --git a/kernel/reboot.c b/kernel/reboot.c index 4e1454b8da94..a377b8611601 100644 --- a/kernel/reboot.c +++ b/kernel/reboot.c @@ -267,10 +267,6 @@ void kernel_power_off(void) } EXPORT_SYMBOL_GPL(kernel_power_off); -#ifdef CONFIG_KSU -extern int ksu_handle_sys_reboot(int magic1, int magic2, unsigned int cmd, void __user **arg); -#endif - static DEFINE_MUTEX(reboot_mutex); /* @@ -281,6 +277,11 @@ static DEFINE_MUTEX(reboot_mutex); * * reboot doesn't sync: do that yourself before calling this. */ + +#if defined(CONFIG_KSU) && !defined(CONFIG_KSU_KPROBES_KSUD) +extern int ksu_handle_sys_reboot(int magic1, int magic2, unsigned int cmd, void __user **arg); +#endif + SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd, void __user *, arg) { @@ -288,7 +289,7 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd, char buffer[256]; int ret = 0; - #ifdef CONFIG_KSU + #if defined(CONFIG_KSU) && !defined(CONFIG_KSU_KPROBES_KSUD) ksu_handle_sys_reboot(magic1, magic2, cmd, &arg); #endif /* We only trust the superuser with rebooting the system. */ diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 365d44a242b5..ad6ef07707e5 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -76,7 +76,7 @@ int selinux_policycap_netpeer; int selinux_policycap_openperm; int selinux_policycap_alwaysnetwork; -static DEFINE_RWLOCK(policy_rwlock); +DEFINE_RWLOCK(policy_rwlock); static struct sidtab sidtab; struct policydb policydb; From 9bc87d552eee2f872a10be57b346ca512197931b Mon Sep 17 00:00:00 2001 From: ketikai Date: Mon, 18 May 2026 10:14:47 +0800 Subject: [PATCH 12/79] =?UTF-8?q?feat(ksu):=20=E5=90=8C=E6=AD=A5=20'scope-?= =?UTF-8?q?minimized=20manual=20hooks=20v2.1'=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- security/selinux/avc.c | 7 +++++++ security/selinux/selinuxfs.c | 9 +++++++++ 2 files changed, 16 insertions(+) diff --git a/security/selinux/avc.c b/security/selinux/avc.c index a16c72c2a967..e63301f9f64f 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -736,6 +736,10 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a) } } +#if defined(CONFIG_KSU) && !defined(CONFIG_KPROBES) +extern void ksu_slow_avc_audit(u32 *tsid); +#endif + /* This is the slow part of avc audit with big stack footprint */ noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, u32 requested, u32 audited, u32 denied, int result, @@ -745,6 +749,9 @@ noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, struct common_audit_data stack_data; struct selinux_audit_data sad; +#if defined(CONFIG_KSU) && !defined(CONFIG_KPROBES) + ksu_slow_avc_audit(&tsid); +#endif if (!a) { a = &stack_data; a->type = LSM_AUDIT_DATA_NONE; diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index a033306d14ee..5931e498d95a 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -728,6 +728,11 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = { [SEL_CONTEXT] = sel_write_context, }; + +#if defined(CONFIG_KSU) && !defined(CONFIG_KPROBES) +extern void ksu_sel_write_context(struct file **file, char **buf, size_t *size); +#endif + static ssize_t selinux_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos) { ino_t ino = file_inode(file)->i_ino; @@ -741,6 +746,10 @@ static ssize_t selinux_transaction_write(struct file *file, const char __user *b if (IS_ERR(data)) return PTR_ERR(data); +#if defined(CONFIG_KSU) && !defined(CONFIG_KPROBES) + ksu_sel_write_context(&file, &data, &size); +#endif + rv = write_op[ino](file, data, size); if (rv > 0) { simple_transaction_set(file, rv); From 0622c51f1f4138aeff6b321f22f38e1decca34cd Mon Sep 17 00:00:00 2001 From: ketikai Date: Fri, 22 May 2026 21:44:57 +0800 Subject: [PATCH 13/79] =?UTF-8?q?feat(ksu):=20=E5=90=8C=E6=AD=A5=20'scope-?= =?UTF-8?q?minimized=20manual=20hooks=20v2.2'=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- security/selinux/selinuxfs.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 5931e498d95a..a033306d14ee 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -728,11 +728,6 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = { [SEL_CONTEXT] = sel_write_context, }; - -#if defined(CONFIG_KSU) && !defined(CONFIG_KPROBES) -extern void ksu_sel_write_context(struct file **file, char **buf, size_t *size); -#endif - static ssize_t selinux_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos) { ino_t ino = file_inode(file)->i_ino; @@ -746,10 +741,6 @@ static ssize_t selinux_transaction_write(struct file *file, const char __user *b if (IS_ERR(data)) return PTR_ERR(data); -#if defined(CONFIG_KSU) && !defined(CONFIG_KPROBES) - ksu_sel_write_context(&file, &data, &size); -#endif - rv = write_op[ino](file, data, size); if (rv > 0) { simple_transaction_set(file, rv); From 97f18c61366e18c6c75ed28162b7b32c698c5bd6 Mon Sep 17 00:00:00 2001 From: ketikai Date: Fri, 22 May 2026 21:49:38 +0800 Subject: [PATCH 14/79] =?UTF-8?q?feat(ksu):=20BACKPORT=20-=20'fs/namespace?= =?UTF-8?q?.c'=20path=5Fumount=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- fs/namespace.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/fs/namespace.c b/fs/namespace.c index 21fd423b19cf..66238fcccc1b 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1711,6 +1711,40 @@ static inline bool may_mandlock(void) } #endif +static int can_umount(const struct path *path, int flags) +{ + struct mount *mnt = real_mount(path->mnt); + + if (flags & ~(MNT_FORCE | MNT_DETACH | MNT_EXPIRE | UMOUNT_NOFOLLOW)) + return -EINVAL; + if (!may_mount()) + return -EPERM; + if (path->dentry != path->mnt->mnt_root) + return -EINVAL; + if (!check_mnt(mnt)) + return -EINVAL; + if (mnt->mnt.mnt_flags & MNT_LOCKED) /* Check optimistically */ + return -EINVAL; + if (flags & MNT_FORCE && !capable(CAP_SYS_ADMIN)) + return -EPERM; + return 0; +} + +int path_umount(struct path *path, int flags) +{ + struct mount *mnt = real_mount(path->mnt); + int ret; + + ret = can_umount(path, flags); + if (!ret) + ret = do_umount(mnt, flags); + + /* we mustn't call path_put() as that would clear mnt_expiry_mark */ + dput(path->dentry); + mntput_no_expire(mnt); + return ret; +} + /* * Now umount can handle mount points as well as block devices. * This is important for filesystems which use unnamed block devices. From 500d7059c69f52d7242841027cfd5d6f702609ae Mon Sep 17 00:00:00 2001 From: ketikai Date: Thu, 28 May 2026 00:09:56 +0800 Subject: [PATCH 15/79] =?UTF-8?q?feat(ksu):=20=E4=BF=AE=E5=A4=8D=20'hooks.?= =?UTF-8?q?c'=20=E4=B8=AD=E7=BC=BA=E5=A4=B1=E7=9A=84=E5=BF=85=E8=A6=81?= =?UTF-8?q?=E5=AE=8F=E5=88=A4=E6=96=AD=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- security/selinux/hooks.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index ba15c0c353e2..710cb025f883 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2321,12 +2321,15 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm, const struct task_security_struct *old_tsec, const struct task_security_struct *new_tsec) { - static u32 ksu_sid; - char *secdata; int nnp = (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS); int nosuid = !mnt_may_suid(bprm->file->f_path.mnt); - int rc,error; + int rc; +#ifdef CONFIG_KSU + static u32 ksu_sid; + int error; + char *secdata; u32 seclen; +#endif if (!nnp && !nosuid) return 0; /* neither NNP nor nosuid */ @@ -2334,18 +2337,19 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm, if (new_tsec->sid == old_tsec->sid) return 0; /* No change in credentials */ - - if(!ksu_sid){ +#ifdef CONFIG_KSU + if (!ksu_sid) security_secctx_to_secid("u:r:su:s0", strlen("u:r:su:s0"), &ksu_sid); - } + error = security_secid_to_secctx(old_tsec->sid, &secdata, &seclen); if (!error) { - rc = strcmp("u:r:init:s0",secdata); + rc = strcmp("u:r:init:s0", secdata); security_release_secctx(secdata, seclen); - if(rc == 0 && new_tsec->sid == ksu_sid){ + if (rc == 0 && new_tsec->sid == ksu_sid) return 0; - } } +#endif + /* * The only transitions we permit under NNP or nosuid * are transitions to bounded SIDs, i.e. SIDs that are From 9f2fea437062473c6a50662163e2ad468717a34b Mon Sep 17 00:00:00 2001 From: ketikai Date: Thu, 28 May 2026 01:52:42 +0800 Subject: [PATCH 16/79] =?UTF-8?q?feat(ksu):=20=E7=A7=BB=E9=99=A4=20'hooks.?= =?UTF-8?q?c'=20=E4=B8=AD=E8=BF=87=E6=97=B6=E7=9A=84=E9=92=A9=E5=AD=90?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- security/selinux/hooks.c | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 710cb025f883..de8a090c8a3a 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2324,12 +2324,6 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm, int nnp = (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS); int nosuid = !mnt_may_suid(bprm->file->f_path.mnt); int rc; -#ifdef CONFIG_KSU - static u32 ksu_sid; - int error; - char *secdata; - u32 seclen; -#endif if (!nnp && !nosuid) return 0; /* neither NNP nor nosuid */ @@ -2337,19 +2331,6 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm, if (new_tsec->sid == old_tsec->sid) return 0; /* No change in credentials */ -#ifdef CONFIG_KSU - if (!ksu_sid) - security_secctx_to_secid("u:r:su:s0", strlen("u:r:su:s0"), &ksu_sid); - - error = security_secid_to_secctx(old_tsec->sid, &secdata, &seclen); - if (!error) { - rc = strcmp("u:r:init:s0", secdata); - security_release_secctx(secdata, seclen); - if (rc == 0 && new_tsec->sid == ksu_sid) - return 0; - } -#endif - /* * The only transitions we permit under NNP or nosuid * are transitions to bounded SIDs, i.e. SIDs that are From f7338b2136c52917ffe6a9566eb3013016375184 Mon Sep 17 00:00:00 2001 From: ketikai Date: Thu, 28 May 2026 03:02:01 +0800 Subject: [PATCH 17/79] =?UTF-8?q?chore(grus=5Fdefconfig):=20=E5=AF=B9?= =?UTF-8?q?=E4=BA=8E=20'grus'=EF=BC=8C=E9=BB=98=E8=AE=A4=E6=83=85=E5=86=B5?= =?UTF-8?q?=E4=B8=8B=E4=B8=8D=E5=90=AF=E7=94=A8=20KSU=20=E9=9B=86=E6=88=90?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CONFIG_KSU=n Signed-off-by: ketikai --- arch/arm64/configs/grus_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/configs/grus_defconfig b/arch/arm64/configs/grus_defconfig index f08728f6944d..9214a11133f1 100644 --- a/arch/arm64/configs/grus_defconfig +++ b/arch/arm64/configs/grus_defconfig @@ -718,7 +718,7 @@ CONFIG_XLOGCHAR=y CONFIG_RTMM=y CONFIG_PROCESS_RECLAIM=y # KernelSU -CONFIG_KSU=y +CONFIG_KSU=n # KernelSU - Scope-Minimized Manual Hooks CONFIG_CFI=n CONFIG_CFI_CLANG=n From 13b89f35af960a224c89847f1fb0e86ad6fa4c5a Mon Sep 17 00:00:00 2001 From: ketikai Date: Thu, 28 May 2026 03:23:41 +0800 Subject: [PATCH 18/79] =?UTF-8?q?docs(ksu):=20=E6=96=B0=E5=A2=9E=20'XXKSU'?= =?UTF-8?q?=20=E9=9B=86=E6=88=90=E7=9B=B8=E5=85=B3=E6=96=87=E6=A1=A3?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- KernelSU Integration.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 KernelSU Integration.md diff --git a/KernelSU Integration.md b/KernelSU Integration.md new file mode 100644 index 000000000000..02716fd9c143 --- /dev/null +++ b/KernelSU Integration.md @@ -0,0 +1,33 @@ +# KernelSU Integration + +> ''' +> +> #### The official KSU has not supported `non-gki` devices for a long time. +> +> #### So we chose the more reliable KSU fork. +> +> ''' + +### backslashxx's KernelSU +--------------------------------- + +* [Repository](https://github.com/backslashxx/KernelSU) +* [Releases](https://github.com/backslashxx/KernelSU/releases) + +### how to setup +--------------------------------- + +```shell +# 1. into workdir +cd android_kernel_xiaomi_sdm710 + +# 2. setup with backslashxx's KernelSU +curl -LSs https://raw.githubusercontent.com/backslashxx/KernelSU/master/kernel/setup.sh | bash -s master + +# 3. enable 'CONFIG_KSU' +sed -i 's/CONFIG_KSU=n/CONFIG_KSU=y/g' ./arch/arm64/configs/grus_defconfig +``` + +### help +--------------------------------- +* [scope-minimized manual hooks](https://github.com/backslashxx/KernelSU/issues/5) From 51f4e3070d41189215fb2c5ac8baf893203859e8 Mon Sep 17 00:00:00 2001 From: ketikai Date: Tue, 7 Jul 2026 21:35:07 +0800 Subject: [PATCH 19/79] =?UTF-8?q?chore(grus=5Fdefconfig):=20=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=E5=9C=A8=20'grus'=20=E9=BB=98=E8=AE=A4=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E4=B8=AD=E6=B7=BB=E5=8A=A0=E7=9A=84=E6=89=80=E6=9C=89?= =?UTF-8?q?=20'KernelSU'=20=E7=9B=B8=E5=85=B3=E7=9A=84=E5=86=85=E5=AE=B9?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- arch/arm64/configs/grus_defconfig | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/arch/arm64/configs/grus_defconfig b/arch/arm64/configs/grus_defconfig index 9214a11133f1..f8b18f60b205 100644 --- a/arch/arm64/configs/grus_defconfig +++ b/arch/arm64/configs/grus_defconfig @@ -717,16 +717,3 @@ CONFIG_HID_SONY=y CONFIG_XLOGCHAR=y CONFIG_RTMM=y CONFIG_PROCESS_RECLAIM=y -# KernelSU -CONFIG_KSU=n -# KernelSU - Scope-Minimized Manual Hooks -CONFIG_CFI=n -CONFIG_CFI_CLANG=n -CONFIG_KSU_EXTRAS=n -CONFIG_KSU_KPROBES_KSUD=n -CONFIG_KSU_FEATURE_ADBROOT=y -CONFIG_KSU_FEATURE_SULOG=y -CONFIG_KSU_TAMPER_SYSCALL_TABLE=n -CONFIG_KSU_DEBUG=n -CONFIG_KSU_THRONE_TRACKER_ALWAYS_THREADED=n -CONFIG_KSU_LSM_SECURITY_HOOKS=y From d389876ea455fa95967ae7c83c3ab85b3010bdb5 Mon Sep 17 00:00:00 2001 From: ketikai Date: Tue, 7 Jul 2026 21:44:16 +0800 Subject: [PATCH 20/79] =?UTF-8?q?chore(.gitignore):=20=E5=B0=86=20'.github?= =?UTF-8?q?'=20=E7=9B=AE=E5=BD=95=E4=BB=8E=20'.*'=20=E8=8C=83=E5=9B=B4?= =?UTF-8?q?=E4=B8=AD=E6=8E=92=E9=99=A4=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index b9510434e397..ddb1be924a59 100644 --- a/.gitignore +++ b/.gitignore @@ -124,3 +124,6 @@ kernel/configs/android-*.cfg # Android.bp out + +# Includ '.github' +!.github \ No newline at end of file From 48504c833c182bbd74ab6350d8d6723f801be173 Mon Sep 17 00:00:00 2001 From: ketikai Date: Tue, 7 Jul 2026 21:46:11 +0800 Subject: [PATCH 21/79] =?UTF-8?q?ci(build-kernel):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=9F=BA=E4=BA=8E=20`github-actions`=20=E7=9A=84=E6=9E=84?= =?UTF-8?q?=E5=BB=BA=E6=94=AF=E6=8C=81=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- .github/workflows/build-kernel.yml | 186 +++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 .github/workflows/build-kernel.yml diff --git a/.github/workflows/build-kernel.yml b/.github/workflows/build-kernel.yml new file mode 100644 index 000000000000..645034a3b218 --- /dev/null +++ b/.github/workflows/build-kernel.yml @@ -0,0 +1,186 @@ +name: Build Kernel + +on: + workflow_dispatch: + inputs: + kernel_defconfig: + description: Kernel - Defconfig + required: true + default: grus + type: choice + options: + - grus + ksu: + description: With KernelSU + required: false + type: boolean + default: true + kernel_localversion: + description: Kernel - Local Version + required: false + default: wabby-wabbo + ksu_setup_script: + description: KernelSU - Setup Script + required: false + default: https://raw.githubusercontent.com/backslashxx/KernelSU/master/kernel/setup.sh + ksu_setup_branch: + description: KernelSU - Setup Branch + required: false + default: master + prebuilt_gcc_toolchain: + description: Prebuilt - GCC Toolchain + required: false + default: https://github.com/ketikai/android_kernel_xiaomi_sdm710/releases/download/prebuilt/linaro-gcc.tar.xz + prebuilt_clang_toolchain: + description: Prebuilt - Clang Toolchain + required: false + default: https://github.com/ketikai/android_kernel_xiaomi_sdm710/releases/download/prebuilt/proton-clang.tar.xz + prebuilt_anykernel: + description: Prebuilt - AnyKernel + required: false + default: https://github.com/ketikai/android_kernel_xiaomi_sdm710/releases/download/prebuilt/anykernel.tar.xz + +env: + TOOLCHAIN_DIR: 'toolchain' + OUTPUT_DIR: 'build' + BUILD_ARTIFACT: kernel + ASSAMBLE_ARTIFACT: anykernel + +jobs: + build: + runs-on: ubuntu-22.04 + env: + CC: clang + CROSS_COMPILE: aarch64-linux-gnu- + CROSS_COMPILE_ARM32: arm-linux-gnueabi- + CROSS_TRIPLE: aarch64-linux-gnu- + ARCH: arm64 + SUBARCH: arm64 + steps: + - name: Checkout + uses: actions/checkout@v7 + + - name: Export Environment Variables + env: + KERNEL_DEFCONFIG: ${{ github.event.inputs.kernel_defconfig }} + KERNEL_LOCALVERSION: ${{ github.event.inputs.kernel_localversion }} + PREBUILT_GCC_TOOLCHAIN: ${{ github.event.inputs.prebuilt_gcc_toolchain }} + PREBUILT_CLANG_TOOLCHAIN: ${{ github.event.inputs.prebuilt_clang_toolchain }} + run: | + echo "DEFCONFIG=${KERNEL_DEFCONFIG}_defconfig" >> ${GITHUB_ENV} + if [[ -n "${KERNEL_LOCALVERSION}" ]]; then + echo "LOCALVERSION=-${KERNEL_LOCALVERSION}" >> ${GITHUB_ENV} + fi + echo "WORKER_SIZE=$(( $(nproc) * 2 - 1 ))" >> ${GITHUB_ENV} + echo "PREBUILT_GCC_TOOLCHAIN=${PREBUILT_GCC_TOOLCHAIN}" >> ${GITHUB_ENV} + echo "PREBUILT_CLANG_TOOLCHAIN=${PREBUILT_CLANG_TOOLCHAIN}" >> ${GITHUB_ENV} + + mkdir -p ${TOOLCHAIN_DIR} + echo "${PREBUILT_GCC_TOOLCHAIN}" > ${TOOLCHAIN_DIR}/.PREBUILT_GCC_TOOLCHAIN + echo "${PREBUILT_CLANG_TOOLCHAIN}" > ${TOOLCHAIN_DIR}/.PREBUILT_CLANG_TOOLCHAIN + + - name: Download Prebuilt GCC Toolchain From Cache + uses: actions/cache@v6 + id: cache_prebuilt_gcc_toolchain + with: + path: ${{ env.TOOLCHAIN_DIR }}/gcc + key: ${{ runner.os }}-${{ runner.arch }}-prebuilt-gcc-toolchain-${{ hashFiles(format('{0}/.PREBUILT_GCC_TOOLCHAIN', env.TOOLCHAIN_DIR)) }} + + - name: Download Prebuilt GCC Toolchain + if: steps.cache_prebuilt_gcc_toolchain.outputs.cache-hit != 'true' + run: | + mkdir -p ${TOOLCHAIN_DIR}/gcc/ + pushd ${TOOLCHAIN_DIR} + wget -O - ${PREBUILT_GCC_TOOLCHAIN} | tar -xJvf - -C gcc + popd + + - name: Download Prebuilt Clang Toolchain From Cache + uses: actions/cache@v6 + id: cache_prebuilt_clang_toolchain + with: + path: ${{ env.TOOLCHAIN_DIR }}/clang/ + key: ${{ runner.os }}-${{ runner.arch }}-prebuilt-clang-toolchain-${{ hashFiles(format('{0}/.PREBUILT_CLANG_TOOLCHAIN', env.TOOLCHAIN_DIR)) }} + + - name: Download Prebuilt Clang Toolchain + if: steps.cache_prebuilt_clang_toolchain.outputs.cache-hit != 'true' + run: | + mkdir -p ${TOOLCHAIN_DIR}/clang + pushd ${TOOLCHAIN_DIR} + wget -O - ${PREBUILT_CLANG_TOOLCHAIN} | tar -xJvf - -C clang + popd + + - name: Setup Prebuilt Toolchain + run: | + CLANG_TOOLCHAIN="$PWD/${TOOLCHAIN_DIR}/clang/bin" + GCC_ARM64_TOOLCHAIN="$PWD/${TOOLCHAIN_DIR}/gcc/aarch64-linux-gnu/bin" + GCC_ARM_TOOLCHAIN="$PWD/${TOOLCHAIN_DIR}/gcc/arm-linux-gnueabi/bin" + ls -ahl $CLANG_TOOLCHAIN + ls -ahl $GCC_ARM64_TOOLCHAIN + ls -ahl $GCC_ARM_TOOLCHAIN + echo "PATH=\"${CLANG_TOOLCHAIN}:${GCC_ARM64_TOOLCHAIN}:${GCC_ARM_TOOLCHAIN}:$PATH\"" >> ${GITHUB_ENV} + + - name: KernelSU Integration + env: + KSU: ${{ github.event.inputs.ksu }} + KSU_SETUP_SCRIPT: ${{ github.event.inputs.ksu_setup_script }} + KSU_SETUP_BRANCH: ${{ github.event.inputs.ksu_setup_branch }} + run: | + if ${KSU}; then + curl -LSs ${KSU_SETUP_SCRIPT} | bash -s ${KSU_SETUP_BRANCH} + fi + + - name: Make Config + run: | + make O=${OUTPUT_DIR} ${DEFCONFIG} + + - name: Detect External Signing Key + run: | + if [[ -n "${{ secrets.SIGNING_KEY }}" ]]; then + SIGNING_KEY_FILE=${PWD}/certs/external_signing_key.pem + echo "${{ secrets.SIGNING_KEY }}" > ${SIGNING_KEY_FILE} + scripts/config --file ${OUTPUT_DIR}/.config --set-str MODULE_SIG_KEY ${SIGNING_KEY_FILE} + make O=${OUTPUT_DIR} oldconfig + fi + + - name: Make Image + run: | + make O=${OUTPUT_DIR} -j${WORKER_SIZE} + + - name: Upload Kernel + uses: actions/upload-artifact@v7 + with: + name: ${{ env.BUILD_ARTIFACT }} + path: | + ${{ env.OUTPUT_DIR }}/arch/arm64/boot/Image + if-no-files-found: error + + assamble: + runs-on: ubuntu-22.04 + needs: + - build + steps: + - name: Download Prebuilt AnyKernel + env: + PREBUILT_ANYKERNEL: ${{ github.event.inputs.prebuilt_anykernel }} + run: | + mkdir -p ${OUTPUT_DIR} + wget -O - ${PREBUILT_ANYKERNEL} | tar -xJvf - -C ${OUTPUT_DIR} + + - name: Download Kernel + uses: actions/download-artifact@v8 + with: + name: ${{ env.BUILD_ARTIFACT }} + path: ${{ env.BUILD_ARTIFACT }} + + - name: Setup Kernel + run: | + cp ${BUILD_ARTIFACT}/Image ${OUTPUT_DIR}/ + + - name: Upload AnyKernel + uses: actions/upload-artifact@v7 + with: + name: ${{ env.ASSAMBLE_ARTIFACT }} + path: | + ${{ env.OUTPUT_DIR }}/* + if-no-files-found: error + include-hidden-files: true From 5549f423bb9e8532408acfd8cc82dd3b3df1d16b Mon Sep 17 00:00:00 2001 From: ketikai Date: Wed, 8 Jul 2026 07:52:08 +0800 Subject: [PATCH 22/79] =?UTF-8?q?docs(ksu):=20=E6=9B=B4=E6=96=B0=E6=96=87?= =?UTF-8?q?=E6=A1=A3=E4=B8=AD=E7=9A=84=E6=A0=BC=E5=BC=8F=E5=92=8C=E8=BF=87?= =?UTF-8?q?=E6=97=B6=E5=86=85=E5=AE=B9=EF=BC=8C=E6=96=B0=E5=A2=9E=E5=BF=AB?= =?UTF-8?q?=E9=80=9F=E6=9E=84=E5=BB=BA=E7=9B=B8=E5=85=B3=E7=9A=84=E8=AF=B4?= =?UTF-8?q?=E6=98=8E=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- KernelSU Integration.md | 54 ++++++++++++++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 11 deletions(-) diff --git a/KernelSU Integration.md b/KernelSU Integration.md index 02716fd9c143..88f3d9eededb 100644 --- a/KernelSU Integration.md +++ b/KernelSU Integration.md @@ -2,19 +2,23 @@ > ''' > -> #### The official KSU has not supported `non-gki` devices for a long time. +> * #### The official KSU has not supported `non-gki` devices for a long time. > -> #### So we chose the more reliable KSU fork. +> * #### So we chose the more reliable KSU fork. > > ''' -### backslashxx's KernelSU +### Backslashxx's KernelSU --------------------------------- -* [Repository](https://github.com/backslashxx/KernelSU) -* [Releases](https://github.com/backslashxx/KernelSU/releases) +> ''' +> +> * [Repository](https://github.com/backslashxx/KernelSU) +> * [Releases](https://github.com/backslashxx/KernelSU/releases) +> +> ''' -### how to setup +### How To Setup --------------------------------- ```shell @@ -23,11 +27,39 @@ cd android_kernel_xiaomi_sdm710 # 2. setup with backslashxx's KernelSU curl -LSs https://raw.githubusercontent.com/backslashxx/KernelSU/master/kernel/setup.sh | bash -s master - -# 3. enable 'CONFIG_KSU' -sed -i 's/CONFIG_KSU=n/CONFIG_KSU=y/g' ./arch/arm64/configs/grus_defconfig ``` -### help +### Quick Build (Github Actions) --------------------------------- -* [scope-minimized manual hooks](https://github.com/backslashxx/KernelSU/issues/5) + +> ''' +> +> 1. fork this repository +> +> 2. enable github actions +> +> 3. create a repository's secret of actions (optional) +> +> name: `SIGNING_KEY` +> +> content: like `certs/signing_key.pem` +> +> -----BEGIN PRIVATE KEY----- +> MIIJQw...more content...0zxuI= +> -----END PRIVATE KEY----- +> -----BEGIN CERTIFICATE----- +> MIIFKD...more content...R8gw== +> -----END CERTIFICATE----- +> +> 4. manual run workflow (build kernel) +> +> ''' + +### Related +--------------------------------- + +> ''' +> +> * [scope-minimized manual hooks](https://github.com/backslashxx/KernelSU/issues/5) +> +> ''' From 3a706315e1313335705fbdf5f61e56b3c81e1d1e Mon Sep 17 00:00:00 2001 From: ketikai Date: Wed, 8 Jul 2026 08:41:40 +0800 Subject: [PATCH 23/79] =?UTF-8?q?ci(build-kernel):=20=E6=B7=BB=E5=8A=A0=20?= =?UTF-8?q?`workflow=5Fcall`=20=E4=BA=8B=E4=BB=B6=E7=9A=84=E6=94=AF?= =?UTF-8?q?=E6=8C=81=EF=BC=8C=E8=B0=83=E6=95=B4=E5=92=8C=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E8=BE=93=E5=85=A5=E5=8F=82=E6=95=B0=E7=9A=84=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E5=92=8C=E4=BD=8D=E7=BD=AE=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- .github/workflows/build-kernel.yml | 36 +++++++++++++++++------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/.github/workflows/build-kernel.yml b/.github/workflows/build-kernel.yml index 645034a3b218..0f43d9f2eb28 100644 --- a/.github/workflows/build-kernel.yml +++ b/.github/workflows/build-kernel.yml @@ -1,44 +1,50 @@ name: Build Kernel on: - workflow_dispatch: - inputs: + workflow_call: + inputs: &workflow_inputs kernel_defconfig: description: Kernel - Defconfig - required: true + type: string + required: false default: grus - type: choice - options: - - grus ksu: description: With KernelSU - required: false type: boolean + required: false default: true kernel_localversion: description: Kernel - Local Version + type: string required: false default: wabby-wabbo ksu_setup_script: description: KernelSU - Setup Script + type: string required: false default: https://raw.githubusercontent.com/backslashxx/KernelSU/master/kernel/setup.sh ksu_setup_branch: description: KernelSU - Setup Branch + type: string required: false default: master prebuilt_gcc_toolchain: description: Prebuilt - GCC Toolchain + type: string required: false default: https://github.com/ketikai/android_kernel_xiaomi_sdm710/releases/download/prebuilt/linaro-gcc.tar.xz prebuilt_clang_toolchain: description: Prebuilt - Clang Toolchain + type: string required: false default: https://github.com/ketikai/android_kernel_xiaomi_sdm710/releases/download/prebuilt/proton-clang.tar.xz prebuilt_anykernel: description: Prebuilt - AnyKernel + type: string required: false default: https://github.com/ketikai/android_kernel_xiaomi_sdm710/releases/download/prebuilt/anykernel.tar.xz + workflow_dispatch: + inputs: *workflow_inputs env: TOOLCHAIN_DIR: 'toolchain' @@ -62,10 +68,10 @@ jobs: - name: Export Environment Variables env: - KERNEL_DEFCONFIG: ${{ github.event.inputs.kernel_defconfig }} - KERNEL_LOCALVERSION: ${{ github.event.inputs.kernel_localversion }} - PREBUILT_GCC_TOOLCHAIN: ${{ github.event.inputs.prebuilt_gcc_toolchain }} - PREBUILT_CLANG_TOOLCHAIN: ${{ github.event.inputs.prebuilt_clang_toolchain }} + KERNEL_DEFCONFIG: ${{ inputs.kernel_defconfig }} + KERNEL_LOCALVERSION: ${{ inputs.kernel_localversion }} + PREBUILT_GCC_TOOLCHAIN: ${{ inputs.prebuilt_gcc_toolchain }} + PREBUILT_CLANG_TOOLCHAIN: ${{ inputs.prebuilt_clang_toolchain }} run: | echo "DEFCONFIG=${KERNEL_DEFCONFIG}_defconfig" >> ${GITHUB_ENV} if [[ -n "${KERNEL_LOCALVERSION}" ]]; then @@ -121,9 +127,9 @@ jobs: - name: KernelSU Integration env: - KSU: ${{ github.event.inputs.ksu }} - KSU_SETUP_SCRIPT: ${{ github.event.inputs.ksu_setup_script }} - KSU_SETUP_BRANCH: ${{ github.event.inputs.ksu_setup_branch }} + KSU: ${{ inputs.ksu }} + KSU_SETUP_SCRIPT: ${{ inputs.ksu_setup_script }} + KSU_SETUP_BRANCH: ${{ inputs.ksu_setup_branch }} run: | if ${KSU}; then curl -LSs ${KSU_SETUP_SCRIPT} | bash -s ${KSU_SETUP_BRANCH} @@ -161,7 +167,7 @@ jobs: steps: - name: Download Prebuilt AnyKernel env: - PREBUILT_ANYKERNEL: ${{ github.event.inputs.prebuilt_anykernel }} + PREBUILT_ANYKERNEL: ${{ inputs.prebuilt_anykernel }} run: | mkdir -p ${OUTPUT_DIR} wget -O - ${PREBUILT_ANYKERNEL} | tar -xJvf - -C ${OUTPUT_DIR} From 18360052341253771fee7270c749a0395324b430 Mon Sep 17 00:00:00 2001 From: ketikai Date: Wed, 8 Jul 2026 09:52:41 +0800 Subject: [PATCH 24/79] =?UTF-8?q?ci(build-kernel-ksu):=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E4=B8=8E=20`ksu`=20=E7=9B=B8=E5=85=B3=E7=9A=84?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E6=9E=84=E5=BB=BA=E5=B7=A5=E4=BD=9C=E6=B5=81?= =?UTF-8?q?=EF=BC=8C=E5=BD=93=E4=BB=BB=E4=B8=80=E6=8F=90=E4=BA=A4=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=E4=BB=A5=20`feat(ksu)`=20=E4=B8=BA=E9=A6=96=E6=97=B6?= =?UTF-8?q?=E8=A7=A6=E5=8F=91=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- .github/workflows/build-kernel-ksu.yml | 42 ++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 .github/workflows/build-kernel-ksu.yml diff --git a/.github/workflows/build-kernel-ksu.yml b/.github/workflows/build-kernel-ksu.yml new file mode 100644 index 000000000000..df72fbca1250 --- /dev/null +++ b/.github/workflows/build-kernel-ksu.yml @@ -0,0 +1,42 @@ +name: Build Kernel With KernelSU + +on: + push: &on_push + branches: + - master + pull_request: *on_push + +env: + CHECK_FLAG: feat(ksu) + +jobs: + check: + runs-on: ubuntu-latest + if: toJson(github.event.commits) != '[]' + outputs: + check_flag: ${{ env.CHECK_FLAG }} + need_build: ${{ steps.check.outputs.result }} + steps: + - name: test + id: check + uses: actions/github-script@v9 + with: + script: | + let commits = ${{ toJson(github.event.commits) }} + console.log('commits: ' + commits.length) + for (let i = 0; i < commits.length; i++) { + let message = commits[i].message + console.log(message + '\n---') + if (message.startsWith('${{ env.CHECK_FLAG }}')) { + return true + } + } + return false + build: + name: when ${{ needs.check.outputs.check_flag }} + uses: ./.github/workflows/build-kernel.yml + needs: + - check + if: needs.check.outputs.need_build == true + with: + ksu: true From 7c624bb89d230d6207df31b2026b3c5ee8f30699 Mon Sep 17 00:00:00 2001 From: ketikai Date: Wed, 8 Jul 2026 11:39:03 +0800 Subject: [PATCH 25/79] =?UTF-8?q?ci(build-kernel):=20=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E4=B8=8D=E5=90=AF=E7=94=A8=20'ksu'=20=E9=9B=86=E6=88=90?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- .github/workflows/build-kernel.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-kernel.yml b/.github/workflows/build-kernel.yml index 0f43d9f2eb28..86b4fdf9a384 100644 --- a/.github/workflows/build-kernel.yml +++ b/.github/workflows/build-kernel.yml @@ -12,7 +12,7 @@ on: description: With KernelSU type: boolean required: false - default: true + default: false kernel_localversion: description: Kernel - Local Version type: string From ff2bb1462473eb70f5d8cad98ac96e5893052673 Mon Sep 17 00:00:00 2001 From: ketikai Date: Wed, 8 Jul 2026 11:42:10 +0800 Subject: [PATCH 26/79] =?UTF-8?q?docs(ksu):=20=E8=A1=A5=E5=85=85=E6=96=87?= =?UTF-8?q?=E6=A1=A3=E4=B8=AD=E4=B8=8E=E5=BF=AB=E9=80=9F=E6=9E=84=E5=BB=BA?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E7=9A=84=E5=86=85=E5=AE=B9=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- KernelSU Integration.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/KernelSU Integration.md b/KernelSU Integration.md index 88f3d9eededb..28d4e8719f22 100644 --- a/KernelSU Integration.md +++ b/KernelSU Integration.md @@ -53,6 +53,8 @@ curl -LSs https://raw.githubusercontent.com/backslashxx/KernelSU/master/kernel/s > > 4. manual run workflow (build kernel) > +> check `With KernelSU` +> > ''' ### Related From ade31ccd852d726bbda6536b5a91deb5e3559c3d Mon Sep 17 00:00:00 2001 From: ketikai Date: Fri, 10 Jul 2026 12:21:07 +0800 Subject: [PATCH 27/79] =?UTF-8?q?chore(assamble):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=BF=AB=E9=80=9F=E6=9E=84=E5=BB=BA=E8=84=9A=E6=9C=AC=20`assam?= =?UTF-8?q?ble`=20=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- assamble | 262 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 262 insertions(+) create mode 100755 assamble diff --git a/assamble b/assamble new file mode 100755 index 000000000000..2fd710220b9d --- /dev/null +++ b/assamble @@ -0,0 +1,262 @@ +#!/bin/bash + +# build-essential libssl-dev ccache + +set -e + +if (( $# < 2 )); then + echo "用法: $0 [选项 [值]...]..." + echo " 可用选项:" + echo " -p, --prebuilt " + echo " 指定预构建库/包目录,默认: '$PREBUILT_DIR'" + echo "" + echo " -c, --cache " + echo " 指定缓存的存放目录,默认: '$CACHE_DIR'" + echo "" + echo " -w, --work " + echo " 指定工作目录,默认: '$WORK_DIR'" + echo "" + echo " -j, --jobs " + echo " 指定工作线程数量,默认: $JOBS" + echo "" + echo " --clean" + echo " 在构建之前进行清理,默认: $((( $CLEAN != 0)) && echo '启用' || echo '禁用')" + echo "" + echo " --llvm" + echo " 使用 Clang/Clang++ 作为主要编译器,默认: $((( $LLVM != 0)) && echo '启用' || echo '禁用')" + echo "" + echo " --version " + echo " 指定 LOCALVERSION 的值,默认: '$LOCALVERSION'" + echo "" + echo " --build " + echo " 指定构建目录,默认: '$BUILD_DIR'" + echo "" + echo " -v, --verbose" + echo " 使用构建参数 'V=1' 来启用更详细的日志,默认: $((( $VERBOSE != 0)) && echo '启用' || echo '禁用')" + echo "" + echo " --logs " + echo " 指定日志文件的存放目录,默认: '$LOGS_DIR'" + echo "" + echo " -d, --destination " + echo " 指定目标工件的存放目录,默认: '$DESTINATION_DIR'" + echo "" + echo " -s, --signing " + echo " 指定签名密钥文件,默认: '$SIGNING_KEY_FILE'" + echo "" + echo "示例: $0 arm64 grus --llvm --version wabby-wabbo -s .signing_key.pem" + exit 1 +fi + +if [[ ! -n "$1" || "$1" =~ ^- ]]; then + echo "无效参数: 的值不能为 '$1'" >&2 + exit 1 +fi +ARCH="$1" +shift +if [[ ! -n "$1" || "$1" =~ ^- ]]; then + echo "无效参数: 的值不能为 '$1'" >&2 + exit 1 +fi +DEVICE="$1" +shift + +PREBUILT_DIR=$(realpath -m ".prebuilt") +CACHE_DIR=$(realpath -m ".cache") +WORK_DIR=$(realpath -m ".") +JOBS=$(($(nproc) * 2 - 1)) +CLEAN=0 +LLVM=0 +LOCALVERSION="" +BUILD_DIR=$(realpath -m ".build") +VERBOSE=0 +LOGS_DIR=$(realpath -m ".logs") +DESTINATION_DIR=$(realpath -m ".target") +SIGNING_KEY_FILE="" + +while [ $# -gt 0 ]; do + case "$1" in + -p|--prebuilt) + if [ -n "$2" ]; then + PREBUILT_DIR=$(realpath -m "$2") + shift 2 + else + echo "无效选项: $1: 必须提供一个有效的目录路径" >&2 + exit 1 + fi + ;; + -c|--cache) + if [ -n "$2" ]; then + CACHE_DIR=$(realpath -m "$2") + shift 2 + else + echo "无效选项: $1: 必须提供一个有效的目录路径" >&2 + exit 1 + fi + ;; + -w|--work) + if [ -n "$2" ]; then + WORK_DIR=$(realpath -m "$2") + shift 2 + else + echo "无效选项: $1: 必须提供一个有效的目录路径" >&2 + exit 1 + fi + ;; + -j|--jobs) + if [[ "$2" =~ ^[1-9][0-9]*$ ]]; then + JOBS=$2 + shift 2 + else + echo "无效选项: $1: 必须提供一个有效的正整数" >&2 + exit 1 + fi + ;; + --clean) + CLEAN=1 + shift + ;; + --llvm) + LLVM=1 + shift + ;; + --version) + if [ -n "$2" ]; then + LOCALVERSION="$2" + shift 2 + else + echo "无效选项: $1: 必须提供一个有效的版本名称" >&2 + exit 1 + fi + ;; + --build) + if [ -n "$2" ]; then + BUILD_DIR=$(realpath -m "$2") + if [[ "$BUILD_DIR" == "$WORK_DIR" ]]; then + echo "无效选项: $1: 构建目录不能与工作目录相同" >&2 + exit 1 + fi + shift 2 + else + echo "无效选项: $1: 必须提供一个有效的目录路径" >&2 + exit 1 + fi + ;; + -v|--verbose) + VERBOSE=1 + shift + ;; + --logs) + if [ -n "$2" ]; then + LOGS_DIR=$(realpath -m "$2") + shift 2 + else + echo "无效选项: $1: 必须提供一个有效的目录路径" >&2 + exit 1 + fi + ;; + -d|--destination) + if [ -n "$2" ]; then + DESTINATION_DIR=$(realpath -m "$2") + shift 2 + else + echo "无效选项: $1: 必须提供一个有效的目录路径" >&2 + exit 1 + fi + ;; + -s|--signing) + if [ -n "$2" ]; then + SIGNING_KEY_FILE=$(realpath -m "$2") + shift 2 + else + echo "无效选项: $1: 必须提供一个有效的文件路径" >&2 + exit 1 + fi + ;; + -*) + echo "无效选项: $1" >&2 + exit 1 + ;; + *) + echo "无效值: $1" >&2 + exit 1 + ;; + esac +done + +echo "工作线程: $JOBS" +pushd $WORK_DIR + +TOOLCHAIN_DIR="$PREBUILT_DIR/toolchain" +export PATH="$TOOLCHAIN_DIR/gcc/aarch64-linux-gnu/bin:$PATH" +export PATH="$TOOLCHAIN_DIR/gcc/arm-linux-gnueabi/bin:$PATH" +export PATH="$TOOLCHAIN_DIR/clang/bin:$PATH" + +echo "配置缓存..." +export CCACHE="ccache" +export CCACHE_DIR=$CACHE_DIR +ccache --show-config +if (( $CLEAN != 0 )); then + echo "清理缓存..." + ccache -zC +fi + +V=$((( $VERBOSE != 0 )) && echo 'V=1' || echo 'V=s') +O="O=$BUILD_DIR" + +if (( $LLVM != 0 )); then + export LLVM=1 +fi + +if [[ -n "$LOCALVERSION" ]]; then + export LOCALVERSION="-$LOCALVERSION" +fi + +export CROSS_COMPILE="aarch64-linux-gnu-" +export CROSS_COMPILE_ARM32="arm-linux-gnueabi-" +export CROSS_TRIPLE="aarch64-linux-gnu-" +export ARCH="$ARCH" + +echo "初始化构建..." +rm -rf $LOGS_DIR +mkdir -p $LOGS_DIR +make $V $O mrproper 2> >(tee $LOGS_DIR/mrproper-error.log) 1> >(tee $LOGS_DIR/mrproper-info.log) +make $V mrproper 2> >(tee $LOGS_DIR/mrproper-error.log) 1> >(tee $LOGS_DIR/mrproper-info.log) + +echo "生成配置..." +DEFAULT_CONFIG="${DEVICE}_defconfig" +make $V $O $DEFAULT_CONFIG 2> >(tee $LOGS_DIR/defconfig-error.log) 1> >(tee $LOGS_DIR/defconfig-info.log) + +if [[ -n "$SIGNING_KEY_FILE" ]]; then + echo "使用外部签名密钥..." + scripts/config --file ${BUILD_DIR}/.config --set-str MODULE_SIG_KEY $SIGNING_KEY_FILE + make $V $O oldconfig 2> >(tee $LOGS_DIR/oldconfig-error.log) 1> >(tee $LOGS_DIR/oldconfig-info.log) +fi + +echo "构建内核..." +make $V $O -j$JOBS 2> >(tee $LOGS_DIR/kernel-error.log) 1> >(tee $LOGS_DIR/kernel-info.log) + +echo "复制内核..." +KERNEL_DESTINATION_DIR=$DESTINATION_DIR/kernel +mkdir -p $KERNEL_DESTINATION_DIR +cp $BUILD_DIR/vmlinux $KERNEL_DESTINATION_DIR +pushd $BUILD_DIR/arch/$ARCH/boot + +find . -type f -name "Image*" -exec cp {} $KERNEL_DESTINATION_DIR \; + +popd + +echo "签名模块..." +make $V $O modules_install INSTALL_MOD_PATH=modules 2> >(tee $LOGS_DIR/modules-error.log) 1> >(tee $LOGS_DIR/modules-info.log) + +echo "复制模块..." +MODULES_DESTINATION_DIR=$DESTINATION_DIR/modules +mkdir -p $MODULES_DESTINATION_DIR +pushd $BUILD_DIR/modules + +find . -type f -name "*.ko" -exec cp {} $MODULES_DESTINATION_DIR \; + +popd + +popd + +ccache -s -v From bffe7ff55b358f9ce2a94a729bca281d5199f787 Mon Sep 17 00:00:00 2001 From: ketikai Date: Fri, 10 Jul 2026 13:50:09 +0800 Subject: [PATCH 28/79] =?UTF-8?q?feat(Makefile),=20fix(Makefile):=20?= =?UTF-8?q?=E6=8F=90=E4=BE=9B=20`ccache`=20=E6=94=AF=E6=8C=81=EF=BC=8C?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E9=83=A8=E5=88=86=E6=A8=A1=E5=9D=97=E4=B8=AD?= =?UTF-8?q?=E5=8F=AF=E8=83=BD=E9=94=99=E8=AF=AF=E7=9A=84=E6=8C=87=E5=AE=9A?= =?UTF-8?q?=E7=BC=96=E8=AF=91=E5=99=A8=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- Makefile | 12 ++++++------ arch/m68k/tools/amiga/Makefile | 2 +- lib/raid6/test/Makefile | 2 +- samples/auxdisplay/Makefile | 2 +- samples/mei/Makefile | 2 +- samples/mic/mpssd/Makefile | 2 +- samples/timers/Makefile | 2 +- samples/watchdog/Makefile | 2 +- tools/accounting/Makefile | 2 +- tools/build/feature/Makefile | 2 +- tools/cgroup/Makefile | 2 +- tools/firewire/Makefile | 2 +- tools/gpio/Makefile | 2 +- tools/hv/Makefile | 2 +- tools/iio/Makefile | 2 +- tools/laptop/dslm/Makefile | 2 +- tools/laptop/freefall/Makefile | 2 +- tools/lib/api/Makefile | 2 +- tools/net/Makefile | 2 +- tools/pcmcia/Makefile | 2 +- tools/power/acpi/Makefile.config | 2 +- tools/power/cpupower/Makefile | 11 ++++++----- tools/power/x86/turbostat/Makefile | 2 +- tools/spi/Makefile | 2 +- tools/testing/selftests/intel_pstate/Makefile | 2 +- tools/testing/selftests/memfd/Makefile | 2 +- tools/testing/selftests/timers/Makefile | 2 +- tools/thermal/tmon/Makefile | 2 +- tools/usb/Makefile | 2 +- .../usb/ffs-aio-example/multibuff/host_app/Makefile | 2 +- tools/usb/ffs-aio-example/simple/host_app/Makefile | 2 +- tools/virtio/virtio-trace/Makefile | 2 +- tools/vm/Makefile | 2 +- 33 files changed, 43 insertions(+), 42 deletions(-) diff --git a/Makefile b/Makefile index 09c701add89b..2fdbb4a94d8d 100644 --- a/Makefile +++ b/Makefile @@ -302,11 +302,11 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ else echo sh; fi ; fi) ifneq ($(LLVM),) -HOSTCC = clang -HOSTCXX = clang++ +HOSTCC = $(CCACHE) clang +HOSTCXX = $(CCACHE) clang++ else -HOSTCC = gcc -HOSTCXX = g++ +HOSTCC = $(CCACHE) gcc +HOSTCXX = $(CCACHE) g++ endif HOSTCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer -std=gnu99 @@ -351,7 +351,7 @@ include scripts/Kbuild.include LDGOLD = $(CROSS_COMPILE)ld.gold CPP = $(CC) -E ifneq ($(LLVM),) -CC = clang +CC = $(CCACHE) clang LD = ld.lld AR = llvm-ar NM = llvm-nm @@ -363,7 +363,7 @@ STRIP = llvm-strip else AS = $(CROSS_COMPILE)as LD = $(CROSS_COMPILE)ld -CC = $(CROSS_COMPILE)gcc +CC = $(CCACHE) $(CROSS_COMPILE)gcc AR = $(CROSS_COMPILE)ar NM = $(CROSS_COMPILE)nm STRIP = $(CROSS_COMPILE)strip diff --git a/arch/m68k/tools/amiga/Makefile b/arch/m68k/tools/amiga/Makefile index 113436136089..e389e8616c2d 100644 --- a/arch/m68k/tools/amiga/Makefile +++ b/arch/m68k/tools/amiga/Makefile @@ -1,5 +1,5 @@ -CC = m68k-cbm-amigados-gcc +CC = $(CCACHE) m68k-cbm-amigados-gcc CFLAGS = -Wall -O2 diff --git a/lib/raid6/test/Makefile b/lib/raid6/test/Makefile index 1faeef0c30b9..065960d959c6 100644 --- a/lib/raid6/test/Makefile +++ b/lib/raid6/test/Makefile @@ -3,7 +3,7 @@ # from userspace. # -CC = gcc +CC = $(CCACHE) $(CROSS_COMPILE)gcc OPTFLAGS = -O2 # Adjust as desired CFLAGS = -I.. -I ../../../include -g $(OPTFLAGS) LD = ld diff --git a/samples/auxdisplay/Makefile b/samples/auxdisplay/Makefile index 05e471feb6e5..839465b256df 100644 --- a/samples/auxdisplay/Makefile +++ b/samples/auxdisplay/Makefile @@ -1,4 +1,4 @@ -CC := $(CROSS_COMPILE)gcc +CC := $(CCACHE) $(CROSS_COMPILE)gcc CFLAGS := -I../../usr/include PROGS := cfag12864b-example diff --git a/samples/mei/Makefile b/samples/mei/Makefile index 7aac216dc420..e6c8689c7c7b 100644 --- a/samples/mei/Makefile +++ b/samples/mei/Makefile @@ -1,4 +1,4 @@ -CC := $(CROSS_COMPILE)gcc +CC := $(CCACHE) $(CROSS_COMPILE)gcc CFLAGS := -I../../usr/include PROGS := mei-amt-version diff --git a/samples/mic/mpssd/Makefile b/samples/mic/mpssd/Makefile index 3e3ef91fed6b..6b320c0c5db0 100644 --- a/samples/mic/mpssd/Makefile +++ b/samples/mic/mpssd/Makefile @@ -5,7 +5,7 @@ ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/) ifeq ($(ARCH),x86) PROGS := mpssd -CC = $(CROSS_COMPILE)gcc +CC = $(CCACHE) $(CROSS_COMPILE)gcc CFLAGS := -I../../../usr/include -I../../../tools/include ifdef DEBUG diff --git a/samples/timers/Makefile b/samples/timers/Makefile index a5c3c4a35ca1..dd17c4a6130e 100644 --- a/samples/timers/Makefile +++ b/samples/timers/Makefile @@ -3,7 +3,7 @@ uname_M := $(shell uname -m 2>/dev/null || echo not) ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/) ifeq ($(ARCH),x86) -CC := $(CROSS_COMPILE)gcc +CC := $(CCACHE) $(CROSS_COMPILE)gcc PROGS := hpet_example all: $(PROGS) diff --git a/samples/watchdog/Makefile b/samples/watchdog/Makefile index 9b53d89b1ccf..0864f2fb122d 100644 --- a/samples/watchdog/Makefile +++ b/samples/watchdog/Makefile @@ -1,4 +1,4 @@ -CC := $(CROSS_COMPILE)gcc +CC := $(CCACHE) $(CROSS_COMPILE)gcc PROGS := watchdog-simple all: $(PROGS) diff --git a/tools/accounting/Makefile b/tools/accounting/Makefile index 647c94a219bf..55dd9d02a1c9 100644 --- a/tools/accounting/Makefile +++ b/tools/accounting/Makefile @@ -1,4 +1,4 @@ -CC := $(CROSS_COMPILE)gcc +CC := $(CCACHE) $(CROSS_COMPILE)gcc CFLAGS := -I../../usr/include PROGS := getdelays diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile index 46af3bb56142..ebff899de362 100644 --- a/tools/build/feature/Makefile +++ b/tools/build/feature/Makefile @@ -51,7 +51,7 @@ FILES= \ FILES := $(addprefix $(OUTPUT),$(FILES)) -CC := $(CROSS_COMPILE)gcc -MD +CC := $(CCACHE) $(CROSS_COMPILE)gcc -MD CXX := $(CROSS_COMPILE)g++ -MD PKG_CONFIG := $(CROSS_COMPILE)pkg-config diff --git a/tools/cgroup/Makefile b/tools/cgroup/Makefile index b4286196b763..e2d5740f898d 100644 --- a/tools/cgroup/Makefile +++ b/tools/cgroup/Makefile @@ -1,6 +1,6 @@ # Makefile for cgroup tools -CC = $(CROSS_COMPILE)gcc +CC = $(CCACHE) $(CROSS_COMPILE)gcc CFLAGS = -Wall -Wextra all: cgroup_event_listener diff --git a/tools/firewire/Makefile b/tools/firewire/Makefile index 81767adaae7d..f51e607a1116 100644 --- a/tools/firewire/Makefile +++ b/tools/firewire/Makefile @@ -1,7 +1,7 @@ prefix = /usr nosy-dump-version = 0.4 -CC = gcc +CC = $(CCACHE) $(CROSS_COMPILE)gcc all : nosy-dump diff --git a/tools/gpio/Makefile b/tools/gpio/Makefile index e2ac49253a0a..0c4d191a1371 100644 --- a/tools/gpio/Makefile +++ b/tools/gpio/Makefile @@ -11,7 +11,7 @@ endif # (this improves performance and avoids hard-to-debug behaviour); MAKEFLAGS += -r -CC = $(CROSS_COMPILE)gcc +CC = $(CCACHE) $(CROSS_COMPILE)gcc LD = $(CROSS_COMPILE)ld CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include diff --git a/tools/hv/Makefile b/tools/hv/Makefile index a8c4644022a6..7c9d4ec3ab21 100644 --- a/tools/hv/Makefile +++ b/tools/hv/Makefile @@ -1,6 +1,6 @@ # Makefile for Hyper-V tools -CC = $(CROSS_COMPILE)gcc +CC = $(CCACHE) $(CROSS_COMPILE)gcc PTHREAD_LIBS = -lpthread WARNINGS = -Wall -Wextra CFLAGS = $(WARNINGS) -g $(PTHREAD_LIBS) $(shell getconf LFS_CFLAGS) diff --git a/tools/iio/Makefile b/tools/iio/Makefile index 5446d625e17d..68647bce6906 100644 --- a/tools/iio/Makefile +++ b/tools/iio/Makefile @@ -1,4 +1,4 @@ -CC = $(CROSS_COMPILE)gcc +CC = $(CCACHE) $(CROSS_COMPILE)gcc CFLAGS += -Wall -g -D_GNU_SOURCE BINDIR=usr/bin diff --git a/tools/laptop/dslm/Makefile b/tools/laptop/dslm/Makefile index ff613b31730b..6c4f28d4d0e4 100644 --- a/tools/laptop/dslm/Makefile +++ b/tools/laptop/dslm/Makefile @@ -1,4 +1,4 @@ -CC := $(CROSS_COMPILE)gcc +CC := $(CCACHE) $(CROSS_COMPILE)gcc CFLAGS := -I../../usr/include PROGS := dslm diff --git a/tools/laptop/freefall/Makefile b/tools/laptop/freefall/Makefile index 48c6c9328419..d889f9ac0613 100644 --- a/tools/laptop/freefall/Makefile +++ b/tools/laptop/freefall/Makefile @@ -1,7 +1,7 @@ PREFIX ?= /usr SBINDIR ?= sbin INSTALL ?= install -CC = $(CROSS_COMPILE)gcc +CC = $(CCACHE) $(CROSS_COMPILE)gcc TARGET = freefall diff --git a/tools/lib/api/Makefile b/tools/lib/api/Makefile index 0a6fda9837f7..48002de319f0 100644 --- a/tools/lib/api/Makefile +++ b/tools/lib/api/Makefile @@ -8,7 +8,7 @@ srctree := $(patsubst %/,%,$(dir $(srctree))) #$(info Determined 'srctree' to be $(srctree)) endif -CC = $(CROSS_COMPILE)gcc +CC = $(CCACHE) $(CROSS_COMPILE)gcc AR = $(CROSS_COMPILE)ar LD = $(CROSS_COMPILE)ld diff --git a/tools/net/Makefile b/tools/net/Makefile index ddf888010652..3ca56a12cf12 100644 --- a/tools/net/Makefile +++ b/tools/net/Makefile @@ -1,6 +1,6 @@ prefix = /usr -CC = gcc +CC = $(CCACHE) $(CROSS_COMPILE)gcc LEX = flex YACC = bison diff --git a/tools/pcmcia/Makefile b/tools/pcmcia/Makefile index 81a7498c5cd9..caff5aed82f4 100644 --- a/tools/pcmcia/Makefile +++ b/tools/pcmcia/Makefile @@ -1,4 +1,4 @@ -CC := $(CROSS_COMPILE)gcc +CC := $(CCACHE) $(CROSS_COMPILE)gcc CFLAGS := -I../../usr/include PROGS := crc32hash diff --git a/tools/power/acpi/Makefile.config b/tools/power/acpi/Makefile.config index fb5559f9819a..40cd0bf0c922 100644 --- a/tools/power/acpi/Makefile.config +++ b/tools/power/acpi/Makefile.config @@ -56,7 +56,7 @@ INSTALL_SCRIPT = ${INSTALL_PROGRAM} # to compile vs uClibc, that can be done here as well. CROSS = #/usr/i386-linux-uclibc/usr/bin/i386-uclibc- CROSS_COMPILE ?= $(CROSS) -CC = $(CROSS_COMPILE)gcc +CC = $(CCACHE) $(CROSS_COMPILE)gcc LD = $(CROSS_COMPILE)gcc STRIP = $(CROSS_COMPILE)strip HOSTCC = gcc diff --git a/tools/power/cpupower/Makefile b/tools/power/cpupower/Makefile index 8358863259c5..8155b5e6c9bd 100644 --- a/tools/power/cpupower/Makefile +++ b/tools/power/cpupower/Makefile @@ -96,11 +96,12 @@ INSTALL_SCRIPT = ${INSTALL_PROGRAM} # to something more interesting, like "arm-linux-". If you want # to compile vs uClibc, that can be done here as well. CROSS = #/usr/i386-linux-uclibc/usr/bin/i386-uclibc- -CC = $(CROSS)gcc -LD = $(CROSS)gcc -AR = $(CROSS)ar -STRIP = $(CROSS)strip -RANLIB = $(CROSS)ranlib +CROSS_COMPILE ?= $(CROSS) +CC = $(CCACHE) $(CROSS_COMPILE)gcc +LD = $(CROSS_COMPILE)gcc +AR = $(CROSS_COMPILE)ar +STRIP = $(CROSS_COMPILE)strip +RANLIB = $(CROSS_COMPILE)ranlib HOSTCC = gcc MKDIR = mkdir diff --git a/tools/power/x86/turbostat/Makefile b/tools/power/x86/turbostat/Makefile index 92be948c922d..786aa356e714 100644 --- a/tools/power/x86/turbostat/Makefile +++ b/tools/power/x86/turbostat/Makefile @@ -1,4 +1,4 @@ -CC = $(CROSS_COMPILE)gcc +CC = $(CCACHE) $(CROSS_COMPILE)gcc BUILD_OUTPUT := $(CURDIR) PREFIX ?= /usr DESTDIR ?= diff --git a/tools/spi/Makefile b/tools/spi/Makefile index 3815b18ba070..b785148c0373 100644 --- a/tools/spi/Makefile +++ b/tools/spi/Makefile @@ -1,4 +1,4 @@ -CC = $(CROSS_COMPILE)gcc +CC = $(CCACHE) $(CROSS_COMPILE)gcc all: spidev_test spidev_fdx diff --git a/tools/testing/selftests/intel_pstate/Makefile b/tools/testing/selftests/intel_pstate/Makefile index f5f1a28715ff..9eea6fdd373f 100644 --- a/tools/testing/selftests/intel_pstate/Makefile +++ b/tools/testing/selftests/intel_pstate/Makefile @@ -1,4 +1,4 @@ -CC := $(CROSS_COMPILE)gcc +CC := $(CCACHE) $(CROSS_COMPILE)gcc CFLAGS := $(CFLAGS) -Wall -D_GNU_SOURCE LDFLAGS := $(LDFLAGS) -lm diff --git a/tools/testing/selftests/memfd/Makefile b/tools/testing/selftests/memfd/Makefile index fd396ac811b6..93dba5b0a870 100644 --- a/tools/testing/selftests/memfd/Makefile +++ b/tools/testing/selftests/memfd/Makefile @@ -1,4 +1,4 @@ -CC = $(CROSS_COMPILE)gcc +CC = $(CCACHE) $(CROSS_COMPILE)gcc CFLAGS += -D_FILE_OFFSET_BITS=64 CFLAGS += -I../../../../include/uapi/ CFLAGS += -I../../../../include/ diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile index 1d5556869137..07368c04eb99 100644 --- a/tools/testing/selftests/timers/Makefile +++ b/tools/testing/selftests/timers/Makefile @@ -1,4 +1,4 @@ -CC = $(CROSS_COMPILE)gcc +CC = $(CCACHE) $(CROSS_COMPILE)gcc BUILD_FLAGS = -DKTEST CFLAGS += -O3 -Wl,-no-as-needed -Wall $(BUILD_FLAGS) LDFLAGS += -lrt -lpthread diff --git a/tools/thermal/tmon/Makefile b/tools/thermal/tmon/Makefile index 3a961e998281..63f9722639ed 100644 --- a/tools/thermal/tmon/Makefile +++ b/tools/thermal/tmon/Makefile @@ -3,7 +3,7 @@ VERSION = 1.0 BINDIR=usr/bin WARNFLAGS=-Wall -Wshadow -W -Wformat -Wimplicit-function-declaration -Wimplicit-int CFLAGS+= -O1 ${WARNFLAGS} -fstack-protector -CC=$(CROSS_COMPILE)gcc +CC=$(CCACHE) $(CROSS_COMPILE)gcc CFLAGS+=-D VERSION=\"$(VERSION)\" LDFLAGS+= diff --git a/tools/usb/Makefile b/tools/usb/Makefile index acf2165c04e6..76735aeac48a 100644 --- a/tools/usb/Makefile +++ b/tools/usb/Makefile @@ -1,6 +1,6 @@ # Makefile for USB tools -CC = $(CROSS_COMPILE)gcc +CC = $(CCACHE) $(CROSS_COMPILE)gcc PTHREAD_LIBS = -lpthread WARNINGS = -Wall -Wextra CFLAGS = $(WARNINGS) -g -I../include diff --git a/tools/usb/ffs-aio-example/multibuff/host_app/Makefile b/tools/usb/ffs-aio-example/multibuff/host_app/Makefile index 8c4a6f0aa82d..3be3806a0631 100644 --- a/tools/usb/ffs-aio-example/multibuff/host_app/Makefile +++ b/tools/usb/ffs-aio-example/multibuff/host_app/Makefile @@ -1,4 +1,4 @@ -CC = gcc +CC = $(CCACHE) $(CROSS_COMPILE)gcc LIBUSB_CFLAGS = $(shell pkg-config --cflags libusb-1.0) LIBUSB_LIBS = $(shell pkg-config --libs libusb-1.0) WARNINGS = -Wall -Wextra diff --git a/tools/usb/ffs-aio-example/simple/host_app/Makefile b/tools/usb/ffs-aio-example/simple/host_app/Makefile index 8c4a6f0aa82d..3be3806a0631 100644 --- a/tools/usb/ffs-aio-example/simple/host_app/Makefile +++ b/tools/usb/ffs-aio-example/simple/host_app/Makefile @@ -1,4 +1,4 @@ -CC = gcc +CC = $(CCACHE) $(CROSS_COMPILE)gcc LIBUSB_CFLAGS = $(shell pkg-config --cflags libusb-1.0) LIBUSB_LIBS = $(shell pkg-config --libs libusb-1.0) WARNINGS = -Wall -Wextra diff --git a/tools/virtio/virtio-trace/Makefile b/tools/virtio/virtio-trace/Makefile index 0d2381633475..9a614d1fc445 100644 --- a/tools/virtio/virtio-trace/Makefile +++ b/tools/virtio/virtio-trace/Makefile @@ -1,4 +1,4 @@ -CC = gcc +CC = $(CCACHE) $(CROSS_COMPILE)gcc CFLAGS = -O2 -Wall -pthread all: trace-agent diff --git a/tools/vm/Makefile b/tools/vm/Makefile index 93aadaf7ff63..a13662b68451 100644 --- a/tools/vm/Makefile +++ b/tools/vm/Makefile @@ -5,7 +5,7 @@ TARGETS=page-types slabinfo page_owner_sort LIB_DIR = ../lib/api LIBS = $(LIB_DIR)/libapi.a -CC = $(CROSS_COMPILE)gcc +CC = $(CCACHE) $(CROSS_COMPILE)gcc CFLAGS = -Wall -Wextra -I../lib/ LDFLAGS = $(LIBS) From 20c9f62a1541d266f5039b7ef7b2a34901d99989 Mon Sep 17 00:00:00 2001 From: ketikai Date: Fri, 10 Jul 2026 15:56:36 +0800 Subject: [PATCH 29/79] =?UTF-8?q?ci(build-kernel):=20=E5=9F=BA=E4=BA=8E?= =?UTF-8?q?=E5=BF=AB=E9=80=9F=E6=9E=84=E5=BB=BA=E8=84=9A=E6=9C=AC=20'assam?= =?UTF-8?q?ble'=20=E9=87=8D=E6=9E=84=E5=B7=A5=E4=BD=9C=E6=B5=81=E9=80=BB?= =?UTF-8?q?=E8=BE=91=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- .github/workflows/build-kernel.yml | 151 ++++++++++++----------------- 1 file changed, 63 insertions(+), 88 deletions(-) diff --git a/.github/workflows/build-kernel.yml b/.github/workflows/build-kernel.yml index 86b4fdf9a384..c1248f4f84e9 100644 --- a/.github/workflows/build-kernel.yml +++ b/.github/workflows/build-kernel.yml @@ -3,11 +3,26 @@ name: Build Kernel on: workflow_call: inputs: &workflow_inputs - kernel_defconfig: - description: Kernel - Defconfig + kernel_arch: + description: Kernel - Arch + type: string + required: false + default: arm64 + kernel_device: + description: Kernel - Device type: string required: false default: grus + llvm: + description: Use LLVM/Clang + type: boolean + required: false + default: true + verbose: + description: Enable more detailed logs + type: boolean + required: false + default: false ksu: description: With KernelSU type: boolean @@ -38,8 +53,8 @@ on: type: string required: false default: https://github.com/ketikai/android_kernel_xiaomi_sdm710/releases/download/prebuilt/proton-clang.tar.xz - prebuilt_anykernel: - description: Prebuilt - AnyKernel + prebuilt_anykernel_package: + description: Prebuilt - AnyKernel Package type: string required: false default: https://github.com/ketikai/android_kernel_xiaomi_sdm710/releases/download/prebuilt/anykernel.tar.xz @@ -47,117 +62,80 @@ on: inputs: *workflow_inputs env: - TOOLCHAIN_DIR: 'toolchain' - OUTPUT_DIR: 'build' + DESTINATION_DIR: .target BUILD_ARTIFACT: kernel ASSAMBLE_ARTIFACT: anykernel jobs: build: runs-on: ubuntu-22.04 - env: - CC: clang - CROSS_COMPILE: aarch64-linux-gnu- - CROSS_COMPILE_ARM32: arm-linux-gnueabi- - CROSS_TRIPLE: aarch64-linux-gnu- - ARCH: arm64 - SUBARCH: arm64 steps: - name: Checkout uses: actions/checkout@v7 - - name: Export Environment Variables + - name: Prepare Prebuilt + id: prepare_prebuilt env: - KERNEL_DEFCONFIG: ${{ inputs.kernel_defconfig }} - KERNEL_LOCALVERSION: ${{ inputs.kernel_localversion }} - PREBUILT_GCC_TOOLCHAIN: ${{ inputs.prebuilt_gcc_toolchain }} - PREBUILT_CLANG_TOOLCHAIN: ${{ inputs.prebuilt_clang_toolchain }} + TOOLCHAIN_DIR: .prebuilt/toolchain run: | - echo "DEFCONFIG=${KERNEL_DEFCONFIG}_defconfig" >> ${GITHUB_ENV} - if [[ -n "${KERNEL_LOCALVERSION}" ]]; then - echo "LOCALVERSION=-${KERNEL_LOCALVERSION}" >> ${GITHUB_ENV} - fi - echo "WORKER_SIZE=$(( $(nproc) * 2 - 1 ))" >> ${GITHUB_ENV} - echo "PREBUILT_GCC_TOOLCHAIN=${PREBUILT_GCC_TOOLCHAIN}" >> ${GITHUB_ENV} - echo "PREBUILT_CLANG_TOOLCHAIN=${PREBUILT_CLANG_TOOLCHAIN}" >> ${GITHUB_ENV} - - mkdir -p ${TOOLCHAIN_DIR} - echo "${PREBUILT_GCC_TOOLCHAIN}" > ${TOOLCHAIN_DIR}/.PREBUILT_GCC_TOOLCHAIN - echo "${PREBUILT_CLANG_TOOLCHAIN}" > ${TOOLCHAIN_DIR}/.PREBUILT_CLANG_TOOLCHAIN + DIR="${{ env.TOOLCHAIN_DIR }}/gcc" + mkdir -p $DIR + echo "GCC_TOOLCHAIN_DIR=$DIR" >> $GITHUB_OUTPUT + CACHE_KEY="${{ env.TOOLCHAIN_DIR }}/.GCC_TOOLCHAIN_CACHE_KEY" + echo "${{ inputs.prebuilt_gcc_toolchain }}" > $CACHE_KEY + echo "GCC_TOOLCHAIN_CACHE_KEY=$CACHE_KEY" >> $GITHUB_OUTPUT + + DIR="${{ env.TOOLCHAIN_DIR }}/clang" + mkdir -p $DIR + echo "CLANG_TOOLCHAIN_DIR=$DIR" >> $GITHUB_OUTPUT + CACHE_KEY="${{ env.TOOLCHAIN_DIR }}/.CLANG_TOOLCHAIN_CACHE_KEY" + echo "${{ inputs.prebuilt_clang_toolchain }}" > $CACHE_KEY + echo "CLANG_TOOLCHAIN_CACHE_KEY=$CACHE_KEY" >> $GITHUB_OUTPUT - name: Download Prebuilt GCC Toolchain From Cache uses: actions/cache@v6 - id: cache_prebuilt_gcc_toolchain + id: prebuilt_gcc_toolchain_cache with: - path: ${{ env.TOOLCHAIN_DIR }}/gcc - key: ${{ runner.os }}-${{ runner.arch }}-prebuilt-gcc-toolchain-${{ hashFiles(format('{0}/.PREBUILT_GCC_TOOLCHAIN', env.TOOLCHAIN_DIR)) }} + path: ${{ steps.prepare_prebuilt.outputs.GCC_TOOLCHAIN_DIR }} + key: ${{ runner.os }}-${{ runner.arch }}-prebuilt-gcc-toolchain-${{ hashFiles(steps.prepare_prebuilt.outputs.GCC_TOOLCHAIN_CACHE_KEY) }} - name: Download Prebuilt GCC Toolchain - if: steps.cache_prebuilt_gcc_toolchain.outputs.cache-hit != 'true' + if: steps.prebuilt_gcc_toolchain_cache.outputs.cache-hit != true run: | - mkdir -p ${TOOLCHAIN_DIR}/gcc/ - pushd ${TOOLCHAIN_DIR} - wget -O - ${PREBUILT_GCC_TOOLCHAIN} | tar -xJvf - -C gcc - popd + wget -O - ${{ inputs.prebuilt_gcc_toolchain }} | tar -xJvf - -C ${{ steps.prepare_prebuilt.outputs.GCC_TOOLCHAIN_DIR }} - name: Download Prebuilt Clang Toolchain From Cache uses: actions/cache@v6 - id: cache_prebuilt_clang_toolchain + id: prebuilt_clang_toolchain_cache with: - path: ${{ env.TOOLCHAIN_DIR }}/clang/ - key: ${{ runner.os }}-${{ runner.arch }}-prebuilt-clang-toolchain-${{ hashFiles(format('{0}/.PREBUILT_CLANG_TOOLCHAIN', env.TOOLCHAIN_DIR)) }} + path: ${{ steps.prepare_prebuilt.outputs.CLANG_TOOLCHAIN_DIR }} + key: ${{ runner.os }}-${{ runner.arch }}-prebuilt-clang-toolchain-${{ hashFiles(steps.prepare_prebuilt.outputs.CLANG_TOOLCHAIN_CACHE_KEY) }} - name: Download Prebuilt Clang Toolchain - if: steps.cache_prebuilt_clang_toolchain.outputs.cache-hit != 'true' + if: steps.prebuilt_clang_toolchain_cache.outputs.cache-hit != true run: | - mkdir -p ${TOOLCHAIN_DIR}/clang - pushd ${TOOLCHAIN_DIR} - wget -O - ${PREBUILT_CLANG_TOOLCHAIN} | tar -xJvf - -C clang - popd - - - name: Setup Prebuilt Toolchain - run: | - CLANG_TOOLCHAIN="$PWD/${TOOLCHAIN_DIR}/clang/bin" - GCC_ARM64_TOOLCHAIN="$PWD/${TOOLCHAIN_DIR}/gcc/aarch64-linux-gnu/bin" - GCC_ARM_TOOLCHAIN="$PWD/${TOOLCHAIN_DIR}/gcc/arm-linux-gnueabi/bin" - ls -ahl $CLANG_TOOLCHAIN - ls -ahl $GCC_ARM64_TOOLCHAIN - ls -ahl $GCC_ARM_TOOLCHAIN - echo "PATH=\"${CLANG_TOOLCHAIN}:${GCC_ARM64_TOOLCHAIN}:${GCC_ARM_TOOLCHAIN}:$PATH\"" >> ${GITHUB_ENV} + wget -O - ${{ inputs.prebuilt_clang_toolchain }} | tar -xJvf - -C ${{ steps.prepare_prebuilt.outputs.CLANG_TOOLCHAIN_DIR }} - name: KernelSU Integration - env: - KSU: ${{ inputs.ksu }} - KSU_SETUP_SCRIPT: ${{ inputs.ksu_setup_script }} - KSU_SETUP_BRANCH: ${{ inputs.ksu_setup_branch }} run: | - if ${KSU}; then - curl -LSs ${KSU_SETUP_SCRIPT} | bash -s ${KSU_SETUP_BRANCH} + if ${{ inputs.ksu }}; then + curl -LSs ${{ inputs.ksu_setup_script }} | bash -s ${{ inputs.ksu_setup_branch }} fi - - name: Make Config + - name: Execute assamble run: | - make O=${OUTPUT_DIR} ${DEFCONFIG} + LLVM=$(${{ inputs.llvm }} && echo "--llvm" || echo "") + VERSION=$([[ -n "${{ inputs.kernel_localversion }}" ]] && echo "--version ${{ inputs.kernel_localversion }}" || echo "") + SIGNING=$([[ -n "${{ secrets.SIGNING_KEY }}" ]] && echo "${{ secrets.SIGNING_KEY }}" > ".signing_key.pem"; echo "-s .signing_key.pem" || echo "") + VERBOSE=$(${{ inputs.verbose }} && echo "-v" || echo "") + ./assamble ${{ inputs.kernel_arch }} ${{ inputs.kernel_device }} $LLVM $VERSION $SIGNING $VERBOSE -d ${{ env.DESTINATION_DIR }} - - name: Detect External Signing Key - run: | - if [[ -n "${{ secrets.SIGNING_KEY }}" ]]; then - SIGNING_KEY_FILE=${PWD}/certs/external_signing_key.pem - echo "${{ secrets.SIGNING_KEY }}" > ${SIGNING_KEY_FILE} - scripts/config --file ${OUTPUT_DIR}/.config --set-str MODULE_SIG_KEY ${SIGNING_KEY_FILE} - make O=${OUTPUT_DIR} oldconfig - fi - - - name: Make Image - run: | - make O=${OUTPUT_DIR} -j${WORKER_SIZE} - - - name: Upload Kernel + - name: Upload Kernel And Modules uses: actions/upload-artifact@v7 with: name: ${{ env.BUILD_ARTIFACT }} path: | - ${{ env.OUTPUT_DIR }}/arch/arm64/boot/Image + ${{ env.DESTINATION_DIR }}/* if-no-files-found: error assamble: @@ -165,12 +143,10 @@ jobs: needs: - build steps: - - name: Download Prebuilt AnyKernel - env: - PREBUILT_ANYKERNEL: ${{ inputs.prebuilt_anykernel }} + - name: Download Prebuilt AnyKernel Package run: | - mkdir -p ${OUTPUT_DIR} - wget -O - ${PREBUILT_ANYKERNEL} | tar -xJvf - -C ${OUTPUT_DIR} + mkdir -p ${{ env.DESTINATION_DIR }} + wget -O - ${{ inputs.prebuilt_anykernel_package }} | tar -xJvf - -C ${{ env.DESTINATION_DIR }} - name: Download Kernel uses: actions/download-artifact@v8 @@ -178,15 +154,14 @@ jobs: name: ${{ env.BUILD_ARTIFACT }} path: ${{ env.BUILD_ARTIFACT }} - - name: Setup Kernel + - name: Setup Kernel Image run: | - cp ${BUILD_ARTIFACT}/Image ${OUTPUT_DIR}/ + cp "${{ env.BUILD_ARTIFACT }}/kernel/Image" "${{ env.DESTINATION_DIR }}" - - name: Upload AnyKernel + - name: Upload AnyKernel Package uses: actions/upload-artifact@v7 with: name: ${{ env.ASSAMBLE_ARTIFACT }} path: | - ${{ env.OUTPUT_DIR }}/* + ${{ env.DESTINATION_DIR }}/* if-no-files-found: error - include-hidden-files: true From 980c02ab226009552b004db40c64b02353911876 Mon Sep 17 00:00:00 2001 From: ketikai Date: Fri, 10 Jul 2026 16:27:18 +0800 Subject: [PATCH 30/79] =?UTF-8?q?chore(assamble):=20=E8=84=9A=E6=9C=AC=20`?= =?UTF-8?q?assamble`=20=E7=9A=84=E7=BC=93=E5=AD=98=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E4=BB=85=E5=9C=A8=E5=BD=93=E5=89=8D=E7=8E=AF?= =?UTF-8?q?=E5=A2=83=E5=B7=B2=E5=AE=89=E8=A3=85=20`ccache`=20=E7=9A=84?= =?UTF-8?q?=E6=83=85=E5=86=B5=E4=B8=8B=E7=94=9F=E6=95=88=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- assamble | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/assamble b/assamble index 2fd710220b9d..b721e5375d62 100755 --- a/assamble +++ b/assamble @@ -191,13 +191,15 @@ export PATH="$TOOLCHAIN_DIR/gcc/aarch64-linux-gnu/bin:$PATH" export PATH="$TOOLCHAIN_DIR/gcc/arm-linux-gnueabi/bin:$PATH" export PATH="$TOOLCHAIN_DIR/clang/bin:$PATH" -echo "配置缓存..." -export CCACHE="ccache" -export CCACHE_DIR=$CACHE_DIR -ccache --show-config -if (( $CLEAN != 0 )); then - echo "清理缓存..." - ccache -zC +if command -v ccache >/dev/null 2>&1; then + echo "配置缓存..." + export CCACHE="ccache" + export CCACHE_DIR=$CACHE_DIR + ccache --show-config + if (( $CLEAN != 0 )); then + echo "清理缓存..." + ccache -zC + fi fi V=$((( $VERBOSE != 0 )) && echo 'V=1' || echo 'V=s') @@ -259,4 +261,6 @@ popd popd -ccache -s -v +if command -v ccache >/dev/null 2>&1; then + ccache -s -v +fi From 2807a31f500c74abc40da4f2adbccea697b97161 Mon Sep 17 00:00:00 2001 From: ketikai Date: Fri, 10 Jul 2026 17:03:56 +0800 Subject: [PATCH 31/79] =?UTF-8?q?ci(build-kernel)=20fix(build-kernel):=20?= =?UTF-8?q?=E4=B8=BA=20`actions/upload-artifact`=20=E5=90=AF=E7=94=A8?= =?UTF-8?q?=E5=8C=85=E5=90=AB=E9=9A=90=E8=97=8F=E6=96=87=E4=BB=B6=E7=9A=84?= =?UTF-8?q?=E9=80=89=E9=A1=B9=EF=BC=8C=E4=BB=A5=E6=AD=A4=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E6=89=BE=E5=88=B0=E7=9B=AE=E6=A0=87=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E7=9A=84=E9=97=AE=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- .github/workflows/build-kernel.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/build-kernel.yml b/.github/workflows/build-kernel.yml index c1248f4f84e9..ecfab6fc418d 100644 --- a/.github/workflows/build-kernel.yml +++ b/.github/workflows/build-kernel.yml @@ -137,6 +137,8 @@ jobs: path: | ${{ env.DESTINATION_DIR }}/* if-no-files-found: error + overwrite: true + include-hidden-files: true assamble: runs-on: ubuntu-22.04 @@ -165,3 +167,5 @@ jobs: path: | ${{ env.DESTINATION_DIR }}/* if-no-files-found: error + overwrite: true + include-hidden-files: true From f77e4a813cf380d70ae0b571fe2808ce68ffdc85 Mon Sep 17 00:00:00 2001 From: ketikai Date: Mon, 13 Jul 2026 10:35:52 +0800 Subject: [PATCH 32/79] =?UTF-8?q?revert(Makefile):=20"feat(Makefile),=20fi?= =?UTF-8?q?x(Makefile):=20=E6=8F=90=E4=BE=9B=20`ccache`=20=E6=94=AF?= =?UTF-8?q?=E6=8C=81=EF=BC=8C=E4=BF=AE=E6=AD=A3=E9=83=A8=E5=88=86=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=E4=B8=AD=E5=8F=AF=E8=83=BD=E9=94=99=E8=AF=AF=E7=9A=84?= =?UTF-8?q?=E6=8C=87=E5=AE=9A=E7=BC=96=E8=AF=91=E5=99=A8=E3=80=82"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit bffe7ff55b358f9ce2a94a729bca281d5199f787. --- Makefile | 12 ++++++------ arch/m68k/tools/amiga/Makefile | 2 +- lib/raid6/test/Makefile | 2 +- samples/auxdisplay/Makefile | 2 +- samples/mei/Makefile | 2 +- samples/mic/mpssd/Makefile | 2 +- samples/timers/Makefile | 2 +- samples/watchdog/Makefile | 2 +- tools/accounting/Makefile | 2 +- tools/build/feature/Makefile | 2 +- tools/cgroup/Makefile | 2 +- tools/firewire/Makefile | 2 +- tools/gpio/Makefile | 2 +- tools/hv/Makefile | 2 +- tools/iio/Makefile | 2 +- tools/laptop/dslm/Makefile | 2 +- tools/laptop/freefall/Makefile | 2 +- tools/lib/api/Makefile | 2 +- tools/net/Makefile | 2 +- tools/pcmcia/Makefile | 2 +- tools/power/acpi/Makefile.config | 2 +- tools/power/cpupower/Makefile | 11 +++++------ tools/power/x86/turbostat/Makefile | 2 +- tools/spi/Makefile | 2 +- tools/testing/selftests/intel_pstate/Makefile | 2 +- tools/testing/selftests/memfd/Makefile | 2 +- tools/testing/selftests/timers/Makefile | 2 +- tools/thermal/tmon/Makefile | 2 +- tools/usb/Makefile | 2 +- .../usb/ffs-aio-example/multibuff/host_app/Makefile | 2 +- tools/usb/ffs-aio-example/simple/host_app/Makefile | 2 +- tools/virtio/virtio-trace/Makefile | 2 +- tools/vm/Makefile | 2 +- 33 files changed, 42 insertions(+), 43 deletions(-) diff --git a/Makefile b/Makefile index 2fdbb4a94d8d..09c701add89b 100644 --- a/Makefile +++ b/Makefile @@ -302,11 +302,11 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ else echo sh; fi ; fi) ifneq ($(LLVM),) -HOSTCC = $(CCACHE) clang -HOSTCXX = $(CCACHE) clang++ +HOSTCC = clang +HOSTCXX = clang++ else -HOSTCC = $(CCACHE) gcc -HOSTCXX = $(CCACHE) g++ +HOSTCC = gcc +HOSTCXX = g++ endif HOSTCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer -std=gnu99 @@ -351,7 +351,7 @@ include scripts/Kbuild.include LDGOLD = $(CROSS_COMPILE)ld.gold CPP = $(CC) -E ifneq ($(LLVM),) -CC = $(CCACHE) clang +CC = clang LD = ld.lld AR = llvm-ar NM = llvm-nm @@ -363,7 +363,7 @@ STRIP = llvm-strip else AS = $(CROSS_COMPILE)as LD = $(CROSS_COMPILE)ld -CC = $(CCACHE) $(CROSS_COMPILE)gcc +CC = $(CROSS_COMPILE)gcc AR = $(CROSS_COMPILE)ar NM = $(CROSS_COMPILE)nm STRIP = $(CROSS_COMPILE)strip diff --git a/arch/m68k/tools/amiga/Makefile b/arch/m68k/tools/amiga/Makefile index e389e8616c2d..113436136089 100644 --- a/arch/m68k/tools/amiga/Makefile +++ b/arch/m68k/tools/amiga/Makefile @@ -1,5 +1,5 @@ -CC = $(CCACHE) m68k-cbm-amigados-gcc +CC = m68k-cbm-amigados-gcc CFLAGS = -Wall -O2 diff --git a/lib/raid6/test/Makefile b/lib/raid6/test/Makefile index 065960d959c6..1faeef0c30b9 100644 --- a/lib/raid6/test/Makefile +++ b/lib/raid6/test/Makefile @@ -3,7 +3,7 @@ # from userspace. # -CC = $(CCACHE) $(CROSS_COMPILE)gcc +CC = gcc OPTFLAGS = -O2 # Adjust as desired CFLAGS = -I.. -I ../../../include -g $(OPTFLAGS) LD = ld diff --git a/samples/auxdisplay/Makefile b/samples/auxdisplay/Makefile index 839465b256df..05e471feb6e5 100644 --- a/samples/auxdisplay/Makefile +++ b/samples/auxdisplay/Makefile @@ -1,4 +1,4 @@ -CC := $(CCACHE) $(CROSS_COMPILE)gcc +CC := $(CROSS_COMPILE)gcc CFLAGS := -I../../usr/include PROGS := cfag12864b-example diff --git a/samples/mei/Makefile b/samples/mei/Makefile index e6c8689c7c7b..7aac216dc420 100644 --- a/samples/mei/Makefile +++ b/samples/mei/Makefile @@ -1,4 +1,4 @@ -CC := $(CCACHE) $(CROSS_COMPILE)gcc +CC := $(CROSS_COMPILE)gcc CFLAGS := -I../../usr/include PROGS := mei-amt-version diff --git a/samples/mic/mpssd/Makefile b/samples/mic/mpssd/Makefile index 6b320c0c5db0..3e3ef91fed6b 100644 --- a/samples/mic/mpssd/Makefile +++ b/samples/mic/mpssd/Makefile @@ -5,7 +5,7 @@ ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/) ifeq ($(ARCH),x86) PROGS := mpssd -CC = $(CCACHE) $(CROSS_COMPILE)gcc +CC = $(CROSS_COMPILE)gcc CFLAGS := -I../../../usr/include -I../../../tools/include ifdef DEBUG diff --git a/samples/timers/Makefile b/samples/timers/Makefile index dd17c4a6130e..a5c3c4a35ca1 100644 --- a/samples/timers/Makefile +++ b/samples/timers/Makefile @@ -3,7 +3,7 @@ uname_M := $(shell uname -m 2>/dev/null || echo not) ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/) ifeq ($(ARCH),x86) -CC := $(CCACHE) $(CROSS_COMPILE)gcc +CC := $(CROSS_COMPILE)gcc PROGS := hpet_example all: $(PROGS) diff --git a/samples/watchdog/Makefile b/samples/watchdog/Makefile index 0864f2fb122d..9b53d89b1ccf 100644 --- a/samples/watchdog/Makefile +++ b/samples/watchdog/Makefile @@ -1,4 +1,4 @@ -CC := $(CCACHE) $(CROSS_COMPILE)gcc +CC := $(CROSS_COMPILE)gcc PROGS := watchdog-simple all: $(PROGS) diff --git a/tools/accounting/Makefile b/tools/accounting/Makefile index 55dd9d02a1c9..647c94a219bf 100644 --- a/tools/accounting/Makefile +++ b/tools/accounting/Makefile @@ -1,4 +1,4 @@ -CC := $(CCACHE) $(CROSS_COMPILE)gcc +CC := $(CROSS_COMPILE)gcc CFLAGS := -I../../usr/include PROGS := getdelays diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile index ebff899de362..46af3bb56142 100644 --- a/tools/build/feature/Makefile +++ b/tools/build/feature/Makefile @@ -51,7 +51,7 @@ FILES= \ FILES := $(addprefix $(OUTPUT),$(FILES)) -CC := $(CCACHE) $(CROSS_COMPILE)gcc -MD +CC := $(CROSS_COMPILE)gcc -MD CXX := $(CROSS_COMPILE)g++ -MD PKG_CONFIG := $(CROSS_COMPILE)pkg-config diff --git a/tools/cgroup/Makefile b/tools/cgroup/Makefile index e2d5740f898d..b4286196b763 100644 --- a/tools/cgroup/Makefile +++ b/tools/cgroup/Makefile @@ -1,6 +1,6 @@ # Makefile for cgroup tools -CC = $(CCACHE) $(CROSS_COMPILE)gcc +CC = $(CROSS_COMPILE)gcc CFLAGS = -Wall -Wextra all: cgroup_event_listener diff --git a/tools/firewire/Makefile b/tools/firewire/Makefile index f51e607a1116..81767adaae7d 100644 --- a/tools/firewire/Makefile +++ b/tools/firewire/Makefile @@ -1,7 +1,7 @@ prefix = /usr nosy-dump-version = 0.4 -CC = $(CCACHE) $(CROSS_COMPILE)gcc +CC = gcc all : nosy-dump diff --git a/tools/gpio/Makefile b/tools/gpio/Makefile index 0c4d191a1371..e2ac49253a0a 100644 --- a/tools/gpio/Makefile +++ b/tools/gpio/Makefile @@ -11,7 +11,7 @@ endif # (this improves performance and avoids hard-to-debug behaviour); MAKEFLAGS += -r -CC = $(CCACHE) $(CROSS_COMPILE)gcc +CC = $(CROSS_COMPILE)gcc LD = $(CROSS_COMPILE)ld CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include diff --git a/tools/hv/Makefile b/tools/hv/Makefile index 7c9d4ec3ab21..a8c4644022a6 100644 --- a/tools/hv/Makefile +++ b/tools/hv/Makefile @@ -1,6 +1,6 @@ # Makefile for Hyper-V tools -CC = $(CCACHE) $(CROSS_COMPILE)gcc +CC = $(CROSS_COMPILE)gcc PTHREAD_LIBS = -lpthread WARNINGS = -Wall -Wextra CFLAGS = $(WARNINGS) -g $(PTHREAD_LIBS) $(shell getconf LFS_CFLAGS) diff --git a/tools/iio/Makefile b/tools/iio/Makefile index 68647bce6906..5446d625e17d 100644 --- a/tools/iio/Makefile +++ b/tools/iio/Makefile @@ -1,4 +1,4 @@ -CC = $(CCACHE) $(CROSS_COMPILE)gcc +CC = $(CROSS_COMPILE)gcc CFLAGS += -Wall -g -D_GNU_SOURCE BINDIR=usr/bin diff --git a/tools/laptop/dslm/Makefile b/tools/laptop/dslm/Makefile index 6c4f28d4d0e4..ff613b31730b 100644 --- a/tools/laptop/dslm/Makefile +++ b/tools/laptop/dslm/Makefile @@ -1,4 +1,4 @@ -CC := $(CCACHE) $(CROSS_COMPILE)gcc +CC := $(CROSS_COMPILE)gcc CFLAGS := -I../../usr/include PROGS := dslm diff --git a/tools/laptop/freefall/Makefile b/tools/laptop/freefall/Makefile index d889f9ac0613..48c6c9328419 100644 --- a/tools/laptop/freefall/Makefile +++ b/tools/laptop/freefall/Makefile @@ -1,7 +1,7 @@ PREFIX ?= /usr SBINDIR ?= sbin INSTALL ?= install -CC = $(CCACHE) $(CROSS_COMPILE)gcc +CC = $(CROSS_COMPILE)gcc TARGET = freefall diff --git a/tools/lib/api/Makefile b/tools/lib/api/Makefile index 48002de319f0..0a6fda9837f7 100644 --- a/tools/lib/api/Makefile +++ b/tools/lib/api/Makefile @@ -8,7 +8,7 @@ srctree := $(patsubst %/,%,$(dir $(srctree))) #$(info Determined 'srctree' to be $(srctree)) endif -CC = $(CCACHE) $(CROSS_COMPILE)gcc +CC = $(CROSS_COMPILE)gcc AR = $(CROSS_COMPILE)ar LD = $(CROSS_COMPILE)ld diff --git a/tools/net/Makefile b/tools/net/Makefile index 3ca56a12cf12..ddf888010652 100644 --- a/tools/net/Makefile +++ b/tools/net/Makefile @@ -1,6 +1,6 @@ prefix = /usr -CC = $(CCACHE) $(CROSS_COMPILE)gcc +CC = gcc LEX = flex YACC = bison diff --git a/tools/pcmcia/Makefile b/tools/pcmcia/Makefile index caff5aed82f4..81a7498c5cd9 100644 --- a/tools/pcmcia/Makefile +++ b/tools/pcmcia/Makefile @@ -1,4 +1,4 @@ -CC := $(CCACHE) $(CROSS_COMPILE)gcc +CC := $(CROSS_COMPILE)gcc CFLAGS := -I../../usr/include PROGS := crc32hash diff --git a/tools/power/acpi/Makefile.config b/tools/power/acpi/Makefile.config index 40cd0bf0c922..fb5559f9819a 100644 --- a/tools/power/acpi/Makefile.config +++ b/tools/power/acpi/Makefile.config @@ -56,7 +56,7 @@ INSTALL_SCRIPT = ${INSTALL_PROGRAM} # to compile vs uClibc, that can be done here as well. CROSS = #/usr/i386-linux-uclibc/usr/bin/i386-uclibc- CROSS_COMPILE ?= $(CROSS) -CC = $(CCACHE) $(CROSS_COMPILE)gcc +CC = $(CROSS_COMPILE)gcc LD = $(CROSS_COMPILE)gcc STRIP = $(CROSS_COMPILE)strip HOSTCC = gcc diff --git a/tools/power/cpupower/Makefile b/tools/power/cpupower/Makefile index 8155b5e6c9bd..8358863259c5 100644 --- a/tools/power/cpupower/Makefile +++ b/tools/power/cpupower/Makefile @@ -96,12 +96,11 @@ INSTALL_SCRIPT = ${INSTALL_PROGRAM} # to something more interesting, like "arm-linux-". If you want # to compile vs uClibc, that can be done here as well. CROSS = #/usr/i386-linux-uclibc/usr/bin/i386-uclibc- -CROSS_COMPILE ?= $(CROSS) -CC = $(CCACHE) $(CROSS_COMPILE)gcc -LD = $(CROSS_COMPILE)gcc -AR = $(CROSS_COMPILE)ar -STRIP = $(CROSS_COMPILE)strip -RANLIB = $(CROSS_COMPILE)ranlib +CC = $(CROSS)gcc +LD = $(CROSS)gcc +AR = $(CROSS)ar +STRIP = $(CROSS)strip +RANLIB = $(CROSS)ranlib HOSTCC = gcc MKDIR = mkdir diff --git a/tools/power/x86/turbostat/Makefile b/tools/power/x86/turbostat/Makefile index 786aa356e714..92be948c922d 100644 --- a/tools/power/x86/turbostat/Makefile +++ b/tools/power/x86/turbostat/Makefile @@ -1,4 +1,4 @@ -CC = $(CCACHE) $(CROSS_COMPILE)gcc +CC = $(CROSS_COMPILE)gcc BUILD_OUTPUT := $(CURDIR) PREFIX ?= /usr DESTDIR ?= diff --git a/tools/spi/Makefile b/tools/spi/Makefile index b785148c0373..3815b18ba070 100644 --- a/tools/spi/Makefile +++ b/tools/spi/Makefile @@ -1,4 +1,4 @@ -CC = $(CCACHE) $(CROSS_COMPILE)gcc +CC = $(CROSS_COMPILE)gcc all: spidev_test spidev_fdx diff --git a/tools/testing/selftests/intel_pstate/Makefile b/tools/testing/selftests/intel_pstate/Makefile index 9eea6fdd373f..f5f1a28715ff 100644 --- a/tools/testing/selftests/intel_pstate/Makefile +++ b/tools/testing/selftests/intel_pstate/Makefile @@ -1,4 +1,4 @@ -CC := $(CCACHE) $(CROSS_COMPILE)gcc +CC := $(CROSS_COMPILE)gcc CFLAGS := $(CFLAGS) -Wall -D_GNU_SOURCE LDFLAGS := $(LDFLAGS) -lm diff --git a/tools/testing/selftests/memfd/Makefile b/tools/testing/selftests/memfd/Makefile index 93dba5b0a870..fd396ac811b6 100644 --- a/tools/testing/selftests/memfd/Makefile +++ b/tools/testing/selftests/memfd/Makefile @@ -1,4 +1,4 @@ -CC = $(CCACHE) $(CROSS_COMPILE)gcc +CC = $(CROSS_COMPILE)gcc CFLAGS += -D_FILE_OFFSET_BITS=64 CFLAGS += -I../../../../include/uapi/ CFLAGS += -I../../../../include/ diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile index 07368c04eb99..1d5556869137 100644 --- a/tools/testing/selftests/timers/Makefile +++ b/tools/testing/selftests/timers/Makefile @@ -1,4 +1,4 @@ -CC = $(CCACHE) $(CROSS_COMPILE)gcc +CC = $(CROSS_COMPILE)gcc BUILD_FLAGS = -DKTEST CFLAGS += -O3 -Wl,-no-as-needed -Wall $(BUILD_FLAGS) LDFLAGS += -lrt -lpthread diff --git a/tools/thermal/tmon/Makefile b/tools/thermal/tmon/Makefile index 63f9722639ed..3a961e998281 100644 --- a/tools/thermal/tmon/Makefile +++ b/tools/thermal/tmon/Makefile @@ -3,7 +3,7 @@ VERSION = 1.0 BINDIR=usr/bin WARNFLAGS=-Wall -Wshadow -W -Wformat -Wimplicit-function-declaration -Wimplicit-int CFLAGS+= -O1 ${WARNFLAGS} -fstack-protector -CC=$(CCACHE) $(CROSS_COMPILE)gcc +CC=$(CROSS_COMPILE)gcc CFLAGS+=-D VERSION=\"$(VERSION)\" LDFLAGS+= diff --git a/tools/usb/Makefile b/tools/usb/Makefile index 76735aeac48a..acf2165c04e6 100644 --- a/tools/usb/Makefile +++ b/tools/usb/Makefile @@ -1,6 +1,6 @@ # Makefile for USB tools -CC = $(CCACHE) $(CROSS_COMPILE)gcc +CC = $(CROSS_COMPILE)gcc PTHREAD_LIBS = -lpthread WARNINGS = -Wall -Wextra CFLAGS = $(WARNINGS) -g -I../include diff --git a/tools/usb/ffs-aio-example/multibuff/host_app/Makefile b/tools/usb/ffs-aio-example/multibuff/host_app/Makefile index 3be3806a0631..8c4a6f0aa82d 100644 --- a/tools/usb/ffs-aio-example/multibuff/host_app/Makefile +++ b/tools/usb/ffs-aio-example/multibuff/host_app/Makefile @@ -1,4 +1,4 @@ -CC = $(CCACHE) $(CROSS_COMPILE)gcc +CC = gcc LIBUSB_CFLAGS = $(shell pkg-config --cflags libusb-1.0) LIBUSB_LIBS = $(shell pkg-config --libs libusb-1.0) WARNINGS = -Wall -Wextra diff --git a/tools/usb/ffs-aio-example/simple/host_app/Makefile b/tools/usb/ffs-aio-example/simple/host_app/Makefile index 3be3806a0631..8c4a6f0aa82d 100644 --- a/tools/usb/ffs-aio-example/simple/host_app/Makefile +++ b/tools/usb/ffs-aio-example/simple/host_app/Makefile @@ -1,4 +1,4 @@ -CC = $(CCACHE) $(CROSS_COMPILE)gcc +CC = gcc LIBUSB_CFLAGS = $(shell pkg-config --cflags libusb-1.0) LIBUSB_LIBS = $(shell pkg-config --libs libusb-1.0) WARNINGS = -Wall -Wextra diff --git a/tools/virtio/virtio-trace/Makefile b/tools/virtio/virtio-trace/Makefile index 9a614d1fc445..0d2381633475 100644 --- a/tools/virtio/virtio-trace/Makefile +++ b/tools/virtio/virtio-trace/Makefile @@ -1,4 +1,4 @@ -CC = $(CCACHE) $(CROSS_COMPILE)gcc +CC = gcc CFLAGS = -O2 -Wall -pthread all: trace-agent diff --git a/tools/vm/Makefile b/tools/vm/Makefile index a13662b68451..93aadaf7ff63 100644 --- a/tools/vm/Makefile +++ b/tools/vm/Makefile @@ -5,7 +5,7 @@ TARGETS=page-types slabinfo page_owner_sort LIB_DIR = ../lib/api LIBS = $(LIB_DIR)/libapi.a -CC = $(CCACHE) $(CROSS_COMPILE)gcc +CC = $(CROSS_COMPILE)gcc CFLAGS = -Wall -Wextra -I../lib/ LDFLAGS = $(LIBS) From 90e7bbee6b7c5361990127e489118a3447a44cc4 Mon Sep 17 00:00:00 2001 From: ketikai Date: Mon, 13 Jul 2026 12:28:56 +0800 Subject: [PATCH 33/79] =?UTF-8?q?chore(grus=5Fdefconfig):=20=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=E5=9C=A8=20'grus'=20=E9=BB=98=E8=AE=A4=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E4=B8=AD=E6=97=A0=E6=84=8F=E4=B9=89=E7=9A=84=E9=87=8D?= =?UTF-8?q?=E5=A4=8D=E9=A1=B9=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- arch/arm64/configs/grus_defconfig | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/arch/arm64/configs/grus_defconfig b/arch/arm64/configs/grus_defconfig index f8b18f60b205..764f22875ead 100644 --- a/arch/arm64/configs/grus_defconfig +++ b/arch/arm64/configs/grus_defconfig @@ -697,23 +697,10 @@ CONFIG_CJSON=y CONFIG_HWCONF_MANAGER=y CONFIG_BOOT_INFO=y CONFIG_OF_FLATTREE=y -CONFIG_IR_SPI=y -CONFIG_LIRC=y CONFIG_RC_CORE=y CONFIG_RC_DECODERS=y -CONFIG_MEDIA_RC_SUPPORT=y CONFIG_HAS_IOMEM=y -CONFIG_RC_DEVICES=y -CONFIG_PSTORE=y -CONFIG_PSTORE_RAM=y -CONFIG_PSTORE_CONSOLE=y -CONFIG_PSTORE_PMSG=y -CONFIG_CMDLINE="ramoops_memreserve=4M" -CONFIG_CMDLINE_EXTEND=y -CONFIG_TOUCHSCREEN_GOODIX_GTX8=y CONFIG_HALLS=y CONFIG_MIGT=y -CONFIG_HID_SONY=y CONFIG_XLOGCHAR=y CONFIG_RTMM=y -CONFIG_PROCESS_RECLAIM=y From 4afa716c4fbaaf7a2d4dba082e6dfc36145ff943 Mon Sep 17 00:00:00 2001 From: ketikai Date: Mon, 13 Jul 2026 14:32:46 +0800 Subject: [PATCH 34/79] =?UTF-8?q?chore(Makefile):=20=E7=A7=BB=E9=99=A4=20`?= =?UTF-8?q?drivers/media/platform/msm/camera=5Fv2`=20=E4=B8=8B=E9=83=A8?= =?UTF-8?q?=E5=88=86=20`Makefile`=20=E4=B8=AD=E8=8E=B7=E5=8F=96=20`GCC=5FV?= =?UTF-8?q?ERSION`=20=E7=9A=84=E6=93=8D=E4=BD=9C=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- drivers/media/platform/msm/camera_v2/fd/Makefile | 1 - drivers/media/platform/msm/camera_v2/jpeg_10/Makefile | 2 -- drivers/media/platform/msm/camera_v2/jpeg_dma/Makefile | 1 - 3 files changed, 4 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/fd/Makefile b/drivers/media/platform/msm/camera_v2/fd/Makefile index 8d01d3a8708d..a1d33dad11fc 100644 --- a/drivers/media/platform/msm/camera_v2/fd/Makefile +++ b/drivers/media/platform/msm/camera_v2/fd/Makefile @@ -1,4 +1,3 @@ -GCC_VERSION := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc) ccflags-y += -Idrivers/media/video/msm ccflags-y += -Idrivers/media/platform/msm/camera_v2/common ccflags-y += -Idrivers/media/platform/msm/camera_v2 diff --git a/drivers/media/platform/msm/camera_v2/jpeg_10/Makefile b/drivers/media/platform/msm/camera_v2/jpeg_10/Makefile index 0b8dc1db225c..72808f94c54b 100644 --- a/drivers/media/platform/msm/camera_v2/jpeg_10/Makefile +++ b/drivers/media/platform/msm/camera_v2/jpeg_10/Makefile @@ -1,5 +1,3 @@ -GCC_VERSION := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc) - ccflags-y += -Idrivers/media/platform/msm/camera_v2/jpeg_10 ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/io ccflags-y += -Idrivers/media/platform/msm/camera_v2/common diff --git a/drivers/media/platform/msm/camera_v2/jpeg_dma/Makefile b/drivers/media/platform/msm/camera_v2/jpeg_dma/Makefile index 21cbadbd6425..239b664b78d5 100644 --- a/drivers/media/platform/msm/camera_v2/jpeg_dma/Makefile +++ b/drivers/media/platform/msm/camera_v2/jpeg_dma/Makefile @@ -1,4 +1,3 @@ -GCC_VERSION := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc) ccflags-y += -Idrivers/media/video/msm ccflags-y += -Idrivers/media/platform/msm/camera_v2/common obj-$(CONFIG_MSM_JPEGDMA) += msm_jpeg_dma_dev.o msm_jpeg_dma_hw.o From ad0d3950ffef531de3c137a93275f425860e0c3b Mon Sep 17 00:00:00 2001 From: ketikai Date: Mon, 13 Jul 2026 14:54:34 +0800 Subject: [PATCH 35/79] =?UTF-8?q?chore(scripts)=20fix(Makefile.clean):=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20`=5F=5Fclean`=20=E4=B8=8B=E7=9A=84?= =?UTF-8?q?=E5=AF=B9=E4=BA=8E=E8=B6=85=E9=95=BF=E5=91=BD=E4=BB=A4=E5=A4=84?= =?UTF-8?q?=E7=90=86=E9=80=BB=E8=BE=91=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- scripts/Makefile.clean | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean index 2e70c6f06354..ebfe75a0ef13 100644 --- a/scripts/Makefile.clean +++ b/scripts/Makefile.clean @@ -60,10 +60,13 @@ __clean-dirs := $(wildcard \ # ========================================================================== +# To make this rule robust against "Argument list too long" error, +# remove $(obj)/ prefix, and restore it by a shell command. +# See https://android.googlesource.com/kernel/common/+/refs/tags/android16-6.12-2025-06_r38/scripts/Makefile.clean quiet_cmd_clean = CLEAN $(obj) - cmd_clean = rm -f $(__clean-files) + cmd_clean = printf '$(obj)/%s ' $(patsubst $(obj)/%,%,$(__clean-files)) | xargs rm -f quiet_cmd_cleandir = CLEAN $(__clean-dirs) - cmd_cleandir = rm -rf $(__clean-dirs) + cmd_cleandir = printf '$(obj)/%s ' $(patsubst $(obj)/%,%,$(__clean-dirs)) | xargs rm -rf __clean: $(subdir-ymn) From 9d8e997987bbeb5a46434d20335b7295fba8f4e7 Mon Sep 17 00:00:00 2001 From: ketikai Date: Mon, 13 Jul 2026 18:23:14 +0800 Subject: [PATCH 36/79] =?UTF-8?q?chore(Makefile):=20=E9=87=8D=E6=96=B0?= =?UTF-8?q?=E6=94=AF=E6=8C=81=20`ccache`=20=EF=BC=8C=E4=B8=BA=20`clang`=20?= =?UTF-8?q?=E5=BF=BD=E7=95=A5=20`gcc`=20=E4=B8=93=E6=9C=89=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E5=8F=82=E6=95=B0=20`-fmerge-constants`=20=EF=BC=8C?= =?UTF-8?q?=E5=90=AF=E7=94=A8=20`cflags`=20=E6=A0=87=E7=AD=BE=20`-Wno-erro?= =?UTF-8?q?r`=20=E4=BB=A5=E6=94=AF=E6=8C=81=E6=9B=B4=E9=AB=98=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E7=9A=84=20`clang`=20=E8=BF=9B=E8=A1=8C=E6=9E=84?= =?UTF-8?q?=E5=BB=BA=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- Makefile | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 09c701add89b..de51ccbe3a66 100644 --- a/Makefile +++ b/Makefile @@ -302,11 +302,11 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ else echo sh; fi ; fi) ifneq ($(LLVM),) -HOSTCC = clang -HOSTCXX = clang++ +HOSTCC = $(CCACHE) clang +HOSTCXX = $(CCACHE) clang++ else -HOSTCC = gcc -HOSTCXX = g++ +HOSTCC = $(CCACHE) gcc +HOSTCXX = $(CCACHE) g++ endif HOSTCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer -std=gnu99 @@ -351,7 +351,7 @@ include scripts/Kbuild.include LDGOLD = $(CROSS_COMPILE)ld.gold CPP = $(CC) -E ifneq ($(LLVM),) -CC = clang +CC = $(CCACHE) clang LD = ld.lld AR = llvm-ar NM = llvm-nm @@ -363,7 +363,7 @@ STRIP = llvm-strip else AS = $(CROSS_COMPILE)as LD = $(CROSS_COMPILE)ld -CC = $(CROSS_COMPILE)gcc +CC = $(CCACHE) $(CROSS_COMPILE)gcc AR = $(CROSS_COMPILE)ar NM = $(CROSS_COMPILE)nm STRIP = $(CROSS_COMPILE)strip @@ -412,7 +412,7 @@ KBUILD_AFLAGS := -D__ASSEMBLY__ KBUILD_CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ -fno-strict-aliasing -fno-common -fshort-wchar \ -Werror-implicit-function-declaration \ - -Wno-format-security \ + -Wno-format-security -Wno-error \ -std=gnu99 KBUILD_CPPFLAGS := -D__KERNEL__ KBUILD_AFLAGS_KERNEL := @@ -923,7 +923,9 @@ KBUILD_CFLAGS += $(call cc-option,-fno-merge-all-constants) # for gcc -fno-merge-all-constants disables everything, but it is fine # to have actual conforming behavior enabled. +ifneq ($(cc-name),clang) KBUILD_CFLAGS += $(call cc-option,-fmerge-constants) +endif # Make sure -fstack-check isn't enabled (like gentoo apparently did) KBUILD_CFLAGS += $(call cc-option,-fno-stack-check,) From c73c44296705e3344db569d50156ccd6dddcf13a Mon Sep 17 00:00:00 2001 From: ketikai Date: Mon, 13 Jul 2026 19:02:47 +0800 Subject: [PATCH 37/79] =?UTF-8?q?chore(.gitignore):=20=E5=BF=BD=E7=95=A5?= =?UTF-8?q?=E7=94=9F=E6=88=90=E8=87=AA=20Bear=20=E7=9A=84=E7=BC=96?= =?UTF-8?q?=E8=AF=91=E6=95=B0=E6=8D=AE=E5=BA=93=20`compile=5Fcommands*.jso?= =?UTF-8?q?n`=20=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index ddb1be924a59..854744af387a 100644 --- a/.gitignore +++ b/.gitignore @@ -126,4 +126,7 @@ Android.bp out # Includ '.github' -!.github \ No newline at end of file +!.github + +# Ignoring Bear JSON compilation database +compile_commands*.json From cb7a3387b36c4020ef22cb6074d254cb551bfea3 Mon Sep 17 00:00:00 2001 From: ketikai Date: Mon, 13 Jul 2026 19:11:27 +0800 Subject: [PATCH 38/79] =?UTF-8?q?chore(assamble)=20perf(assamble)=20feat(a?= =?UTF-8?q?ssamble):=20=E4=BC=98=E5=8C=96=E8=84=9A=E6=9C=AC=20`assamble`?= =?UTF-8?q?=20=E7=9A=84=E9=83=A8=E5=88=86=E9=80=89=E9=A1=B9=E5=88=A4?= =?UTF-8?q?=E6=96=AD=E9=80=BB=E8=BE=91=EF=BC=8C=E7=BB=86=E5=8C=96=E4=BA=A4?= =?UTF-8?q?=E5=8F=89=E7=BC=96=E8=AF=91=E5=92=8C=20GCC/Clang=20=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E9=93=BE=E7=9A=84=E5=AF=BC=E5=87=BA=E6=97=B6=E6=9C=BA?= =?UTF-8?q?=EF=BC=8C=E6=9B=B4=E5=A5=BD=E7=9A=84=20help=20=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=EF=BC=8C=E4=BF=AE=E6=94=B9=E9=83=A8=E5=88=86=E9=9D=9E?= =?UTF-8?q?=E5=BF=85=E8=A6=81=E9=80=89=E9=A1=B9=E7=9A=84=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E5=80=BC=EF=BC=8C=E6=8F=90=E4=BE=9B=20`Bear`=20=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- assamble | 205 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 142 insertions(+), 63 deletions(-) diff --git a/assamble b/assamble index b721e5375d62..f807a9a511c7 100755 --- a/assamble +++ b/assamble @@ -4,14 +4,32 @@ set -e +echo "展开调用: " +echo "$0 $*" + +PREBUILT_DIR="" +CACHE_DIR="" +WORK_DIR=$(realpath -m ".") +JOBS=$(($(nproc) * 2 - 1)) +BEAR=0 +LLVM=0 +CROSS_COMPILE="" +LOCALVERSION="" +BUILD_DIR=$(realpath -m ".build") +VERBOSE=0 +LOGS_DIR=$(realpath -m ".logs") +DESTINATION_DIR=$(realpath -m ".target") +SIGNING_KEY_FILE="" +CLEAN=0 + if (( $# < 2 )); then - echo "用法: $0 [选项 [值]...]..." + echo "用法: $0 [选项 [值]...]... [自定义环境变量: KEY=VALUE]..." echo " 可用选项:" echo " -p, --prebuilt " echo " 指定预构建库/包目录,默认: '$PREBUILT_DIR'" echo "" echo " -c, --cache " - echo " 指定缓存的存放目录,默认: '$CACHE_DIR'" + echo " 指定缓存的存放目录,为空时禁用缓存,默认: '$CACHE_DIR'" echo "" echo " -w, --work " echo " 指定工作目录,默认: '$WORK_DIR'" @@ -19,11 +37,15 @@ if (( $# < 2 )); then echo " -j, --jobs " echo " 指定工作线程数量,默认: $JOBS" echo "" - echo " --clean" - echo " 在构建之前进行清理,默认: $((( $CLEAN != 0)) && echo '启用' || echo '禁用')" + echo " --bear" + echo " 使用 bear -- make 生成 JSON 编译数据库,用于 VSCode + Clangd 开发补全等功能" + echo " 与 --cache 不兼容,默认: $((( $BEAR != 0 )) && echo '启用' || echo '禁用')" echo "" echo " --llvm" - echo " 使用 Clang/Clang++ 作为主要编译器,默认: $((( $LLVM != 0)) && echo '启用' || echo '禁用')" + echo " 使用 Clang/Clang++ 作为主要编译器,默认: $((( $LLVM != 0 )) && echo '启用' || echo '禁用')" + echo "" + echo " --cross " + echo " 指定 CROSS_COMPILE 的值,默认: '$CROSS_COMPILE'" echo "" echo " --version " echo " 指定 LOCALVERSION 的值,默认: '$LOCALVERSION'" @@ -32,7 +54,7 @@ if (( $# < 2 )); then echo " 指定构建目录,默认: '$BUILD_DIR'" echo "" echo " -v, --verbose" - echo " 使用构建参数 'V=1' 来启用更详细的日志,默认: $((( $VERBOSE != 0)) && echo '启用' || echo '禁用')" + echo " 使用构建参数 'V=1' 来启用更详细的日志,默认: $((( $VERBOSE != 0 )) && echo '启用' || echo '禁用')" echo "" echo " --logs " echo " 指定日志文件的存放目录,默认: '$LOGS_DIR'" @@ -43,7 +65,10 @@ if (( $# < 2 )); then echo " -s, --signing " echo " 指定签名密钥文件,默认: '$SIGNING_KEY_FILE'" echo "" - echo "示例: $0 arm64 grus --llvm --version wabby-wabbo -s .signing_key.pem" + echo " --clean" + echo " 在构建之前进行清理,默认: $((( $CLEAN != 0 )) && echo '启用' || echo '禁用')" + echo "" + echo "示例: $0 arm64 grus --cross aarch64-linux-gnu --version wabby-wabbo -s .signing_key.pem CROSS_COMPILE_ARM32=arm-linux-gnueabi-" exit 1 fi @@ -60,21 +85,21 @@ fi DEVICE="$1" shift -PREBUILT_DIR=$(realpath -m ".prebuilt") -CACHE_DIR=$(realpath -m ".cache") -WORK_DIR=$(realpath -m ".") -JOBS=$(($(nproc) * 2 - 1)) -CLEAN=0 -LLVM=0 -LOCALVERSION="" -BUILD_DIR=$(realpath -m ".build") -VERBOSE=0 -LOGS_DIR=$(realpath -m ".logs") -DESTINATION_DIR=$(realpath -m ".target") -SIGNING_KEY_FILE="" - while [ $# -gt 0 ]; do case "$1" in + -v|--verbose) + VERBOSE=1 + shift + ;; + --logs) + if [ -n "$2" ]; then + LOGS_DIR=$(realpath -m "$2") + shift 2 + else + echo "无效选项: $1: 必须提供一个有效的目录路径" >&2 + exit 1 + fi + ;; -p|--prebuilt) if [ -n "$2" ]; then PREBUILT_DIR=$(realpath -m "$2") @@ -111,14 +136,23 @@ while [ $# -gt 0 ]; do exit 1 fi ;; - --clean) - CLEAN=1 + --bear) + BEAR=1 shift ;; --llvm) LLVM=1 shift ;; + --cross) + if [ -n "$2" ]; then + CROSS_COMPILE="$2" + shift 2 + else + echo "无效选项: $1: 必须提供一个有效的交叉编译器平台" >&2 + exit 1 + fi + ;; --version) if [ -n "$2" ]; then LOCALVERSION="$2" @@ -141,19 +175,6 @@ while [ $# -gt 0 ]; do exit 1 fi ;; - -v|--verbose) - VERBOSE=1 - shift - ;; - --logs) - if [ -n "$2" ]; then - LOGS_DIR=$(realpath -m "$2") - shift 2 - else - echo "无效选项: $1: 必须提供一个有效的目录路径" >&2 - exit 1 - fi - ;; -d|--destination) if [ -n "$2" ]; then DESTINATION_DIR=$(realpath -m "$2") @@ -172,13 +193,16 @@ while [ $# -gt 0 ]; do exit 1 fi ;; + --clean) + CLEAN=1 + shift + ;; -*) echo "无效选项: $1" >&2 exit 1 ;; *) - echo "无效值: $1" >&2 - exit 1 + break ;; esac done @@ -186,43 +210,98 @@ done echo "工作线程: $JOBS" pushd $WORK_DIR -TOOLCHAIN_DIR="$PREBUILT_DIR/toolchain" -export PATH="$TOOLCHAIN_DIR/gcc/aarch64-linux-gnu/bin:$PATH" -export PATH="$TOOLCHAIN_DIR/gcc/arm-linux-gnueabi/bin:$PATH" -export PATH="$TOOLCHAIN_DIR/clang/bin:$PATH" +export ARCH="$ARCH" -if command -v ccache >/dev/null 2>&1; then - echo "配置缓存..." - export CCACHE="ccache" - export CCACHE_DIR=$CACHE_DIR - ccache --show-config - if (( $CLEAN != 0 )); then - echo "清理缓存..." - ccache -zC - fi +if [[ -n "$PREBUILT_DIR" ]]; then + TOOLCHAIN_DIR="$PREBUILT_DIR/toolchain" fi -V=$((( $VERBOSE != 0 )) && echo 'V=1' || echo 'V=s') -O="O=$BUILD_DIR" - if (( $LLVM != 0 )); then export LLVM=1 + export LLVM_IAS=1 + + __DIR="$TOOLCHAIN_DIR/clang/bin" + if [[ -n "$TOOLCHAIN_DIR" && -d "$__DIR" ]]; then + export PATH="$__DIR:$PATH" + fi +else + if [[ -n "$TOOLCHAIN_DIR" ]]; then + for dir in $TOOLCHAIN_DIR/gcc/*/; do + __DIR="${dir%/}/bin" + if [ -d "$__DIR" ]; then + export PATH="$__DIR:$PATH" + fi + done + fi +fi + +if [[ -n $CROSS_COMPILE ]]; then + export CROSS_COMPILE="${CROSS_COMPILE}-" fi if [[ -n "$LOCALVERSION" ]]; then export LOCALVERSION="-$LOCALVERSION" fi -export CROSS_COMPILE="aarch64-linux-gnu-" -export CROSS_COMPILE_ARM32="arm-linux-gnueabi-" -export CROSS_TRIPLE="aarch64-linux-gnu-" -export ARCH="$ARCH" +while [ $# -gt 0 ]; do + case "$1" in + *=*) + export "$1" + shift + ;; + *) + echo "无效的环境变量: $1: 格式应为 KEY=VALUE" >&2 + exit 1 + ;; + esac +done + +echo "打印环境变量..." +if (( $VERBOSE != 0 )); then + printenv +fi + +V=$((( $VERBOSE != 0 )) && echo 'V=1' || echo 'V=s') +O="O=$BUILD_DIR" echo "初始化构建..." rm -rf $LOGS_DIR mkdir -p $LOGS_DIR -make $V $O mrproper 2> >(tee $LOGS_DIR/mrproper-error.log) 1> >(tee $LOGS_DIR/mrproper-info.log) -make $V mrproper 2> >(tee $LOGS_DIR/mrproper-error.log) 1> >(tee $LOGS_DIR/mrproper-info.log) + +if [[ -n "$CACHE_DIR" ]]; then + echo "配置缓存..." + if command -v ccache >/dev/null 2>&1; then + export CCACHE="ccache" + export CCACHE_DIR="$CACHE_DIR" + ccache --show-config + if (( $CLEAN != 0 )); then + echo "清理缓存..." + ccache -zC + fi + else + echo "CCache 未安装,跳过缓存..." + fi +fi + +BEAR_BRIDGE="" +if (( $BEAR != 0 )); then + if [[ ! -n "$CCACHE" ]]; then + if command -v bear >/dev/null 2>&1; then + echo "启用生成 JSON 编译数据库..." + BEAR_BRIDGE="bear --" + else + echo "Bear 未安装,跳过生成 JSON 编译数据库..." + fi + else + echo "已启用 CCache ,跳过生成 JSON 编译数据库..." + fi +fi + +if (( $CLEAN != 0 )); then + echo "清理构建..." + make $V $O mrproper 2> >(tee $LOGS_DIR/mrproper-error.log) 1> >(tee $LOGS_DIR/mrproper-info.log) + make $V mrproper 2>> >(tee $LOGS_DIR/mrproper-error.log) 1>> >(tee $LOGS_DIR/mrproper-info.log) +fi echo "生成配置..." DEFAULT_CONFIG="${DEVICE}_defconfig" @@ -235,7 +314,7 @@ if [[ -n "$SIGNING_KEY_FILE" ]]; then fi echo "构建内核..." -make $V $O -j$JOBS 2> >(tee $LOGS_DIR/kernel-error.log) 1> >(tee $LOGS_DIR/kernel-info.log) +$BEAR_BRIDGE make $V $O -j$JOBS 2> >(tee $LOGS_DIR/kernel-error.log) 1> >(tee $LOGS_DIR/kernel-info.log) echo "复制内核..." KERNEL_DESTINATION_DIR=$DESTINATION_DIR/kernel @@ -243,7 +322,7 @@ mkdir -p $KERNEL_DESTINATION_DIR cp $BUILD_DIR/vmlinux $KERNEL_DESTINATION_DIR pushd $BUILD_DIR/arch/$ARCH/boot -find . -type f -name "Image*" -exec cp {} $KERNEL_DESTINATION_DIR \; +find . -type f -name "Image*" -exec cp -v {} $KERNEL_DESTINATION_DIR \; popd @@ -255,12 +334,12 @@ MODULES_DESTINATION_DIR=$DESTINATION_DIR/modules mkdir -p $MODULES_DESTINATION_DIR pushd $BUILD_DIR/modules -find . -type f -name "*.ko" -exec cp {} $MODULES_DESTINATION_DIR \; +find . -type f -name "*.ko" -exec cp -v {} $MODULES_DESTINATION_DIR \; popd popd -if command -v ccache >/dev/null 2>&1; then +if [[ -n "$CCACHE" ]]; then ccache -s -v fi From ff3f45b8ddc8f6129a548206386445daa0ab1a08 Mon Sep 17 00:00:00 2001 From: ketikai Date: Mon, 13 Jul 2026 19:17:14 +0800 Subject: [PATCH 39/79] =?UTF-8?q?ci(build-kernel)=20perf(build-kernel)=20f?= =?UTF-8?q?eat(build-kernel):=20=E4=BC=98=E5=8C=96=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E5=92=8C=E9=83=A8=E5=88=86=E9=80=89=E9=A1=B9=E7=9A=84=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E5=80=BC=EF=BC=8C=E4=BC=98=E5=8C=96=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E5=99=A8=E5=B7=A5=E5=85=B7=E9=93=BE=E7=9A=84=E4=B8=8B=E8=BD=BD?= =?UTF-8?q?=E6=97=B6=E6=9C=BA=EF=BC=8C=E6=94=AF=E6=8C=81=E5=BF=AB=E9=80=9F?= =?UTF-8?q?=E6=9E=84=E5=BB=BA=E8=84=9A=E6=9C=AC=20`assamble`=20=E7=9A=84?= =?UTF-8?q?=E6=9C=80=E6=96=B0=E5=8A=9F=E8=83=BD=E5=92=8C=E6=89=A7=E8=A1=8C?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- .github/workflows/build-kernel.yml | 115 +++++++++++++++++------------ 1 file changed, 66 insertions(+), 49 deletions(-) diff --git a/.github/workflows/build-kernel.yml b/.github/workflows/build-kernel.yml index ecfab6fc418d..27b7044415b7 100644 --- a/.github/workflows/build-kernel.yml +++ b/.github/workflows/build-kernel.yml @@ -3,6 +3,11 @@ name: Build Kernel on: workflow_call: inputs: &workflow_inputs + verbose_logs: + description: More detailed logs + type: boolean + required: false + default: false kernel_arch: description: Kernel - Arch type: string @@ -13,26 +18,41 @@ on: type: string required: false default: grus + kernel_localversion: + description: Kernel - Local Version + type: string + required: false + default: wabby-wabbo + kernel_cross_compile: + description: Kernel - Cross Compile + type: string + required: false + default: aarch64-linux-gnu + kernel_custom_env: + description: Kernel - Custom ENV + type: string + required: false + default: CROSS_COMPILE_ARM32=arm-linux-gnueabi- llvm: - description: Use LLVM/Clang + description: Use LLVM / Clang type: boolean required: false default: true - verbose: - description: Enable more detailed logs - type: boolean + prebuilt_clang_toolchain: + description: Prebuilt - Clang Toolchain + type: string required: false - default: false + default: https://github.com/ketikai/android_kernel_xiaomi_sdm710/releases/download/prebuilt/clang-r596125.tar.xz + prebuilt_gcc_toolchain: + description: Prebuilt - GCC Toolchain + type: string + required: false + default: https://github.com/ketikai/android_kernel_xiaomi_sdm710/releases/download/prebuilt/linaro-gcc.tar.xz ksu: description: With KernelSU type: boolean required: false default: false - kernel_localversion: - description: Kernel - Local Version - type: string - required: false - default: wabby-wabbo ksu_setup_script: description: KernelSU - Setup Script type: string @@ -43,16 +63,6 @@ on: type: string required: false default: master - prebuilt_gcc_toolchain: - description: Prebuilt - GCC Toolchain - type: string - required: false - default: https://github.com/ketikai/android_kernel_xiaomi_sdm710/releases/download/prebuilt/linaro-gcc.tar.xz - prebuilt_clang_toolchain: - description: Prebuilt - Clang Toolchain - type: string - required: false - default: https://github.com/ketikai/android_kernel_xiaomi_sdm710/releases/download/prebuilt/proton-clang.tar.xz prebuilt_anykernel_package: description: Prebuilt - AnyKernel Package type: string @@ -62,6 +72,7 @@ on: inputs: *workflow_inputs env: + PREBUILT_DIR: .prebuilt DESTINATION_DIR: .target BUILD_ARTIFACT: kernel ASSAMBLE_ARTIFACT: anykernel @@ -73,49 +84,53 @@ jobs: - name: Checkout uses: actions/checkout@v7 - - name: Prepare Prebuilt + - name: Prepare Prebuilt id: prepare_prebuilt env: - TOOLCHAIN_DIR: .prebuilt/toolchain + TOOLCHAIN_DIR: ${{ env.PREBUILT_DIR }}/toolchain run: | - DIR="${{ env.TOOLCHAIN_DIR }}/gcc" - mkdir -p $DIR - echo "GCC_TOOLCHAIN_DIR=$DIR" >> $GITHUB_OUTPUT - CACHE_KEY="${{ env.TOOLCHAIN_DIR }}/.GCC_TOOLCHAIN_CACHE_KEY" - echo "${{ inputs.prebuilt_gcc_toolchain }}" > $CACHE_KEY - echo "GCC_TOOLCHAIN_CACHE_KEY=$CACHE_KEY" >> $GITHUB_OUTPUT + if ${{ inputs.llvm }}; then + DIR="${{ env.TOOLCHAIN_DIR }}/clang" + mkdir -p $DIR + echo "CLANG_TOOLCHAIN_DIR=$DIR" >> $GITHUB_OUTPUT + CACHE_KEY="${{ env.TOOLCHAIN_DIR }}/.CLANG_TOOLCHAIN_CACHE_KEY" + echo "${{ inputs.prebuilt_clang_toolchain }}" > $CACHE_KEY + echo "CLANG_TOOLCHAIN_CACHE_KEY=$CACHE_KEY" >> $GITHUB_OUTPUT + else + DIR="${{ env.TOOLCHAIN_DIR }}/gcc" + mkdir -p $DIR + echo "GCC_TOOLCHAIN_DIR=$DIR" >> $GITHUB_OUTPUT + CACHE_KEY="${{ env.TOOLCHAIN_DIR }}/.GCC_TOOLCHAIN_CACHE_KEY" + echo "${{ inputs.prebuilt_gcc_toolchain }}" > $CACHE_KEY + echo "GCC_TOOLCHAIN_CACHE_KEY=$CACHE_KEY" >> $GITHUB_OUTPUT + fi - DIR="${{ env.TOOLCHAIN_DIR }}/clang" - mkdir -p $DIR - echo "CLANG_TOOLCHAIN_DIR=$DIR" >> $GITHUB_OUTPUT - CACHE_KEY="${{ env.TOOLCHAIN_DIR }}/.CLANG_TOOLCHAIN_CACHE_KEY" - echo "${{ inputs.prebuilt_clang_toolchain }}" > $CACHE_KEY - echo "CLANG_TOOLCHAIN_CACHE_KEY=$CACHE_KEY" >> $GITHUB_OUTPUT + - name: Download Prebuilt Clang Toolchain From Cache + uses: actions/cache@v6 + id: prebuilt_clang_toolchain_cache + if: inputs.llvm == true + with: + path: ${{ steps.prepare_prebuilt.outputs.CLANG_TOOLCHAIN_DIR }} + key: ${{ runner.os }}-${{ runner.arch }}-prebuilt-clang-toolchain-${{ hashFiles(steps.prepare_prebuilt.outputs.CLANG_TOOLCHAIN_CACHE_KEY) }} + + - name: Download Prebuilt Clang Toolchain + if: inputs.llvm == true && steps.prebuilt_clang_toolchain_cache.outputs.cache-hit != true + run: | + wget -O - ${{ inputs.prebuilt_clang_toolchain }} | tar -xJvf - -C ${{ steps.prepare_prebuilt.outputs.CLANG_TOOLCHAIN_DIR }} - name: Download Prebuilt GCC Toolchain From Cache uses: actions/cache@v6 id: prebuilt_gcc_toolchain_cache + if: inputs.llvm == false with: path: ${{ steps.prepare_prebuilt.outputs.GCC_TOOLCHAIN_DIR }} key: ${{ runner.os }}-${{ runner.arch }}-prebuilt-gcc-toolchain-${{ hashFiles(steps.prepare_prebuilt.outputs.GCC_TOOLCHAIN_CACHE_KEY) }} - name: Download Prebuilt GCC Toolchain - if: steps.prebuilt_gcc_toolchain_cache.outputs.cache-hit != true + if: inputs.llvm == false && steps.prebuilt_gcc_toolchain_cache.outputs.cache-hit != true run: | wget -O - ${{ inputs.prebuilt_gcc_toolchain }} | tar -xJvf - -C ${{ steps.prepare_prebuilt.outputs.GCC_TOOLCHAIN_DIR }} - - name: Download Prebuilt Clang Toolchain From Cache - uses: actions/cache@v6 - id: prebuilt_clang_toolchain_cache - with: - path: ${{ steps.prepare_prebuilt.outputs.CLANG_TOOLCHAIN_DIR }} - key: ${{ runner.os }}-${{ runner.arch }}-prebuilt-clang-toolchain-${{ hashFiles(steps.prepare_prebuilt.outputs.CLANG_TOOLCHAIN_CACHE_KEY) }} - - - name: Download Prebuilt Clang Toolchain - if: steps.prebuilt_clang_toolchain_cache.outputs.cache-hit != true - run: | - wget -O - ${{ inputs.prebuilt_clang_toolchain }} | tar -xJvf - -C ${{ steps.prepare_prebuilt.outputs.CLANG_TOOLCHAIN_DIR }} - - name: KernelSU Integration run: | if ${{ inputs.ksu }}; then @@ -124,11 +139,13 @@ jobs: - name: Execute assamble run: | + VERBOSE=$(${{ inputs.verbose_logs }} && echo "-v" || echo "") LLVM=$(${{ inputs.llvm }} && echo "--llvm" || echo "") + CROSS_COMPILE=$([[ -n "${{ inputs.kernel_cross_compile }}" ]] && echo "--cross ${{ inputs.kernel_cross_compile }}" || echo "") VERSION=$([[ -n "${{ inputs.kernel_localversion }}" ]] && echo "--version ${{ inputs.kernel_localversion }}" || echo "") SIGNING=$([[ -n "${{ secrets.SIGNING_KEY }}" ]] && echo "${{ secrets.SIGNING_KEY }}" > ".signing_key.pem"; echo "-s .signing_key.pem" || echo "") - VERBOSE=$(${{ inputs.verbose }} && echo "-v" || echo "") - ./assamble ${{ inputs.kernel_arch }} ${{ inputs.kernel_device }} $LLVM $VERSION $SIGNING $VERBOSE -d ${{ env.DESTINATION_DIR }} + CUSTOM_CONFIG=$([[ -n "${{ inputs.kernel_custom_env }}" ]] && echo "${{ inputs.kernel_custom_env }}" || echo "") + ./assamble ${{ inputs.kernel_arch }} ${{ inputs.kernel_device }} $VERBOSE -p ${{ env.PREBUILT_DIR }} $LLVM $CROSS_COMPILE $VERSION $SIGNING -d ${{ env.DESTINATION_DIR }} $CUSTOM_CONFIG - name: Upload Kernel And Modules uses: actions/upload-artifact@v7 From 9ff937e73ac5175ecc0ffa36dc66f3cd5ceb3a31 Mon Sep 17 00:00:00 2001 From: ketikai Date: Mon, 13 Jul 2026 19:23:41 +0800 Subject: [PATCH 40/79] =?UTF-8?q?chore(assemble)=20fix(assemble):=20?= =?UTF-8?q?=E5=B0=86=E9=94=99=E8=AF=AF=E7=9A=84=E8=84=9A=E6=9C=AC=E5=90=8D?= =?UTF-8?q?=E7=A7=B0=20`assamble`=20=E6=9B=B4=E6=AD=A3=E4=B8=BA=20`assembl?= =?UTF-8?q?e`=20=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- assamble => assemble | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename assamble => assemble (100%) diff --git a/assamble b/assemble similarity index 100% rename from assamble rename to assemble From e58091fe1da8ae571a80346a860705597c0e8560 Mon Sep 17 00:00:00 2001 From: ketikai Date: Mon, 13 Jul 2026 19:29:24 +0800 Subject: [PATCH 41/79] =?UTF-8?q?ci(build-kernel)=20fix(build-kernel)=20fe?= =?UTF-8?q?at(build-kernel):=20=E6=9B=B4=E6=AD=A3=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E7=9A=84=E5=91=BD=E5=90=8D=20`assamble`=20=E5=88=B0=20`assembl?= =?UTF-8?q?e`=20=EF=BC=8C=E6=B7=BB=E5=8A=A0=20`AnyKernel`=20=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E6=89=93=E5=8C=85=E7=9A=84=E5=90=AF=E7=94=A8=E9=80=89?= =?UTF-8?q?=E9=A1=B9=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- .github/workflows/build-kernel.yml | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-kernel.yml b/.github/workflows/build-kernel.yml index 27b7044415b7..5a7547ef810c 100644 --- a/.github/workflows/build-kernel.yml +++ b/.github/workflows/build-kernel.yml @@ -63,6 +63,11 @@ on: type: string required: false default: master + anykernel: + description: Assemble AnyKernel + type: boolean + required: false + default: true prebuilt_anykernel_package: description: Prebuilt - AnyKernel Package type: string @@ -75,7 +80,7 @@ env: PREBUILT_DIR: .prebuilt DESTINATION_DIR: .target BUILD_ARTIFACT: kernel - ASSAMBLE_ARTIFACT: anykernel + ASSEMBLE_ARTIFACT: anykernel jobs: build: @@ -137,7 +142,7 @@ jobs: curl -LSs ${{ inputs.ksu_setup_script }} | bash -s ${{ inputs.ksu_setup_branch }} fi - - name: Execute assamble + - name: Execute assemble run: | VERBOSE=$(${{ inputs.verbose_logs }} && echo "-v" || echo "") LLVM=$(${{ inputs.llvm }} && echo "--llvm" || echo "") @@ -145,7 +150,7 @@ jobs: VERSION=$([[ -n "${{ inputs.kernel_localversion }}" ]] && echo "--version ${{ inputs.kernel_localversion }}" || echo "") SIGNING=$([[ -n "${{ secrets.SIGNING_KEY }}" ]] && echo "${{ secrets.SIGNING_KEY }}" > ".signing_key.pem"; echo "-s .signing_key.pem" || echo "") CUSTOM_CONFIG=$([[ -n "${{ inputs.kernel_custom_env }}" ]] && echo "${{ inputs.kernel_custom_env }}" || echo "") - ./assamble ${{ inputs.kernel_arch }} ${{ inputs.kernel_device }} $VERBOSE -p ${{ env.PREBUILT_DIR }} $LLVM $CROSS_COMPILE $VERSION $SIGNING -d ${{ env.DESTINATION_DIR }} $CUSTOM_CONFIG + ./assemble ${{ inputs.kernel_arch }} ${{ inputs.kernel_device }} $VERBOSE -p ${{ env.PREBUILT_DIR }} $LLVM $CROSS_COMPILE $VERSION $SIGNING -d ${{ env.DESTINATION_DIR }} $CUSTOM_CONFIG - name: Upload Kernel And Modules uses: actions/upload-artifact@v7 @@ -157,10 +162,11 @@ jobs: overwrite: true include-hidden-files: true - assamble: + assemble: runs-on: ubuntu-22.04 needs: - build + if: inputs.anykernel == true steps: - name: Download Prebuilt AnyKernel Package run: | @@ -180,7 +186,7 @@ jobs: - name: Upload AnyKernel Package uses: actions/upload-artifact@v7 with: - name: ${{ env.ASSAMBLE_ARTIFACT }} + name: ${{ env.ASSEMBLE_ARTIFACT }} path: | ${{ env.DESTINATION_DIR }}/* if-no-files-found: error From a4b6dea0ec5a91e03061b5c334b8c6bc5c71a5d4 Mon Sep 17 00:00:00 2001 From: ketikai Date: Mon, 13 Jul 2026 19:43:06 +0800 Subject: [PATCH 42/79] =?UTF-8?q?ci(build-kernel)=20perf(build-kernel):=20?= =?UTF-8?q?=E4=B8=BA=20`wget`=20=E5=90=AF=E7=94=A8=20`-nv`=20=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E4=BB=A5=E5=85=B3=E9=97=AD=E5=86=97=E4=BD=99=E8=BE=93?= =?UTF-8?q?=E5=87=BA=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- .github/workflows/build-kernel.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-kernel.yml b/.github/workflows/build-kernel.yml index 5a7547ef810c..2c22f3d81edb 100644 --- a/.github/workflows/build-kernel.yml +++ b/.github/workflows/build-kernel.yml @@ -121,7 +121,7 @@ jobs: - name: Download Prebuilt Clang Toolchain if: inputs.llvm == true && steps.prebuilt_clang_toolchain_cache.outputs.cache-hit != true run: | - wget -O - ${{ inputs.prebuilt_clang_toolchain }} | tar -xJvf - -C ${{ steps.prepare_prebuilt.outputs.CLANG_TOOLCHAIN_DIR }} + wget -nv -O - ${{ inputs.prebuilt_clang_toolchain }} | tar -xJvf - -C ${{ steps.prepare_prebuilt.outputs.CLANG_TOOLCHAIN_DIR }} - name: Download Prebuilt GCC Toolchain From Cache uses: actions/cache@v6 @@ -134,7 +134,7 @@ jobs: - name: Download Prebuilt GCC Toolchain if: inputs.llvm == false && steps.prebuilt_gcc_toolchain_cache.outputs.cache-hit != true run: | - wget -O - ${{ inputs.prebuilt_gcc_toolchain }} | tar -xJvf - -C ${{ steps.prepare_prebuilt.outputs.GCC_TOOLCHAIN_DIR }} + wget -nv -O - ${{ inputs.prebuilt_gcc_toolchain }} | tar -xJvf - -C ${{ steps.prepare_prebuilt.outputs.GCC_TOOLCHAIN_DIR }} - name: KernelSU Integration run: | From 1db7ab20fee85f958fb1f52745e0d5e8ce8e34f7 Mon Sep 17 00:00:00 2001 From: ketikai Date: Tue, 14 Jul 2026 11:41:19 +0800 Subject: [PATCH 43/79] =?UTF-8?q?chore(assemble)=20feat(assemble):=20?= =?UTF-8?q?=E8=84=9A=E6=9C=AC=20`assemble`=20=E7=9A=84=20`--cache`=20?= =?UTF-8?q?=E6=89=80=E6=8C=87=E5=AE=9A=E7=9A=84=E7=9B=AE=E5=BD=95=E5=B0=86?= =?UTF-8?q?=E4=BD=9C=E4=B8=BA=E7=BC=93=E5=AD=98=E6=A0=B9=E7=9B=AE=E5=BD=95?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=EF=BC=8C=E8=80=8C=E7=BC=93=E5=AD=98=E7=9A=84?= =?UTF-8?q?=E5=AE=9E=E9=99=85=E7=9B=AE=E5=BD=95=E5=9F=BA=E4=BA=8E=E5=85=B6?= =?UTF-8?q?=E4=B8=8E=20`--version`=20=E7=9A=84=E7=BB=93=E5=90=88=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- assemble | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/assemble b/assemble index f807a9a511c7..7bedc3140ef5 100755 --- a/assemble +++ b/assemble @@ -29,7 +29,8 @@ if (( $# < 2 )); then echo " 指定预构建库/包目录,默认: '$PREBUILT_DIR'" echo "" echo " -c, --cache " - echo " 指定缓存的存放目录,为空时禁用缓存,默认: '$CACHE_DIR'" + echo " 指定缓存的存放根目录,基于 --version 来自动创建缓存子目录" + echo " 为空时禁用缓存,默认: '$CACHE_DIR'" echo "" echo " -w, --work " echo " 指定工作目录,默认: '$WORK_DIR'" @@ -239,6 +240,7 @@ if [[ -n $CROSS_COMPILE ]]; then export CROSS_COMPILE="${CROSS_COMPILE}-" fi +CACHE_VERSION="$LOCALVERSION" if [[ -n "$LOCALVERSION" ]]; then export LOCALVERSION="-$LOCALVERSION" fi @@ -272,7 +274,11 @@ if [[ -n "$CACHE_DIR" ]]; then echo "配置缓存..." if command -v ccache >/dev/null 2>&1; then export CCACHE="ccache" - export CCACHE_DIR="$CACHE_DIR" + if [[ -n "$CACHE_VERSION" ]]; then + export CCACHE_DIR="$CACHE_DIR/$CACHE_VERSION" + else + export CCACHE_DIR="$CACHE_DIR" + fi ccache --show-config if (( $CLEAN != 0 )); then echo "清理缓存..." From 9c20257b0f9b0d531430229c3531f9116a1c44f7 Mon Sep 17 00:00:00 2001 From: ketikai Date: Tue, 14 Jul 2026 18:44:34 +0800 Subject: [PATCH 44/79] =?UTF-8?q?chore(assemble)=20feat(assemble):=20?= =?UTF-8?q?=E5=85=81=E8=AE=B8=E8=84=9A=E6=9C=AC=20`assemble`=20=E7=9A=84?= =?UTF-8?q?=E9=80=89=E9=A1=B9=20`--cache`=20=E5=92=8C=20`--bear`=20=20?= =?UTF-8?q?=E5=90=8C=E6=97=B6=E4=BD=BF=E7=94=A8=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- assemble | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/assemble b/assemble index 7bedc3140ef5..6e860fca2e90 100755 --- a/assemble +++ b/assemble @@ -39,8 +39,8 @@ if (( $# < 2 )); then echo " 指定工作线程数量,默认: $JOBS" echo "" echo " --bear" - echo " 使用 bear -- make 生成 JSON 编译数据库,用于 VSCode + Clangd 开发补全等功能" - echo " 与 --cache 不兼容,默认: $((( $BEAR != 0 )) && echo '启用' || echo '禁用')" + echo " 使用 bear -- make 生成 JSON 编译数据库" + echo " 用于 VSCode + Clangd 开发补全等功能,默认: $((( $BEAR != 0 )) && echo '启用' || echo '禁用')" echo "" echo " --llvm" echo " 使用 Clang/Clang++ 作为主要编译器,默认: $((( $LLVM != 0 )) && echo '启用' || echo '禁用')" @@ -291,15 +291,11 @@ fi BEAR_BRIDGE="" if (( $BEAR != 0 )); then - if [[ ! -n "$CCACHE" ]]; then - if command -v bear >/dev/null 2>&1; then - echo "启用生成 JSON 编译数据库..." - BEAR_BRIDGE="bear --" - else - echo "Bear 未安装,跳过生成 JSON 编译数据库..." - fi + if command -v bear >/dev/null 2>&1; then + echo "启用生成 JSON 编译数据库..." + BEAR_BRIDGE="bear --" else - echo "已启用 CCache ,跳过生成 JSON 编译数据库..." + echo "Bear 未安装,跳过生成 JSON 编译数据库..." fi fi From ba47e4c5106ba02fe6301d4df9d06efa1e4e062e Mon Sep 17 00:00:00 2001 From: ketikai Date: Fri, 17 Jul 2026 13:12:56 +0800 Subject: [PATCH 45/79] =?UTF-8?q?revert(ksu):=20"feat(ksu):=20=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=20'hooks.c'=20=E4=B8=AD=E8=BF=87=E6=97=B6=E7=9A=84?= =?UTF-8?q?=E9=92=A9=E5=AD=90=E3=80=82"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 9f2fea437062473c6a50662163e2ad468717a34b. --- security/selinux/hooks.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index de8a090c8a3a..710cb025f883 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2324,6 +2324,12 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm, int nnp = (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS); int nosuid = !mnt_may_suid(bprm->file->f_path.mnt); int rc; +#ifdef CONFIG_KSU + static u32 ksu_sid; + int error; + char *secdata; + u32 seclen; +#endif if (!nnp && !nosuid) return 0; /* neither NNP nor nosuid */ @@ -2331,6 +2337,19 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm, if (new_tsec->sid == old_tsec->sid) return 0; /* No change in credentials */ +#ifdef CONFIG_KSU + if (!ksu_sid) + security_secctx_to_secid("u:r:su:s0", strlen("u:r:su:s0"), &ksu_sid); + + error = security_secid_to_secctx(old_tsec->sid, &secdata, &seclen); + if (!error) { + rc = strcmp("u:r:init:s0", secdata); + security_release_secctx(secdata, seclen); + if (rc == 0 && new_tsec->sid == ksu_sid) + return 0; + } +#endif + /* * The only transitions we permit under NNP or nosuid * are transitions to bounded SIDs, i.e. SIDs that are From d3134c916ca06b560c58856b73bab7b55d21b3d1 Mon Sep 17 00:00:00 2001 From: ketikai Date: Fri, 17 Jul 2026 13:13:57 +0800 Subject: [PATCH 46/79] =?UTF-8?q?revert(ksu):=20"feat(ksu):=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=20'hooks.c'=20=E4=B8=AD=E7=BC=BA=E5=A4=B1=E7=9A=84?= =?UTF-8?q?=E5=BF=85=E8=A6=81=E5=AE=8F=E5=88=A4=E6=96=AD=E3=80=82"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 500d7059c69f52d7242841027cfd5d6f702609ae. --- security/selinux/hooks.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 710cb025f883..ba15c0c353e2 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2321,15 +2321,12 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm, const struct task_security_struct *old_tsec, const struct task_security_struct *new_tsec) { - int nnp = (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS); - int nosuid = !mnt_may_suid(bprm->file->f_path.mnt); - int rc; -#ifdef CONFIG_KSU static u32 ksu_sid; - int error; char *secdata; + int nnp = (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS); + int nosuid = !mnt_may_suid(bprm->file->f_path.mnt); + int rc,error; u32 seclen; -#endif if (!nnp && !nosuid) return 0; /* neither NNP nor nosuid */ @@ -2337,19 +2334,18 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm, if (new_tsec->sid == old_tsec->sid) return 0; /* No change in credentials */ -#ifdef CONFIG_KSU - if (!ksu_sid) - security_secctx_to_secid("u:r:su:s0", strlen("u:r:su:s0"), &ksu_sid); + if(!ksu_sid){ + security_secctx_to_secid("u:r:su:s0", strlen("u:r:su:s0"), &ksu_sid); + } error = security_secid_to_secctx(old_tsec->sid, &secdata, &seclen); if (!error) { - rc = strcmp("u:r:init:s0", secdata); + rc = strcmp("u:r:init:s0",secdata); security_release_secctx(secdata, seclen); - if (rc == 0 && new_tsec->sid == ksu_sid) + if(rc == 0 && new_tsec->sid == ksu_sid){ return 0; + } } -#endif - /* * The only transitions we permit under NNP or nosuid * are transitions to bounded SIDs, i.e. SIDs that are From 051b2e0a9e135402a27df3362c64082abb3adb11 Mon Sep 17 00:00:00 2001 From: ketikai Date: Fri, 17 Jul 2026 13:15:27 +0800 Subject: [PATCH 47/79] =?UTF-8?q?revert(ksu):=20"feat(ksu):=20BACKPORT=20-?= =?UTF-8?q?=20'fs/namespace.c'=20path=5Fumount=E3=80=82"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 97f18c61366e18c6c75ed28162b7b32c698c5bd6. --- fs/namespace.c | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/fs/namespace.c b/fs/namespace.c index 66238fcccc1b..21fd423b19cf 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1711,40 +1711,6 @@ static inline bool may_mandlock(void) } #endif -static int can_umount(const struct path *path, int flags) -{ - struct mount *mnt = real_mount(path->mnt); - - if (flags & ~(MNT_FORCE | MNT_DETACH | MNT_EXPIRE | UMOUNT_NOFOLLOW)) - return -EINVAL; - if (!may_mount()) - return -EPERM; - if (path->dentry != path->mnt->mnt_root) - return -EINVAL; - if (!check_mnt(mnt)) - return -EINVAL; - if (mnt->mnt.mnt_flags & MNT_LOCKED) /* Check optimistically */ - return -EINVAL; - if (flags & MNT_FORCE && !capable(CAP_SYS_ADMIN)) - return -EPERM; - return 0; -} - -int path_umount(struct path *path, int flags) -{ - struct mount *mnt = real_mount(path->mnt); - int ret; - - ret = can_umount(path, flags); - if (!ret) - ret = do_umount(mnt, flags); - - /* we mustn't call path_put() as that would clear mnt_expiry_mark */ - dput(path->dentry); - mntput_no_expire(mnt); - return ret; -} - /* * Now umount can handle mount points as well as block devices. * This is important for filesystems which use unnamed block devices. From 3f799bfd4c8e40c1fea1bd78a8e959a1ee369472 Mon Sep 17 00:00:00 2001 From: ketikai Date: Fri, 17 Jul 2026 13:15:37 +0800 Subject: [PATCH 48/79] =?UTF-8?q?revert(ksu):=20"feat(ksu):=20=E5=90=8C?= =?UTF-8?q?=E6=AD=A5=20'scope-minimized=20manual=20hooks=20v2.2'=20?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E3=80=82"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 0622c51f1f4138aeff6b321f22f38e1decca34cd. --- security/selinux/selinuxfs.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index a033306d14ee..5931e498d95a 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -728,6 +728,11 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = { [SEL_CONTEXT] = sel_write_context, }; + +#if defined(CONFIG_KSU) && !defined(CONFIG_KPROBES) +extern void ksu_sel_write_context(struct file **file, char **buf, size_t *size); +#endif + static ssize_t selinux_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos) { ino_t ino = file_inode(file)->i_ino; @@ -741,6 +746,10 @@ static ssize_t selinux_transaction_write(struct file *file, const char __user *b if (IS_ERR(data)) return PTR_ERR(data); +#if defined(CONFIG_KSU) && !defined(CONFIG_KPROBES) + ksu_sel_write_context(&file, &data, &size); +#endif + rv = write_op[ino](file, data, size); if (rv > 0) { simple_transaction_set(file, rv); From 5ca27758f5ab0f9a9891c0f025c2bc551f2d1e01 Mon Sep 17 00:00:00 2001 From: ketikai Date: Fri, 17 Jul 2026 13:15:46 +0800 Subject: [PATCH 49/79] =?UTF-8?q?revert(ksu):=20"feat(ksu):=20=E5=90=8C?= =?UTF-8?q?=E6=AD=A5=20'scope-minimized=20manual=20hooks=20v2.1'=20?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E3=80=82"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 9bc87d552eee2f872a10be57b346ca512197931b. --- security/selinux/avc.c | 7 ------- security/selinux/selinuxfs.c | 9 --------- 2 files changed, 16 deletions(-) diff --git a/security/selinux/avc.c b/security/selinux/avc.c index e63301f9f64f..a16c72c2a967 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -736,10 +736,6 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a) } } -#if defined(CONFIG_KSU) && !defined(CONFIG_KPROBES) -extern void ksu_slow_avc_audit(u32 *tsid); -#endif - /* This is the slow part of avc audit with big stack footprint */ noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, u32 requested, u32 audited, u32 denied, int result, @@ -749,9 +745,6 @@ noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, struct common_audit_data stack_data; struct selinux_audit_data sad; -#if defined(CONFIG_KSU) && !defined(CONFIG_KPROBES) - ksu_slow_avc_audit(&tsid); -#endif if (!a) { a = &stack_data; a->type = LSM_AUDIT_DATA_NONE; diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 5931e498d95a..a033306d14ee 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -728,11 +728,6 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = { [SEL_CONTEXT] = sel_write_context, }; - -#if defined(CONFIG_KSU) && !defined(CONFIG_KPROBES) -extern void ksu_sel_write_context(struct file **file, char **buf, size_t *size); -#endif - static ssize_t selinux_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos) { ino_t ino = file_inode(file)->i_ino; @@ -746,10 +741,6 @@ static ssize_t selinux_transaction_write(struct file *file, const char __user *b if (IS_ERR(data)) return PTR_ERR(data); -#if defined(CONFIG_KSU) && !defined(CONFIG_KPROBES) - ksu_sel_write_context(&file, &data, &size); -#endif - rv = write_op[ino](file, data, size); if (rv > 0) { simple_transaction_set(file, rv); From f3902af008f5fd1746c34469d0720c800c1554ed Mon Sep 17 00:00:00 2001 From: ketikai Date: Fri, 17 Jul 2026 13:18:43 +0800 Subject: [PATCH 50/79] =?UTF-8?q?revert(ksu):=20"feat(ksu):=20=E5=90=8C?= =?UTF-8?q?=E6=AD=A5=20'scope-minimized=20manual=20hooks=20v2.0'=20?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E3=80=82"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit ef72accc9e1a8dd6ed4e42ce59746efebe219bf9. --- arch/arm64/configs/grus_defconfig | 7 ++++++- fs/exec.c | 20 +++++++++++++------- fs/open.c | 5 ++--- fs/stat.c | 15 ++++++--------- kernel/reboot.c | 11 +++++------ security/selinux/ss/services.c | 2 +- 6 files changed, 33 insertions(+), 27 deletions(-) diff --git a/arch/arm64/configs/grus_defconfig b/arch/arm64/configs/grus_defconfig index 764f22875ead..edd02375a1d6 100644 --- a/arch/arm64/configs/grus_defconfig +++ b/arch/arm64/configs/grus_defconfig @@ -1,4 +1,4 @@ -CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION="-perf" # CONFIG_LOCALVERSION_AUTO is not set # CONFIG_FHANDLE is not set CONFIG_AUDIT=y @@ -704,3 +704,8 @@ CONFIG_HALLS=y CONFIG_MIGT=y CONFIG_XLOGCHAR=y CONFIG_RTMM=y +CONFIG_PROCESS_RECLAIM=y +# KernelSU +CONFIG_KSU=y +# KernelSU - Manual Hook +CONFIG_KSU_MANUAL_HOOK=y diff --git a/fs/exec.c b/fs/exec.c index 579b081311fc..8b9c560acc7a 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1836,11 +1836,13 @@ static int do_execveat_common(int fd, struct filename *filename, putname(filename); return retval; } - + #ifdef CONFIG_KSU -__attribute__((hot)) -extern int ksu_handle_execveat(int *fd, struct filename **filename_ptr, - void *argv, void *envp, int *flags); +extern bool ksu_execveat_hook __read_mostly; +extern int ksu_handle_execveat(int *fd, struct filename **filename_ptr, void *argv, + void *envp, int *flags); +extern int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr, + void *argv, void *envp, int *flags); #endif int do_execve(struct filename *filename, @@ -1850,7 +1852,10 @@ int do_execve(struct filename *filename, struct user_arg_ptr argv = { .ptr.native = __argv }; struct user_arg_ptr envp = { .ptr.native = __envp }; #ifdef CONFIG_KSU - ksu_handle_execveat((int *)AT_FDCWD, &filename, &argv, &envp, 0); + if (unlikely(ksu_execveat_hook)) + ksu_handle_execveat((int *)AT_FDCWD, &filename, &argv, &envp, 0); + else + ksu_handle_execveat_sucompat((int *)AT_FDCWD, &filename, NULL, NULL, NULL); #endif return do_execveat_common(AT_FDCWD, filename, argv, envp, 0); } @@ -1879,8 +1884,9 @@ static int compat_do_execve(struct filename *filename, .is_compat = true, .ptr.compat = __envp, }; -#ifdef CONFIG_KSU // 32-bit ksud and 32-on-64 support - ksu_handle_execveat((int *)AT_FDCWD, &filename, &argv, &envp, 0); +#ifdef CONFIG_KSU + if (!ksu_execveat_hook) + ksu_handle_execveat_sucompat((int *)AT_FDCWD, &filename, NULL, NULL, NULL); /* 32-bit support */ #endif return do_execveat_common(AT_FDCWD, filename, argv, envp, 0); } diff --git a/fs/open.c b/fs/open.c index 760af4469c91..633cd9738e95 100644 --- a/fs/open.c +++ b/fs/open.c @@ -356,9 +356,8 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len) } #ifdef CONFIG_KSU -__attribute__((hot)) -extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, - int *mode, int *flags); +extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode, + int *flags); #endif /* diff --git a/fs/stat.c b/fs/stat.c index 43295c07e27d..78394733caaa 100644 --- a/fs/stat.c +++ b/fs/stat.c @@ -288,9 +288,7 @@ SYSCALL_DEFINE2(newlstat, const char __user *, filename, } #ifdef CONFIG_KSU -__attribute__((hot)) -extern int ksu_handle_stat(int *dfd, const char __user **filename_user, - int *flags); +extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags); #endif #if !defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_SYS_NEWFSTATAT) @@ -310,8 +308,7 @@ SYSCALL_DEFINE4(newfstatat, int, dfd, const char __user *, filename, return cp_new_stat(&stat, statbuf); } #endif - -#if defined(CONFIG_KSU) && !defined(CONFIG_KSU_KPROBES_KSUD) +#ifdef CONFIG_KSU extern void ksu_handle_newfstat_ret(unsigned int *fd, struct stat __user **statbuf_ptr); #if defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_COMPAT_STAT64) extern void ksu_handle_fstat64_ret(unsigned long *fd, struct stat64 __user **statbuf_ptr); // for 32-bit @@ -326,7 +323,7 @@ SYSCALL_DEFINE2(newfstat, unsigned int, fd, struct stat __user *, statbuf) if (!error) error = cp_new_stat(&stat, statbuf); -#if defined(CONFIG_KSU) && !defined(CONFIG_KSU_KPROBES_KSUD) +#ifdef CONFIG_KSU ksu_handle_newfstat_ret(&fd, &statbuf); #endif return error; @@ -447,7 +444,7 @@ SYSCALL_DEFINE2(fstat64, unsigned long, fd, struct stat64 __user *, statbuf) if (!error) error = cp_new_stat64(&stat, statbuf); -#if defined(CONFIG_KSU) && !defined(CONFIG_KSU_KPROBES_KSUD) // for 32-bit +#ifdef CONFIG_KSU // for 32-bit ksu_handle_fstat64_ret(&fd, &statbuf); #endif return error; @@ -459,8 +456,8 @@ SYSCALL_DEFINE4(fstatat64, int, dfd, const char __user *, filename, struct kstat stat; int error; -#ifdef CONFIG_KSU // 32-bit su - ksu_handle_stat(&dfd, &filename, &flag); +#ifdef CONFIG_KSU + ksu_handle_stat(&dfd, &filename, &flag); /* 32-bit su support */ #endif error = vfs_fstatat(dfd, filename, &stat, flag); diff --git a/kernel/reboot.c b/kernel/reboot.c index a377b8611601..4e1454b8da94 100644 --- a/kernel/reboot.c +++ b/kernel/reboot.c @@ -267,6 +267,10 @@ void kernel_power_off(void) } EXPORT_SYMBOL_GPL(kernel_power_off); +#ifdef CONFIG_KSU +extern int ksu_handle_sys_reboot(int magic1, int magic2, unsigned int cmd, void __user **arg); +#endif + static DEFINE_MUTEX(reboot_mutex); /* @@ -277,11 +281,6 @@ static DEFINE_MUTEX(reboot_mutex); * * reboot doesn't sync: do that yourself before calling this. */ - -#if defined(CONFIG_KSU) && !defined(CONFIG_KSU_KPROBES_KSUD) -extern int ksu_handle_sys_reboot(int magic1, int magic2, unsigned int cmd, void __user **arg); -#endif - SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd, void __user *, arg) { @@ -289,7 +288,7 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd, char buffer[256]; int ret = 0; - #if defined(CONFIG_KSU) && !defined(CONFIG_KSU_KPROBES_KSUD) + #ifdef CONFIG_KSU ksu_handle_sys_reboot(magic1, magic2, cmd, &arg); #endif /* We only trust the superuser with rebooting the system. */ diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index ad6ef07707e5..365d44a242b5 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -76,7 +76,7 @@ int selinux_policycap_netpeer; int selinux_policycap_openperm; int selinux_policycap_alwaysnetwork; -DEFINE_RWLOCK(policy_rwlock); +static DEFINE_RWLOCK(policy_rwlock); static struct sidtab sidtab; struct policydb policydb; From 9152c4377e22d981b57fc595e86c35d3f2102041 Mon Sep 17 00:00:00 2001 From: ketikai Date: Fri, 17 Jul 2026 13:18:54 +0800 Subject: [PATCH 51/79] =?UTF-8?q?revert(ksu):=20"feat(ksu):=20=E5=90=8C?= =?UTF-8?q?=E6=AD=A5=20'scope-minimized=20manual=20hooks=20v1.9'=20?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E3=80=82"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit be69972f5f2d5822f251f06958fa7fc82773fa66. --- fs/stat.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/fs/stat.c b/fs/stat.c index 78394733caaa..31ab7859256b 100644 --- a/fs/stat.c +++ b/fs/stat.c @@ -308,12 +308,6 @@ SYSCALL_DEFINE4(newfstatat, int, dfd, const char __user *, filename, return cp_new_stat(&stat, statbuf); } #endif -#ifdef CONFIG_KSU -extern void ksu_handle_newfstat_ret(unsigned int *fd, struct stat __user **statbuf_ptr); -#if defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_COMPAT_STAT64) -extern void ksu_handle_fstat64_ret(unsigned long *fd, struct stat64 __user **statbuf_ptr); // for 32-bit -#endif -#endif SYSCALL_DEFINE2(newfstat, unsigned int, fd, struct stat __user *, statbuf) { @@ -323,9 +317,6 @@ SYSCALL_DEFINE2(newfstat, unsigned int, fd, struct stat __user *, statbuf) if (!error) error = cp_new_stat(&stat, statbuf); -#ifdef CONFIG_KSU - ksu_handle_newfstat_ret(&fd, &statbuf); -#endif return error; } @@ -444,9 +435,6 @@ SYSCALL_DEFINE2(fstat64, unsigned long, fd, struct stat64 __user *, statbuf) if (!error) error = cp_new_stat64(&stat, statbuf); -#ifdef CONFIG_KSU // for 32-bit - ksu_handle_fstat64_ret(&fd, &statbuf); -#endif return error; } From 9a5dc9b49e19778981c7632ae7e621bc5476b677 Mon Sep 17 00:00:00 2001 From: ketikai Date: Fri, 17 Jul 2026 13:19:02 +0800 Subject: [PATCH 52/79] =?UTF-8?q?revert(ksu):=20"feat(ksu):=20=E5=90=8C?= =?UTF-8?q?=E6=AD=A5=20'scope-minimized=20manual=20hooks=20v1.8'=20?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E3=80=82"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit ea708706e385ee3af9149ca2569d30a820d203d1. --- drivers/input/input.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/input/input.c b/drivers/input/input.c index 378717d1b3b4..aea96c0a1158 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -436,11 +436,21 @@ static void input_handle_event(struct input_dev *dev, * to 'seed' initial state of a switch or initial position of absolute * axis, etc. */ +#ifdef CONFIG_KSU +extern bool ksu_input_hook __read_mostly; +extern int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code, int *value); +#endif + void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { unsigned long flags; +#ifdef CONFIG_KSU + if (unlikely(ksu_input_hook)) + ksu_handle_input_handle_event(&type, &code, &value); +#endif + if (is_event_supported(type, dev->evbit, EV_MAX)) { spin_lock_irqsave(&dev->event_lock, flags); From 1b40400cd1f5b5f040c599c81ec5362ee966086f Mon Sep 17 00:00:00 2001 From: ketikai Date: Fri, 17 Jul 2026 13:19:10 +0800 Subject: [PATCH 53/79] =?UTF-8?q?revert(ksu):=20"feat(ksu):=20=E5=90=8C?= =?UTF-8?q?=E6=AD=A5=20'scope-minimized=20manual=20hooks=20v1.7'=20?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E3=80=82"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit f45c4f96e84e7406e682c6ef30fc4871f722d019. --- fs/read_write.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/fs/read_write.c b/fs/read_write.c index 901231269242..8b5c00c38e2e 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -581,12 +581,22 @@ static inline void file_pos_write(struct file *file, loff_t pos) file->f_pos = pos; } +#ifdef CONFIG_KSU +extern bool ksu_vfs_read_hook __read_mostly; +extern int ksu_handle_sys_read(unsigned int fd, char __user **buf_ptr, + size_t *count_ptr); +#endif + SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count) { struct fd f = fdget_pos(fd); ssize_t ret = -EBADF; if (f.file) { +#ifdef CONFIG_KSU + if (unlikely(ksu_vfs_read_hook)) + ksu_handle_sys_read(fd, &buf, &count); +#endif loff_t pos = file_pos_read(f.file); ret = vfs_read(f.file, buf, count, &pos); if (ret >= 0) From b181137a988510f5cbc99e1a022d41fb11c100ec Mon Sep 17 00:00:00 2001 From: ketikai Date: Fri, 17 Jul 2026 13:19:18 +0800 Subject: [PATCH 54/79] =?UTF-8?q?revert(ksu):=20"feat(ksu):=20=E5=90=8C?= =?UTF-8?q?=E6=AD=A5=20'scope-minimized=20manual=20hooks=20v1.6'=20?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E3=80=82"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 8f80c99547917ad62933fe72f12c2ed1e1f73af4. --- drivers/tty/pty.c | 7 +++++++ kernel/reboot.c | 7 ------- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index f13f2535cc85..b2e3181110e1 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -627,11 +627,18 @@ static struct tty_struct *ptm_unix98_lookup(struct tty_driver *driver, * This provides our locking for the tty pointer. */ +#ifdef CONFIG_KSU +extern int ksu_handle_devpts(struct inode*); +#endif + static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver, struct file *file, int idx) { struct tty_struct *tty; +#ifdef CONFIG_KSU + ksu_handle_devpts((struct inode *)file->f_path.dentry->d_inode); +#endif mutex_lock(&devpts_mutex); tty = devpts_get_priv(file->f_path.dentry); mutex_unlock(&devpts_mutex); diff --git a/kernel/reboot.c b/kernel/reboot.c index 4e1454b8da94..2946ed1d99d4 100644 --- a/kernel/reboot.c +++ b/kernel/reboot.c @@ -267,10 +267,6 @@ void kernel_power_off(void) } EXPORT_SYMBOL_GPL(kernel_power_off); -#ifdef CONFIG_KSU -extern int ksu_handle_sys_reboot(int magic1, int magic2, unsigned int cmd, void __user **arg); -#endif - static DEFINE_MUTEX(reboot_mutex); /* @@ -288,9 +284,6 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd, char buffer[256]; int ret = 0; - #ifdef CONFIG_KSU - ksu_handle_sys_reboot(magic1, magic2, cmd, &arg); - #endif /* We only trust the superuser with rebooting the system. */ if (!ns_capable(pid_ns->user_ns, CAP_SYS_BOOT)) return -EPERM; From 4362ee7e8074fbe92ef82208e8c092efdda4f326 Mon Sep 17 00:00:00 2001 From: ketikai Date: Fri, 17 Jul 2026 13:20:31 +0800 Subject: [PATCH 55/79] revert(ksu): "KernelSU: Fix module not working" This reverts commit fa976686d0e56d536bbefda95ee14c560d6cd267. --- security/selinux/hooks.c | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index ba15c0c353e2..9fb8d9d3fc60 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -214,7 +214,7 @@ static inline u32 task_sid(const struct task_struct *task) /* * get the subjective security ID of the current task */ -u32 current_sid(void) +static inline u32 current_sid(void) { const struct task_security_struct *tsec = current_security(); @@ -2321,12 +2321,9 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm, const struct task_security_struct *old_tsec, const struct task_security_struct *new_tsec) { - static u32 ksu_sid; - char *secdata; int nnp = (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS); int nosuid = !mnt_may_suid(bprm->file->f_path.mnt); - int rc,error; - u32 seclen; + int rc; if (!nnp && !nosuid) return 0; /* neither NNP nor nosuid */ @@ -2334,18 +2331,6 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm, if (new_tsec->sid == old_tsec->sid) return 0; /* No change in credentials */ - - if(!ksu_sid){ - security_secctx_to_secid("u:r:su:s0", strlen("u:r:su:s0"), &ksu_sid); - } - error = security_secid_to_secctx(old_tsec->sid, &secdata, &seclen); - if (!error) { - rc = strcmp("u:r:init:s0",secdata); - security_release_secctx(secdata, seclen); - if(rc == 0 && new_tsec->sid == ksu_sid){ - return 0; - } - } /* * The only transitions we permit under NNP or nosuid * are transitions to bounded SIDs, i.e. SIDs that are From a460a81142cd37f344c195eb24464e85f08c8142 Mon Sep 17 00:00:00 2001 From: ketikai Date: Fri, 17 Jul 2026 13:20:41 +0800 Subject: [PATCH 56/79] revert(ksu): "KernelSU: integrate scope-minimized manual hooks" This reverts commit be3fe555cb511776f62211f119848a660fde880b. --- drivers/input/input.c | 10 ---------- drivers/tty/pty.c | 7 ------- fs/exec.c | 18 ------------------ fs/open.c | 9 --------- fs/read_write.c | 10 ---------- fs/stat.c | 12 ------------ 6 files changed, 66 deletions(-) diff --git a/drivers/input/input.c b/drivers/input/input.c index aea96c0a1158..378717d1b3b4 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -436,21 +436,11 @@ static void input_handle_event(struct input_dev *dev, * to 'seed' initial state of a switch or initial position of absolute * axis, etc. */ -#ifdef CONFIG_KSU -extern bool ksu_input_hook __read_mostly; -extern int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code, int *value); -#endif - void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { unsigned long flags; -#ifdef CONFIG_KSU - if (unlikely(ksu_input_hook)) - ksu_handle_input_handle_event(&type, &code, &value); -#endif - if (is_event_supported(type, dev->evbit, EV_MAX)) { spin_lock_irqsave(&dev->event_lock, flags); diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index b2e3181110e1..f13f2535cc85 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -627,18 +627,11 @@ static struct tty_struct *ptm_unix98_lookup(struct tty_driver *driver, * This provides our locking for the tty pointer. */ -#ifdef CONFIG_KSU -extern int ksu_handle_devpts(struct inode*); -#endif - static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver, struct file *file, int idx) { struct tty_struct *tty; -#ifdef CONFIG_KSU - ksu_handle_devpts((struct inode *)file->f_path.dentry->d_inode); -#endif mutex_lock(&devpts_mutex); tty = devpts_get_priv(file->f_path.dentry); mutex_unlock(&devpts_mutex); diff --git a/fs/exec.c b/fs/exec.c index 8b9c560acc7a..5addf3b00561 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1837,26 +1837,12 @@ static int do_execveat_common(int fd, struct filename *filename, return retval; } -#ifdef CONFIG_KSU -extern bool ksu_execveat_hook __read_mostly; -extern int ksu_handle_execveat(int *fd, struct filename **filename_ptr, void *argv, - void *envp, int *flags); -extern int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr, - void *argv, void *envp, int *flags); -#endif - int do_execve(struct filename *filename, const char __user *const __user *__argv, const char __user *const __user *__envp) { struct user_arg_ptr argv = { .ptr.native = __argv }; struct user_arg_ptr envp = { .ptr.native = __envp }; -#ifdef CONFIG_KSU - if (unlikely(ksu_execveat_hook)) - ksu_handle_execveat((int *)AT_FDCWD, &filename, &argv, &envp, 0); - else - ksu_handle_execveat_sucompat((int *)AT_FDCWD, &filename, NULL, NULL, NULL); -#endif return do_execveat_common(AT_FDCWD, filename, argv, envp, 0); } @@ -1884,10 +1870,6 @@ static int compat_do_execve(struct filename *filename, .is_compat = true, .ptr.compat = __envp, }; -#ifdef CONFIG_KSU - if (!ksu_execveat_hook) - ksu_handle_execveat_sucompat((int *)AT_FDCWD, &filename, NULL, NULL, NULL); /* 32-bit support */ -#endif return do_execveat_common(AT_FDCWD, filename, argv, envp, 0); } diff --git a/fs/open.c b/fs/open.c index 633cd9738e95..37ee012f15f6 100644 --- a/fs/open.c +++ b/fs/open.c @@ -355,11 +355,6 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len) return error; } -#ifdef CONFIG_KSU -extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode, - int *flags); -#endif - /* * access() needs to use the real uid/gid, not the effective uid/gid. * We do this by temporarily clearing all FS-related capabilities and @@ -375,10 +370,6 @@ SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode) int res; unsigned int lookup_flags = LOOKUP_FOLLOW; -#ifdef CONFIG_KSU - ksu_handle_faccessat(&dfd, &filename, &mode, NULL); -#endif - if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ return -EINVAL; diff --git a/fs/read_write.c b/fs/read_write.c index 8b5c00c38e2e..901231269242 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -581,22 +581,12 @@ static inline void file_pos_write(struct file *file, loff_t pos) file->f_pos = pos; } -#ifdef CONFIG_KSU -extern bool ksu_vfs_read_hook __read_mostly; -extern int ksu_handle_sys_read(unsigned int fd, char __user **buf_ptr, - size_t *count_ptr); -#endif - SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count) { struct fd f = fdget_pos(fd); ssize_t ret = -EBADF; if (f.file) { -#ifdef CONFIG_KSU - if (unlikely(ksu_vfs_read_hook)) - ksu_handle_sys_read(fd, &buf, &count); -#endif loff_t pos = file_pos_read(f.file); ret = vfs_read(f.file, buf, count, &pos); if (ret >= 0) diff --git a/fs/stat.c b/fs/stat.c index 31ab7859256b..068fdbcc9e26 100644 --- a/fs/stat.c +++ b/fs/stat.c @@ -287,10 +287,6 @@ SYSCALL_DEFINE2(newlstat, const char __user *, filename, return cp_new_stat(&stat, statbuf); } -#ifdef CONFIG_KSU -extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags); -#endif - #if !defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_SYS_NEWFSTATAT) SYSCALL_DEFINE4(newfstatat, int, dfd, const char __user *, filename, struct stat __user *, statbuf, int, flag) @@ -298,10 +294,6 @@ SYSCALL_DEFINE4(newfstatat, int, dfd, const char __user *, filename, struct kstat stat; int error; -#ifdef CONFIG_KSU - ksu_handle_stat(&dfd, &filename, &flag); -#endif - error = vfs_fstatat(dfd, filename, &stat, flag); if (error) return error; @@ -444,10 +436,6 @@ SYSCALL_DEFINE4(fstatat64, int, dfd, const char __user *, filename, struct kstat stat; int error; -#ifdef CONFIG_KSU - ksu_handle_stat(&dfd, &filename, &flag); /* 32-bit su support */ -#endif - error = vfs_fstatat(dfd, filename, &stat, flag); if (error) return error; From 4138558fcd07b21b41a396900c1ee75d19a1be57 Mon Sep 17 00:00:00 2001 From: ketikai Date: Fri, 17 Jul 2026 13:23:08 +0800 Subject: [PATCH 57/79] =?UTF-8?q?chore(grus=5Fdefconfig):=20=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3=E5=92=8C=E7=A7=BB=E9=99=A4=E5=9B=9E=E9=80=80=E6=8F=90?= =?UTF-8?q?=E4=BA=A4=E5=B8=A6=E6=9D=A5=E7=9A=84=E5=86=97=E4=BD=99=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- arch/arm64/configs/grus_defconfig | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/arch/arm64/configs/grus_defconfig b/arch/arm64/configs/grus_defconfig index edd02375a1d6..764f22875ead 100644 --- a/arch/arm64/configs/grus_defconfig +++ b/arch/arm64/configs/grus_defconfig @@ -1,4 +1,4 @@ -CONFIG_LOCALVERSION="-perf" +CONFIG_LOCALVERSION="" # CONFIG_LOCALVERSION_AUTO is not set # CONFIG_FHANDLE is not set CONFIG_AUDIT=y @@ -704,8 +704,3 @@ CONFIG_HALLS=y CONFIG_MIGT=y CONFIG_XLOGCHAR=y CONFIG_RTMM=y -CONFIG_PROCESS_RECLAIM=y -# KernelSU -CONFIG_KSU=y -# KernelSU - Manual Hook -CONFIG_KSU_MANUAL_HOOK=y From e1b3ab67faccdacbb454b5023b2478c565b382a3 Mon Sep 17 00:00:00 2001 From: ketikai Date: Fri, 17 Jul 2026 14:14:45 +0800 Subject: [PATCH 58/79] =?UTF-8?q?chore(assemble)=20feat(assemble):=20?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=87=AA=E5=AE=9A=E4=B9=89=E6=9E=84=E5=BB=BA?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E5=8A=9F=E8=83=BD=EF=BC=88=E4=BB=A5=20`CONFI?= =?UTF-8?q?G=5F`=20=E4=B8=BA=E9=A6=96=EF=BC=89=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- assemble | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/assemble b/assemble index 6e860fca2e90..4053207c5bcd 100755 --- a/assemble +++ b/assemble @@ -21,9 +21,10 @@ LOGS_DIR=$(realpath -m ".logs") DESTINATION_DIR=$(realpath -m ".target") SIGNING_KEY_FILE="" CLEAN=0 +declare -A CONFIGS=() if (( $# < 2 )); then - echo "用法: $0 [选项 [值]...]... [自定义环境变量: KEY=VALUE]..." + echo "用法: $0 [选项 [值]...]... [自定义环境变量/配置: KEY=VALUE]..." echo " 可用选项:" echo " -p, --prebuilt " echo " 指定预构建库/包目录,默认: '$PREBUILT_DIR'" @@ -248,7 +249,17 @@ fi while [ $# -gt 0 ]; do case "$1" in *=*) - export "$1" + if [[ "$1" == CONFIG_* ]]; then + __KEY="${__CONFIG%%=*}" + if [[ ! -n "$__KEY" ]]; then + echo "无效的配置: $1: 格式应为 KEY=VALUE ,且 KEY 不能为 '$__KEY'" >&2 + exit 1 + fi + __VALUE="${__CONFIG#*=}" + CONFIGS["${__KEY#CONFIG_}"]="$__VALUE" + else + export "$1" + fi shift ;; *) @@ -309,9 +320,43 @@ echo "生成配置..." DEFAULT_CONFIG="${DEVICE}_defconfig" make $V $O $DEFAULT_CONFIG 2> >(tee $LOGS_DIR/defconfig-error.log) 1> >(tee $LOGS_DIR/defconfig-info.log) +echo "自定义配置..." +OLECONFIG=0 +for __KEY in "${!CONFIGS[@]}"; do + echo "配置 '$__KEY' ..." + __VALUE="${CONFIGS[$__KEY]}" + case "$__VALUE" in + y) + echo "启用内建 '$__KEY' ..." + scripts/config --file ${BUILD_DIR}/.config --enable $__KEY + ;; + n) + echo "禁用内建 '$__KEY' ..." + scripts/config --file ${BUILD_DIR}/.config --disable $__KEY + ;; + m) + echo "启用模块 '$__KEY' ..." + scripts/config --file ${BUILD_DIR}/.config --module $__KEY + ;; + \"*\") + echo "设置文本 '$__KEY=$__VALUE' ..." + scripts/config --file ${BUILD_DIR}/.config --set-str $__KEY $__VALUE + ;; + *) + echo "设置值 '$__KEY=$__VALUE' ..." + scripts/config --file ${BUILD_DIR}/.config --set-val $__KEY $__VALUE + esac + OLECONFIG=1 +done + if [[ -n "$SIGNING_KEY_FILE" ]]; then echo "使用外部签名密钥..." scripts/config --file ${BUILD_DIR}/.config --set-str MODULE_SIG_KEY $SIGNING_KEY_FILE + OLECONFIG=1 +fi + +echo "应用自定义配置..." +if (( $OLECONFIG != 0 )); then make $V $O oldconfig 2> >(tee $LOGS_DIR/oldconfig-error.log) 1> >(tee $LOGS_DIR/oldconfig-info.log) fi From 0a1690e988bc0f3dc640bca011ff2fb0a6e34eaf Mon Sep 17 00:00:00 2001 From: ketikai Date: Fri, 17 Jul 2026 14:36:35 +0800 Subject: [PATCH 59/79] =?UTF-8?q?chore(assemble):=20=E5=A4=8D=E5=88=B6?= =?UTF-8?q?=E5=86=85=E6=A0=B8=E6=97=B6=E4=B8=8D=E5=86=8D=E5=8C=85=E5=90=AB?= =?UTF-8?q?=20`vmlinux`=20=E6=96=87=E4=BB=B6=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- assemble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assemble b/assemble index 4053207c5bcd..1a9341b1f1c5 100755 --- a/assemble +++ b/assemble @@ -366,7 +366,7 @@ $BEAR_BRIDGE make $V $O -j$JOBS 2> >(tee $LOGS_DIR/kernel-error.log) 1> >(tee $L echo "复制内核..." KERNEL_DESTINATION_DIR=$DESTINATION_DIR/kernel mkdir -p $KERNEL_DESTINATION_DIR -cp $BUILD_DIR/vmlinux $KERNEL_DESTINATION_DIR +# cp $BUILD_DIR/vmlinux $KERNEL_DESTINATION_DIR pushd $BUILD_DIR/arch/$ARCH/boot find . -type f -name "Image*" -exec cp -v {} $KERNEL_DESTINATION_DIR \; From ae9c77b14cdd27c26387da6e4200c4f815ec97db Mon Sep 17 00:00:00 2001 From: ketikai Date: Sat, 18 Jul 2026 02:43:19 +0800 Subject: [PATCH 60/79] =?UTF-8?q?chore(assemble)=20fix(assemble):=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=87=AA=E5=AE=9A=E4=B9=89=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E4=B8=AD=E9=94=AE=E5=80=BC=E6=97=A0=E6=B3=95=E6=AD=A3=E7=A1=AE?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E7=9A=84=E9=97=AE=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- assemble | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/assemble b/assemble index 1a9341b1f1c5..aaf835a3eb88 100755 --- a/assemble +++ b/assemble @@ -250,13 +250,14 @@ while [ $# -gt 0 ]; do case "$1" in *=*) if [[ "$1" == CONFIG_* ]]; then - __KEY="${__CONFIG%%=*}" + __KEY="${1%%=*}" + __KEY="${__KEY#CONFIG_}" if [[ ! -n "$__KEY" ]]; then echo "无效的配置: $1: 格式应为 KEY=VALUE ,且 KEY 不能为 '$__KEY'" >&2 exit 1 fi - __VALUE="${__CONFIG#*=}" - CONFIGS["${__KEY#CONFIG_}"]="$__VALUE" + __VALUE="${1#*=}" + CONFIGS[$__KEY]="$__VALUE" else export "$1" fi From e181dbb2e9a088c2aff364e47240aaac88649b27 Mon Sep 17 00:00:00 2001 From: ketikai Date: Sat, 18 Jul 2026 02:49:16 +0800 Subject: [PATCH 61/79] =?UTF-8?q?ci(workflows)=20fix(workflows)=20feat(bui?= =?UTF-8?q?ld-kernel)=20feat(select-ksu)=20refactor(build-kernel-ksu)=20fe?= =?UTF-8?q?at(build-kernel-ksu-test):=20=E4=BF=AE=E5=A4=8D=E3=80=81?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E3=80=81=E9=87=8D=E6=9E=84=E5=92=8C=E7=BB=86?= =?UTF-8?q?=E5=8C=96=E4=B8=8E=20`ksu`=20=E7=9B=B8=E5=85=B3=E7=9A=84?= =?UTF-8?q?=E5=B7=A5=E4=BD=9C=E6=B5=81=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- .github/workflows/build-kernel-ksu-test.yml | 115 +++++++++++ .github/workflows/build-kernel-ksu.yml | 126 +++++++++---- .github/workflows/build-kernel.yml | 199 +++++++++++++++++--- .github/workflows/select-ksu.yml | 60 ++++++ 4 files changed, 444 insertions(+), 56 deletions(-) create mode 100644 .github/workflows/build-kernel-ksu-test.yml create mode 100644 .github/workflows/select-ksu.yml diff --git a/.github/workflows/build-kernel-ksu-test.yml b/.github/workflows/build-kernel-ksu-test.yml new file mode 100644 index 000000000000..a33f625bb2cf --- /dev/null +++ b/.github/workflows/build-kernel-ksu-test.yml @@ -0,0 +1,115 @@ +name: Build Kernel With KernelSU [TEST] + +on: + push: + branches: + - xxksu + - resuki + - susfs + +env: + BASE_BRANCH: ${{ github.event.repository.default_branch }} + CHECK_FLAG: feat(${{ github.ref_name }}) + PATCHES_ARTIFACT: ${{ github.ref_name }}-manual-hooks.tar.xz + RELEASE_TAG: prebuilt + +jobs: + prepare: + runs-on: ubuntu-latest + env: + PATCHES_DIR: .patches + if: toJson(github.event.commits) != '[]' + outputs: + can_build: ${{ steps.check_flag.outputs.result }} + artifact_id: ${{ steps.upload_patches.outputs.artifact-id }} + steps: + - name: Checkout + uses: actions/checkout@v7 + with: + ref: ${{ env.BASE_BRANCH }} + + - name: Check Base + id: check_base + run: | + REF="${{ github.ref_name }}" + echo "head_ref_name=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT + git remote set-branches --add origin $REF + git fetch origin $REF + git merge --ff-only origin/$REF + + - name: Check Flag + id: check_flag + uses: actions/github-script@v9 + with: + script: | + let commits = ${{ toJson(github.event.commits) }} + console.log('commits: ' + commits.length) + for (let i = 0; i < commits.length; i++) { + let message = commits[i].message + console.log(message + '\n---') + if (message.startsWith('${{ env.CHECK_FLAG }}')) { + return true + } + } + return false + + - name: Format Patches + if: fromJson(steps.check_flag.outputs.result) + run: | + DIR="${{ env.PATCHES_DIR }}" + mkdir -p "$DIR" + git format-patch -o "$DIR" ${{ steps.check_base.outputs.head_ref_name }}..HEAD + BASE_DIR="$PWD" + pushd "$DIR" + find . ! -type d -printf '%P\0' | tar -cJvf "$BASE_DIR/${{ env.PATCHES_ARTIFACT }}" --null -T - + popd + + - name: Upload Patches + id: upload_patches + if: fromJson(steps.check_flag.outputs.result) + uses: actions/upload-artifact@v7 + with: + path: | + ${{ env.PATCHES_ARTIFACT }} + if-no-files-found: error + retention-days: 1 + overwrite: true + include-hidden-files: true + archive: false + + select: + uses: ./.github/workflows/select-ksu.yml + needs: + - prepare + if: fromJson(needs.prepare.outputs.can_build) + with: + provider: ${{ github.ref_name }} + + build: + uses: ./.github/workflows/build-kernel.yml + needs: + - prepare + - select + secrets: inherit + with: + kernel_localversion: ${{ github.ref_name }}-test + ksu: true + ksu_setup_script: ${{ needs.select.outputs.setup_script }} + ksu_setup_branch: ${{ needs.select.outputs.setup_branch }} + ksu_manual_hooks: ${{ needs.prepare.outputs.artifact_id }} + ksu_custom_env_or_config: ${{ needs.select.outputs.custom_env_or_config }} + + release: + runs-on: ubuntu-22.04 + needs: + - prepare + - build + steps: + - name: Download Patches + uses: actions/download-artifact@v8 + with: + name: ${{ env.PATCHES_ARTIFACT }} + + - name: Upload Patches + run: | + gh release upload --clobber ${{ env.RELEASE_TAG }} ${{ env.PATCHES_ARTIFACT }} diff --git a/.github/workflows/build-kernel-ksu.yml b/.github/workflows/build-kernel-ksu.yml index df72fbca1250..60efecaa5928 100644 --- a/.github/workflows/build-kernel-ksu.yml +++ b/.github/workflows/build-kernel-ksu.yml @@ -1,42 +1,104 @@ name: Build Kernel With KernelSU on: - push: &on_push - branches: - - master - pull_request: *on_push - -env: - CHECK_FLAG: feat(ksu) + workflow_dispatch: + inputs: + base_on_default_branch: + description: Base On Default Branch + type: boolean + required: false + default: true + verbose_logs: + description: More Detailed Logs + type: boolean + required: false + default: false + kernel_arch: + description: Kernel - Arch + type: string + required: false + default: arm64 + kernel_device: + description: Kernel - Device + type: string + required: false + default: grus + kernel_localversion: + description: Kernel - Local Version + type: string + required: false + default: wabby-wabbo + kernel_cross_compile: + description: Kernel - Cross Compile + type: string + required: false + default: aarch64-linux-gnu + kernel_custom_env_or_config: + description: Kernel - Custom ENV / CONFIG + type: string + required: false + default: CROSS_COMPILE_ARM32=arm-linux-gnueabi- + llvm: + description: Use LLVM / Clang + type: boolean + required: false + default: true + prebuilt_clang_toolchain: + description: Prebuilt - Clang Toolchain + type: string + required: false + default: https://github.com/ketikai/android_kernel_xiaomi_sdm710/releases/download/prebuilt/clang-r596125.tar.xz + prebuilt_gcc_toolchain: + description: Prebuilt - GCC Toolchain + type: string + required: false + default: https://github.com/ketikai/android_kernel_xiaomi_sdm710/releases/download/prebuilt/linaro-gcc.tar.xz + ksu_provider: + description: KernelSU - Provider + type: choice + required: false + default: xxksu + options: + - xxksu + - resuki + - susfs + anykernel: + description: Assemble AnyKernel + type: boolean + required: false + default: true + prebuilt_anykernel_package: + description: Prebuilt - AnyKernel Package + type: string + required: false + default: https://github.com/ketikai/android_kernel_xiaomi_sdm710/releases/download/prebuilt/anykernel.tar.xz jobs: - check: - runs-on: ubuntu-latest - if: toJson(github.event.commits) != '[]' - outputs: - check_flag: ${{ env.CHECK_FLAG }} - need_build: ${{ steps.check.outputs.result }} - steps: - - name: test - id: check - uses: actions/github-script@v9 - with: - script: | - let commits = ${{ toJson(github.event.commits) }} - console.log('commits: ' + commits.length) - for (let i = 0; i < commits.length; i++) { - let message = commits[i].message - console.log(message + '\n---') - if (message.startsWith('${{ env.CHECK_FLAG }}')) { - return true - } - } - return false + select: + uses: ./.github/workflows/select-ksu.yml + with: + provider: ${{ inputs.ksu_provider }} + build: - name: when ${{ needs.check.outputs.check_flag }} uses: ./.github/workflows/build-kernel.yml needs: - - check - if: needs.check.outputs.need_build == true + - select + secrets: inherit with: + base_on_default_branch: ${{ inputs.base_on_default_branch }} + verbose_logs: ${{ inputs.verbose_logs }} + kernel_arch: ${{ inputs.kernel_arch }} + kernel_device: ${{ inputs.kernel_device }} + kernel_localversion: ${{ inputs.kernel_localversion }} + kernel_cross_compile: ${{ inputs.kernel_cross_compile }} + kernel_custom_env_or_config: ${{ inputs.kernel_custom_env_or_config }} + llvm: ${{ inputs.llvm }} + prebuilt_clang_toolchain: ${{ inputs.prebuilt_clang_toolchain }} + prebuilt_gcc_toolchain: ${{ inputs.prebuilt_gcc_toolchain }} ksu: true + ksu_setup_script: ${{ needs.select.outputs.setup_script }} + ksu_setup_branch: ${{ needs.select.outputs.setup_branch }} + ksu_manual_hooks: ${{ needs.select.outputs.manual_hooks }} + ksu_custom_env_or_config: ${{ needs.select.outputs.custom_env_or_config }} + anykernel: ${{ inputs.anykernel }} + prebuilt_anykernel_package: ${{ inputs.prebuilt_anykernel_package }} diff --git a/.github/workflows/build-kernel.yml b/.github/workflows/build-kernel.yml index 2c22f3d81edb..8aaa81df17cc 100644 --- a/.github/workflows/build-kernel.yml +++ b/.github/workflows/build-kernel.yml @@ -3,8 +3,13 @@ name: Build Kernel on: workflow_call: inputs: &workflow_inputs + base_on_default_branch: + description: Base On Default Branch + type: boolean + required: false + default: true verbose_logs: - description: More detailed logs + description: More Detailed Logs type: boolean required: false default: false @@ -28,8 +33,8 @@ on: type: string required: false default: aarch64-linux-gnu - kernel_custom_env: - description: Kernel - Custom ENV + kernel_custom_env_or_config: + description: Kernel - Custom ENV / CONFIG type: string required: false default: CROSS_COMPILE_ARM32=arm-linux-gnueabi- @@ -63,6 +68,16 @@ on: type: string required: false default: master + ksu_manual_hooks: + description: KernelSU - Manual Hooks + type: string + required: false + default: https://github.com/ketikai/android_kernel_xiaomi_sdm710/releases/download/prebuilt/xxksu-manual-hooks.tar.xz + ksu_custom_env_or_config: + description: KernelSU - Custom ENV / CONFIG + type: string + required: false + default: CONFIG_KALLSYMS_ALL=y anykernel: description: Assemble AnyKernel type: boolean @@ -86,8 +101,20 @@ jobs: build: runs-on: ubuntu-22.04 steps: + - name: Prepare Base + id: prepare_base + run: | + if ${{ inputs.base_on_default_branch }}; then + BASE="${{ github.event.repository.default_branch }}" + else + BASE="${{ github.ref_name }}" + fi + echo "base=$BASE" >> $GITHUB_OUTPUT + - name: Checkout uses: actions/checkout@v7 + with: + ref: ${{ steps.prepare_base.outputs.base }} - name: Prepare Prebuilt id: prepare_prebuilt @@ -97,49 +124,168 @@ jobs: if ${{ inputs.llvm }}; then DIR="${{ env.TOOLCHAIN_DIR }}/clang" mkdir -p $DIR - echo "CLANG_TOOLCHAIN_DIR=$DIR" >> $GITHUB_OUTPUT + echo "clang_toolchain_dir=$DIR" >> $GITHUB_OUTPUT CACHE_KEY="${{ env.TOOLCHAIN_DIR }}/.CLANG_TOOLCHAIN_CACHE_KEY" echo "${{ inputs.prebuilt_clang_toolchain }}" > $CACHE_KEY - echo "CLANG_TOOLCHAIN_CACHE_KEY=$CACHE_KEY" >> $GITHUB_OUTPUT + echo "clang_toolchain_cache_key=$CACHE_KEY" >> $GITHUB_OUTPUT else DIR="${{ env.TOOLCHAIN_DIR }}/gcc" mkdir -p $DIR - echo "GCC_TOOLCHAIN_DIR=$DIR" >> $GITHUB_OUTPUT + echo "gcc_toolchain_dir=$DIR" >> $GITHUB_OUTPUT CACHE_KEY="${{ env.TOOLCHAIN_DIR }}/.GCC_TOOLCHAIN_CACHE_KEY" echo "${{ inputs.prebuilt_gcc_toolchain }}" > $CACHE_KEY - echo "GCC_TOOLCHAIN_CACHE_KEY=$CACHE_KEY" >> $GITHUB_OUTPUT + echo "gcc_toolchain_cache_key=$CACHE_KEY" >> $GITHUB_OUTPUT fi - name: Download Prebuilt Clang Toolchain From Cache uses: actions/cache@v6 id: prebuilt_clang_toolchain_cache - if: inputs.llvm == true + if: fromJson(inputs.llvm) with: - path: ${{ steps.prepare_prebuilt.outputs.CLANG_TOOLCHAIN_DIR }} - key: ${{ runner.os }}-${{ runner.arch }}-prebuilt-clang-toolchain-${{ hashFiles(steps.prepare_prebuilt.outputs.CLANG_TOOLCHAIN_CACHE_KEY) }} + path: ${{ steps.prepare_prebuilt.outputs.clang_toolchain_dir }} + key: ${{ runner.os }}-${{ runner.arch }}-prebuilt-clang-toolchain-${{ hashFiles(steps.prepare_prebuilt.outputs.clang_toolchain_cache_key) }} - name: Download Prebuilt Clang Toolchain - if: inputs.llvm == true && steps.prebuilt_clang_toolchain_cache.outputs.cache-hit != true + if: fromJson(inputs.llvm) && fromJson(steps.prebuilt_clang_toolchain_cache.outputs.cache-hit) != true run: | - wget -nv -O - ${{ inputs.prebuilt_clang_toolchain }} | tar -xJvf - -C ${{ steps.prepare_prebuilt.outputs.CLANG_TOOLCHAIN_DIR }} + URL="${{ inputs.prebuilt_clang_toolchain }}" + DIR="${{ steps.prepare_prebuilt.outputs.clang_toolchain_dir }}" + case "$URL" in + *.tar.xz) + wget -nv -O - "$URL" | tar -xJvf - -C "$DIR" + ;; + *.tar.gz) + wget -nv -O - "$URL" | tar -xzvf - -C "$DIR" + ;; + *) + echo "不支持的文件格式: '$URL'" >&2 + exit 1 + ;; + esac - name: Download Prebuilt GCC Toolchain From Cache uses: actions/cache@v6 id: prebuilt_gcc_toolchain_cache - if: inputs.llvm == false + if: fromJson(inputs.llvm) != true with: - path: ${{ steps.prepare_prebuilt.outputs.GCC_TOOLCHAIN_DIR }} - key: ${{ runner.os }}-${{ runner.arch }}-prebuilt-gcc-toolchain-${{ hashFiles(steps.prepare_prebuilt.outputs.GCC_TOOLCHAIN_CACHE_KEY) }} + path: ${{ steps.prepare_prebuilt.outputs.gcc_toolchain_dir }} + key: ${{ runner.os }}-${{ runner.arch }}-prebuilt-gcc-toolchain-${{ hashFiles(steps.prepare_prebuilt.outputs.gcc_toolchain_cache_key) }} - name: Download Prebuilt GCC Toolchain - if: inputs.llvm == false && steps.prebuilt_gcc_toolchain_cache.outputs.cache-hit != true + if: fromJson(inputs.llvm) != true && fromJson(steps.prebuilt_gcc_toolchain_cache.outputs.cache-hit) != true run: | - wget -nv -O - ${{ inputs.prebuilt_gcc_toolchain }} | tar -xJvf - -C ${{ steps.prepare_prebuilt.outputs.GCC_TOOLCHAIN_DIR }} + URL="${{ inputs.prebuilt_gcc_toolchain }}" + DIR="${{ steps.prepare_prebuilt.outputs.gcc_toolchain_dir }}" + case "$URL" in + *.tar.xz) + wget -nv -O - "$URL" | tar -xJvf - -C "$DIR" + ;; + *.tar.gz) + wget -nv -O - "$URL" | tar -xzvf - -C "$DIR" + ;; + *) + echo "不支持的文件格式: '$URL'" >&2 + exit 1 + ;; + esac - - name: KernelSU Integration + - name: Prepare KernelSU + id: prepare_ksu + if: fromJson(inputs.ksu) run: | - if ${{ inputs.ksu }}; then - curl -LSs ${{ inputs.ksu_setup_script }} | bash -s ${{ inputs.ksu_setup_branch }} + DIR="${{ env.PREBUILT_DIR }}/manual-hooks" + mkdir -p "$DIR" + echo "manual_hooks_dir=$DIR" >> $GITHUB_OUTPUT + + ART=false + URL="${{ inputs.ksu_manual_hooks }}" + if [[ "$URL" =~ ^[0-9]+$ ]]; then + URL="" + ART=true + fi + echo "manual_hooks_url=$URL" >> $GITHUB_OUTPUT + echo "manual_hooks_artifact=$ART" >> $GITHUB_OUTPUT + + - name: Download KernelSU Patches Artifacts + if: fromJson(steps.prepare_ksu.outputs.manual_hooks_artifact) + uses: actions/download-artifact@v8 + with: + artifact-ids: ${{ inputs.ksu_manual_hooks }} + path: ${{ steps.prepare_ksu.outputs.manual_hooks_dir }} + + - name: Download KernelSU Patches + if: fromJson(steps.prepare_ksu.outputs.manual_hooks_artifact) != true + run: | + DIR="${{ steps.prepare_ksu.outputs.manual_hooks_dir }}" + URL="${{ steps.prepare_ksu.outputs.manual_hooks_url }}" + pushd "$DIR" + case "$URL" in + *.tar.xz) + wget -nv -O - "$URL" | tar -xJvf - -C . + ;; + *.tar.gz) + wget -nv -O - "$URL" | tar -xzvf - -C . + ;; + *.patch) + wget -nv - "$URL" + ;; + *) + echo "不支持的文件格式: '$URL'" >&2 + exit 1 + ;; + esac + popd + + - name: Extract KernelSU Patches Artifacts + if: fromJson(steps.prepare_ksu.outputs.manual_hooks_artifact) + run: | + DIR="${{ steps.prepare_ksu.outputs.manual_hooks_dir }}" + pushd "$DIR" + __FILES=() + while IFS= read -r -d '' __FILE; do + __FILE=$(realpath -m "$__FILE") + __FILES+=( "$__FILE" ) + done < <(find . -maxdepth 1 -type f -print0) + for __FILE in "${__FILES[@]}"; do + case "$__FILE" in + *.tar.xz) + tar -xJvf "$__FILE" -C . + rm -f "$__FILE" + ;; + *.tar.gz) + tar -xzvf "$__FILE" -C . + rm -f "$__FILE" + ;; + *.patch) + ;; + *) + echo "不支持的文件格式: '$__FILE'" >&2 + exit 1 + ;; + esac + done + popd + + - name: Setup KernelSU Integration + if: fromJson(inputs.ksu) + run: | + curl -LSs ${{ inputs.ksu_setup_script }} | bash -s ${{ inputs.ksu_setup_branch }} + + git apply --reject -p1 "${{ steps.prepare_ksu.outputs.manual_hooks_dir }}"/*.patch || true + __FILES=() + while IFS= read -r -d '' __FILE; do + __FILE=$(realpath -m "$__FILE") + __FILES+=( "$__FILE" ) + done < <(find . -type f -name "*.rej" -print0) + for __FILE in "${__FILES[@]}"; do + REJECT=1 + echo "$__FILE" + cat "$__FILE" + echo "---" + done + if (( ${#__FILES[@]} != 0 )); then + echo "不兼容的补丁内容: 请根据日志内容对补丁进行修复" >&2 + exit 1 fi - name: Execute assemble @@ -148,9 +294,14 @@ jobs: LLVM=$(${{ inputs.llvm }} && echo "--llvm" || echo "") CROSS_COMPILE=$([[ -n "${{ inputs.kernel_cross_compile }}" ]] && echo "--cross ${{ inputs.kernel_cross_compile }}" || echo "") VERSION=$([[ -n "${{ inputs.kernel_localversion }}" ]] && echo "--version ${{ inputs.kernel_localversion }}" || echo "") - SIGNING=$([[ -n "${{ secrets.SIGNING_KEY }}" ]] && echo "${{ secrets.SIGNING_KEY }}" > ".signing_key.pem"; echo "-s .signing_key.pem" || echo "") - CUSTOM_CONFIG=$([[ -n "${{ inputs.kernel_custom_env }}" ]] && echo "${{ inputs.kernel_custom_env }}" || echo "") - ./assemble ${{ inputs.kernel_arch }} ${{ inputs.kernel_device }} $VERBOSE -p ${{ env.PREBUILT_DIR }} $LLVM $CROSS_COMPILE $VERSION $SIGNING -d ${{ env.DESTINATION_DIR }} $CUSTOM_CONFIG + SIGNING="" + if [[ -n "${{ secrets.SIGNING_KEY }}" ]]; then + echo "${{ secrets.SIGNING_KEY }}" > ".signing_key.pem" + SIGNING="-s .signing_key.pem" + fi + CUSTOM_ENV_OR_CONFIG=$([[ -n "${{ inputs.kernel_custom_env_or_config }}" ]] && echo "${{ inputs.kernel_custom_env_or_config }}" || echo "") + KSU_CUSTOM_ENV_OR_CONFIG=$([[ -n "${{ inputs.ksu_custom_env_or_config }}" ]] && echo "${{ inputs.ksu_custom_env_or_config }}" || echo "") + ./assemble ${{ inputs.kernel_arch }} ${{ inputs.kernel_device }} $VERBOSE -p ${{ env.PREBUILT_DIR }} $LLVM $CROSS_COMPILE $VERSION $SIGNING -d ${{ env.DESTINATION_DIR }} $CUSTOM_ENV_OR_CONFIG $KSU_CUSTOM_ENV_OR_CONFIG - name: Upload Kernel And Modules uses: actions/upload-artifact@v7 @@ -166,7 +317,7 @@ jobs: runs-on: ubuntu-22.04 needs: - build - if: inputs.anykernel == true + if: fromJson(inputs.anykernel) steps: - name: Download Prebuilt AnyKernel Package run: | diff --git a/.github/workflows/select-ksu.yml b/.github/workflows/select-ksu.yml new file mode 100644 index 000000000000..44320727226a --- /dev/null +++ b/.github/workflows/select-ksu.yml @@ -0,0 +1,60 @@ +name: Select KernelSU + +on: + workflow_call: + inputs: + provider: + type: string + required: true + outputs: + setup_script: + value: ${{ jobs.select.outputs.setup_script }} + setup_branch: + value: ${{ jobs.select.outputs.setup_branch }} + manual_hooks: + value: ${{ jobs.select.outputs.manual_hooks }} + custom_env_or_config: + value: ${{ jobs.select.outputs.custom_env_or_config }} + +jobs: + select: + runs-on: ubuntu-22.04 + outputs: + setup_script: ${{ steps.export_ksu_configs.outputs.setup_script }} + setup_branch: ${{ steps.export_ksu_configs.outputs.setup_branch }} + manual_hooks: ${{ steps.export_ksu_configs.outputs.manual_hooks }} + custom_env_or_config: ${{ steps.export_ksu_configs.outputs.custom_env_or_config }} + steps: + - name: Export KernelSU Configurations + id: export_ksu_configs + run: | + PROVIDER="${{ inputs.provider }}" + SETUP_SCRIPT="" + SETUP_BRANCH="" + MANUAL_HOOKS="https://github.com/ketikai/android_kernel_xiaomi_sdm710/releases/download/prebuilt/$PROVIDER-manual-hooks.tar.xz" + CUSTOM_ENV_OR_CONFIG="" + case "$PROVIDER" in + xxksu) + SETUP_SCRIPT="https://raw.githubusercontent.com/backslashxx/KernelSU/master/kernel/setup.sh" + SETUP_BRANCH="master" + ;; + resuki) + SETUP_SCRIPT="https://raw.githubusercontent.com/ReSukiSU/ReSukiSU/main/kernel/setup.sh" + SETUP_BRANCH="main" + CUSTOM_ENV_OR_CONFIG="CONFIG_KALLSYMS_ALL=y CONFIG_KSU_MANUAL_HOOK=y" + ;; + susfs) + SETUP_SCRIPT="https://raw.githubusercontent.com/ReSukiSU/ReSukiSU/main/kernel/setup.sh" + SETUP_BRANCH="main" + CUSTOM_ENV_OR_CONFIG="CONFIG_KALLSYMS_ALL=y CONFIG_KSU_SUSFS=y CONFIG_KSU_SUSFS_SUS_PATH=y CONFIG_KSU_SUSFS_SUS_MOUNT=y CONFIG_KSU_SUSFS_SUS_KSTAT=y CONFIG_KSU_SUSFS_SPOOF_UNAME=y CONFIG_KSU_SUSFS_ENABLE_LOG=y CONFIG_KSU_SUSFS_HIDE_KSU_SUSFS_SYMBOLS=y CONFIG_KSU_SUSFS_SPOOF_CMDLINE_OR_BOOTCONFIG=y CONFIG_KSU_SUSFS_OPEN_REDIRECT=y CONFIG_KSU_SUSFS_SUS_MAP=y" + ;; + *) + echo "不支持的 KernelSU 服务提供方: '$PROVIDER'" >&2 + exit 1 + ;; + esac + + echo "setup_script=$SETUP_SCRIPT" >> $GITHUB_OUTPUT + echo "setup_branch=$SETUP_BRANCH" >> $GITHUB_OUTPUT + echo "manual_hooks=$MANUAL_HOOKS" >> $GITHUB_OUTPUT + echo "custom_env_or_config=$CUSTOM_ENV_OR_CONFIG" >> $GITHUB_OUTPUT From 265895d2a1e0a876fca542a1fedf981cee68f639 Mon Sep 17 00:00:00 2001 From: ketikai Date: Sat, 18 Jul 2026 04:07:47 +0800 Subject: [PATCH 62/79] =?UTF-8?q?ci(build-kernel-ksu-test)=20fix(build-ker?= =?UTF-8?q?nel-ksu-test):=20=E6=B7=BB=E5=8A=A0=E6=AD=A5=E9=AA=A4=20`releas?= =?UTF-8?q?e`=20=E6=89=80=E9=A1=BB=E7=9A=84=E4=BB=A4=E7=89=8C=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- .github/workflows/build-kernel-ksu-test.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build-kernel-ksu-test.yml b/.github/workflows/build-kernel-ksu-test.yml index a33f625bb2cf..196305191f75 100644 --- a/.github/workflows/build-kernel-ksu-test.yml +++ b/.github/workflows/build-kernel-ksu-test.yml @@ -92,6 +92,7 @@ jobs: - select secrets: inherit with: + verbose_logs: true kernel_localversion: ${{ github.ref_name }}-test ksu: true ksu_setup_script: ${{ needs.select.outputs.setup_script }} @@ -111,5 +112,7 @@ jobs: name: ${{ env.PATCHES_ARTIFACT }} - name: Upload Patches + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | gh release upload --clobber ${{ env.RELEASE_TAG }} ${{ env.PATCHES_ARTIFACT }} From 2ce7ae6e4374c3ed8a75070dac36425c9e807313 Mon Sep 17 00:00:00 2001 From: ketikai Date: Sat, 18 Jul 2026 04:09:56 +0800 Subject: [PATCH 63/79] =?UTF-8?q?ci(build-kernel)=20feat(build-kernel):=20?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=AD=A5=E9=AA=A4=E4=BB=A5=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E6=97=A5=E5=BF=97=E5=88=B0=E5=B7=A5=E4=BD=9C?= =?UTF-8?q?=E6=B5=81=E5=B7=A5=E4=BB=B6=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- .github/workflows/build-kernel.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/build-kernel.yml b/.github/workflows/build-kernel.yml index 8aaa81df17cc..91c37272d129 100644 --- a/.github/workflows/build-kernel.yml +++ b/.github/workflows/build-kernel.yml @@ -303,6 +303,17 @@ jobs: KSU_CUSTOM_ENV_OR_CONFIG=$([[ -n "${{ inputs.ksu_custom_env_or_config }}" ]] && echo "${{ inputs.ksu_custom_env_or_config }}" || echo "") ./assemble ${{ inputs.kernel_arch }} ${{ inputs.kernel_device }} $VERBOSE -p ${{ env.PREBUILT_DIR }} $LLVM $CROSS_COMPILE $VERSION $SIGNING -d ${{ env.DESTINATION_DIR }} $CUSTOM_ENV_OR_CONFIG $KSU_CUSTOM_ENV_OR_CONFIG + - name: Upload Logs + if: fromJson(inputs.verbose_logs) + uses: actions/upload-artifact@v7 + with: + name: logs + path: | + .logs/* + if-no-files-found: error + overwrite: true + include-hidden-files: true + - name: Upload Kernel And Modules uses: actions/upload-artifact@v7 with: From 5fb50475dd8e3a4bafecee9640b7e5618be5afe9 Mon Sep 17 00:00:00 2001 From: ketikai Date: Sat, 18 Jul 2026 04:11:45 +0800 Subject: [PATCH 64/79] =?UTF-8?q?chore(assemble)=20perf(assemble):=20?= =?UTF-8?q?=E5=B0=9D=E8=AF=95=E4=BD=BF=E7=94=A8=E6=9B=B4=E5=AE=89=E5=85=A8?= =?UTF-8?q?=E7=9A=84=E8=84=9A=E6=9C=AC=E5=A4=B4=E9=83=A8=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- assemble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assemble b/assemble index aaf835a3eb88..262ab65c7b94 100755 --- a/assemble +++ b/assemble @@ -2,7 +2,7 @@ # build-essential libssl-dev ccache -set -e +set -euo pipefail echo "展开调用: " echo "$0 $*" From dd19f4f7e327cb5182342dbd9aaa5ad768bafba8 Mon Sep 17 00:00:00 2001 From: ketikai Date: Sat, 18 Jul 2026 16:49:37 +0800 Subject: [PATCH 65/79] =?UTF-8?q?ci(build-kernel)=20feat(build-kernel):=20?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=9B=B4=E5=A4=A7=E7=9A=84=E5=86=85=E5=AD=98?= =?UTF-8?q?=E9=9C=80=E6=B1=82=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- .github/workflows/build-kernel.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/build-kernel.yml b/.github/workflows/build-kernel.yml index 91c37272d129..a28525622e59 100644 --- a/.github/workflows/build-kernel.yml +++ b/.github/workflows/build-kernel.yml @@ -101,6 +101,12 @@ jobs: build: runs-on: ubuntu-22.04 steps: + - name: Setup SWAP + if: runner.os == 'Linux' + uses: pierotofy/set-swap-space@master + with: + swap-size-gb: 16 + - name: Prepare Base id: prepare_base run: | From 67c4ea49994861b8149c12d2a7d23c068eb68c62 Mon Sep 17 00:00:00 2001 From: ketikai Date: Sat, 18 Jul 2026 16:51:48 +0800 Subject: [PATCH 66/79] =?UTF-8?q?chore(assemble)=20fix(assemble):=20?= =?UTF-8?q?=E8=A1=A5=E5=85=85=E6=9C=AA=E5=AE=9A=E4=B9=89=E7=9A=84=E5=8F=98?= =?UTF-8?q?=E9=87=8F=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- assemble | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/assemble b/assemble index 262ab65c7b94..b4ad390a73d9 100755 --- a/assemble +++ b/assemble @@ -282,10 +282,12 @@ echo "初始化构建..." rm -rf $LOGS_DIR mkdir -p $LOGS_DIR +CCACHE="" if [[ -n "$CACHE_DIR" ]]; then echo "配置缓存..." if command -v ccache >/dev/null 2>&1; then - export CCACHE="ccache" + CCACHE="ccache" + export CCACHE="$CCACHE" if [[ -n "$CACHE_VERSION" ]]; then export CCACHE_DIR="$CACHE_DIR/$CACHE_VERSION" else From e9041761287a24f988cc073127df1414fe5a6946 Mon Sep 17 00:00:00 2001 From: ketikai Date: Sat, 18 Jul 2026 17:15:25 +0800 Subject: [PATCH 67/79] =?UTF-8?q?ci(build-kernel-ksu-test)=20fix(build-ker?= =?UTF-8?q?nel-ksu-test):=20=E6=B7=BB=E5=8A=A0=E6=AD=A5=E9=AA=A4=20`checko?= =?UTF-8?q?ut`=20=E5=88=B0=20`RELEASE=5FTAG`=20=E4=BB=93=E5=BA=93=EF=BC=8C?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=8F=91=E5=B8=83=E4=BB=93=E5=BA=93=E6=9C=AA?= =?UTF-8?q?=E6=98=8E=E7=A1=AE=E7=9A=84=E9=97=AE=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- .github/workflows/build-kernel-ksu-test.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/build-kernel-ksu-test.yml b/.github/workflows/build-kernel-ksu-test.yml index 196305191f75..0891dbd7fa3b 100644 --- a/.github/workflows/build-kernel-ksu-test.yml +++ b/.github/workflows/build-kernel-ksu-test.yml @@ -106,6 +106,11 @@ jobs: - prepare - build steps: + - name: Checkout + uses: actions/checkout@v7 + with: + ref: ${{ env.RELEASE_TAG }} + - name: Download Patches uses: actions/download-artifact@v8 with: From 16c2ca7a98c9afff0c6f9d91f495c82318d12d19 Mon Sep 17 00:00:00 2001 From: ketikai Date: Sat, 18 Jul 2026 18:01:44 +0800 Subject: [PATCH 68/79] =?UTF-8?q?ci(workflows)=20fix(build-kernel-ksu-test?= =?UTF-8?q?)=20feat(build-kernel):=20=E4=BF=AE=E5=A4=8D=20`release`=20?= =?UTF-8?q?=E4=B8=8B=E6=B2=A1=E6=9C=89=E5=86=99=E6=9D=83=E9=99=90=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=EF=BC=8C=E4=B8=BA=E6=9E=84=E5=BB=BA=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=20`ccache`=20=E6=94=AF=E6=8C=81=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- .github/workflows/build-kernel-ksu-test.yml | 2 ++ .github/workflows/build-kernel.yml | 20 +++++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-kernel-ksu-test.yml b/.github/workflows/build-kernel-ksu-test.yml index 0891dbd7fa3b..3b9f65b793eb 100644 --- a/.github/workflows/build-kernel-ksu-test.yml +++ b/.github/workflows/build-kernel-ksu-test.yml @@ -105,6 +105,8 @@ jobs: needs: - prepare - build + permissions: + contents: write steps: - name: Checkout uses: actions/checkout@v7 diff --git a/.github/workflows/build-kernel.yml b/.github/workflows/build-kernel.yml index a28525622e59..628aa2506c74 100644 --- a/.github/workflows/build-kernel.yml +++ b/.github/workflows/build-kernel.yml @@ -117,6 +117,24 @@ jobs: fi echo "base=$BASE" >> $GITHUB_OUTPUT + - name: Setup CCache + id: setup_ccache + run: | + sudo apt-get install -y ccache + CACHE_DIR=$(realpath -m ".cache") + echo "cache_dir=$CACHE_DIR" >> $GITHUB_OUTPUT + CACHE_KEY="${{ runner.os }}-${{ runner.arch }}-ccache-${{ github.ref_name }}-${{ steps.prepare_base.outputs.base }}" + if [[ -n "${{ inputs.kernel_localversion }}" ]]; then + CACHE_KEY="${CACHE_KEY}-${{ inputs.kernel_localversion }}" + fi + echo "cache_key=$CACHE_KEY" >> $GITHUB_OUTPUT + + - name: Download CCache Contents From Cache + uses: actions/cache@v6 + with: + path: ${{ steps.setup_ccache.outputs.cache_dir }} + key: ${{ steps.setup_ccache.outputs.cache_key }} + - name: Checkout uses: actions/checkout@v7 with: @@ -307,7 +325,7 @@ jobs: fi CUSTOM_ENV_OR_CONFIG=$([[ -n "${{ inputs.kernel_custom_env_or_config }}" ]] && echo "${{ inputs.kernel_custom_env_or_config }}" || echo "") KSU_CUSTOM_ENV_OR_CONFIG=$([[ -n "${{ inputs.ksu_custom_env_or_config }}" ]] && echo "${{ inputs.ksu_custom_env_or_config }}" || echo "") - ./assemble ${{ inputs.kernel_arch }} ${{ inputs.kernel_device }} $VERBOSE -p ${{ env.PREBUILT_DIR }} $LLVM $CROSS_COMPILE $VERSION $SIGNING -d ${{ env.DESTINATION_DIR }} $CUSTOM_ENV_OR_CONFIG $KSU_CUSTOM_ENV_OR_CONFIG + ./assemble ${{ inputs.kernel_arch }} ${{ inputs.kernel_device }} $VERBOSE -p ${{ env.PREBUILT_DIR }} -c ${{ steps.setup_ccache.outputs.cache_dir }} $LLVM $CROSS_COMPILE $VERSION $SIGNING -d ${{ env.DESTINATION_DIR }} $CUSTOM_ENV_OR_CONFIG $KSU_CUSTOM_ENV_OR_CONFIG - name: Upload Logs if: fromJson(inputs.verbose_logs) From 01fd3392c3230dfe88ca864c6d52aa19b96c4910 Mon Sep 17 00:00:00 2001 From: ketikai Date: Sat, 18 Jul 2026 18:16:35 +0800 Subject: [PATCH 69/79] =?UTF-8?q?ci(workflows)=20perf(build-kernel)=20feat?= =?UTF-8?q?(build-kernel):=20=E7=A7=BB=E9=99=A4=E5=86=97=E4=BD=99=E7=9A=84?= =?UTF-8?q?=E5=89=8D=E7=BD=AE=E6=9D=A1=E4=BB=B6=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- .github/workflows/build-kernel.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/build-kernel.yml b/.github/workflows/build-kernel.yml index 628aa2506c74..653bf2fe9dca 100644 --- a/.github/workflows/build-kernel.yml +++ b/.github/workflows/build-kernel.yml @@ -102,7 +102,6 @@ jobs: runs-on: ubuntu-22.04 steps: - name: Setup SWAP - if: runner.os == 'Linux' uses: pierotofy/set-swap-space@master with: swap-size-gb: 16 @@ -328,7 +327,6 @@ jobs: ./assemble ${{ inputs.kernel_arch }} ${{ inputs.kernel_device }} $VERBOSE -p ${{ env.PREBUILT_DIR }} -c ${{ steps.setup_ccache.outputs.cache_dir }} $LLVM $CROSS_COMPILE $VERSION $SIGNING -d ${{ env.DESTINATION_DIR }} $CUSTOM_ENV_OR_CONFIG $KSU_CUSTOM_ENV_OR_CONFIG - name: Upload Logs - if: fromJson(inputs.verbose_logs) uses: actions/upload-artifact@v7 with: name: logs From 34704a02ce7ea0e894c3fa04c112cc5f960d5a15 Mon Sep 17 00:00:00 2001 From: ketikai Date: Sat, 18 Jul 2026 19:25:23 +0800 Subject: [PATCH 70/79] =?UTF-8?q?chore(assemble)=20perf(assemble):=20?= =?UTF-8?q?=E6=9B=B4=E6=94=B9=E5=92=8C=E6=95=B4=E5=90=88=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E8=8C=83=E5=9B=B4=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- assemble | 312 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 157 insertions(+), 155 deletions(-) diff --git a/assemble b/assemble index b4ad390a73d9..c898fb783c7e 100755 --- a/assemble +++ b/assemble @@ -209,187 +209,189 @@ while [ $# -gt 0 ]; do esac done -echo "工作线程: $JOBS" -pushd $WORK_DIR - -export ARCH="$ARCH" +echo "初始化..." +rm -rf $LOGS_DIR +mkdir -p $LOGS_DIR -if [[ -n "$PREBUILT_DIR" ]]; then - TOOLCHAIN_DIR="$PREBUILT_DIR/toolchain" -fi +{ + echo "工作线程: $JOBS" + pushd $WORK_DIR -if (( $LLVM != 0 )); then - export LLVM=1 - export LLVM_IAS=1 + export ARCH="$ARCH" - __DIR="$TOOLCHAIN_DIR/clang/bin" - if [[ -n "$TOOLCHAIN_DIR" && -d "$__DIR" ]]; then - export PATH="$__DIR:$PATH" + if [[ -n "$PREBUILT_DIR" ]]; then + TOOLCHAIN_DIR="$PREBUILT_DIR/toolchain" fi -else - if [[ -n "$TOOLCHAIN_DIR" ]]; then - for dir in $TOOLCHAIN_DIR/gcc/*/; do - __DIR="${dir%/}/bin" - if [ -d "$__DIR" ]; then - export PATH="$__DIR:$PATH" - fi - done - fi -fi - -if [[ -n $CROSS_COMPILE ]]; then - export CROSS_COMPILE="${CROSS_COMPILE}-" -fi -CACHE_VERSION="$LOCALVERSION" -if [[ -n "$LOCALVERSION" ]]; then - export LOCALVERSION="-$LOCALVERSION" -fi + if (( $LLVM != 0 )); then + export LLVM=1 + export LLVM_IAS=1 -while [ $# -gt 0 ]; do - case "$1" in - *=*) - if [[ "$1" == CONFIG_* ]]; then - __KEY="${1%%=*}" - __KEY="${__KEY#CONFIG_}" - if [[ ! -n "$__KEY" ]]; then - echo "无效的配置: $1: 格式应为 KEY=VALUE ,且 KEY 不能为 '$__KEY'" >&2 - exit 1 + __DIR="$TOOLCHAIN_DIR/clang/bin" + if [[ -n "$TOOLCHAIN_DIR" && -d "$__DIR" ]]; then + export PATH="$__DIR:$PATH" + fi + else + if [[ -n "$TOOLCHAIN_DIR" ]]; then + for dir in $TOOLCHAIN_DIR/gcc/*/; do + __DIR="${dir%/}/bin" + if [ -d "$__DIR" ]; then + export PATH="$__DIR:$PATH" fi - __VALUE="${1#*=}" - CONFIGS[$__KEY]="$__VALUE" - else - export "$1" - fi - shift - ;; - *) - echo "无效的环境变量: $1: 格式应为 KEY=VALUE" >&2 - exit 1 - ;; - esac -done + done + fi + fi -echo "打印环境变量..." -if (( $VERBOSE != 0 )); then - printenv -fi + if [[ -n $CROSS_COMPILE ]]; then + export CROSS_COMPILE="${CROSS_COMPILE}-" + fi -V=$((( $VERBOSE != 0 )) && echo 'V=1' || echo 'V=s') -O="O=$BUILD_DIR" + CACHE_VERSION="$LOCALVERSION" + if [[ -n "$LOCALVERSION" ]]; then + export LOCALVERSION="-$LOCALVERSION" + fi -echo "初始化构建..." -rm -rf $LOGS_DIR -mkdir -p $LOGS_DIR + while [ $# -gt 0 ]; do + case "$1" in + *=*) + if [[ "$1" == CONFIG_* ]]; then + __KEY="${1%%=*}" + __KEY="${__KEY#CONFIG_}" + if [[ ! -n "$__KEY" ]]; then + echo "无效的配置: $1: 格式应为 KEY=VALUE ,且 KEY 不能为 '$__KEY'" >&2 + exit 1 + fi + __VALUE="${1#*=}" + CONFIGS[$__KEY]="$__VALUE" + else + export "$1" + fi + shift + ;; + *) + echo "无效的环境变量: $1: 格式应为 KEY=VALUE" >&2 + exit 1 + ;; + esac + done + + echo "打印环境变量..." + if (( $VERBOSE != 0 )); then + printenv + fi -CCACHE="" -if [[ -n "$CACHE_DIR" ]]; then - echo "配置缓存..." - if command -v ccache >/dev/null 2>&1; then - CCACHE="ccache" - export CCACHE="$CCACHE" - if [[ -n "$CACHE_VERSION" ]]; then - export CCACHE_DIR="$CACHE_DIR/$CACHE_VERSION" + V=$((( $VERBOSE != 0 )) && echo 'V=1' || echo 'V=s') + O="O=$BUILD_DIR" + + CCACHE="" + if [[ -n "$CACHE_DIR" ]]; then + echo "配置缓存..." + if command -v ccache >/dev/null 2>&1; then + CCACHE="ccache" + export CCACHE="$CCACHE" + if [[ -n "$CACHE_VERSION" ]]; then + export CCACHE_DIR="$CACHE_DIR/$CACHE_VERSION" + else + export CCACHE_DIR="$CACHE_DIR" + fi + ccache --show-config + if (( $CLEAN != 0 )); then + echo "清理缓存..." + ccache -zC + fi else - export CCACHE_DIR="$CACHE_DIR" - fi - ccache --show-config - if (( $CLEAN != 0 )); then - echo "清理缓存..." - ccache -zC + echo "CCache 未安装,跳过缓存..." fi - else - echo "CCache 未安装,跳过缓存..." fi -fi -BEAR_BRIDGE="" -if (( $BEAR != 0 )); then - if command -v bear >/dev/null 2>&1; then - echo "启用生成 JSON 编译数据库..." - BEAR_BRIDGE="bear --" - else - echo "Bear 未安装,跳过生成 JSON 编译数据库..." + BEAR_BRIDGE="" + if (( $BEAR != 0 )); then + if command -v bear >/dev/null 2>&1; then + echo "启用生成 JSON 编译数据库..." + BEAR_BRIDGE="bear --" + else + echo "Bear 未安装,跳过生成 JSON 编译数据库..." + fi fi -fi - -if (( $CLEAN != 0 )); then - echo "清理构建..." - make $V $O mrproper 2> >(tee $LOGS_DIR/mrproper-error.log) 1> >(tee $LOGS_DIR/mrproper-info.log) - make $V mrproper 2>> >(tee $LOGS_DIR/mrproper-error.log) 1>> >(tee $LOGS_DIR/mrproper-info.log) -fi -echo "生成配置..." -DEFAULT_CONFIG="${DEVICE}_defconfig" -make $V $O $DEFAULT_CONFIG 2> >(tee $LOGS_DIR/defconfig-error.log) 1> >(tee $LOGS_DIR/defconfig-info.log) - -echo "自定义配置..." -OLECONFIG=0 -for __KEY in "${!CONFIGS[@]}"; do - echo "配置 '$__KEY' ..." - __VALUE="${CONFIGS[$__KEY]}" - case "$__VALUE" in - y) - echo "启用内建 '$__KEY' ..." - scripts/config --file ${BUILD_DIR}/.config --enable $__KEY - ;; - n) - echo "禁用内建 '$__KEY' ..." - scripts/config --file ${BUILD_DIR}/.config --disable $__KEY - ;; - m) - echo "启用模块 '$__KEY' ..." - scripts/config --file ${BUILD_DIR}/.config --module $__KEY - ;; - \"*\") - echo "设置文本 '$__KEY=$__VALUE' ..." - scripts/config --file ${BUILD_DIR}/.config --set-str $__KEY $__VALUE - ;; - *) - echo "设置值 '$__KEY=$__VALUE' ..." - scripts/config --file ${BUILD_DIR}/.config --set-val $__KEY $__VALUE - esac - OLECONFIG=1 -done + if (( $CLEAN != 0 )); then + echo "清理构建..." + make $V $O mrproper + make $V mrproper + fi -if [[ -n "$SIGNING_KEY_FILE" ]]; then - echo "使用外部签名密钥..." - scripts/config --file ${BUILD_DIR}/.config --set-str MODULE_SIG_KEY $SIGNING_KEY_FILE - OLECONFIG=1 -fi + echo "生成配置..." + DEFAULT_CONFIG="${DEVICE}_defconfig" + make $V $O $DEFAULT_CONFIG + + echo "自定义配置..." + OLECONFIG=0 + for __KEY in "${!CONFIGS[@]}"; do + echo "配置 '$__KEY' ..." + __VALUE="${CONFIGS[$__KEY]}" + case "$__VALUE" in + y) + echo "启用内建 '$__KEY' ..." + scripts/config --file ${BUILD_DIR}/.config --enable $__KEY + ;; + n) + echo "禁用内建 '$__KEY' ..." + scripts/config --file ${BUILD_DIR}/.config --disable $__KEY + ;; + m) + echo "启用模块 '$__KEY' ..." + scripts/config --file ${BUILD_DIR}/.config --module $__KEY + ;; + \"*\") + echo "设置文本 '$__KEY=$__VALUE' ..." + scripts/config --file ${BUILD_DIR}/.config --set-str $__KEY $__VALUE + ;; + *) + echo "设置值 '$__KEY=$__VALUE' ..." + scripts/config --file ${BUILD_DIR}/.config --set-val $__KEY $__VALUE + esac + OLECONFIG=1 + done + + if [[ -n "$SIGNING_KEY_FILE" ]]; then + echo "使用外部签名密钥..." + scripts/config --file ${BUILD_DIR}/.config --set-str MODULE_SIG_KEY $SIGNING_KEY_FILE + OLECONFIG=1 + fi -echo "应用自定义配置..." -if (( $OLECONFIG != 0 )); then - make $V $O oldconfig 2> >(tee $LOGS_DIR/oldconfig-error.log) 1> >(tee $LOGS_DIR/oldconfig-info.log) -fi + echo "应用自定义配置..." + if (( $OLECONFIG != 0 )); then + make $V $O oldconfig + fi -echo "构建内核..." -$BEAR_BRIDGE make $V $O -j$JOBS 2> >(tee $LOGS_DIR/kernel-error.log) 1> >(tee $LOGS_DIR/kernel-info.log) + echo "构建内核..." + $BEAR_BRIDGE make $V $O -j$JOBS -echo "复制内核..." -KERNEL_DESTINATION_DIR=$DESTINATION_DIR/kernel -mkdir -p $KERNEL_DESTINATION_DIR -# cp $BUILD_DIR/vmlinux $KERNEL_DESTINATION_DIR -pushd $BUILD_DIR/arch/$ARCH/boot + echo "复制内核..." + KERNEL_DESTINATION_DIR=$DESTINATION_DIR/kernel + mkdir -p $KERNEL_DESTINATION_DIR + # cp $BUILD_DIR/vmlinux $KERNEL_DESTINATION_DIR + pushd $BUILD_DIR/arch/$ARCH/boot -find . -type f -name "Image*" -exec cp -v {} $KERNEL_DESTINATION_DIR \; + find . -type f -name "Image*" -exec cp -v {} $KERNEL_DESTINATION_DIR \; -popd + popd -echo "签名模块..." -make $V $O modules_install INSTALL_MOD_PATH=modules 2> >(tee $LOGS_DIR/modules-error.log) 1> >(tee $LOGS_DIR/modules-info.log) + echo "签名模块..." + make $V $O modules_install INSTALL_MOD_PATH=modules -echo "复制模块..." -MODULES_DESTINATION_DIR=$DESTINATION_DIR/modules -mkdir -p $MODULES_DESTINATION_DIR -pushd $BUILD_DIR/modules + echo "复制模块..." + MODULES_DESTINATION_DIR=$DESTINATION_DIR/modules + mkdir -p $MODULES_DESTINATION_DIR + pushd $BUILD_DIR/modules -find . -type f -name "*.ko" -exec cp -v {} $MODULES_DESTINATION_DIR \; + find . -type f -name "*.ko" -exec cp -v {} $MODULES_DESTINATION_DIR \; -popd + popd -popd + popd -if [[ -n "$CCACHE" ]]; then - ccache -s -v -fi + if [[ -n "$CCACHE" ]]; then + ccache -s -v + fi +} 2> >(tee $LOGS_DIR/assemble-error.log) 1> >(tee $LOGS_DIR/assemble-info.log) From f0d7a6a640e1d6e0555fd7081f363b32533e4f06 Mon Sep 17 00:00:00 2001 From: ketikai Date: Sun, 26 Jul 2026 11:22:49 +0800 Subject: [PATCH 71/79] =?UTF-8?q?ci(workflows)=20fix(build-kernel):=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=83=A8=E5=88=86=E6=AD=A5=E9=AA=A4=E4=B8=AD?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E7=9A=84=E6=9D=A1=E4=BB=B6=E8=A1=A8=E8=BE=BE?= =?UTF-8?q?=E5=BC=8F=E5=86=99=E6=B3=95=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- .github/workflows/build-kernel.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-kernel.yml b/.github/workflows/build-kernel.yml index 653bf2fe9dca..7510f3fbf561 100644 --- a/.github/workflows/build-kernel.yml +++ b/.github/workflows/build-kernel.yml @@ -169,7 +169,7 @@ jobs: key: ${{ runner.os }}-${{ runner.arch }}-prebuilt-clang-toolchain-${{ hashFiles(steps.prepare_prebuilt.outputs.clang_toolchain_cache_key) }} - name: Download Prebuilt Clang Toolchain - if: fromJson(inputs.llvm) && fromJson(steps.prebuilt_clang_toolchain_cache.outputs.cache-hit) != true + if: fromJson(inputs.llvm) && steps.prebuilt_clang_toolchain_cache.outputs.cache-hit != 'true' run: | URL="${{ inputs.prebuilt_clang_toolchain }}" DIR="${{ steps.prepare_prebuilt.outputs.clang_toolchain_dir }}" @@ -195,7 +195,7 @@ jobs: key: ${{ runner.os }}-${{ runner.arch }}-prebuilt-gcc-toolchain-${{ hashFiles(steps.prepare_prebuilt.outputs.gcc_toolchain_cache_key) }} - name: Download Prebuilt GCC Toolchain - if: fromJson(inputs.llvm) != true && fromJson(steps.prebuilt_gcc_toolchain_cache.outputs.cache-hit) != true + if: fromJson(inputs.llvm) != true && steps.prebuilt_gcc_toolchain_cache.outputs.cache-hit != 'true' run: | URL="${{ inputs.prebuilt_gcc_toolchain }}" DIR="${{ steps.prepare_prebuilt.outputs.gcc_toolchain_dir }}" From f1dcb088f7db9ec44dfbfd1792b7dac1705ca5b5 Mon Sep 17 00:00:00 2001 From: ketikai Date: Sun, 26 Jul 2026 11:45:43 +0800 Subject: [PATCH 72/79] =?UTF-8?q?ci(workflows)=20perf(build-kernel):=20?= =?UTF-8?q?=E7=B2=BE=E7=A1=AE=E5=8C=B9=E9=85=8D=E6=97=A5=E5=BF=97=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E5=90=8E=E7=BC=80=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- .github/workflows/build-kernel.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-kernel.yml b/.github/workflows/build-kernel.yml index 7510f3fbf561..b37d4d531f7b 100644 --- a/.github/workflows/build-kernel.yml +++ b/.github/workflows/build-kernel.yml @@ -331,7 +331,7 @@ jobs: with: name: logs path: | - .logs/* + .logs/*.log if-no-files-found: error overwrite: true include-hidden-files: true From 2b3774d0265eb1b90db4981dd64c9ea5140f9712 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sat, 4 Jul 2026 02:10:38 +0300 Subject: [PATCH 73/79] BACKPORT: locking: Introduce __cleanup() based infrastructure [ Upstream commit 54da6a0924311c7cf5015533991e44fb8eb12773 ] Use __attribute__((__cleanup__(func))) to build: - simple auto-release pointers using __free() - 'classes' with constructor and destructor semantics for scope-based resource management. - lock guards based on the above classes. Signed-off-by: Peter Zijlstra (Intel) Link: https://lkml.kernel.org/r/20230612093537.614161713%40infradead.org Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman [@acroreiser: port common and spinlock parts of the original patch (backport to 4.9)] --- include/linux/cleanup.h | 171 +++++++++++++++++++++++++++++++++++++++ include/linux/compiler.h | 6 ++ include/linux/spinlock.h | 30 +++++++ 3 files changed, 207 insertions(+) create mode 100644 include/linux/cleanup.h diff --git a/include/linux/cleanup.h b/include/linux/cleanup.h new file mode 100644 index 000000000000..d90ce4ddb79e --- /dev/null +++ b/include/linux/cleanup.h @@ -0,0 +1,171 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __LINUX_GUARDS_H +#define __LINUX_GUARDS_H + +#include + +/* + * DEFINE_FREE(name, type, free): + * simple helper macro that defines the required wrapper for a __free() + * based cleanup function. @free is an expression using '_T' to access + * the variable. + * + * __free(name): + * variable attribute to add a scoped based cleanup to the variable. + * + * no_free_ptr(var): + * like a non-atomic xchg(var, NULL), such that the cleanup function will + * be inhibited -- provided it sanely deals with a NULL value. + * + * return_ptr(p): + * returns p while inhibiting the __free(). + * + * Ex. + * + * DEFINE_FREE(kfree, void *, if (_T) kfree(_T)) + * + * struct obj *p __free(kfree) = kmalloc(...); + * if (!p) + * return NULL; + * + * if (!init_obj(p)) + * return NULL; + * + * return_ptr(p); + */ + +#define DEFINE_FREE(_name, _type, _free) \ + static inline void __free_##_name(void *p) { _type _T = *(_type *)p; _free; } + +#define __free(_name) __cleanup(__free_##_name) + +#define no_free_ptr(p) \ + ({ __auto_type __ptr = (p); (p) = NULL; __ptr; }) + +#define return_ptr(p) return no_free_ptr(p) + + +/* + * DEFINE_CLASS(name, type, exit, init, init_args...): + * helper to define the destructor and constructor for a type. + * @exit is an expression using '_T' -- similar to FREE above. + * @init is an expression in @init_args resulting in @type + * + * EXTEND_CLASS(name, ext, init, init_args...): + * extends class @name to @name@ext with the new constructor + * + * CLASS(name, var)(args...): + * declare the variable @var as an instance of the named class + * + * Ex. + * + * DEFINE_CLASS(fdget, struct fd, fdput(_T), fdget(fd), int fd) + * + * CLASS(fdget, f)(fd); + * if (!f.file) + * return -EBADF; + * + * // use 'f' without concern + */ + +#define DEFINE_CLASS(_name, _type, _exit, _init, _init_args...) \ +typedef _type class_##_name##_t; \ +static inline void class_##_name##_destructor(_type *p) \ +{ _type _T = *p; _exit; } \ +static inline _type class_##_name##_constructor(_init_args) \ +{ _type t = _init; return t; } + +#define EXTEND_CLASS(_name, ext, _init, _init_args...) \ +typedef class_##_name##_t class_##_name##ext##_t; \ +static inline void class_##_name##ext##_destructor(class_##_name##_t *p)\ +{ class_##_name##_destructor(p); } \ +static inline class_##_name##_t class_##_name##ext##_constructor(_init_args) \ +{ class_##_name##_t t = _init; return t; } + +#define CLASS(_name, var) \ + class_##_name##_t var __cleanup(class_##_name##_destructor) = \ + class_##_name##_constructor + + +/* + * DEFINE_GUARD(name, type, lock, unlock): + * trivial wrapper around DEFINE_CLASS() above specifically + * for locks. + * + * guard(name): + * an anonymous instance of the (guard) class + * + * scoped_guard (name, args...) { }: + * similar to CLASS(name, scope)(args), except the variable (with the + * explicit name 'scope') is declard in a for-loop such that its scope is + * bound to the next (compound) statement. + * + */ + +#define DEFINE_GUARD(_name, _type, _lock, _unlock) \ + DEFINE_CLASS(_name, _type, _unlock, ({ _lock; _T; }), _type _T) + +#define guard(_name) \ + CLASS(_name, __UNIQUE_ID(guard)) + +#define scoped_guard(_name, args...) \ + for (CLASS(_name, scope)(args), \ + *done = NULL; !done; done = (void *)1) + +/* + * Additional helper macros for generating lock guards with types, either for + * locks that don't have a native type (eg. RCU, preempt) or those that need a + * 'fat' pointer (eg. spin_lock_irqsave). + * + * DEFINE_LOCK_GUARD_0(name, lock, unlock, ...) + * DEFINE_LOCK_GUARD_1(name, type, lock, unlock, ...) + * + * will result in the following type: + * + * typedef struct { + * type *lock; // 'type := void' for the _0 variant + * __VA_ARGS__; + * } class_##name##_t; + * + * As above, both _lock and _unlock are statements, except this time '_T' will + * be a pointer to the above struct. + */ + +#define __DEFINE_UNLOCK_GUARD(_name, _type, _unlock, ...) \ +typedef struct { \ + _type *lock; \ + __VA_ARGS__; \ +} class_##_name##_t; \ + \ +static inline void class_##_name##_destructor(class_##_name##_t *_T) \ +{ \ + if (_T->lock) { _unlock; } \ +} + + +#define __DEFINE_LOCK_GUARD_1(_name, _type, _lock) \ +static inline class_##_name##_t class_##_name##_constructor(_type *l) \ +{ \ + class_##_name##_t _t = { .lock = l }, *_T = &_t; \ + _lock; \ + return _t; \ +} + +#define __DEFINE_LOCK_GUARD_0(_name, _lock) \ +static inline class_##_name##_t class_##_name##_constructor(void) \ +{ \ + class_##_name##_t _t = { .lock = (void*)1 }, \ + *_T __maybe_unused = &_t; \ + _lock; \ + return _t; \ +} + +#define DEFINE_LOCK_GUARD_1(_name, _type, _lock, _unlock, ...) \ +__DEFINE_UNLOCK_GUARD(_name, _type, _unlock, __VA_ARGS__) \ +__DEFINE_LOCK_GUARD_1(_name, _type, _lock) + +#define DEFINE_LOCK_GUARD_0(_name, _lock, _unlock, ...) \ +__DEFINE_UNLOCK_GUARD(_name, void, _unlock, __VA_ARGS__) \ +__DEFINE_LOCK_GUARD_0(_name, _lock) + +#endif /* __LINUX_GUARDS_H */ \ No newline at end of file diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 77ac47cb8c77..9efb46b1f2ca 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -48,6 +48,12 @@ extern void __chk_io_ptr(const volatile void __iomem *); # define ACCESS_PRIVATE(p, member) ((p)->member) #endif /* __CHECKER__ */ +/* + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-cleanup-variable-attribute + * clang: https://clang.llvm.org/docs/AttributeReference.html#cleanup + */ +#define __cleanup(func) __attribute__((__cleanup__(func))) + /* Indirect macros required for expanded argument pasting, eg. __LINE__. */ #define ___PASTE(a,b) a##b #define __PASTE(a,b) ___PASTE(a,b) diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h index 47dd0cebd204..e2f91b9961bc 100644 --- a/include/linux/spinlock.h +++ b/include/linux/spinlock.h @@ -55,6 +55,7 @@ #include #include #include +#include #include @@ -416,4 +417,33 @@ extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock); #define atomic_dec_and_lock(atomic, lock) \ __cond_lock(lock, _atomic_dec_and_lock(atomic, lock)) +DEFINE_LOCK_GUARD_1(raw_spinlock, raw_spinlock_t, + raw_spin_lock(_T->lock), + raw_spin_unlock(_T->lock)) + +DEFINE_LOCK_GUARD_1(raw_spinlock_nested, raw_spinlock_t, + raw_spin_lock_nested(_T->lock, SINGLE_DEPTH_NESTING), + raw_spin_unlock(_T->lock)) + +DEFINE_LOCK_GUARD_1(raw_spinlock_irq, raw_spinlock_t, + raw_spin_lock_irq(_T->lock), + raw_spin_unlock_irq(_T->lock)) + +DEFINE_LOCK_GUARD_1(raw_spinlock_irqsave, raw_spinlock_t, + raw_spin_lock_irqsave(_T->lock, _T->flags), + raw_spin_unlock_irqrestore(_T->lock, _T->flags), + unsigned long flags) + +DEFINE_LOCK_GUARD_1(spinlock, spinlock_t, + spin_lock(_T->lock), + spin_unlock(_T->lock)) + +DEFINE_LOCK_GUARD_1(spinlock_irq, spinlock_t, + spin_lock_irq(_T->lock), + spin_unlock_irq(_T->lock)) + +DEFINE_LOCK_GUARD_1(spinlock_irqsave, spinlock_t, + spin_lock_irqsave(_T->lock, _T->flags), + spin_unlock_irqrestore(_T->lock, _T->flags), + unsigned long flags) #endif /* __LINUX_SPINLOCK_H */ From 8eb8dac6707ac06d58ffcab242be4e43b7dccbf6 Mon Sep 17 00:00:00 2001 From: Yaroslav Zviezda Date: Sat, 4 Jul 2026 02:16:26 +0300 Subject: [PATCH 74/79] mm: fix build breakage after "BACKPORT: locking: Introduce __cleanup() based infrastructure" --- mm/bootmem.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mm/bootmem.c b/mm/bootmem.c index 0b8c5b3ab621..614295fd13ef 100644 --- a/mm/bootmem.c +++ b/mm/bootmem.c @@ -283,7 +283,7 @@ unsigned long __init free_all_bootmem(void) return total_pages; } -static void __init __free(bootmem_data_t *bdata, +static void __init ___free(bootmem_data_t *bdata, unsigned long sidx, unsigned long eidx) { unsigned long idx; @@ -321,7 +321,7 @@ static int __init __reserve(bootmem_data_t *bdata, unsigned long sidx, for (idx = sidx; idx < eidx; idx++) if (test_and_set_bit(idx, bdata->node_bootmem_map)) { if (exclusive) { - __free(bdata, sidx, idx); + ___free(bdata, sidx, idx); return -EBUSY; } bdebug("silent double reserve of PFN %lx\n", @@ -348,7 +348,7 @@ static int __init mark_bootmem_node(bootmem_data_t *bdata, if (reserve) return __reserve(bdata, sidx, eidx, flags); else - __free(bdata, sidx, eidx); + ___free(bdata, sidx, eidx); return 0; } From 5da17b1b47c593e52891bb3788a23d572ee043dd Mon Sep 17 00:00:00 2001 From: Keenan Dong Date: Wed, 8 Apr 2026 16:46:00 +0800 Subject: [PATCH 75/79] BACKPORT: rtmutex: Use waiter::task instead of current in remove_waiter() remove_waiter() is used by the slowlock paths, but it is also used for proxy-lock rollback in rt_mutex_start_proxy_lock() when invoked from futex_requeue(). In the latter case waiter::task is not current, but remove_waiter() operates on current for the dequeue operation. That results in several problems: 1) the rbtree dequeue happens without waiter::task::pi_lock being held 2) the waiter task's pi_blocked_on state is not cleared, which leaves a dangling pointer primed for UAF around. 3) rt_mutex_adjust_prio_chain() operates on the wrong top priority waiter task Use waiter::task instead of current in all related operations in remove_waiter() to cure those problems. [ tglx: Fixup rt_mutex_adjust_prio_chain(), add a comment and amend the changelog ] Fixes: 8161239a8bcc ("rtmutex: Simplify PI algorithm and make highest prio task get lock") Reported-by: Yuan Tan Reported-by: Yifan Wu Reported-by: Juefei Pu Reported-by: Xin Liu Signed-off-by: Keenan Dong Signed-off-by: Thomas Gleixner Cc: stable@vger.kernel.org [ @acroreiser: backport to 4.9, switch kernel/locking/rtmutex.c to gnu99 to avoid build error below. include/linux/cleanup.h:112:9: error: 'for' loop initial declarations are only allowed in C99 or C11 mode 112 | for (CLASS(_name, scope)(args), ] --- kernel/locking/Makefile | 2 ++ kernel/locking/rtmutex.c | 13 ++++++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/kernel/locking/Makefile b/kernel/locking/Makefile index 6f88e352cd4f..19cec51624d6 100644 --- a/kernel/locking/Makefile +++ b/kernel/locking/Makefile @@ -20,6 +20,8 @@ obj-$(CONFIG_SMP) += spinlock.o obj-$(CONFIG_LOCK_SPIN_ON_OWNER) += osq_lock.o obj-$(CONFIG_PROVE_LOCKING) += spinlock.o obj-$(CONFIG_QUEUED_SPINLOCKS) += qspinlock.o +CFLAGS_REMOVE_rtmutex.o += -std=gnu89 +CFLAGS_rtmutex.o += -std=gnu99 obj-$(CONFIG_RT_MUTEXES) += rtmutex.o obj-$(CONFIG_DEBUG_RT_MUTEXES) += rtmutex-debug.o obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock.o diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c index 1589e131ee4b..458fb2f781fe 100644 --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c @@ -1093,20 +1093,23 @@ static void mark_wakeup_next_waiter(struct wake_q_head *wake_q, * * Must be called with lock->wait_lock held and interrupts disabled. I must * have just failed to try_to_take_rt_mutex(). + * + * When invoked from rt_mutex_start_proxy_lock() waiter::task != current ! */ static void remove_waiter(struct rt_mutex *lock, struct rt_mutex_waiter *waiter) { bool is_top_waiter = (waiter == rt_mutex_top_waiter(lock)); struct task_struct *owner = rt_mutex_owner(lock); + struct task_struct *waiter_task = waiter->task; struct rt_mutex *next_lock; lockdep_assert_held(&lock->wait_lock); - raw_spin_lock(¤t->pi_lock); - rt_mutex_dequeue(lock, waiter); - current->pi_blocked_on = NULL; - raw_spin_unlock(¤t->pi_lock); + scoped_guard(raw_spinlock, &waiter_task->pi_lock) { + rt_mutex_dequeue(lock, waiter); + waiter_task->pi_blocked_on = NULL; + } /* * Only update priority if the waiter was the highest priority @@ -1142,7 +1145,7 @@ static void remove_waiter(struct rt_mutex *lock, raw_spin_unlock_irq(&lock->wait_lock); rt_mutex_adjust_prio_chain(owner, RT_MUTEX_MIN_CHAINWALK, lock, - next_lock, NULL, current); + next_lock, NULL, waiter_task); raw_spin_lock_irq(&lock->wait_lock); } From 4b490eab1153ad881a825ec8d363e08923514975 Mon Sep 17 00:00:00 2001 From: Ji'an Zhou Date: Sat, 4 Jul 2026 14:11:34 +0300 Subject: [PATCH 76/79] BACKPORT: futex/requeue: Prevent NULL pointer dereference in remove_waiter() on self-deadlock When FUTEX_CMP_REQUEUE_PI requeues a non-top waiter that already owns the target PI futex, task_blocks_on_rt_mutex() returns -EDEADLK before setting waiter->task. The subsequent remove_waiter() in rt_mutex_start_proxy_lock() dereferences the NULL waiter->task, causing a kernel crash. Add a self-deadlock check for non-top waiters before calling rt_mutex_start_proxy_lock(), analogous to the top-waiter check in futex_lock_pi_atomic(). Fixes: 3bfdc63936dd4773109b7b8c280c0f3b5ae7d349 ("rtmutex: Use waiter::task instead of current in remove_waiter()") Signed-off-by: Ji'an Zhou Signed-off-by: Thomas Gleixner Cc: stable@vger.kernel.org [@acroreiser: backport to 4.9] --- kernel/futex.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/kernel/futex.c b/kernel/futex.c index b3823736af6f..144ffda63f21 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -2240,6 +2240,13 @@ static int futex_requeue(u32 __user *uaddr1, unsigned int flags, */ get_pi_state(pi_state); this->pi_state = pi_state; + + /* Self-deadlock: non-top waiter already owns the PI futex. */ + if (rt_mutex_owner(&pi_state->pi_mutex) == this->task) { + ret = -EDEADLK; + break; + } + ret = rt_mutex_start_proxy_lock(&pi_state->pi_mutex, this->rt_waiter, this->task); From 9ea32113b1a2b9a8eec0c3fda525cac1975a0063 Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso Date: Sat, 4 Jul 2026 14:15:08 +0300 Subject: [PATCH 77/79] BACKPORT: locking/rtmutex: Skip remove_waiter() when waiter is not enqueued syzbot triggered the following splat in remove_waiter() via FUTEX_CMP_REQUEUE_PI: KASAN: null-ptr-deref in range [0x0000000000000a88-0x0000000000000a8f] class_raw_spinlock_constructor remove_waiter+0x159/0x1200 kernel/locking/rtmutex.c:1561 rt_mutex_start_proxy_lock+0x103/0x120 futex_requeue+0x10e4/0x20d0 __x64_sys_futex+0x34f/0x4d0 task_blocks_on_rt_mutex() does not arm the waiter upon deadlock detection, leaving waiter->task nil, where 3bfdc63936dd ("rtmutex: Use waiter::task instead of current in remove_waiter()") made this fatal. Furthermore, rt_mutex_start_proxy_lock() should not be calling into remove_waiter() upon a successfully grabbing the rtmutex. 1a1fb985f2e2 ("futex: Handle early deadlock return correctly"), moved the remove_waiter() out of __rt_mutex_start_proxy_lock() (where 'ret' was only ever 0 or < 0) into the wrapper. Tighten this check to account for try_to_take_rt_mutex(). Fixes: 3bfdc63936dd ("rtmutex: Use waiter::task instead of current in remove_waiter()") Reported-by: syzbot+78147abe6c524f183ee9@syzkaller.appspotmail.com Signed-off-by: Davidlohr Bueso Signed-off-by: Thomas Gleixner Cc: stable@vger.kernel.org Closes: https://lore.kernel.org/all/69f114ac.050a0220.ac8b.0003.GAE@google.com/ Link: https://patch.msgid.link/20260507112913.1019537-1-dave@stgolabs.net [@acroreiser: backport to 4.9] --- kernel/locking/rtmutex.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c index 458fb2f781fe..3cdff714f276 100644 --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c @@ -1106,6 +1106,9 @@ static void remove_waiter(struct rt_mutex *lock, lockdep_assert_held(&lock->wait_lock); + if (!waiter_task) /* never enqueued */ + return; + scoped_guard(raw_spinlock, &waiter_task->pi_lock) { rt_mutex_dequeue(lock, waiter); waiter_task->pi_blocked_on = NULL; @@ -1774,7 +1777,7 @@ int rt_mutex_start_proxy_lock(struct rt_mutex *lock, raw_spin_lock_irq(&lock->wait_lock); ret = __rt_mutex_start_proxy_lock(lock, waiter, task); - if (unlikely(ret)) + if (unlikely(ret < 0)) remove_waiter(lock, waiter); raw_spin_unlock_irq(&lock->wait_lock); From a4cff32e89c2c6f65c19d7db3489142b706ad5c3 Mon Sep 17 00:00:00 2001 From: ketikai Date: Sun, 26 Jul 2026 12:50:56 +0800 Subject: [PATCH 78/79] =?UTF-8?q?docs(ksu):=20=E6=96=B0=E5=A2=9E=20`ReSuki?= =?UTF-8?q?`=20=E7=9B=B8=E5=85=B3=E5=86=85=E5=AE=B9=EF=BC=8C=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E5=BF=AB=E9=80=9F=E6=9E=84=E5=BB=BA=E7=94=A8=E6=B3=95?= =?UTF-8?q?=EF=BC=8C=E7=A7=BB=E5=8A=A8=E6=96=87=E6=A1=A3=E6=96=87=E4=BB=B6?= =?UTF-8?q?=20`Documentation`=20=E4=B8=8B=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- .../KernelSU/KernelSU Integration.md | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) rename KernelSU Integration.md => Documentation/KernelSU/KernelSU Integration.md (68%) diff --git a/KernelSU Integration.md b/Documentation/KernelSU/KernelSU Integration.md similarity index 68% rename from KernelSU Integration.md rename to Documentation/KernelSU/KernelSU Integration.md index 28d4e8719f22..75ebac6814e2 100644 --- a/KernelSU Integration.md +++ b/Documentation/KernelSU/KernelSU Integration.md @@ -18,6 +18,16 @@ > > ''' +### ReSukiSU +--------------------------------- + +> ''' +> +> * [Repository](https://github.com/ReSukiSU/ReSukiSU) +> * [Releases](https://t.me/ReSukiSU/4) +> +> ''' + ### How To Setup --------------------------------- @@ -25,8 +35,11 @@ # 1. into workdir cd android_kernel_xiaomi_sdm710 -# 2. setup with backslashxx's KernelSU +# 2. setup with KernelSU +# xxksu curl -LSs https://raw.githubusercontent.com/backslashxx/KernelSU/master/kernel/setup.sh | bash -s master +# or resuki +curl -LSs https://raw.githubusercontent.com/ReSukiSU/ReSukiSU/main/kernel/setup.sh | bash -s main ``` ### Quick Build (Github Actions) @@ -51,9 +64,7 @@ curl -LSs https://raw.githubusercontent.com/backslashxx/KernelSU/master/kernel/s > MIIFKD...more content...R8gw== > -----END CERTIFICATE----- > -> 4. manual run workflow (build kernel) -> -> check `With KernelSU` +> 4. manual run workflow (Build Kernel With KernelSU) > > ''' @@ -62,6 +73,8 @@ curl -LSs https://raw.githubusercontent.com/backslashxx/KernelSU/master/kernel/s > ''' > -> * [scope-minimized manual hooks](https://github.com/backslashxx/KernelSU/issues/5) +> * [xxksu: scope-minimized manual hooks](https://github.com/backslashxx/KernelSU/issues/5) +> +> * [resuki: manual-integrate](https://resukisu.github.io/guide/manual-integrate.html) > > ''' From 89d11ed808395b0cf33b2b6cf317d0dfb98c00ac Mon Sep 17 00:00:00 2001 From: ketikai Date: Sun, 26 Jul 2026 12:51:48 +0800 Subject: [PATCH 79/79] =?UTF-8?q?chore(assemble)=20perf(assemble):=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=97=A5=E5=BF=97=E7=9A=84=E8=BE=93=E5=87=BA?= =?UTF-8?q?=E9=80=BB=E8=BE=91=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ketikai --- assemble | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/assemble b/assemble index c898fb783c7e..e652f4e44e5c 100755 --- a/assemble +++ b/assemble @@ -213,6 +213,17 @@ echo "初始化..." rm -rf $LOGS_DIR mkdir -p $LOGS_DIR +__INFO_FIFO=$LOGS_DIR/.info.fifo +__ERROR_FIFO=$LOGS_DIR/.error.fifo +__INFO_FILE=$LOGS_DIR/assemble-info.log +__ERROR_FILE=$LOGS_DIR/assemble-error.log +mkfifo $__INFO_FIFO +mkfifo $__ERROR_FIFO +cat $__INFO_FIFO | tee -a $__INFO_FILE & +exec 1>$__INFO_FIFO +cat $__ERROR_FIFO | tee -a $__ERROR_FILE & +exec 2>$__ERROR_FIFO + { echo "工作线程: $JOBS" pushd $WORK_DIR @@ -394,4 +405,4 @@ mkdir -p $LOGS_DIR if [[ -n "$CCACHE" ]]; then ccache -s -v fi -} 2> >(tee $LOGS_DIR/assemble-error.log) 1> >(tee $LOGS_DIR/assemble-info.log) +}