|
| 1 | +kernelsu-objs := ksu.o |
| 2 | +kernelsu-objs += allowlist.o |
| 3 | +kernelsu-objs += app_profile.o |
| 4 | +kernelsu-objs += apk_sign.o |
| 5 | +kernelsu-objs += sucompat.o |
| 6 | +kernelsu-objs += syscall_hook_manager.o |
| 7 | +kernelsu-objs += throne_tracker.o |
| 8 | +kernelsu-objs += pkg_observer.o |
| 9 | +kernelsu-objs += setuid_hook.o |
| 10 | +kernelsu-objs += lsm_hooks.o |
| 11 | +kernelsu-objs += kernel_compat.o |
| 12 | +kernelsu-objs += kernel_umount.o |
| 13 | +kernelsu-objs += supercalls.o |
| 14 | +kernelsu-objs += su_mount_ns.o |
| 15 | +kernelsu-objs += feature.o |
| 16 | +kernelsu-objs += ksud.o |
| 17 | +kernelsu-objs += seccomp_cache.o |
| 18 | +kernelsu-objs += file_wrapper.o |
| 19 | +kernelsu-objs += util.o |
| 20 | +kernelsu-objs += extras.o |
| 21 | + |
| 22 | +kernelsu-objs += extras.o |
| 23 | + |
| 24 | +kernelsu-objs += selinux/selinux.o |
| 25 | +kernelsu-objs += selinux/sepolicy.o |
| 26 | +kernelsu-objs += selinux/rules.o |
| 27 | +ccflags-y += -I$(srctree)/security/selinux -I$(srctree)/security/selinux/include |
| 28 | +ccflags-y += -I$(objtree)/security/selinux -include $(srctree)/include/uapi/asm-generic/errno.h |
| 29 | + |
| 30 | +obj-$(CONFIG_KSU) += kernelsu.o |
| 31 | + |
| 32 | +# Check if this is a git repository |
| 33 | +# For in-tree build: check $(srctree)/$(src)/../.git |
| 34 | +# For out-of-tree build: check $(MDIR)/../.git |
| 35 | +ifeq ($(shell test -e $(srctree)/$(src)/../.git && echo "in-tree"),in-tree) |
| 36 | +# In-tree build (git submodule) |
| 37 | +$(shell cd $(srctree)/$(src); /usr/bin/env PATH="$$PATH":/usr/bin:/usr/local/bin [ -f ../.git/shallow ] && git fetch --unshallow) |
| 38 | +KSU_GIT_VERSION := $(shell cd $(srctree)/$(src); /usr/bin/env PATH="$$PATH":/usr/bin:/usr/local/bin git rev-list --count HEAD) |
| 39 | +KSU_GIT_TAG := $(shell cd $(srctree)/$(src); /usr/bin/env PATH="$$PATH":/usr/bin:/usr/local/bin git describe --tags --abbrev=0 2>/dev/null) |
| 40 | +KSU_GIT_VERSION_VALID := 1 |
| 41 | +else ifeq ($(shell test -e $(MDIR)/../.git && echo "out-of-tree"),out-of-tree) |
| 42 | +# Out-of-tree build (standalone repository) |
| 43 | +$(shell cd $(MDIR); /usr/bin/env PATH="$$PATH":/usr/bin:/usr/local/bin [ -f ../.git/shallow ] && git fetch --unshallow) |
| 44 | +KSU_GIT_VERSION := $(shell cd $(MDIR); /usr/bin/env PATH="$$PATH":/usr/bin:/usr/local/bin git rev-list --count HEAD) |
| 45 | +KSU_GIT_TAG := $(shell cd $(MDIR); /usr/bin/env PATH="$$PATH":/usr/bin:/usr/local/bin git describe --tags --abbrev=0 2>/dev/null) |
| 46 | +KSU_GIT_VERSION_VALID := 1 |
| 47 | +endif |
| 48 | + |
| 49 | +# Calculate version if git version is available |
| 50 | +ifdef KSU_GIT_VERSION_VALID |
| 51 | +# ksu_version: major * 30000 + git version for historical reasons |
| 52 | +$(eval KSU_VERSION=$(shell expr 30000 + $(KSU_GIT_VERSION) + 60)) |
| 53 | +$(info -- KernelSU-Next version: $(KSU_VERSION)) |
| 54 | +ccflags-y += -DKSU_VERSION=$(KSU_VERSION) |
| 55 | +else |
| 56 | +# If there is no .git directory, use default version |
| 57 | +$(warning "KSU_GIT_VERSION not defined! It is better to make KernelSU-Next a git repository!") |
| 58 | +KSU_VERSION_FALLBACK := 32857 |
| 59 | +$(info -- KernelSU-Next version fallback: $(KSU_VERSION_FALLBACK)) |
| 60 | +ccflags-y += -DKSU_VERSION=$(KSU_VERSION_FALLBACK) |
| 61 | +endif |
| 62 | + |
| 63 | +ifdef KSU_GIT_VERSION_VALID |
| 64 | +$(eval KSU_VERSION_TAG=$(KSU_GIT_TAG)) |
| 65 | +$(info -- KernelSU-Next tag: $(KSU_VERSION_TAG)) |
| 66 | +ccflags-y += -DKSU_VERSION_TAG=\"$(KSU_VERSION_TAG)\" |
| 67 | +else |
| 68 | +$(warning "KSU_VERSION_TAG not defined! It is better to make KernelSU-Next a git submodule!") |
| 69 | +KSU_VERSION_TAG_FALLBACK := v3.0.0 |
| 70 | +$(info -- KernelSU-Next tag fallback: $(KSU_VERSION_TAG_FALLBACK)) |
| 71 | +ccflags-y += -DKSU_VERSION_TAG=\"$(KSU_VERSION_TAG_FALLBACK)\" |
| 72 | +endif |
| 73 | + |
| 74 | +ifndef KSU_NEXT_MANAGER_SIZE |
| 75 | +KSU_NEXT_MANAGER_SIZE := 0x3e6 |
| 76 | +endif |
| 77 | + |
| 78 | +ifndef KSU_NEXT_MANAGER_HASH |
| 79 | +KSU_NEXT_MANAGER_HASH := 79e590113c4c4c0c222978e413a5faa801666957b1212a328e46c00c69821bf7 |
| 80 | +endif |
| 81 | + |
| 82 | +ifdef KSU_MANAGER_PACKAGE |
| 83 | +ccflags-y += -DKSU_MANAGER_PACKAGE=\"$(KSU_MANAGER_PACKAGE)\" |
| 84 | +$(info -- KernelSU-Next Manager package name: $(KSU_MANAGER_PACKAGE)) |
| 85 | +endif |
| 86 | + |
| 87 | +$(info -- KernelSU-Next Manager signature size: $(KSU_NEXT_MANAGER_SIZE)) |
| 88 | +$(info -- KernelSU-Next Manager signature hash: $(KSU_NEXT_MANAGER_HASH)) |
| 89 | + |
| 90 | +# RKSU: checks for available hook |
| 91 | +## Logic flipped for HAVE_KSU_HOOK: 0 is success, 1 is failure |
| 92 | +HAVE_KSU_HOOK ?= 1 |
| 93 | + |
| 94 | +# Checks hooks state |
| 95 | +ifeq ($(CONFIG_KSU_KPROBES_HOOK), y) |
| 96 | +$(info -- KernelSU: Hook mode: Kprobes) |
| 97 | +ccflags-y += -DKSU_KPROBES_HOOK |
| 98 | +# Let's make it 0, so it would pass. |
| 99 | +HAVE_KSU_HOOK := 0 |
| 100 | +endif |
| 101 | + |
| 102 | +ifeq ($(CONFIG_KSU_MANUAL_HOOK), y) |
| 103 | +HAVE_KSU_HOOK := $(shell grep -q "ksu_handle_faccessat" $(srctree)/fs/open.c && echo 0 || echo 1) |
| 104 | +ifeq ($(HAVE_KSU_HOOK),0) |
| 105 | +$(info -- KernelSU: Hook mode: Manual) |
| 106 | +endif |
| 107 | +endif |
| 108 | + |
| 109 | +ifneq ($(HAVE_KSU_HOOK),0) |
| 110 | +$(error -- KernelSU: No hooks were defined, please integrate manual hooks in your kernel!) |
| 111 | +endif |
| 112 | + |
| 113 | +# some backports |
| 114 | +ifneq ($(shell grep -Eq "^static int can_umount" $(srctree)/fs/namespace.c; echo $$?),0) |
| 115 | +$(info -- KSU_NEXT: adding function 'static int can_umount(const struct path *path, int flags);' to $(srctree)/fs/namespace.c) |
| 116 | +CAN_UMOUNT = static int can_umount(const struct path *path, int flags)\n\ |
| 117 | +{\n\t\ |
| 118 | + struct mount *mnt = real_mount(path->mnt);\n\t\ |
| 119 | + if (flags & ~(MNT_FORCE | MNT_DETACH | MNT_EXPIRE | UMOUNT_NOFOLLOW))\n\t\t\ |
| 120 | + return -EINVAL;\n\t\ |
| 121 | + if (!may_mount())\n\t\t\ |
| 122 | + return -EPERM;\n\t\ |
| 123 | + if (path->dentry != path->mnt->mnt_root)\n\t\t\ |
| 124 | + return -EINVAL;\n\t\ |
| 125 | + if (!check_mnt(mnt))\n\t\t\ |
| 126 | + return -EINVAL;\n\t\ |
| 127 | + if (mnt->mnt.mnt_flags & MNT_LOCKED)\n\t\t\ |
| 128 | + return -EINVAL;\n\t\ |
| 129 | + if (flags & MNT_FORCE && !capable(CAP_SYS_ADMIN))\n\t\t\ |
| 130 | + return -EPERM;\n\t\ |
| 131 | + return 0;\n\ |
| 132 | +}\n |
| 133 | +$(shell sed -i '/^static bool is_mnt_ns_file/i $(CAN_UMOUNT)' $(srctree)/fs/namespace.c;) |
| 134 | +endif |
| 135 | + |
| 136 | +ifneq ($(shell grep -Eq "^int path_umount" $(srctree)/fs/namespace.c; echo $$?),0) |
| 137 | +$(info -- KSU_NEXT: adding function 'int path_umount(struct path *path, int flags);' to $(srctree)/fs/namespace.c) |
| 138 | +PATH_UMOUNT = int path_umount(struct path *path, int flags)\n\ |
| 139 | +{\n\t\ |
| 140 | + struct mount *mnt = real_mount(path->mnt);\n\t\ |
| 141 | + int ret;\n\t\ |
| 142 | + ret = can_umount(path, flags);\n\t\ |
| 143 | + if (!ret)\n\t\t\ |
| 144 | + ret = do_umount(mnt, flags);\n\t\ |
| 145 | + dput(path->dentry);\n\t\ |
| 146 | + mntput_no_expire(mnt);\n\t\ |
| 147 | + return ret;\n\ |
| 148 | +}\n |
| 149 | +$(shell sed -i '/^static bool is_mnt_ns_file/i $(PATH_UMOUNT)' $(srctree)/fs/namespace.c;) |
| 150 | +endif |
| 151 | + |
| 152 | +ifneq ($(shell grep -Eq "^int path_umount" $(srctree)/fs/internal.h; echo $$?),0) |
| 153 | +$(shell sed -i '/^extern void __init mnt_init/a int path_umount(struct path *path, int flags);' $(srctree)/fs/internal.h;) |
| 154 | +$(info -- KSU_NEXT: adding 'int path_umount(struct path *path, int flags);' to $(srctree)/fs/internal.h) |
| 155 | +endif |
| 156 | + |
| 157 | +ifneq ($(shell grep -q "atomic_t filter_count;" $(srctree)/include/linux/seccomp.h; echo $$?),0) |
| 158 | +$(info -- KSU_NEXT: patching struct seccomp for filter_count) |
| 159 | +$(shell sed -i '/int mode;/a\ atomic_t filter_count;' $(srctree)/include/linux/seccomp.h) |
| 160 | +$(shell sed -i '/#include <linux\/thread_info.h>/a\#include <linux/atomic.h>' $(srctree)/include/linux/seccomp.h) |
| 161 | +endif |
| 162 | + |
| 163 | +# security/selinux backports |
| 164 | +ifneq ($(shell grep -q "selinux_inode(inode)" $(srctree)/security/selinux/hooks.c; echo $$?),0) |
| 165 | +$(info -- KSU_NEXT: patching selinux/hooks.c for selinux_inode) |
| 166 | +$(shell sed -i 's/struct inode_security_struct \*isec = inode->i_security/struct inode_security_struct *isec = selinux_inode(inode)/g' $(srctree)/security/selinux/hooks.c) |
| 167 | +$(shell sed -i 's/return inode->i_security/return selinux_inode(inode)/g' $(srctree)/security/selinux/hooks.c) |
| 168 | +$(shell sed -i 's/return inode->i_security/return selinux_inode(inode)/g' $(srctree)/security/selinux/hooks.c) |
| 169 | +$(shell sed -i 's/\bisec = inode->i_security;/isec = selinux_inode(inode);/' $(srctree)/security/selinux/hooks.c) |
| 170 | +endif |
| 171 | + |
| 172 | +ifneq ($(shell grep -q "selinux_cred" $(srctree)/security/selinux/hooks.c; echo $$?),0) |
| 173 | +$(info -- KSU_NEXT: patching selinux/hooks.c for selinux_cred) |
| 174 | +$(shell sed -i 's/tsec = cred->security;/tsec = selinux_cred(cred);/g' $(srctree)/security/selinux/hooks.c) |
| 175 | +$(shell sed -i 's/const struct task_security_struct \*tsec = cred->security;/const struct task_security_struct *tsec = selinux_cred(cred);/g' $(srctree)/security/selinux/hooks.c) |
| 176 | +$(shell sed -i 's/const struct task_security_struct \*tsec = current_security();/const struct task_security_struct *tsec = selinux_cred(current_cred());/g' $(srctree)/security/selinux/hooks.c) |
| 177 | +$(shell sed -i 's/rc = selinux_determine_inode_label(current_security())/rc = selinux_determine_inode_label(selinux_cred(current_cred()))/g' $(srctree)/security/selinux/hooks.c) |
| 178 | +$(shell sed -i 's/old_tsec = current_security();/old_tsec = selinux_cred(current_cred());/g' $(srctree)/security/selinux/hooks.c) |
| 179 | +$(shell sed -i 's/new_tsec = bprm->cred->security;/new_tsec = selinux_cred(bprm->cred);/g' $(srctree)/security/selinux/hooks.c) |
| 180 | +$(shell sed -i 's/rc = selinux_determine_inode_label(old->security)/rc = selinux_determine_inode_label(selinux_cred(old))/g' $(srctree)/security/selinux/hooks.c) |
| 181 | +$(shell sed -i 's/tsec = new->security;/tsec = selinux_cred(new);/g' $(srctree)/security/selinux/hooks.c) |
| 182 | +$(shell sed -i 's/tsec = new_creds->security;/tsec = selinux_cred(new_creds);/g' $(srctree)/security/selinux/hooks.c) |
| 183 | +$(shell sed -i 's/old_tsec = old->security;/old_tsec = selinux_cred(old);/g' $(srctree)/security/selinux/hooks.c) |
| 184 | +$(shell sed -i 's/const struct task_security_struct \*old_tsec = old->security;/const struct task_security_struct *old_tsec = selinux_cred(old);/g' $(srctree)/security/selinux/hooks.c) |
| 185 | +$(shell sed -i 's/struct task_security_struct \*tsec = new->security;/struct task_security_struct *tsec = selinux_cred(new);/g' $(srctree)/security/selinux/hooks.c) |
| 186 | +$(shell sed -i 's/__tsec = current_security();/__tsec = selinux_cred(current_cred());/' $(srctree)/security/selinux/hooks.c) |
| 187 | +$(shell sed -i 's/__tsec = __task_cred(p)->security;/__tsec = selinux_cred(__task_cred(p));/' $(srctree)/security/selinux/hooks.c) |
| 188 | +endif |
| 189 | + |
| 190 | +ifneq ($(shell grep -q "selinux_inode(inode)" $(srctree)/security/selinux/selinuxfs.c; echo $$?),0) |
| 191 | +$(info -- KSU_NEXT: patching selinux/selinuxfs.c for selinux_inode) |
| 192 | +$(shell sed -i 's/(struct inode_security_struct \*)inode->i_security/selinux_inode(inode)/g' $(srctree)/security/selinux/selinuxfs.c) |
| 193 | +endif |
| 194 | + |
| 195 | +ifneq ($(shell grep -q "selinux_cred" $(srctree)/security/selinux/xfrm.c; echo $$?),0) |
| 196 | +$(info -- KSU_NEXT: patching selinux/xfrm.c for selinux_cred) |
| 197 | +$(shell sed -i 's/const struct task_security_struct \*tsec = current_security();/const struct task_security_struct *tsec = selinux_cred(current_cred());/g' $(srctree)/security/selinux/xfrm.c) |
| 198 | +endif |
| 199 | + |
| 200 | +ifneq ($(shell grep -q "selinux_inode" $(srctree)/security/selinux/include/objsec.h; echo $$?),0) |
| 201 | +$(info -- KSU_NEXT: patching selinux/include/objsec.h for selinux_inode) |
| 202 | +$(shell sed -i '/#endif \/\* _SELINUX_OBJSEC_H_ \*\//i\static inline struct inode_security_struct *selinux_inode(\n\t\t\t\t\t\tconst struct inode *inode)\n{\n\treturn inode->i_security;\n}\n' $(srctree)/security/selinux/include/objsec.h) |
| 203 | +endif |
| 204 | + |
| 205 | +ifneq ($(shell grep -q "task_security_struct\s\+\*selinux_cred" $(srctree)/security/selinux/include/objsec.h; echo $$?),0) |
| 206 | +$(info -- KSU_NEXT: patching selinux/include/objsec.h for selinux_cred) |
| 207 | +$(shell sed -i '/#endif \/\* _SELINUX_OBJSEC_H_ \*\//i\static inline struct task_security_struct *selinux_cred(const struct cred *cred)\n{\n\treturn cred->security;\n}\n' $(srctree)/security/selinux/include/objsec.h) |
| 208 | +endif |
| 209 | + |
| 210 | +# SELinux drivers check |
| 211 | +ifeq ($(shell grep -q "current_sid(void)" $(srctree)/security/selinux/include/objsec.h; echo $$?),0) |
| 212 | +ccflags-y += -DKSU_COMPAT_HAS_CURRENT_SID |
| 213 | +endif |
| 214 | +ifeq ($(shell grep -q "struct selinux_state " $(srctree)/security/selinux/include/security.h; echo $$?),0) |
| 215 | +ccflags-y += -DKSU_COMPAT_USE_SELINUX_STATE |
| 216 | +endif |
| 217 | + |
| 218 | +# Handle optional backports |
| 219 | +ifeq ($(shell grep -q "strncpy_from_user_nofault" $(srctree)/include/linux/uaccess.h; echo $$?),0) |
| 220 | +ccflags-y += -DKSU_OPTIONAL_STRNCPY |
| 221 | +endif |
| 222 | + |
| 223 | +ifeq ($(shell grep -q "ssize_t kernel_read" $(srctree)/fs/read_write.c; echo $$?),0) |
| 224 | +ccflags-y += -DKSU_OPTIONAL_KERNEL_READ |
| 225 | +endif |
| 226 | + |
| 227 | +ifeq ($(shell grep "ssize_t kernel_write" $(srctree)/fs/read_write.c | grep -q "const void" ; echo $$?),0) |
| 228 | +ccflags-y += -DKSU_OPTIONAL_KERNEL_WRITE |
| 229 | +endif |
| 230 | + |
| 231 | +ifeq ($(shell grep -q "int\s\+path_mount" $(srctree)/fs/namespace.c; echo $$?),0) |
| 232 | +ccflags-y += -DKSU_HAS_PATH_MOUNT |
| 233 | +endif |
| 234 | + |
| 235 | +ifeq ($(shell grep -q "int\s\+path_umount" $(srctree)/fs/namespace.c; echo $$?),0) |
| 236 | +ccflags-y += -DKSU_HAS_PATH_UMOUNT |
| 237 | +endif |
| 238 | + |
| 239 | +# some old kernel backport this, let's check if put_seccomp_filter still exist |
| 240 | +ifneq ($(shell grep -wq "put_seccomp_filter" $(srctree)/kernel/seccomp.c $(srctree)/include/linux/seccomp.h; echo $$?),0) |
| 241 | +ifeq ($(shell grep -wq "seccomp_filter_release" $(srctree)/kernel/seccomp.c $(srctree)/include/linux/seccomp.h; echo $$?),0) |
| 242 | +ccflags-y += -DKSU_OPTIONAL_SECCOMP_FILTER_RELEASE |
| 243 | +endif |
| 244 | +endif |
| 245 | + |
| 246 | +ifeq ($(shell grep -q "security_inode_init_security_anon" $(srctree)/include/linux/security.h; echo $$?),0) |
| 247 | +ccflags-y += -DKSU_COMPAT_HAS_INIT_SEC_ANON |
| 248 | +endif |
| 249 | + |
| 250 | +# Checks Samsung |
| 251 | +ifeq ($(shell grep -q "CONFIG_KDP_CRED" $(srctree)/kernel/cred.c; echo $$?),0) |
| 252 | +ccflags-y += -DSAMSUNG_UH_DRIVER_EXIST |
| 253 | +endif |
| 254 | + |
| 255 | +ifeq ($(shell grep -q "SEC_SELINUX_PORTING_COMMON" $(srctree)/security/selinux/avc.c; echo $$?),0) |
| 256 | +ccflags-y += -DSAMSUNG_SELINUX_PORTING |
| 257 | +endif |
| 258 | + |
| 259 | +ccflags-y += -DEXPECTED_MANAGER_SIZE=$(KSU_NEXT_MANAGER_SIZE) |
| 260 | +ccflags-y += -DEXPECTED_MANAGER_HASH=\"$(KSU_NEXT_MANAGER_HASH)\" |
| 261 | + |
| 262 | +ccflags-y += -Wno-strict-prototypes -Wno-int-conversion -Wno-gcc-compat -Wno-missing-prototypes |
| 263 | +ccflags-y += -Wno-declaration-after-statement -Wno-unused-function -Wno-unused-variable |
| 264 | + |
| 265 | +# Keep a new line here!! Because someone may append config |
0 commit comments