From 4113009a290b54c71486f50783b618a469682c8f Mon Sep 17 00:00:00 2001 From: Evans Mike Date: Thu, 13 Apr 2023 23:40:33 +0100 Subject: [PATCH] Revert "Add KernelSu driver from tiann/KernelSU@ec0158e" This reverts commit a4004153b0403d972cd50afa67f719d202a73736. --- drivers/Makefile | 2 - drivers/kernelsu/Kconfig | 14 - drivers/kernelsu/LICENSE | 339 ---------- drivers/kernelsu/Makefile | 32 - drivers/kernelsu/allowlist.c | 275 -------- drivers/kernelsu/allowlist.h | 22 - drivers/kernelsu/apk_sign.c | 180 ----- drivers/kernelsu/apk_sign.h | 7 - drivers/kernelsu/arch.h | 68 -- drivers/kernelsu/core_hook.c | 552 ---------------- 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 | 34 - drivers/kernelsu/kernel_compat.h | 42 -- drivers/kernelsu/klog.h | 11 - drivers/kernelsu/ksu.c | 86 --- drivers/kernelsu/ksu.h | 45 -- drivers/kernelsu/ksud.c | 498 -------------- drivers/kernelsu/ksud.h | 10 - drivers/kernelsu/manager.c | 80 --- drivers/kernelsu/manager.h | 38 -- drivers/kernelsu/module_api.c | 33 - drivers/kernelsu/selinux/Makefile | 9 - drivers/kernelsu/selinux/rules.c | 465 ------------- drivers/kernelsu/selinux/selinux.c | 106 --- drivers/kernelsu/selinux/selinux.h | 16 - drivers/kernelsu/selinux/sepolicy.c | 985 ---------------------------- drivers/kernelsu/selinux/sepolicy.h | 46 -- drivers/kernelsu/setup.sh | 33 - drivers/kernelsu/sucompat.c | 208 ------ drivers/kernelsu/uid_observer.c | 136 ---- drivers/kernelsu/uid_observer.h | 10 - 34 files changed, 4426 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.c delete mode 100644 drivers/kernelsu/manager.h delete mode 100644 drivers/kernelsu/module_api.c 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 100755 drivers/kernelsu/setup.sh delete mode 100644 drivers/kernelsu/sucompat.c delete mode 100644 drivers/kernelsu/uid_observer.c delete mode 100644 drivers/kernelsu/uid_observer.h diff --git a/drivers/Makefile b/drivers/Makefile index 5ea354da2668..ca8275dd8884 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -193,5 +193,3 @@ obj-$(CONFIG_TRUSTY) += trusty/ # GNSS driver obj-$(CONFIG_GNSS_SIRF) += gnsssirf/ obj-$(CONFIG_GNSS) += gnss/ - -obj-y += kernelsu/ diff --git a/drivers/kernelsu/Kconfig b/drivers/kernelsu/Kconfig deleted file mode 100644 index d6c633c917f4..000000000000 --- a/drivers/kernelsu/Kconfig +++ /dev/null @@ -1,14 +0,0 @@ -config KSU - tristate "KernelSU module" - default y - depends on KPROBES - depends on OVERLAY_FS - help - This is the KSU privilege driver for android system. - -config KSU_DEBUG - tristate "KernelSU module debug mode" - default n - depends on KSU - help - This enables debug mode for KSU \ No newline at end of file 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 611fba0d64a3..000000000000 --- a/drivers/kernelsu/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -obj-y += ksu.o -obj-y += allowlist.o -kernelsu-objs := apk_sign.o -obj-y += kernelsu.o -obj-y += module_api.o -obj-y += sucompat.o -obj-y += uid_observer.o -obj-y += manager.o -obj-y += core_hook.o -obj-y += ksud.o -obj-y += embed_ksud.o -obj-y += kernel_compat.o - -obj-y += selinux/ -# .git is a text file while the module is imported by 'git submodule add'. -ifeq ($(shell test -e $(srctree)/$(src)/../.git; echo $$?),0) -KSU_GIT_VERSION := $(shell cd $(srctree)/$(src); /usr/bin/env PATH="$$PATH":/usr/bin:/usr/local/bin git rev-list --count HEAD) -ccflags-y += -DKSU_GIT_VERSION=$(KSU_GIT_VERSION) -endif - -ifndef EXPECTED_SIZE -EXPECTED_SIZE := 0x033b -endif - -ifndef EXPECTED_HASH -EXPECTED_HASH := 0xb0b91415 -endif - -ccflags-y += -DEXPECTED_SIZE=$(EXPECTED_SIZE) -ccflags-y += -DEXPECTED_HASH=$(EXPECTED_HASH) -ccflags-y += -Wno-implicit-function-declaration -Wno-strict-prototypes -Wno-int-conversion -Wno-gcc-compat -ccflags-y += -Wno-macro-redefined -Wno-declaration-after-statement diff --git a/drivers/kernelsu/allowlist.c b/drivers/kernelsu/allowlist.c deleted file mode 100644 index 8e445633db72..000000000000 --- a/drivers/kernelsu/allowlist.c +++ /dev/null @@ -1,275 +0,0 @@ -#include "linux/delay.h" -#include "linux/fs.h" -#include "linux/kernel.h" -#include "linux/list.h" -#include "linux/printk.h" -#include "linux/slab.h" -#include "linux/version.h" -#include "klog.h" // IWYU pragma: keep -#include "selinux/selinux.h" -#include "kernel_compat.h" - -#define FILE_MAGIC 0x7f4b5355 // ' KSU', u32 -#define FILE_FORMAT_VERSION 1 // u32 - -static DEFINE_MUTEX(allowlist_mutex); - -struct perm_data { - struct list_head list; - uid_t uid; - bool allow; -}; - -static struct list_head allow_list; - -#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"); - list_for_each (pos, &allow_list) { - p = list_entry(pos, struct perm_data, list); - pr_info("uid :%d, allow: %d\n", p->uid, p->allow); - } -} - -bool ksu_allow_uid(uid_t uid, bool allow, bool persist) -{ - // find the node first! - struct perm_data *p = NULL; - struct list_head *pos = NULL; - bool result = false; - list_for_each (pos, &allow_list) { - p = list_entry(pos, struct perm_data, list); - if (uid == p->uid) { - p->allow = allow; - result = true; - goto exit; - } - } - - // not found, alloc a new node! - p = (struct perm_data *)kmalloc(sizeof(struct perm_data), GFP_KERNEL); - if (!p) { - pr_err("alloc allow node failed.\n"); - return false; - } - p->uid = uid; - p->allow = allow; - - list_add_tail(&p->list, &allow_list); - result = true; - -exit: - if (persist) - persistent_allow_list(); - - return result; -} - -bool ksu_is_allow_uid(uid_t uid) -{ - struct perm_data *p = NULL; - struct list_head *pos = NULL; - - if (uid == 0) { - // already root, but only allow our domain. - return is_ksu_domain(); - } - - list_for_each (pos, &allow_list) { - p = list_entry(pos, struct perm_data, list); - // pr_info("is_allow_uid uid :%d, allow: %d\n", p->uid, p->allow); - if (uid == p->uid) { - return p->allow; - } - } - - return false; -} - -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->allow == allow) { - array[i++] = p->uid; - } - } - *length = i; - - return true; -} - -void do_persistent_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; - KWORKER_INSTALL_KEYRING(); - struct file *fp = - filp_open(KERNEL_SU_ALLOWLIST, O_WRONLY | O_CREAT, 0644); - - if (IS_ERR(fp)) { - pr_err("save_allow_list creat file failed: %d\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 uid :%d, allow: %d\n", p->uid, - p->allow); - ksu_kernel_write_compat(fp, &p->uid, sizeof(p->uid), &off); - ksu_kernel_write_compat(fp, &p->allow, sizeof(p->allow), &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; - KWORKER_INSTALL_KEYRING(); - - // load allowlist now! - fp = filp_open(KERNEL_SU_ALLOWLIST, O_RDONLY, 0); - - if (IS_ERR(fp)) { -#ifdef CONFIG_KSU_DEBUG - int errno = PTR_ERR(fp); - if (errno == -ENOENT) { - ksu_allow_uid(2000, true, - true); // allow adb shell by default - } else { - pr_err("load_allow_list open file failed: %d\n", - PTR_ERR(fp)); - } -#else - pr_err("load_allow_list open file failed: %d\n", PTR_ERR(fp)); -#endif - 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) { - u32 uid; - bool allow = false; - ret = ksu_kernel_read_compat(fp, &uid, sizeof(uid), &off); - if (ret <= 0) { - pr_info("load_allow_list read err: %d\n", ret); - break; - } - ret = ksu_kernel_read_compat(fp, &allow, sizeof(allow), &off); - - pr_info("load_allow_uid: %d, allow: %d\n", uid, allow); - - ksu_allow_uid(uid, allow, false); - } - -exit: - ksu_show_allow_list(); - filp_close(fp, 0); -} - -void ksu_prune_allowlist(bool (*is_uid_exist)(uid_t, 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->uid; - if (!is_uid_exist(uid, data)) { - modified = true; - pr_info("prune uid: %d\n", uid); - list_del(&np->list); - 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) -{ - INIT_LIST_HEAD(&allow_list); - - INIT_WORK(&ksu_save_work, do_persistent_allow_list); - INIT_WORK(&ksu_load_work, do_load_allow_list); -} - -void ksu_allowlist_exit(void) -{ - struct perm_data *np = NULL; - struct perm_data *n = NULL; - - do_persistent_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); -} \ No newline at end of file diff --git a/drivers/kernelsu/allowlist.h b/drivers/kernelsu/allowlist.h deleted file mode 100644 index 8783f2d9302e..000000000000 --- a/drivers/kernelsu/allowlist.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef __KSU_H_ALLOWLIST -#define __KSU_H_ALLOWLIST - -#include "linux/types.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); - -bool ksu_allow_uid(uid_t uid, bool allow, bool persist); - -bool ksu_get_allow_list(int *array, int *length, bool allow); - -void ksu_prune_allowlist(bool (*is_uid_exist)(uid_t, void *), void *data); - -#endif \ No newline at end of file diff --git a/drivers/kernelsu/apk_sign.c b/drivers/kernelsu/apk_sign.c deleted file mode 100644 index 04c0a36a89b9..000000000000 --- a/drivers/kernelsu/apk_sign.c +++ /dev/null @@ -1,180 +0,0 @@ -#include "linux/fs.h" -#include "linux/moduleparam.h" - -#include "apk_sign.h" -#include "klog.h" // IWYU pragma: keep -#include "kernel_compat.h" - -static __always_inline int -check_v2_signature(char *path, unsigned expected_size, unsigned expected_hash) -{ - unsigned char buffer[0x11] = { 0 }; - u32 size4; - u64 size8, size_of_block; - - loff_t pos; - - int sign = -1; - int i; - struct file *fp = filp_open(path, O_RDONLY, 0); - if (IS_ERR(fp)) { - pr_err("open %s error.", path); - return PTR_ERR(fp); - } - - // disable inotify for this file - fp->f_mode |= FMODE_NONOTIFY; - - sign = 1; - // 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; - } - - for (;;) { - 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; - pr_info("id: 0x%08x\n", id); - if ((id ^ 0xdeadbeefu) == 0xafa439f5u || - (id ^ 0xdeadbeefu) == 0x2efed62f) { - 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 0 - int hash = 1; - signed char c; - for (i = 0; i < size4; ++i) { - ksu_kernel_read_compat(fp, &c, 0x1, &pos); - hash = 31 * hash + c; - } - offset += size4; - pr_info(" size: 0x%04x, hash: 0x%08x\n", size4, ((unsigned) hash) ^ 0x14131211u); -#else - if (size4 == expected_size) { - int hash = 1; - signed char c; - for (i = 0; i < size4; ++i) { - ksu_kernel_read_compat(fp, &c, 0x1, &pos); - hash = 31 * hash + c; - } - offset += size4; - if ((((unsigned)hash) ^ 0x14131211u) == - expected_hash) { - sign = 0; - break; - } - } - // don't try again. - break; -#endif - } - pos += (size8 - offset); - } - -clean: - filp_close(fp, 0); - - return sign; -} - -#ifdef CONFIG_KSU_DEBUG - -unsigned ksu_expected_size = EXPECTED_SIZE; -unsigned ksu_expected_hash = EXPECTED_HASH; - -#include "manager.h" - -static int set_expected_size(const char *val, const struct kernel_param *kp) -{ - int rv = param_set_uint(val, kp); - ksu_invalidate_manager_uid(); - pr_info("ksu_expected_size set to %x", ksu_expected_size); - return rv; -} - -static int set_expected_hash(const char *val, const struct kernel_param *kp) -{ - int rv = param_set_uint(val, kp); - ksu_invalidate_manager_uid(); - pr_info("ksu_expected_hash set to %x", ksu_expected_hash); - return rv; -} - -static struct kernel_param_ops expected_size_ops = { - .set = set_expected_size, - .get = param_get_uint, -}; - -static struct kernel_param_ops expected_hash_ops = { - .set = set_expected_hash, - .get = param_get_uint, -}; - -module_param_cb(ksu_expected_size, &expected_size_ops, &ksu_expected_size, - S_IRUSR | S_IWUSR); -module_param_cb(ksu_expected_hash, &expected_hash_ops, &ksu_expected_hash, - S_IRUSR | S_IWUSR); - -int is_manager_apk(char *path) -{ - return check_v2_signature(path, ksu_expected_size, ksu_expected_hash); -} - -#else - -int is_manager_apk(char *path) -{ - return check_v2_signature(path, EXPECTED_SIZE, EXPECTED_HASH); -} - -#endif diff --git a/drivers/kernelsu/apk_sign.h b/drivers/kernelsu/apk_sign.h deleted file mode 100644 index 033971f92737..000000000000 --- a/drivers/kernelsu/apk_sign.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __KSU_H_APK_V2_SIGN -#define __KSU_H_APK_V2_SIGN - -// return 0 if signature match -int is_manager_apk(char *path); - -#endif \ No newline at end of file diff --git a/drivers/kernelsu/arch.h b/drivers/kernelsu/arch.h deleted file mode 100644 index 739421d0d17c..000000000000 --- a/drivers/kernelsu/arch.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef __KSU_H_ARCH -#define __KSU_H_ARCH - -#include "linux/version.h" - -#if defined(__aarch64__) - -#define __PT_PARM1_REG regs[0] -#define __PT_PARM2_REG regs[1] -#define __PT_PARM3_REG regs[2] -#define __PT_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" -#else -#define PRCTL_SYMBOL "sys_prctl" -#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_PARM4_REG r10 -// #define __PT_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" -#else -#define PRCTL_SYMBOL "sys_prctl" -#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_PARM4(x) (__PT_REGS_CAST(x)->__PT_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) - -#endif diff --git a/drivers/kernelsu/core_hook.c b/drivers/kernelsu/core_hook.c deleted file mode 100644 index f8dd398a5864..000000000000 --- a/drivers/kernelsu/core_hook.c +++ /dev/null @@ -1,552 +0,0 @@ -#include "linux/cred.h" -#include "linux/dcache.h" -#include "linux/err.h" -#include "linux/init.h" -#include "linux/kernel.h" -#include "linux/kprobes.h" -#include "linux/lsm_hooks.h" -#include "linux/path.h" -#include "linux/printk.h" -#include "linux/uaccess.h" -#include "linux/uidgid.h" -#include "linux/version.h" -#include "linux/mount.h" - -#include "linux/fs.h" -#include "linux/namei.h" -#include "linux/rcupdate.h" - -#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 "uid_observer.h" -#include "kernel_compat.h" - -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_isolated_uid(uid_t uid) { - #define FIRST_ISOLATED_UID 99000 - #define LAST_ISOLATED_UID 99999 - #define FIRST_APP_ZYGOTE_ISOLATED_UID 90000 - #define LAST_APP_ZYGOTE_ISOLATED_UID 98999 - uid_t appid = uid % 100000; - return (appid >= FIRST_ISOLATED_UID && appid <= LAST_ISOLATED_UID) - || (appid >= FIRST_APP_ZYGOTE_ISOLATED_UID && appid <= LAST_APP_ZYGOTE_ISOLATED_UID); -} - -static struct group_info root_groups = { .usage = ATOMIC_INIT(2) }; - -void escape_to_root(void) -{ - struct cred *cred; - - cred = (struct cred *)__task_cred(current); - - memset(&cred->uid, 0, sizeof(cred->uid)); - memset(&cred->gid, 0, sizeof(cred->gid)); - memset(&cred->suid, 0, sizeof(cred->suid)); - memset(&cred->euid, 0, sizeof(cred->euid)); - memset(&cred->egid, 0, sizeof(cred->egid)); - memset(&cred->fsuid, 0, sizeof(cred->fsuid)); - memset(&cred->fsgid, 0, sizeof(cred->fsgid)); - memset(&cred->cap_inheritable, 0xff, sizeof(cred->cap_inheritable)); - memset(&cred->cap_permitted, 0xff, sizeof(cred->cap_permitted)); - memset(&cred->cap_effective, 0xff, sizeof(cred->cap_effective)); - memset(&cred->cap_bset, 0xff, sizeof(cred->cap_bset)); - memset(&cred->cap_ambient, 0xff, 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 - - // setgroup to root - if (cred->group_info) - put_group_info(cred->group_info); - cred->group_info = get_group_info(&root_groups); - - setup_selinux(); -} - -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", old_dentry->d_iname, - new_dentry->d_iname, buf); - - update_uid(); - - 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; - } - - // always ignore isolated app uid - if (is_isolated_uid(current_uid().val)) { - return 0; - } - - static uid_t last_failed_uid = -1; - if (last_failed_uid == current_uid().val) { - return 0; - } - - // pr_info("option: 0x%x, cmd: %ld\n", option, arg2); - - if (arg2 == CMD_BECOME_MANAGER) { - // quick check - if (is_manager()) { - if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) { - pr_err("become_manager: prctl reply error\n"); - } - return 0; - } - if (ksu_is_manager_uid_valid()) { - pr_info("manager already exist: %d\n", - ksu_get_manager_uid()); - return 0; - } - - // someone wants to be root manager, just check it! - // arg3 should be `/data/data/` - char param[128]; - const char *prefix = "/data/data/"; - if (copy_from_user(param, arg3, sizeof(param))) { - pr_err("become_manager: copy param err\n"); - return 0; - } - - if (startswith(param, (char *)prefix) != 0) { - pr_info("become_manager: invalid param: %s\n", param); - return 0; - } - - // stat the param, app must have permission to do this - // otherwise it may fake the path! - struct path path; - if (kern_path(param, LOOKUP_DIRECTORY, &path)) { - pr_err("become_manager: kern_path err\n"); - return 0; - } - if (path.dentry->d_inode->i_uid.val != current_uid().val) { - pr_err("become_manager: path uid != current uid\n"); - path_put(&path); - return 0; - } - char *pkg = param + strlen(prefix); - pr_info("become_manager: param pkg: %s\n", pkg); - - bool success = become_manager(pkg); - if (success) { - if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) { - pr_err("become_manager: prctl reply error\n"); - } - } - path_put(&path); - return 0; - } - - if (arg2 == CMD_GRANT_ROOT) { - if (is_allow_su()) { - pr_info("allow root for: %d\n", current_uid()); - escape_to_root(); - if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) { - pr_err("grant_root: prctl reply error\n"); - } - } else { - pr_info("deny root for: %d\n", current_uid()); - // add it to deny list! - ksu_allow_uid(current_uid().val, false, true); - } - return 0; - } - - // Both root manager and root processes should be allowed to get version - if (arg2 == CMD_GET_VERSION) { - if (is_manager() || 0 == current_uid().val) { - u32 version = KERNEL_SU_VERSION; - if (copy_to_user(arg3, &version, sizeof(version))) { - pr_err("prctl reply error, cmd: %d\n", arg2); - } - } - return 0; - } - - if (arg2 == CMD_REPORT_EVENT) { - if (0 != current_uid().val) { - 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"); - 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"); - } - break; - } - default: - break; - } - return 0; - } - - if (arg2 == CMD_SET_SEPOLICY) { - if (0 != current_uid().val) { - 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 (!is_manager() && 0 != current_uid().val) { - return 0; - } - 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) { - if (is_manager() || 0 == current_uid().val) { - 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: %d\n", - arg2); - } - } else { - pr_err("prctl copy allowlist error\n"); - } - } - } - return 0; - } - - // all other cmds are for 'root manager' - if (!is_manager()) { - last_failed_uid = current_uid().val; - return 0; - } - - // we are already manager - if (arg2 == CMD_ALLOW_SU || arg2 == CMD_DENY_SU) { - bool allow = arg2 == CMD_ALLOW_SU; - bool success = false; - uid_t uid = (uid_t)arg3; - success = ksu_allow_uid(uid, allow, true); - if (success) { - if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) { - pr_err("prctl reply error, cmd: %d\n", arg2); - } - } - ksu_show_allow_list(); - 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 (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 void try_umount(const char *mnt) { - struct path path; - int err = kern_path(mnt, 0, &path); - if (err) { - return; - } - - // we are only interest in some specific mounts - if (!should_umount(&path)) { - return; - } - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0) - err = path_umount(&path, 0); - if (err) { - pr_info("umount %s failed: %d\n", mnt, err); - } -#endif -} - -int ksu_handle_setuid(struct cred *new, const struct cred *old) { - 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; - } - - // todo: check old process's selinux context, if it is not zygote, ignore it! - - if (!is_appuid(new_uid)) { - // pr_info("handle setuid ignore non application 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; - } - - // umount the target mnt - pr_info("handle umount for uid: %d\n", new_uid.val); - - // fixme: use `collect_mounts` and `iterate_mount` to iterate all mountpoint and - // filter the mountpoint whose target is `/data/adb` - try_umount("/system"); - try_umount("/vendor"); - try_umount("/product"); - - return 0; -} - -// Init functons - -static int handler_pre(struct kprobe *p, struct pt_regs *regs) -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0) - struct pt_regs *real_regs = (struct pt_regs *)PT_REGS_PARM1(regs); -#else - struct pt_regs *real_regs = regs; -#endif - 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); - unsigned long arg4 = (unsigned long)PT_REGS_PARM4(real_regs); - 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_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) -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"); - 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); -} - -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) - 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 -} - -void __init ksu_core_init(void) -{ -#ifndef MODULE - pr_info("ksu_lsm_hook_init\n"); - ksu_lsm_hook_init(); -#else - pr_info("ksu_kprobe_init\n"); - ksu_kprobe_init(); -#endif -} - -void ksu_core_exit(void) -{ -#ifndef MODULE - pr_info("ksu_kprobe_exit\n"); - ksu_kprobe_exit(); -#endif -} diff --git a/drivers/kernelsu/core_hook.h b/drivers/kernelsu/core_hook.h deleted file mode 100644 index 8e8bfc2caef4..000000000000 --- a/drivers/kernelsu/core_hook.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __KSU_H_KSU_CORE -#define __KSU_H_KSU_CORE - -#include "linux/init.h" - -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 c82d9eee5bec..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] = {}; \ No newline at end of file diff --git a/drivers/kernelsu/export_symbol.txt b/drivers/kernelsu/export_symbol.txt deleted file mode 100644 index d476da1669fb..000000000000 --- a/drivers/kernelsu/export_symbol.txt +++ /dev/null @@ -1,2 +0,0 @@ -register_kprobe -unregister_kprobe \ No newline at end of file diff --git a/drivers/kernelsu/include/ksu_hook.h b/drivers/kernelsu/include/ksu_hook.h deleted file mode 100644 index d4a2cddb06e2..000000000000 --- a/drivers/kernelsu/include/ksu_hook.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef __KSU_H_KSHOOK -#define __KSU_H_KSHOOK - -#include "linux/fs.h" -#include "linux/types.h" - -// 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 339650fe63f9..000000000000 --- a/drivers/kernelsu/kernel_compat.c +++ /dev/null @@ -1,34 +0,0 @@ -#include "linux/version.h" -#include "linux/fs.h" -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) -#include "linux/key.h" -#include "linux/errno.h" -struct key *init_session_keyring = NULL; -#endif -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 -} \ No newline at end of file diff --git a/drivers/kernelsu/kernel_compat.h b/drivers/kernelsu/kernel_compat.h deleted file mode 100644 index 8daa40489f72..000000000000 --- a/drivers/kernelsu/kernel_compat.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef __KSU_H_KERNEL_COMPAT -#define __KSU_H_KERNEL_COMPAT - -#include "linux/fs.h" -#include "linux/key.h" -#include "linux/version.h" - -extern struct key *init_session_keyring; - -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); - -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) -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); -} -#define KWORKER_INSTALL_KEYRING() \ - static bool keyring_installed = false; \ - if (init_session_keyring != NULL && !keyring_installed) \ - { \ - install_session_keyring(init_session_keyring); \ - keyring_installed = true; \ - } -#else -#define KWORKER_INSTALL_KEYRING() -#endif - -#endif \ No newline at end of file diff --git a/drivers/kernelsu/klog.h b/drivers/kernelsu/klog.h deleted file mode 100644 index bda4f9cb26dc..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 \ No newline at end of file diff --git a/drivers/kernelsu/ksu.c b/drivers/kernelsu/ksu.c deleted file mode 100644 index cc8fb0065689..000000000000 --- a/drivers/kernelsu/ksu.c +++ /dev/null @@ -1,86 +0,0 @@ -#include "linux/fs.h" -#include "linux/module.h" -#include "linux/workqueue.h" - -#include "allowlist.h" -#include "arch.h" -#include "core_hook.h" -#include "klog.h" // IWYU pragma: keep -#include "ksu.h" -#include "uid_observer.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_enable_sucompat(); -extern void ksu_enable_ksud(); - -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 DEBUG version of KernelSU **"); - pr_alert("** **"); - pr_alert("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **"); - pr_alert("*************************************************************"); -#endif - - ksu_core_init(); - - ksu_workqueue = alloc_workqueue("kernelsu_work_queue", 0, 0); - - ksu_allowlist_init(); - - ksu_uid_observer_init(); - -// #ifdef CONFIG_KPROBES we non gki - ksu_enable_sucompat(); - ksu_enable_ksud(); -// #else -// #warning("KPROBES is disabled, KernelSU may not work, please check https://kernelsu.org/guide/how-to-integrate-for-non-gki.html") -// #endif - - return 0; -} - -void kernelsu_exit(void) -{ - ksu_allowlist_exit(); - - ksu_uid_observer_exit(); - - destroy_workqueue(ksu_workqueue); - - 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 bf4b9b89a06b..000000000000 --- a/drivers/kernelsu/ksu.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef __KSU_H_KSU -#define __KSU_H_KSU - -#include "linux/workqueue.h" - -#ifndef KSU_GIT_VERSION -//#warning "KSU_GIT_VERSION not defined! It is better to make KernelSU a git submodule!" -#define KERNEL_SU_VERSION (16) -#else -#define KERNEL_SU_VERSION (10000 + KSU_GIT_VERSION + 200) // major * 10000 + git version + 200 for historical reasons -#endif - -#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 EVENT_POST_FS_DATA 1 -#define EVENT_BOOT_COMPLETED 2 - -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 8199710ac8bc..000000000000 --- a/drivers/kernelsu/ksud.c +++ /dev/null @@ -1,498 +0,0 @@ -#include "asm/current.h" -#include "linux/string.h" -#include "linux/cred.h" -#include "linux/dcache.h" -#include "linux/err.h" -#include "linux/fs.h" -#include "linux/input-event-codes.h" -#include "linux/kprobes.h" -#include "linux/printk.h" -#include "linux/types.h" -#include "linux/uaccess.h" -#include "linux/version.h" -#include "linux/workqueue.h" -#include "linux/input.h" - -#include "allowlist.h" -#include "arch.h" -#include "klog.h" // IWYU pragma: keep -#include "ksud.h" -#include "selinux/selinux.h" - -static const char KERNEL_SU_RC[] = - "\n" - - "on post-fs-data\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 -static bool vfs_read_hook = true; -static bool execveat_hook = true; -static bool input_hook = true; -#endif - -void on_post_fs_data(void) -{ - static bool done = false; - if (done) { - pr_info("on_post_fs_data already done"); - return; - } - done = true; - pr_info("on_post_fs_data!"); - ksu_load_allow_list(); - // sanity check, this may influence the performance - stop_input_hook(); -} - -#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. - */ -static int 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; -} - -int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr, - void *argv, void *envp, int *flags) -{ -#ifndef CONFIG_KPROBES - if (!execveat_hook) { - return 0; - } -#endif - struct filename *filename; - - static const char app_process[] = "/system/bin/app_process"; - static bool first_app_process = true; - static const char system_bin_init[] = "/system/bin/init"; - static bool init_second_stage_executed = false; - - if (!filename_ptr) - return 0; - - filename = *filename_ptr; - if (IS_ERR(filename)) { - return 0; - } - - if (!memcmp(filename->name, system_bin_init, - sizeof(system_bin_init) - 1)) { - // /system/bin/init executed - struct user_arg_ptr *ptr = (struct user_arg_ptr*) argv; - int argc = count(*ptr, 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(*ptr, 1); - if (p && !IS_ERR(p)) { - char first_arg[16]; - #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0) - strncpy_from_user_nofault(first_arg, p, sizeof(first_arg)); - #elif LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0) - strncpy_from_unsafe_user(first_arg, p, sizeof(first_arg)); - #else - strncpy_from_user(first_arg, p, sizeof(first_arg)); - #endif - pr_info("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; - } - } else { - pr_err("/system/bin/init parse args err!\n"); - } - } - } - - if (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", 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", 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 (!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: %d, rc_count: %d\n", dpath, - current->comm, count, rc_count); - - if (count < rc_count) { - pr_err("count: %d < rc_count: %d", 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: %d\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; -} - -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 (!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); - void *argv = (void *)&PT_REGS_PARM3(regs); - void *envp = (void *)&PT_REGS_PARM4(regs); - int *flags = (int *)&PT_REGS_PARM5(regs); - - return ksu_handle_execveat_ksud(fd, filename_ptr, argv, envp, flags); -} - -static int 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_PARM4(regs); - - return ksu_handle_vfs_read(file_ptr, buf_ptr, count_ptr, pos_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_PARM4(regs); - return ksu_handle_input_handle_event(type, code, value); -} - -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, -}; - -static struct kprobe vfs_read_kp = { - .symbol_name = "vfs_read", - .pre_handler = read_handler_pre, -}; - -static struct kprobe input_handle_event_kp = { - .symbol_name = "input_handle_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_handle_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 - vfs_read_hook = false; -#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 - execveat_hook = false; -#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 - input_hook = false; -#endif -} - -// ksud: module support -void ksu_enable_ksud() -{ -#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_handle_event_kp); - pr_info("ksud: input_handle_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 -} diff --git a/drivers/kernelsu/ksud.h b/drivers/kernelsu/ksud.h deleted file mode 100644 index d5a35aec2bea..000000000000 --- a/drivers/kernelsu/ksud.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __KSU_H_KSUD -#define __KSU_H_KSUD - -#define KSUD_PATH "/data/adb/ksud" - -void on_post_fs_data(void); - -bool ksu_is_safe_mode(void); - -#endif \ No newline at end of file diff --git a/drivers/kernelsu/manager.c b/drivers/kernelsu/manager.c deleted file mode 100644 index 1952808370c8..000000000000 --- a/drivers/kernelsu/manager.c +++ /dev/null @@ -1,80 +0,0 @@ -#include "linux/cred.h" -#include "linux/gfp.h" -#include "linux/slab.h" -#include "linux/uidgid.h" -#include "linux/version.h" - -#include "linux/fdtable.h" -#include "linux/fs.h" -#include "linux/rcupdate.h" - -#include "apk_sign.h" -#include "klog.h" // IWYU pragma: keep -#include "ksu.h" -#include "manager.h" - -uid_t ksu_manager_uid = INVALID_UID; - -bool become_manager(char *pkg) -{ - struct fdtable *files_table; - int i = 0; - struct path files_path; - char *cwd; - char *buf; - bool result = false; - - // must be zygote's direct child, otherwise any app can fork a new process and - // open manager's apk - if (task_uid(current->real_parent).val != 0) { - pr_info("parent is not zygote!\n"); - return false; - } - - buf = (char *)kmalloc(PATH_MAX, GFP_ATOMIC); - if (!buf) { - pr_err("kalloc path failed.\n"); - return false; - } - - files_table = files_fdtable(current->files); - - // todo: use iterate_fd - while (files_table->fd[i] != NULL) { - files_path = files_table->fd[i]->f_path; - if (!d_is_reg(files_path.dentry)) { - i++; - continue; - } - cwd = d_path(&files_path, buf, PATH_MAX); - if (startswith(cwd, "/data/app/") == 0 && - endswith(cwd, "/base.apk") == 0) { - // we have found the apk! - pr_info("found apk: %s", cwd); - if (!strstr(cwd, pkg)) { - pr_info("apk path not match package name!\n"); - i++; - continue; - } - if (is_manager_apk(cwd) == 0) { - // check passed - uid_t uid = current_uid().val; - pr_info("manager uid: %d\n", uid); - - ksu_set_manager_uid(uid); - - result = true; - goto clean; - } else { - pr_info("manager signature invalid!"); - } - - break; - } - i++; - } - -clean: - kfree(buf); - return result; -} diff --git a/drivers/kernelsu/manager.h b/drivers/kernelsu/manager.h deleted file mode 100644 index fcb54f57f9ff..000000000000 --- a/drivers/kernelsu/manager.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef __KSU_H_KSU_MANAGER -#define __KSU_H_KSU_MANAGER - -#include "linux/cred.h" -#include "linux/types.h" - -#define 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 != INVALID_UID; -} - -static inline bool is_manager() -{ - return 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 = INVALID_UID; -} - -bool become_manager(char *pkg); - -#endif diff --git a/drivers/kernelsu/module_api.c b/drivers/kernelsu/module_api.c deleted file mode 100644 index 6a81351d9017..000000000000 --- a/drivers/kernelsu/module_api.c +++ /dev/null @@ -1,33 +0,0 @@ -#include "linux/kallsyms.h" - -#define RE_EXPORT_SYMBOL1(ret, func, t1, v1) \ - ret ksu_##func(t1 v1) \ - { \ - return func(v1); \ - } \ - EXPORT_SYMBOL(ksu_##func); - -#define RE_EXPORT_SYMBOL2(ret, func, t1, v1, t2, v2) \ - ret ksu_##func(t1 v1, t2 v2) \ - { \ - return func(v1, v2); \ - } \ - EXPORT_SYMBOL(ksu_##func); - -RE_EXPORT_SYMBOL1(unsigned long, kallsyms_lookup_name, const char *, name) - -// RE_EXPORT_SYMBOL2(int, register_kprobe, struct kprobe *, p) -// RE_EXPORT_SYMBOL2(void, unregister_kprobe, struct kprobe *, p) - -// RE_EXPORT_SYMBOL2(int, register_kprobe, struct kprobe *, p) -// RE_EXPORT_SYMBOL2(void, unregister_kprobe, struct kprobe *, p) - -// int ksu_register_kprobe(struct kprobe *p); -// void ksu_unregister_kprobe(struct kprobe *p); -// int ksu_register_kprobes(struct kprobe **kps, int num); -// void ksu_unregister_kprobes(struct kprobe **kps, int num); - -// int ksu_register_kretprobe(struct kretprobe *rp); -// void unregister_kretprobe(struct kretprobe *rp); -// int register_kretprobes(struct kretprobe **rps, int num); -// void unregister_kretprobes(struct kretprobe **rps, int num); \ No newline at end of file diff --git a/drivers/kernelsu/selinux/Makefile b/drivers/kernelsu/selinux/Makefile deleted file mode 100644 index ae1609d73ceb..000000000000 --- a/drivers/kernelsu/selinux/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -obj-y += selinux.o -obj-y += sepolicy.o -obj-y += rules.o - - -ccflags-y += -Wno-implicit-function-declaration -Wno-strict-prototypes -Wno-int-conversion -ccflags-y += -Wno-macro-redefined -Wno-declaration-after-statement -Wno-unused-function -ccflags-y += -I$(srctree)/security/selinux -I$(srctree)/security/selinux/include -ccflags-y += -I$(objtree)/security/selinux \ No newline at end of file diff --git a/drivers/kernelsu/selinux/rules.c b/drivers/kernelsu/selinux/rules.c deleted file mode 100644 index 38b3eb315992..000000000000 --- a/drivers/kernelsu/selinux/rules.c +++ /dev/null @@ -1,465 +0,0 @@ -#include "linux/uaccess.h" -#include "linux/types.h" -#include "linux/version.h" - -#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 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 337) -#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, don't apply rules."); - return; - } - - 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); - } - - // 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 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", KERNEL_SU_DOMAIN, ALL, ALL); - - // 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"); - - // Allow all binder transactions - ksu_allow(db, ALL, KERNEL_SU_DOMAIN, "binder", ALL); - - // Allow system server devpts - ksu_allow(db, "system_server", "untrusted_app_all_devpts", "chr_file", - "read"); - ksu_allow(db, "system_server", "untrusted_app_all_devpts", "chr_file", - "write"); - - 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 ((KERNEL_VERSION(4, 14, 0) <= LINUX_VERSION_CODE) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 163))) || (LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 337)) - 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, don't apply policies."); - return 0; - } - - 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", 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", 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", 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", 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 ac14f45f0fea..000000000000 --- a/drivers/kernelsu/selinux/selinux.c +++ /dev/null @@ -1,106 +0,0 @@ -#include "selinux.h" -#include "objsec.h" -#include "linux/version.h" -#include "../klog.h" // IWYU pragma: keep -#if ((KERNEL_VERSION(4, 14, 0) <= LINUX_VERSION_CODE) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 163))) || (LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 337)) -#include "avc.h" -#endif - -#define KERNEL_SU_DOMAIN "u:r:su:s0" - -static u32 ksu_sid; - -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); - pr_info("error: %d, sid: %d\n", error, sid); - if (!error) { - if (!ksu_sid) - ksu_sid = sid; - - tsec->sid = sid; - tsec->create_sid = 0; - tsec->keycreate_sid = 0; - tsec->sockcreate_sid = 0; - } - return error; -} - -void setup_selinux() -{ - if (transive_to_domain(KERNEL_SU_DOMAIN)) { - pr_err("transive domain failed."); - 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 -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 163)) || ((KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 337))) - selinux_state.enforcing = enforce; -#else - selinux_enforcing = enforce; -#endif -#endif -} - -bool getenforce() -{ -#ifdef CONFIG_SECURITY_SELINUX_DISABLE -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 163)) || ((KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 337))) - if (selinux_state.disabled) { -#else - if (selinux_disabled) { -#endif - return false; - } -#endif - -#ifdef CONFIG_SECURITY_SELINUX_DEVELOP -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 163)) || ((KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 337))) - return selinux_state.enforcing; -#else - return selinux_enforcing; -#endif -#else - return true; -#endif -} - -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 337) -/* - * 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() -{ - return ksu_sid && current_sid() == ksu_sid; -} diff --git a/drivers/kernelsu/selinux/selinux.h b/drivers/kernelsu/selinux/selinux.h deleted file mode 100644 index 2ecdd09c220f..000000000000 --- a/drivers/kernelsu/selinux/selinux.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __KSU_H_SELINUX -#define __KSU_H_SELINUX - -#include "linux/types.h" - -void setup_selinux(); - -void setenforce(bool); - -bool getenforce(); - -bool is_ksu_domain(); - -void apply_kernelsu_rules(); - -#endif \ No newline at end of file diff --git a/drivers/kernelsu/selinux/sepolicy.c b/drivers/kernelsu/selinux/sepolicy.c deleted file mode 100644 index a55c6a4f5084..000000000000 --- a/drivers/kernelsu/selinux/sepolicy.c +++ /dev/null @@ -1,985 +0,0 @@ -#include "sepolicy.h" -#include "linux/gfp.h" -#include "linux/printk.h" -#include "linux/slab.h" -#include "linux/version.h" - -#include "../klog.h" // IWYU pragma: keep -#include "ss/symtab.h" - -#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 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 hashtab_for_each(htab, cur) hash_for_each (htab.htable, htab.size, cur) -#else -#define hashtab_for_each(htab, cur) \ - 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) \ - 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)) { - hashtab_for_each(db->p_types.table, node) - { - add_rule_raw(db, - (struct type_datum *)node->datum, - tgt, cls, perm, effect, invert); - }; - } else { - 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)) { - hashtab_for_each(db->p_types.table, node) - { - add_rule_raw(db, src, - (struct type_datum *)node->datum, - cls, perm, effect, invert); - }; - } else { - 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; - 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; - 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; - 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; - 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"); - 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"); - 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 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) - size_t new_size = sizeof(struct ebitmap) * db->p_types.nprim; - struct ebitmap *new_type_attr_map_array = - (krealloc(db->type_attr_map_array, 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_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; - } - - 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_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, - 0); - } - - 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, - 0); - } - 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; - 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]; -#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; - 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 a50712369f42..000000000000 --- a/drivers/kernelsu/selinux/sepolicy.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef __KSU_H_SEPOLICY -#define __KSU_H_SEPOLICY - -#include "linux/types.h" - -#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/setup.sh b/drivers/kernelsu/setup.sh deleted file mode 100755 index 5ee6b1aaf42c..000000000000 --- a/drivers/kernelsu/setup.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/sh -set -eux - -GKI_ROOT=$(pwd) - -echo "[+] GKI_ROOT: $GKI_ROOT" - -if test -d "$GKI_ROOT/common/drivers"; then - DRIVER_DIR="$GKI_ROOT/common/drivers" -elif test -d "$GKI_ROOT/drivers"; then - DRIVER_DIR="$GKI_ROOT/drivers" -else - echo '[ERROR] "drivers/" directory is not found.' - echo '[+] You should modify this scrpit by yourself.' - exit 127 -fi - -test -d "$GKI_ROOT/KernelSU" || git clone https://github.com/tiann/KernelSU -cd "$GKI_ROOT/KernelSU" -git stash && git pull -cd "$GKI_ROOT" - -echo "[+] GKI_ROOT: $GKI_ROOT" -echo "[+] Copy kernel su driver to $DRIVER_DIR" - -test -e "$DRIVER_DIR/kernelsu" || ln -sf "$GKI_ROOT/KernelSU/kernel" "$DRIVER_DIR/kernelsu" - -echo '[+] Add kernel su driver to Makefile' - -DRIVER_MAKEFILE=$DRIVER_DIR/Makefile -grep -q "kernelsu" "$DRIVER_MAKEFILE" || printf "\nobj-y += kernelsu/\n" >> "$DRIVER_MAKEFILE" - -echo '[+] Done.' diff --git a/drivers/kernelsu/sucompat.c b/drivers/kernelsu/sucompat.c deleted file mode 100644 index e3078df78707..000000000000 --- a/drivers/kernelsu/sucompat.c +++ /dev/null @@ -1,208 +0,0 @@ -#include "asm/current.h" -#include "linux/cred.h" -#include "linux/err.h" -#include "linux/fs.h" -#include "linux/kprobes.h" -#include "linux/types.h" -#include "linux/uaccess.h" -#include "linux/version.h" -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) -#include "linux/sched/task_stack.h" -#else -#include "linux/sched.h" -#endif - -#include "allowlist.h" -#include "arch.h" -#include "klog.h" // IWYU pragma: keep -#include "ksud.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)); -} - -int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode, - int *flags) -{ - struct filename *filename; - const char su[] = SU_PATH; - - if (!ksu_is_allow_uid(current_uid().val)) { - return 0; - } - - filename = getname(*filename_user); - - if (IS_ERR(filename)) { - return 0; - } - if (!memcmp(filename->name, su, sizeof(su))) { - pr_info("faccessat su->sh!\n"); - *filename_user = sh_user_path(); - } - - putname(filename); - - return 0; -} - -int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags) -{ - // const char sh[] = SH_PATH; - struct filename *filename; - const char su[] = SU_PATH; - - if (!ksu_is_allow_uid(current_uid().val)) { - return 0; - } - - if (!filename_user) { - return 0; - } - - filename = getname(*filename_user); - - if (IS_ERR(filename)) { - return 0; - } - if (!memcmp(filename->name, su, sizeof(su))) { - pr_info("newfstatat su->sh!\n"); - *filename_user = sh_user_path(); - } - - putname(filename); - - return 0; -} - -int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr, - void *argv, void *envp, int *flags) -{ - struct filename *filename; - const char sh[] = KSUD_PATH; - const char su[] = SU_PATH; - - if (!filename_ptr) - return 0; - - filename = *filename_ptr; - if (IS_ERR(filename)) { - return 0; - } - - if (!ksu_is_allow_uid(current_uid().val)) { - return 0; - } - - if (!memcmp(filename->name, su, sizeof(su))) { - pr_info("do_execveat_common su found\n"); - memcpy((void *)filename->name, sh, sizeof(sh)); - - escape_to_root(); - } - - return 0; -} - -#ifdef CONFIG_KPROBES - -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); - int *flags = (int *)&PT_REGS_PARM4(regs); - - return ksu_handle_faccessat(dfd, filename_user, mode, flags); -} - -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_PARM4(regs); -#endif - - 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); - void *argv = (void *)&PT_REGS_PARM3(regs); - void *envp = (void *)&PT_REGS_PARM4(regs); - int *flags = (int *)&PT_REGS_PARM5(regs); - - return ksu_handle_execveat_sucompat(fd, filename_ptr, argv, envp, - flags); -} - -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, -}; - -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, -}; - -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 - -// sucompat: permited process can execute 'su' to gain root access. -void ksu_enable_sucompat() -{ -#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); -#endif -} diff --git a/drivers/kernelsu/uid_observer.c b/drivers/kernelsu/uid_observer.c deleted file mode 100644 index 2bd148be35ad..000000000000 --- a/drivers/kernelsu/uid_observer.c +++ /dev/null @@ -1,136 +0,0 @@ -#include "linux/err.h" -#include "linux/fs.h" -#include "linux/list.h" -#include "linux/slab.h" -#include "linux/string.h" -#include "linux/types.h" -#include "linux/version.h" -#include "linux/workqueue.h" - -#include "allowlist.h" -#include "klog.h" // IWYU pragma: keep -#include "ksu.h" -#include "manager.h" -#include "uid_observer.h" -#include "kernel_compat.h" - -#define SYSTEM_PACKAGES_LIST_PATH "/data/system/packages.list" -static struct work_struct ksu_update_uid_work; - -struct uid_data { - struct list_head list; - u32 uid; -}; - -static bool is_uid_exist(uid_t uid, 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) { - exist = true; - break; - } - } - return exist; -} - -static void do_update_uid(struct work_struct *work) -{ - KWORKER_INSTALL_KEYRING(); - struct file *fp = filp_open(SYSTEM_PACKAGES_LIST_PATH, O_RDONLY, 0); - if (IS_ERR(fp)) { - pr_err("do_update_uid, open " SYSTEM_PACKAGES_LIST_PATH - " failed: %d\n", - ERR_PTR(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[128]; - 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 = - kmalloc(sizeof(struct uid_data), GFP_ATOMIC); - if (!data) { - goto out; - } - - char *tmp = buf; - const char *delim = " "; - strsep(&tmp, delim); // skip package - char *uid = strsep(&tmp, delim); - if (!uid) { - pr_err("update_uid: uid is NULL!\n"); - continue; - } - - u32 res; - if (kstrtou32(uid, 10, &res)) { - pr_err("update_uid: uid parse err\n"); - continue; - } - data->uid = res; - list_add_tail(&data->list, &uid_list); - // reset line start - line_start = pos; - } - - // 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 (np->uid == ksu_get_manager_uid()) { - manager_exist = true; - break; - } - } - - if (!manager_exist && ksu_is_manager_uid_valid()) { - pr_info("manager is uninstalled, invalidate it!\n"); - ksu_invalidate_manager_uid(); - } - - // 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); - } - filp_close(fp, 0); -} - -void update_uid() -{ - ksu_queue_work(&ksu_update_uid_work); -} - -int ksu_uid_observer_init() -{ - INIT_WORK(&ksu_update_uid_work, do_update_uid); - return 0; -} - -int ksu_uid_observer_exit() -{ - return 0; -} \ No newline at end of file diff --git a/drivers/kernelsu/uid_observer.h b/drivers/kernelsu/uid_observer.h deleted file mode 100644 index 5604b2191d97..000000000000 --- a/drivers/kernelsu/uid_observer.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __KSU_H_UID_OBSERVER -#define __KSU_H_UID_OBSERVER - -int ksu_uid_observer_init(); - -int ksu_uid_observer_exit(); - -void update_uid(); - -#endif \ No newline at end of file