Compare commits

...

587 Commits

Author SHA1 Message Date
Weblate (bot)
9a4ea27e9d Translations update from Hosted Weblate (#1454)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[KernelSU/Manager](https://hosted.weblate.org/projects/kernelsu/manager/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/kernelsu/manager/horizontal-auto.svg)

---------

Co-authored-by: Rex_sa <rex.sa@pm.me>
Co-authored-by: Misaka <79515833+misakazip@users.noreply.github.com>
Co-authored-by: I g o r <igormczampola1@gmail.com>
Co-authored-by: yuztass <inkognito0901@gmail.com>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: Madis Otenurm <robotkoer@gmail.com>
Co-authored-by: dabao1955 <dabao1955@163.com>
Co-authored-by: ngocanhtve <ngocanh.tve@gmail.com>
Co-authored-by: Integral <integral@member.fsf.org>
Co-authored-by: Igor Sorocean <sorocean.igor@gmail.com>
Co-authored-by: weishu tian <twsxtd@gmail.com>
Co-authored-by: Skallr2 <pm563838@gmail.com>
Co-authored-by: charlotte <charlotterose@duck.com>
Co-authored-by: sus <jeffpeng2012@gmail.com>
Co-authored-by: Caner Karaca <canerkaraca_23@hotmail.com>
Co-authored-by: Ali Beyaz <alipolatbeyaz@gmail.com>
2024-03-17 10:19:05 +08:00
igor
339e75be24 website: fix typo (#1456) 2024-03-17 09:08:46 +08:00
weishu
cf210d629f ci: Fix avd build (#1457) 2024-03-17 09:07:52 +08:00
weishu
ca480a5ec3 ci: Add lkm to release 2024-03-16 22:59:22 +08:00
weishu
23263a55de try fix 2024-03-16 12:21:03 +08:00
weishu
f65ea5a340 manager: Add install menu 2024-03-16 11:46:13 +08:00
weishu
ad6e2390f5 manager: Add CN translation 2024-03-16 11:37:31 +08:00
weishu
383f164453 remove ccache, bazel don't use 2024-03-16 11:37:30 +08:00
sewn
f675ce9aba [CI][A13] a13-5.10 patch level 2024-02 (#1449)
My Pixel 7a has a kernel version
`5.10.177-android13-4-00003-ga7208022a7ea-ab1081582`, with a security
patch of 2024-02, but the only available kernel build for that is
security patch 2023-07 which causes a bootloop.
2024-03-16 11:32:32 +08:00
weishu
7fd760f4f4 manager: Fix loading dialog 2024-03-16 11:13:50 +08:00
weishu
972d347a14 manager: Add string resource 2024-03-16 11:13:50 +08:00
weishu
ca8a88f0cc manager: Fix reboot button is missing when flash 2024-03-16 11:13:50 +08:00
weishu
e39be55db8 ksud: Fix magisk detect 2024-03-16 11:13:50 +08:00
Weblate (bot)
d00d3cbf82 Translations update from Hosted Weblate (#1437)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[KernelSU/Manager](https://hosted.weblate.org/projects/kernelsu/manager/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/kernelsu/manager/horizontal-auto.svg)

---------

Co-authored-by: Rex_sa <rex.sa@pm.me>
Co-authored-by: Misaka <79515833+misakazip@users.noreply.github.com>
Co-authored-by: I g o r <igormczampola1@gmail.com>
Co-authored-by: yuztass <inkognito0901@gmail.com>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: Madis Otenurm <robotkoer@gmail.com>
Co-authored-by: dabao1955 <dabao1955@163.com>
Co-authored-by: ngocanhtve <ngocanh.tve@gmail.com>
Co-authored-by: Integral <integral@member.fsf.org>
Co-authored-by: Igor Sorocean <sorocean.igor@gmail.com>
Co-authored-by: weishu tian <twsxtd@gmail.com>
Co-authored-by: Skallr2 <pm563838@gmail.com>
Co-authored-by: charlotte <charlotterose@duck.com>
Co-authored-by: sus <jeffpeng2012@gmail.com>
Co-authored-by: Caner Karaca <canerkaraca_23@hotmail.com>
2024-03-16 11:08:56 +08:00
cachiusa
7168a974be Add nethunter.root template (#1445)
This app requires DAC_OVERRIDE, DAC_READ_SEARCH, SYS_PTRACE, SYS_ADMIN
(for /data/local r/w) and SYS_CHROOT, SETGID (to run chroot and run it's
processes)

Devices with NetHunter installed is already considered compromised due
to lack of security features(like SELinux), therefore users are advised
not to store private data

It's not really worth restricting more capabilities of the app.
2024-03-16 10:54:00 +08:00
TheNeutrinoRaged
ddc086c4ef Update installation.md (#1451)
typo flush -> flash
2024-03-16 10:53:10 +08:00
sus
076511e275 Updated the Traditional Chinese translations for the website and templates. (#1453)
Signed-off-by: sus <54392299+jeffpeng3@users.noreply.github.com>
2024-03-16 10:52:53 +08:00
weishu
9d5529fb09 ksud: Fix magisk detect 2024-03-16 09:22:37 +08:00
weishu
ceb00dfdfd ci: remove avd build disk cache 2024-03-15 22:28:00 +08:00
weishu
39504ec2f3 ci: Fix release 2024-03-15 22:14:42 +08:00
weishu
1642e92c6f ci: Fix symbol strip 2024-03-15 21:00:44 +08:00
weishu
0f220f4044 ci: Fix release and LKM upload 2024-03-15 20:54:32 +08:00
weishu
2c34ec1742 ci: fix avd build 2024-03-15 20:29:53 +08:00
Ylarod
7568d55be1 Build KernelSU as LKM (#1254)
Co-authored-by: weishu <twsxtd@gmail.com>
2024-03-15 18:53:24 +08:00
Coconut
e3998c0744 kernel:Compatible with devices based on Huawei EMUI10 (#1447)
EMUI 10 kernel version is 4.14.xxx.  
The SELinux of Huawei's modified EMUI10 kernel is still similar to the
EMUI 9 version. This commit not support HarmonyOS 2 based EMUI 10.
2024-03-14 15:18:59 +08:00
Ylarod
50914ce39b Fix typo (#1444) 2024-03-13 18:04:58 +08:00
zalnars
6af2480008 Fix typos (#1443) 2024-03-12 13:15:03 +08:00
余空
625e1aafd1 ci: Add more kernel branches (#1442)
* Android12 5.10.205
* Android13 5.10.205
* Android13 5.15.144
* Update os_patch_level
2024-03-11 21:37:16 +08:00
weishu
d77988c1ac ksud: catch dmesg in bootlog 2024-03-11 14:20:27 +08:00
weishu
fe7ec370d4 ksud: fmt & tidy 2024-03-11 14:01:21 +08:00
weishu
ce5aa990ed ksud: don't patch if it's already patched 2024-03-11 12:48:25 +08:00
TinyHai
22a1276a22 manager: a small fix in InstallScreen (#1434)
今天刷一个模块,刷入时要配置一些内容,然后发现每次输出我都得手动滑动一下才能看全内容,就很难受。气得我直接翻源码,就有了这个PR   :P

- 防止logContent在重组时丢失。
- 修复输出内容总是自动滚动到上次内容的最底部,而不是最新内容的最底部的f问题。
2024-03-08 19:35:52 +08:00
loogeo
f9a4186dc7 Update build-kernel-a14.yml (#1432) 2024-03-08 12:39:24 +08:00
lyf
8b29137e83 [CI][A14] a14-5.15 patch level 2024-01 and 2024-02 (#1433)
Since android14 5.15.137 (2024-01) was released with QPR3 Beta2 on Pixel
8(Pro)
2024-03-08 12:39:17 +08:00
igor
ae17001033 website: update translation (#1423) 2024-03-08 10:32:08 +08:00
Syuugo
0eea198c2f Upgrade Gradle and AGP (#1431)
and Fix batch line config
2024-03-08 10:31:41 +08:00
TinyHai
425713fad3 manager: refine dialog component & add an animation to UpdateCard (#1429) 2024-03-08 10:31:14 +08:00
WindyDay
7611accc33 Add docs about Android 14 Kernel (#1421)
First time Pr to this project, not sure if I done it in the correct
format
2024-03-05 23:39:55 +08:00
riChar
323eaa0242 Add types in package.json (#1415)
The package can not be imported into TS project without this option.
[docs](https://www.typescriptlang.org/docs/handbook/declaration-files/publishing.html#including-declarations-in-your-npm-package)
2024-03-04 23:05:38 +08:00
igor
217755bb5a website: fixed typos and update translation (#1407) 2024-03-04 19:16:39 +08:00
weishu
170cd3f912 ci: Add android 15 avd kernel (#1414) 2024-03-04 19:12:48 +08:00
weishu
1d7d406745 manager: change webview debug icon 2024-03-04 15:10:16 +08:00
weishu
c8fc6a0656 ksud: resize image if it is shrinked 2024-03-04 13:50:00 +08:00
weishu
3829894d4d Use fallback method to mount overlayfs when fsopen one failed
Co-authored-by: natsumerinchan
2024-03-04 12:26:19 +08:00
5ec1cff
cd772fa250 manager: allow enable webview debugging (#1412) 2024-03-03 22:24:02 +08:00
weishu
dbe43b1540 ksud: remove permission mode for symlink 2024-03-01 23:10:03 +08:00
weishu
8a59fe1969 ksud: Copy directory permission mode 2024-03-01 22:46:53 +08:00
weishu
2a4fa94af0 ksud: Add more logs 2024-02-29 22:43:48 +08:00
weishu
6de330b00a ksud: Add some logs 2024-02-29 22:40:42 +08:00
weishu
8c0d06bc68 misc: Add just command 2024-02-29 20:35:03 +08:00
weishu
ed254b7ab4 ksud: fmt 2024-02-29 20:34:50 +08:00
weishu
5355625ed6 ksud: correctly copy chr device and keep xattr. close #1397 2024-02-29 19:23:11 +08:00
5ec1cff
7b89ec89c0 ci: support android 14 AVD (#1405) 2024-02-29 17:36:38 +08:00
weishu
5aa025c3f0 ksud: Add ksud to manager's su path 2024-02-29 14:04:10 +08:00
weishu
e39a80f91e webui: use global mount namespace by default. 2024-02-29 13:59:13 +08:00
weishu
622a7d73dc Revert "webui: support mount master mode"
This reverts commit 922703d2ff.
2024-02-29 13:58:44 +08:00
weishu
922703d2ff webui: support mount master mode 2024-02-29 13:55:07 +08:00
Fede2782
f459dfad54 English Faq: add wrong storage size on some Samsung (#1400)
#1389
2024-02-29 13:47:45 +08:00
Wang Han
3e2de84a81 Guard a few logprint in prctl path with KSU_DEBUG (#1402) 2024-02-29 13:47:22 +08:00
weishu
796f8a448a kernel: fix bazel build 2024-02-26 16:54:14 +08:00
Lycs-D
7775ce3938 ci: update android12-5.10 os_patch_level to 2024-01 (#1378) 2024-02-26 15:59:56 +08:00
Mufanc
2fb5334ac6 fix kernelsu.spawn && add type definitions (#1395) 2024-02-26 15:35:23 +08:00
weishu
afe0e691aa kernel: Unshallow the repo in Makefile. close #1365 2024-02-26 12:23:51 +08:00
Celica Sylphil
532796de48 website: Fix zh_CN and ja_JP paths (#1394) 2024-02-26 10:16:20 +08:00
dabao1955
e691c62811 website: fix ja guide broken links (#1392)
Signed-off-by: dabao1955 <dabao1955@163.com>
2024-02-26 09:49:10 +08:00
Weblate (bot)
3f341a4e3a Translations update from Hosted Weblate (#1376)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[KernelSU/Manager](https://hosted.weblate.org/projects/kernelsu/manager/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/kernelsu/manager/horizontal-auto.svg)

---------

Co-authored-by: yuztass <inkognito0901@gmail.com>
Co-authored-by: Federico Lombardo <mlomb.federalberto@gmail.com>
Co-authored-by: I g o r <igormczampola1@gmail.com>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: Kazuki Nakashima <flukfik41@gmail.com>
Co-authored-by: Rex_sa <rex.sa@pm.me>
Co-authored-by: dabao1955 <dabao1955@163.com>
Co-authored-by: / <sahmatov267@gmail.com>
2024-02-25 23:11:08 +08:00
weishu
40d7bc6256 ksud: Fix incorrect dir copy 2024-02-25 22:55:24 +08:00
igor
56dbc980f4 website: update translation (#1377) 2024-02-25 22:48:22 +08:00
weishu
bf71ff133c manager: Add adb file details to log 2024-02-25 22:36:58 +08:00
weishu
a9b156df43 manager: Add ksu file real size to logs 2024-02-25 22:33:04 +08:00
weishu
1690e5db02 manager: Use global mount namespace to gather logs 2024-02-25 22:30:53 +08:00
weishu
300d9d4cca ksud: Force creating new module format to avoid many wired issues. close #1384, close #1381 2024-02-25 22:29:13 +08:00
dabao1955
3f12080dfe website: update Japanese translation (#1387)
Signed-off-by: dabao1955 <dabao1955@163.com>
2024-02-25 20:24:49 +08:00
weishu
b670db2d22 ksud: fix punch hole 2024-02-25 20:21:17 +08:00
heinu
62a31b3dc2 manager: Allow http for more localhost (#1385) 2024-02-25 18:21:52 +08:00
weishu
a395b1011e manager: Allow http for localhost 2024-02-24 11:20:14 +08:00
weishu
406070914a website: Add docs for module WebUI 2024-02-23 22:43:31 +08:00
weishu
8685fa1f60 js: relicense js library to Apache 2.0 2024-02-23 21:30:02 +08:00
weishu
c95163b144 manager: Enter -> Open 2024-02-23 19:47:37 +08:00
weishu
648d56da39 manager: use kernelsu's domain instead of default one 2024-02-23 18:54:40 +08:00
weishu
33c0a9eebd manager: remove http that was introduced before 2024-02-23 18:49:18 +08:00
Weblate (bot)
3f86fb016d Translations update from Hosted Weblate (#1319)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[KernelSU/Manager](https://hosted.weblate.org/projects/kernelsu/manager/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/kernelsu/manager/horizontal-auto.svg)

---------

Co-authored-by: yuztass <inkognito0901@gmail.com>
Co-authored-by: 聖小熊 <as406010503@gmail.com>
Co-authored-by: dabao1955 <dabao1955@163.com>
Co-authored-by: I g o r <igormczampola1@gmail.com>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: Igor Sorocean <sorocean.igor@gmail.com>
Co-authored-by: Skallr2 <pm563838@gmail.com>
Co-authored-by: weishu <twsxtd@gmail.com>
2024-02-23 18:32:56 +08:00
weishu
66316e76f5 manager: Add entry for module ui 2024-02-23 18:28:28 +08:00
weishu
5591a94f87 manager: create new root shell for module installation to avoid block other su operations 2024-02-23 18:28:28 +08:00
weishu
f855f8148a manager: use global mnt shell to aovid nsenter 2024-02-23 18:28:28 +08:00
weishu
0c52f24612 ksud: remove link manager 2024-02-23 18:08:53 +08:00
weishu
9635a00036 manager: use SuFile to load webview assets to avoid spoofing manager's mount namespace 2024-02-23 18:04:08 +08:00
weishu
cbc04ff6df ksud: support global mnt for debug su 2024-02-23 18:04:00 +08:00
igor
8e448767a5 update templates (#1371) 2024-02-23 16:55:53 +08:00
那年雪落
2820779947 kernel: Add back Makefile new line with posix compatible (#1372) 2024-02-23 16:55:22 +08:00
weishu
a99c69f9b4 manager: Usse WebViewAssetLoader instead of file uri. refer: https://developer.android.com/reference/androidx/webkit/WebViewAssetLoader
androidCompileSdkVersion changed to meet webview library requirements
2024-02-23 16:12:53 +08:00
weishu
a829707b16 js: Allow spawn(command, options) call, fix memory leak 2024-02-23 09:16:00 +08:00
weishu
77d16ac896 js: support spawn jsapi 2024-02-23 00:16:04 +08:00
weishu
d02855a40a js: simplify the exec call 2024-02-22 22:41:50 +08:00
weishu
b904680f13 js: Add more API and README 2024-02-22 22:09:27 +08:00
weishu
811c68cac0 js: Add jsapi package 2024-02-22 20:42:15 +08:00
weishu
f20ccc1728 manager: Add jsapi: toast 2024-02-22 20:40:52 +08:00
weishu
66e7db2a4e manager: Add more abilities to js exec 2024-02-22 20:39:46 +08:00
weishu
e6b05b1d3c ksud: fix mount view of manager when 'umount modules by default' is enabled 2024-02-22 19:08:37 +08:00
weishu
329010a694 manager: mount modules webui resources to manager directly. 2024-02-22 16:26:39 +08:00
weishu
9c4d20c0f2 ksud: remove http serve mode 2024-02-22 16:26:14 +08:00
weishu
355b55a01d ksud: use bind mount to serve module webui 2024-02-22 16:26:14 +08:00
Masum Reza
e85646fad4 Added adaway.root template (#1337)
Adaway only needs the following permissions to work properly:
DAC_OVERRIDE, SYS_PTRACE.

Note: [systemless hosts kernelsu
module](https://github.com/symbuzzer/systemless-hosts-KernelSU-module)
needs to be installed, to add support.

This PR only addresses the minimal permission requirements of Adaway to
let it modify hosts file.
2024-02-21 09:57:23 +08:00
dabao1955
4969c5f548 Translate templates into Japanese (#1364)
Signed-off-by: dabao1955 <dabao1955@163.com>
2024-02-21 09:55:26 +08:00
weishu
55f8f2da90 manager: support full screen for webui 2024-02-20 23:25:57 +08:00
weishu
65bff7bf03 manager: Allow localstroage for webview 2024-02-20 20:23:43 +08:00
weishu
30dfbbdc0e ksud: support self stop server 2024-02-20 19:58:40 +08:00
weishu
fceffc9cfe manager: support load module webui 2024-02-20 19:21:07 +08:00
weishu
01b685ce58 kernel: Allow system_server to kill su process 2024-02-20 18:16:43 +08:00
weishu
cbd184421c ksud: Add support for module webui 2024-02-20 16:39:05 +08:00
weishu
b0a42abf4f ksud: Add support for module webui 2024-02-20 16:23:40 +08:00
weishu
cfc982f2f3 ksud: don't reclaim when enable/disable modules 2024-02-19 16:36:41 +08:00
weishu
e0e7058d14 ksud: reclaim sparse space when install/uninstall modules. close #1367 2024-02-19 15:29:03 +08:00
weishu
e0802b0d15 ksud: check image before shrink 2024-02-19 12:31:35 +08:00
igor
81f15ef120 Translate templates into Brazilian Portuguese (#1362)
Co-authored-by: weishu <twsxtd@gmail.com>
2024-02-18 11:40:48 +08:00
Syuugo
20c19d7126 Update mamager configs (#1359)
Upgrade Gradle and AGP.

Fixing workflow.
2024-02-18 11:40:05 +08:00
Pr0pHesyer
a360cd87c0 Update msm8998 in repos.json (#1363)
A repository still under maintenance
2024-02-18 11:39:50 +08:00
Ali Beyaz
ea9b572402 Turkish translations of Root Templates (#1356) 2024-02-17 11:24:39 +08:00
5ec1cff
6bf9e0478e ci: upload manager mappings (#1351) 2024-02-07 01:15:34 +08:00
LoveSy
abf0dacb36 Add fallback to mount syscall (#1349) 2024-02-05 17:36:07 +08:00
github-actions[bot]
263b986bcd [add device]: (#1345)
has been added to the website.
Related issue: https://github.com/tiann/KernelSU/issues/1344

Co-authored-by: GitHub Actions <41898282+github-actions[bot]@users.noreply.github.com>
2024-02-04 10:53:42 +08:00
weishu
15bdd9f507 ci: fix wsa and chromeos ci 2024-02-04 10:52:57 +08:00
backslashxx
810a62f795 [Add devices] daisy, sakura, ysl, sunny/mojito, fog/rain/wind (#1340)
Multiple devices

- Mi A2 Lite (daisy) / Redmi 6 Pro (sakura) + Redmi S2/Y2 (ysl) - 4.9

60a7363a15

4c67fcbcb6
- Redmi Note 10 (sunny/mojito) - 4.14

51cbedbeaa

96634ef252
- Redmi 10C (fog/rain/wind) - 4.19

fd2e365b80

126694822e
2024-02-03 20:40:10 +08:00
weishu
07e475c5dc kernel: prevent become manager when failed. close #1328 2024-02-03 20:03:26 +08:00
Masum Reza
eb02e42bc7 Added shizuku.root template (#1330)
Shizuku only needs DAC_OVERRIDE to execute the script to start the
Shizuku service.
Also added bengali translation for the name and description.
2024-02-02 13:08:55 +08:00
weishu
5db51b0715 manager: fix misleading tips when grant root failed. 2024-02-02 12:25:30 +08:00
weishu
60d2685f7e ksud: Fix dependency 2024-02-02 11:25:54 +08:00
LoveSy
a4b9ea04a4 Use as_ref instead of as_slice (#1336) 2024-02-02 10:40:36 +08:00
LoveSy
f80d0764b5 Use rustix for setgroups (#1334) 2024-02-01 23:35:42 +08:00
LoveSy
f80769a82a Recursive bind mount (#1332) 2024-02-01 23:29:19 +08:00
LoveSy
64269c8c4f Use rustix for prctl (#1333) 2024-02-01 23:28:56 +08:00
weishu
9f04482b90 ksud: allow to set upperdir and workdir for overlayfs 2024-02-01 18:02:10 +08:00
weishu
aca505c3e6 ksud: Fix bind mount failed 2024-02-01 17:15:44 +08:00
weishu
d4826bc97c ksud: fmt 2024-02-01 16:33:33 +08:00
weishu
4efc8164f1 ksud: Fix overlayfs mount 2024-02-01 16:32:18 +08:00
weishu
0fc25cf091 ksud: remove unused methods 2024-02-01 16:32:18 +08:00
Ali Beyaz
ca438291cc Update README_TR.md (#1329) 2024-02-01 15:44:06 +08:00
LoveSy
d6cab60e6d Merge pull request #1325 from tiann/rustix 2024-02-01 14:19:18 +08:00
LoveSy
4d4bd4793f Use new mount api 2024-02-01 01:50:30 +08:00
LoveSy
c1a2cbf1e4 Use rustix to replace some unsafe calls 2024-02-01 00:35:51 +08:00
igor
4b1fb121b4 website: update translation (#1322) 2024-01-31 11:16:57 +08:00
weishu
883a3e3407 ksud: force-stop manager when set-manager 2024-01-31 11:15:23 +08:00
weishu
27bd18f60e ksud: fix potential slow copy 2024-01-30 22:34:33 +08:00
weishu
7cb5fb47e1 ksud: Add command to shrink image 2024-01-30 13:23:49 +08:00
weishu
d43b40572d ksud: clippy 2024-01-30 12:59:24 +08:00
weishu
c99b5b31c1 ksud: fmt 2024-01-30 12:58:20 +08:00
weishu
ca960a2a8f ksud: shrink image before resize 2024-01-30 12:56:59 +08:00
weishu
cce423a2f6 ksud: Add cli for fast copy sparse file 2024-01-30 12:56:59 +08:00
weishu
946fb6f999 ksud: default 1T for sparse file 2024-01-30 12:56:59 +08:00
weishu
b6ecce4317 ksud: use default block size to reduce image size 2024-01-30 12:56:59 +08:00
weishu
be70a91f16 ksud: resize the journal size of image 2024-01-30 12:56:59 +08:00
weishu
71c2790f08 ksud: remove unnecessary image check 2024-01-30 12:56:59 +08:00
Bot_wxt1221
8733b390ca [Change device]Onepluus 6T&6 (#1315)
Because of the different implementation of dynastic partition. It only
boots on crdroid.
2024-01-30 11:08:17 +08:00
c4e106d6f8 website: [pt_BR]: Add description for sparse file (#1321)
Signed-off-by: 明 <akariondev@gmail.com>
Signed-off-by: akari <akariondev@gmail.com>
Co-authored-by: Ylarod <me@ylarod.cn>
Co-authored-by: weishu <twsxtd@gmail.com>
2024-01-30 11:06:41 +08:00
weishu
b612efcfad ksud: sparse file default 256G 2024-01-29 21:49:39 +08:00
weishu
7f53882007 manager: Fix icon for settings update 2024-01-29 21:43:55 +08:00
weishu
23ba3182cf website: Add description for sparse file 2024-01-29 21:42:52 +08:00
weishu
8abd37a35c manager: Add option to disable update close #1303 2024-01-29 21:33:24 +08:00
weishu
d7bc853bfc ksud: use sparse image to avoiding resize image. close #1220 2024-01-29 18:50:19 +08:00
weishu
16c5aba4ff ksud: fix dd failure 2024-01-29 15:51:54 +08:00
Jung-Chi Wang
3914242457 [Add devices] Oneplus 7 Serials (#1317)
Add unofficial support devices

![20240127213056](https://github.com/tiann/KernelSU/assets/447101/feeb6be7-7e96-4572-9062-879fbb1ae08d)
2024-01-27 22:10:40 +08:00
Weblate (bot)
eaa12161d6 Translations update from Hosted Weblate (#1284)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[KernelSU/Manager](https://hosted.weblate.org/projects/kernelsu/manager/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/kernelsu/manager/horizontal-auto.svg)

---------

Co-authored-by: 聖小熊 <as406010503@gmail.com>
Co-authored-by: I g o r <igormczampola1@gmail.com>
Co-authored-by: dabao1955 <dabao1955@163.com>
Co-authored-by: Mahendar Y <mahendar625934@gmail.com>
Co-authored-by: Ali Beyaz <alipolatbeyaz@gmail.com>
Co-authored-by: Integral <integral@murena.io>
Co-authored-by: 周港 <z200645049@gmail.com>
Co-authored-by: LolekLiam <liamstaric@gmail.com>
Co-authored-by: Skallr2 <pm563838@gmail.com>
Co-authored-by: charlotte <charlotterose@duck.com>
2024-01-27 11:31:11 +08:00
秋秋
0f985917f9 ci: Remove ccache patch (#1312)
We don't need it
2024-01-24 14:11:19 +08:00
igor
a569b1c76e docs: fix typos in readme (#1311) 2024-01-23 21:12:11 +08:00
KeJia
7f1ea2e178 [非官方支持设备]修正K-Nel-M1721内核的仓库网址 (#1308)
合并之前没发现偏偏合并以后发现多了个https://
之前的合并请求关闭了,只能再开一个()
2024-01-22 20:35:24 +08:00
Guanran928
da89a45d56 fix typo (#1300)
AdAday -> AdAway
2024-01-22 15:23:56 +08:00
KeJia
dc2fb20d24 [Add devices]Meizu M6 Note (#1305)
Add an unofficial support device
I will follow the updates of KernelSU to maintain the kernel for a long
time
2024-01-22 15:23:38 +08:00
Fede2782
d7625722db [add device]: Samsung Galaxy A34 5G (#1293) 2024-01-19 09:06:55 +08:00
igor
4144f10d9a website: fix translation readme: fix translation (#1297) 2024-01-19 09:06:31 +08:00
aaddaf1a78 website/docs: we don't need to use markdown for this, as it's not exactly a patch or sh file. (#1298)
```
# KernelSU 
CONFIG_KSU=y
```

---------

Signed-off-by: 明 <akariondev@gmail.com>
Signed-off-by: akari <akariondev@gmail.com>
Co-authored-by: Ylarod <me@ylarod.cn>
Co-authored-by: weishu <twsxtd@gmail.com>
2024-01-19 09:05:56 +08:00
weishu
2fec279de3 ksud: use boot partition when replace kernel 2024-01-18 16:27:11 +08:00
weishu
1e676e5dc2 ksud: Fix relative boot image path 2024-01-16 14:05:10 +08:00
weishu
7b63e099ce ksud: Fix build for win 2024-01-16 11:39:21 +08:00
Ylarod
aef943ebe3 ci: remove a14 6.1 2024-01 (#1290)
Not released

https://android.googlesource.com/kernel/common/+/refs/heads/android14-6.1-2024-01
2024-01-15 23:02:25 +08:00
Mufanc
1637864636 manager: pin the selected items to the top of the groups and capabilities list (#1285) 2024-01-15 20:31:59 +08:00
weishu
e934bfb648 kernel: Add init selinux rules. 2024-01-15 20:28:53 +08:00
weishu
653225bb5b ksud: Add support for boot patch 2024-01-15 20:17:10 +08:00
Ylarod
decbdeb5d7 fix android14 ci (#1288) 2024-01-15 11:04:27 +08:00
loogeo
51ca19f267 Update build-kernel-a14.yml to add ANDROID14-6.1.68 (#1287)
add new 6.1.68
2024-01-14 19:41:07 +08:00
Ylarod
5b920f8230 kernel: fix secctx mem leak (#1283)
Co-authored-by: weishu <twsxtd@gmail.com>
2024-01-14 11:15:52 +08:00
Arthur
601ce2120a website: optimize expression and complete Chinese translation (#1278)
Co-authored-by: weishu <twsxtd@gmail.com>
2024-01-09 09:17:25 +08:00
Salvo Giangreco
6d79060e4c [add device]: Samsung Galaxy A54 5G (#1266)
Signed-off-by: BlackMesa123 <giangrecosalvo9@gmail.com>
Co-authored-by: weishu <twsxtd@gmail.com>
2024-01-09 09:17:04 +08:00
igor
e95e87a7a4 website: update how to integrate for non gki (#1282) 2024-01-09 09:16:45 +08:00
Ali Beyaz
144b0cc8e9 Update README_TR.md (#1280) 2024-01-09 09:16:19 +08:00
Celica Sylphil
d9d9066316 website: Fix patches display (#1281)
Option does not match the corresponding patch.

![2024-01-08
20-41-45](https://github.com/tiann/KernelSU/assets/64072399/22066923-8263-4fff-b2f8-a9b04e7ca8b5)
![2024-01-08
20-41-51](https://github.com/tiann/KernelSU/assets/64072399/f345e31a-dd5a-4224-a052-ddaf99aedc5a)
![2024-01-08
20-41-55](https://github.com/tiann/KernelSU/assets/64072399/6c7d4f9f-d588-46aa-ac92-d8eb8c003316)
![2024-01-08
20-41-58](https://github.com/tiann/KernelSU/assets/64072399/906bb033-eddd-4c8c-bd13-00cff799b3df)
2024-01-08 21:08:49 +08:00
Celica Sylphil
3af293f991 website/docs: Update Simplified Chinese translation (#1279) 2024-01-08 19:53:43 +08:00
60c9fabb44 website/docs: add missing #ifdef and #endif in ksu_handle_stat [2/2] (#1277)
Signed-off-by: 明 <akariondev@gmail.com>
Signed-off-by: akari <akariondev@gmail.com>
Co-authored-by: Ylarod <me@ylarod.cn>
Co-authored-by: weishu <twsxtd@gmail.com>
2024-01-08 19:52:29 +08:00
Arthur
23ffc2a3b2 website: fix typo (#1276) 2024-01-08 14:42:41 +08:00
2bab388bbf website/docs/guide: Enable KernelSU support (CONFIG_KSU) (#1274)
### enable CONFIG_KSU on the website documentation.

Added support for KernelSU by enabling CONFIG_KSU in the kernel
defconfig located at `arch/arm64/configs/vendor/your_defconfig`. Please
ensure to verify the correct location of the file. Note that on some
devices, the defconfig may be located in `arch/arm64/configs`.

---------

Signed-off-by: 明 <akariondev@gmail.com>
Signed-off-by: akari <akariondev@gmail.com>
2024-01-08 14:42:17 +08:00
weishu
e9997a07c1 kernel: avoding umount when there isn't any module. close #556 2024-01-08 12:55:08 +08:00
weishu
757e69b15e ksud: report module mounted event to kernel 2024-01-08 12:11:54 +08:00
Ylarod
506385cfad ci: build less wsa image in pr (#1273) 2024-01-08 09:54:14 +08:00
Salvo Giangreco
4b27a9a324 website: update Galaxy A52s/M52 repo link (#1267)
Signed-off-by: BlackMesa123 <giangrecosalvo9@gmail.com>
2024-01-08 00:06:55 +08:00
iceBear67
1326fd32c5 Add unofficial support for Galaxy Note9 (#1268)
第一次构建内核,虽然狗屎,总比没有好(

等有空再清理一下更新仓库,现在能正常使用,也没太大问题
2024-01-07 23:12:23 +08:00
Weblate (bot)
90d63fe184 Translations update from Hosted Weblate (#1259)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[KernelSU/Manager](https://hosted.weblate.org/projects/kernelsu/manager/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/kernelsu/manager/horizontal-auto.svg)

---------

Co-authored-by: Ali Beyaz <alipolatbeyaz@gmail.com>
Co-authored-by: Сергій <sergiy.goncharuk.1@gmail.com>
Co-authored-by: Jia-Bin <cracky.ice@gmail.com>
Co-authored-by: dabao1955 <dabao1955@163.com>
Co-authored-by: I g o r <igormczampola1@gmail.com>
Co-authored-by: Ričards L <ricards.lacis18@gmail.com>
Co-authored-by: Madis Otenurm <robotkoer@gmail.com>
2024-01-07 14:37:28 +08:00
Ylarod
0f8a1346c7 [skip ci] fix ci (#1263) 2024-01-07 12:47:03 +08:00
Yogesh
1fad91a4e2 Added security in README.md (#1258)
Added security  in README.md

---------

Co-authored-by: weishu <twsxtd@gmail.com>
2024-01-06 22:41:14 +08:00
Weblate (bot)
ddff9ee701 Translations update from Hosted Weblate (#1237)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[KernelSU/Manager](https://hosted.weblate.org/projects/kernelsu/manager/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/kernelsu/manager/horizontal-auto.svg)

---------

Co-authored-by: Ali Beyaz <alipolatbeyaz@gmail.com>
Co-authored-by: Сергій <sergiy.goncharuk.1@gmail.com>
Co-authored-by: Jia-Bin <cracky.ice@gmail.com>
Co-authored-by: dabao1955 <dabao1955@163.com>
Co-authored-by: I g o r <igormczampola1@gmail.com>
2024-01-06 21:27:48 +08:00
igor
c7a9655ab9 website: update installation instructions and fix some typos (#1255) 2024-01-06 10:28:50 +08:00
Ylarod
fd7681c3ff [skip ci] Skip building kernel in draft pr (#1256) 2024-01-06 10:28:06 +08:00
Ylarod
e3e4d2eed4 Try umount /sbin in kernel (#1257) 2024-01-06 08:59:30 +08:00
5ec1cff
30e00859b9 ksud: extract binaries properly (#1253) 2024-01-05 23:31:52 +08:00
weishu
faf7a8e3b1 ksud: don't extract on module install 2024-01-05 22:25:41 +08:00
Nullptr
b82fc971dd Remove ksud path to make xi and vvb happy (#1251)
Not creating new historical legacy
2024-01-05 17:28:06 +08:00
Nullptr
52f5727875 Fix temp dir on Android 10 or below (#1250)
Co-authored-by: Ylarod <me@ylarod.cn>
2024-01-05 14:41:33 +08:00
weishu
01711b4114 ksud: minor tweaks 2024-01-04 16:12:22 +08:00
5ec1cff
153ce9a39a ksud: update resetprop (#1247)
- source code from Magisk a0b8aa4d and built with `build.py -r binary
resetprop`
- support waiting on property (`-w`)
2024-01-04 15:47:23 +08:00
Ylarod
f37cc16117 Correctly handle is_ksu_domain, close #972 (#1246)
fix #972
2024-01-04 14:14:31 +08:00
weishu
5f31571cc7 website: fix typo 2024-01-04 12:52:32 +08:00
Quang Minh
92a1267b29 Add Xiaomi MiMix3 (#1245) 2024-01-04 12:32:58 +08:00
weishu
b99701d216 ksud: re-extract ksud when necessary close #1242 2024-01-04 12:09:28 +08:00
5ec1cff
097e291d93 ksud: su supports set gid and groups (#1240)
- When no gid is provided, use uid as gid.
2024-01-03 18:22:01 +08:00
Cheng Haobo
eb3f604ab8 Fix typo in LogEvent.kt (#1244)
Mahcine -> Machine
2024-01-03 16:45:58 +08:00
wxt1221
3d9ca63bac Device: Oneplus 6T and Oneplus 6 (#1239)
crdroid现在使用了改造动态分区,所以我跟进上游也使用了改造动态分区。
2024-01-01 10:47:34 +08:00
weishu
4be7485180 scripts: fix allowlist.bt 2023-12-31 20:11:49 +08:00
weishu
afefe20c96 ci: fix clippy 2023-12-30 09:19:38 +08:00
Nullptr
76e7d7c60c Fix mount order (#1235) 2023-12-30 08:01:51 +08:00
igor
d08f537c89 website: update translation (#1233) 2023-12-29 20:17:47 +08:00
weishu
88e20d102d scripts: add 010Editor template for allowlist file 2023-12-29 18:33:43 +08:00
weishu
32b3ec9844 kernel: truncate allowlist before save 2023-12-29 18:32:45 +08:00
weishu
fbeea49318 website: remove coolapk download link 2023-12-28 21:08:57 +08:00
weishu
5deecb3b50 website: fix build error 2023-12-28 13:43:56 +08:00
weishu
534ac88195 website: update installation instructions 2023-12-28 13:24:49 +08:00
Weblate (bot)
d867c3c5e2 Translations update from Hosted Weblate (#1203)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[KernelSU/Manager](https://hosted.weblate.org/projects/kernelsu/manager/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/kernelsu/manager/horizontal-auto.svg)

---------

Co-authored-by: Ali Beyaz <alipolatbeyaz@gmail.com>
Co-authored-by: melamit <leominer.work@gmail.com>
Co-authored-by: wxt1221 <3264117476@qq.com>
Co-authored-by: NotNoelChannel <notnoel12345678@gmail.com>
2023-12-27 22:17:04 +08:00
YamazakuraH
aca9ac50f3 device: Remove Xiaomi Mi 9 (Cepheus) (#1230)
My Xiaomi Mi 9 is dead
2023-12-27 22:00:35 +08:00
weishu
d6cbda49aa kernel: fix out of bound reading. close #1227 2023-12-27 20:19:21 +08:00
weishu
fe7f509f9d kernel: optimize uid list reading 2023-12-27 19:33:25 +08:00
github-actions[bot]
26da7d590e [add device]: Samsung Galaxy A12s (#1229)
has been added to the website.
Related issue: https://github.com/tiann/KernelSU/issues/1228

Co-authored-by: GitHub Actions <41898282+github-actions[bot]@users.noreply.github.com>
2023-12-24 09:45:52 +08:00
Nullptr
706cd1e73e Mount temp dir at /debug_ramdisk (#1226) 2023-12-23 21:05:26 +08:00
QKIvan
6472b14a59 device: Drop Pixel redbull (#1225) 2023-12-23 19:59:03 +08:00
秋秋
c305dca5ab Remove device:non-GKI kernel(OnePlus 8 Serials) that are no longer maintained (#1223)
Say goodbye
2023-12-23 12:48:55 +08:00
SchweGELBin
94978b7b28 Update ksud.yml (#1221)
Some dependencies need a newer version of rust (1.70.0+) Fixes that to
be able to use 1.67.0.
2023-12-22 10:26:14 +08:00
Syuugo
161b3280c4 Update action uses (#1216) 2023-12-20 09:37:08 +08:00
Huy Minh
e69769d25f Update busybox to 1.36.1 (#1214)
Pulled from Magisk-v26.4.apk

Signed-off-by: Huy Minh <buingoc67@gmail.com>
2023-12-19 20:58:31 +08:00
weishu
a1153683e1 ksud: Fix weird module.prop. close #1191 2023-12-15 18:27:55 +08:00
josedelinux
79341ab501 [add device] pixel 3a (#1208)
[add device] pixel 3a

There is a usable ksu image for Pixel 3a, but it's obsolete and doesn't
work with latest ksu manager
here is my fork with latest ksu
2023-12-14 10:33:59 +08:00
weishu
05b33abb79 kernel: Add 2023-12 kernel ci 2023-12-12 19:33:12 +08:00
Puranjay Savar Mattas
f5095f96fa Aviici: Apply for avicii maintainership (#1198)
I would like to request you to update the details to my kernel as
NeverSettle kernel is no longer under development & the developer has
left development for it, Therefore, I would like to apply with my
kernel.
2023-12-11 10:46:04 +08:00
The_second_Tom
dcd9d65c92 kernel: adapt to kernel above 6.4 (#1196)
Above kernel 6.4, there is no struct_avc member in selinux_state.
2023-12-11 00:13:06 +08:00
QKIvan
fa3dec8852 device: Add Google Pixel 4a 5G & 5 (#1194) 2023-12-09 20:21:26 +08:00
dabao1955
87d10054ae Remove device:non-GKI kernel(OPPO Reno6) that are no longer maintained remove device: (#1197) 2023-12-09 20:21:09 +08:00
dabao1955
1a308afe63 repo:fix broken links (#1189)
some url is broken(404).
2023-12-08 14:53:47 +08:00
f46830f28f repos.json: rename device: non-gki ginkgo (#1192)
for Xiaomi Redmi Note 8/8T (ginkgo/willow)

assign the correct device name

---------

Signed-off-by: 明 <akariondev@gmail.com>
Signed-off-by: akari <akariondev@gmail.com>
2023-12-08 14:53:28 +08:00
weishu
c560d603e6 kernel: Add mitigation to avoid placing manager in lib to bypass check 2023-12-08 14:48:49 +08:00
Weblate (bot)
064de704f2 Translations update from Hosted Weblate (#1146)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[KernelSU/Manager](https://hosted.weblate.org/projects/kernelsu/manager/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/kernelsu/manager/horizontal-auto.svg)

---------

Co-authored-by: Hossain Rizbi <rsajib387@gmail.com>
Co-authored-by: Skallr2 <pm563838@gmail.com>
Co-authored-by: La prière <lapriere@users.noreply.hosted.weblate.org>
Co-authored-by: wxt1221 <3264117476@qq.com>
Co-authored-by: Đorđe Vasiljević <djordje.vasiljevich@gmail.com>
Co-authored-by: Wisnu Gunawan <rem01gaming@gmail.com>
Co-authored-by:  <vanni@f5.si>
2023-12-04 11:52:43 +08:00
Pa1NarK
860911c455 docs(faq): Fix typo in faq.md (#1186) 2023-12-04 11:30:04 +08:00
github-actions[bot]
1d04c5086c [add device]: (#1184)
has been added to the website.
Related issue: https://github.com/tiann/KernelSU/issues/1183

Co-authored-by: GitHub Actions <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: weishu <twsxtd@gmail.com>
2023-12-04 11:29:45 +08:00
Coconut
f4eab986a9 repos.json:Rename Xiaomi Mi 8 Pro(UD)[equuleus]/Explorer Edition[ursa… (#1181)
…] repo name and link
***
Xiaomi Mi 8 Pro(UD)[equuleus]/Explorer Edition[ursa] Repo name has
change.
 So I change the repos.json.
2023-12-04 11:28:28 +08:00
Rem01Gaming
701e85d931 templates/kernelmanager.root: add CAP_SYS_BOOT capability (#1179)
* Needed for kernel flasher
2023-12-04 11:28:09 +08:00
picasso09
bf43654725 [add device]: Realme C11,12,15 (RM6765) (#1176) 2023-12-04 11:27:50 +08:00
Yogesh
a56a922f96 add overlayfs wiki and fix old ambiguous license (#1174)
- added OverlayFS wiki link: https://en.wikipedia.org/wiki/OverlayFS
- fix old ambiguous license:
https://www.gnu.org/licenses/identify-licenses-clearly.en.html

---------

Co-authored-by: weishu <twsxtd@gmail.com>
2023-12-04 11:26:48 +08:00
Ali Beyaz
19a697a968 Update README_TR.md (#1168) 2023-12-04 11:22:42 +08:00
超高校级的錆鱼
c9b540b12c templates: Create cemiuiler.readproc (#1151)
Add a permission template for cemiuiler that only restarts applications
in scope.

增加适用于cemiuiler的权限模板,仅用于重启作用域中的应用,也适用于其他仅需要重启其他应用权限的软件。
2023-11-22 11:02:57 +08:00
dabao1955
cd48f64154 Update README (#1164) 2023-11-21 19:11:33 +08:00
Ali Beyaz
acd2c343e2 Updated README_TR.md (#1161) 2023-11-21 19:11:15 +08:00
igor
dec7f91182 Update README and Website (#1163) 2023-11-21 19:10:55 +08:00
Salvo Giangreco
d2684292e8 [add device]: Samsung Galaxy A52s/M52 5G (#1156)
Signed-off-by: BlackMesa123 <giangrecosalvo9@gmail.com>
2023-11-21 19:02:06 +08:00
CoolestEnoch
07b940d127 [add device]: Huawei nova 2 (pic) (#1153)
Add Huawei nova 2 (pic) device that is a non-GKI kernel (Linux 4.4),
regularly build with Github Actions weekly. This kernel is based on
LineageOS kernel.
2023-11-19 22:38:06 +08:00
Yogesh
845515fa6b README.md: added logo and badges (#1150)
added logo and badges help users quickly and easily identify what they
need or want. And added missing webpage.
2023-11-19 22:36:23 +08:00
weishu
0db7aa573e ci: Add latest kernels 2023-11-19 22:33:17 +08:00
weishu
3783f82b28 manager: upgrade libsu 2023-11-16 11:32:35 +08:00
igor
684973b4bf website: update translation (#1145) 2023-11-15 09:15:14 +08:00
weishu
0617c4440b Docs update (#1143) 2023-11-14 13:56:21 +08:00
igor
9223558197 Website: Fix the GitHub name and improve the grammar in Brazilian Portuguese (#1138) 2023-11-14 11:08:41 +08:00
github-actions[bot]
c13040a0ea [add device]: (#1140)
has been added to the website.
Related issue: https://github.com/tiann/KernelSU/issues/1139

Co-authored-by: GitHub Actions <41898282+github-actions[bot]@users.noreply.github.com>
2023-11-14 11:07:09 +08:00
Aquarius223
b45c4f57c5 website: Optimize the non-GKI page format and repair errors (#1141)
1. Divide the patches into a separate file segment
2. Fix the ISO C90 grammar warning in fs/open.c

Conflict: JA_JP Folder does not do how-to-integrate-for-non-gki.md
Change-Id: I23a611eb937d9cb3da7a2d97046e0b57f1efc4d6

Co-authored-by: admin <paper@localhost>
2023-11-14 11:06:44 +08:00
Weblate (bot)
8196243478 Translations update from Hosted Weblate (#1125)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[KernelSU/Manager](https://hosted.weblate.org/projects/kernelsu/manager/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/kernelsu/manager/horizontal-auto.svg)

---------

Co-authored-by: Ali Beyaz <alipolatbeyaz@gmail.com>
Co-authored-by: Skallr2 <pm563838@gmail.com>
Co-authored-by: hoanghuy309 <hoanghuy309@gmail.com>
Co-authored-by: La prière <lapriere@users.noreply.hosted.weblate.org>
Co-authored-by: Rex_sa <rex.sa@pm.me>
Co-authored-by: Wisnu Gunawan <rem01gaming@gmail.com>
2023-11-13 18:50:20 +08:00
weishu
b7f937b7f9 kernel: fix su not working in shell for 6.1 kernel 2023-11-13 15:06:25 +08:00
Rem01Gaming
8fdff569d6 templates: Update templates and try to get rid with CAP_SYS_ADMIN (#1134)
- The use of CAP_SYS_ADMIN can be avoided in Kernel Manager, but cannot
be avoided in Root Explorer because it's needed for mounting RW/RO.
- Capabilities adjustment
- Fix template typo

---------

Signed-off-by: Rem01Gaming <Rem01_Gaming@proton.me>
2023-11-13 13:24:54 +08:00
Howard Wu
b658d820a1 Fix sitemap hostname (#1135) 2023-11-13 13:09:44 +08:00
weishu
ce56c19ad9 website: enable sitemap 2023-11-13 12:17:01 +08:00
weishu
d27561c505 website: fix vitepress ci 2023-11-13 12:08:22 +08:00
weishu
57898f13c1 website: fix vitepress ci 2023-11-13 12:04:37 +08:00
weishu
5da1767ff8 website: update vitepress ci 2023-11-13 11:58:59 +08:00
weishu
aa21385a36 Upgrade vitepress 2023-11-13 11:46:01 +08:00
dabao1955
697e06125a docs: Update translation instructions in README: Japanese (#1131)
ref:  #1123
2023-11-13 11:03:40 +08:00
95c383ea18 docs: Update translation instructions in docs/README_PT-BR.md (#1127)
To improve collaboration and avoid conflicts, contributors are
encouraged to use Weblate for KernelSU translations. Additionally,
clarify that pull requests for Manager's translation are no longer
accepted.
Issue https://github.com/tiann/KernelSU/pull/1123

---------

Signed-off-by: 明 <akariondev@gmail.com>
Signed-off-by: akari <akariondev@gmail.com>
2023-11-13 11:03:08 +08:00
weishu
048e94ba69 ci: allow manually dispatch website deploy 2023-11-13 10:45:09 +08:00
Rem01Gaming
4a9f1de7a0 templates: Create template for Kernel manager and Root exploler (#1133)
Signed-off-by: Rem01Gaming <Rem01_Gaming@proton.me>
2023-11-13 09:23:45 +08:00
Howard Wu
00438a6d6e Fix ksubot global value (#1130) 2023-11-12 13:34:59 +08:00
Howard Wu
88d4eca8ff Check if contain module id (#1128) 2023-11-12 12:34:18 +08:00
Howard Wu
8a298bb867 [skip ci] Check if the value is null before toInt (#1129) 2023-11-12 12:17:06 +08:00
Ylarod
5526fa2468 Update README.md about translation pr (#1123) 2023-11-10 12:48:17 +08:00
Weblate (bot)
c26a26b92d Translations update from Hosted Weblate (#1115)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[KernelSU/Manager](https://hosted.weblate.org/projects/kernelsu/manager/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/kernelsu/manager/horizontal-auto.svg)

---------

Co-authored-by: Ali Beyaz <alipolatbeyaz@gmail.com>
Co-authored-by: hoanghuy309 <hoanghuy309@gmail.com>
Co-authored-by: nottellingya <jorjoraguilar10@gmail.com>
Co-authored-by: weishu <twsxtd@gmail.com>
2023-11-08 12:29:07 +08:00
Ylarod
75e64eafd2 update tr translate (#1108)
Co-authored-by: Deniz Kalma <75412448+mdksec@users.noreply.github.com>
Co-authored-by: Ali Beyaz <symbuzzer@users.noreply.github.com>
2023-11-07 17:52:46 +08:00
Coconut
961478fa23 Remove non-GKI kernel(Huawei P10) that are no longer maintained (#1119)
Due to job changes, I no longer maintain this kernel. Therefore, I will
delete this repo website link.
2023-11-07 16:04:17 +08:00
Brian
a903b0fa4e docs: Rename mentions of ZygiskOnKernelSU to ZygiskNext (#1114) 2023-11-06 10:26:58 +08:00
Weblate (bot)
0f09b90f5b Translations update from Hosted Weblate (#1088)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[KernelSU/Manager](https://hosted.weblate.org/projects/kernelsu/manager/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/kernelsu/manager/horizontal-auto.svg)

---------

Co-authored-by: Kazuki Nakashima <flukfik41@gmail.com>
Co-authored-by: dabao1955 <dabao1955@163.com>
Co-authored-by: Ali Beyaz <alipolatbeyaz@gmail.com>
Co-authored-by: I g o r <igormczampola1@gmail.com>
Co-authored-by: tit4nnub <vaoaal@gmail.com>
Co-authored-by: Adiemi Azmi <budaknoob7@gmail.com>
Co-authored-by: 李逍遥 <a3327997820@gmail.com>
Co-authored-by: Igor Sorocean <sorocean.igor@gmail.com>
2023-11-02 17:22:27 +08:00
weishu
8b81aeaf70 ci: remove protected symbols 2023-11-02 12:06:08 +08:00
weishu
b4a52f89cc ksud: bump dependencies 2023-11-02 12:05:21 +08:00
weishu
e9df5105b3 Rename bug_report.md to bug_report.yml 2023-10-27 16:56:55 +08:00
weishu
cd2711395a Update bug_report.md 2023-10-27 16:56:10 +08:00
officialputuid
83a8d77018 [add device]: Realme 6 / 7 (RM6785) (#1097)
Change-Id: I7227a2afd01fda5684cdb28a9c4c1b2dc8ef8b65

Signed-off-by: officialputuid <officialputuid@hack.id>
2023-10-27 11:10:59 +08:00
426fde58fd [add device]: Xiaomi Redmi 6 - 6A (#1094) 2023-10-26 12:13:21 +08:00
weishu
59040c3aea website: fix repos.json 2023-10-25 16:45:31 +08:00
Js0n
f4b53daddf fix(bot): prevent flood wait by caching bot session (#1082)
This stop bot from re-login every run.
2023-10-25 11:32:46 +08:00
weishu
4c79ad7a81 manager: Fix module changelog fetch failed. close #1084 2023-10-25 11:11:44 +08:00
weishu
fb6565bd19 ci: fix build for protectd symbols 2023-10-25 09:13:11 +08:00
github-actions[bot]
a3e939ab90 [add device]: (#1091)
has been added to the website.
Related issue: https://github.com/tiann/KernelSU/issues/1090

Co-authored-by: GitHub Actions <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: weishu <twsxtd@gmail.com>
2023-10-25 08:38:07 +08:00
github-actions[bot]
80797548b5 [add device]: non-GKI ginkgo (#1086)
non-GKI ginkgo has been added to the website.
Related issue: https://github.com/tiann/KernelSU/issues/1085

Co-authored-by: GitHub Actions <41898282+github-actions[bot]@users.noreply.github.com>
2023-10-25 08:36:52 +08:00
weishu
f86fce6e16 ci: remove dirty postfix for a14 kernel 2023-10-24 22:59:52 +08:00
weishu
318be535a8 manager: Add missing groups 2023-10-24 22:56:27 +08:00
weishu
92d4de3a73 ci: remove su local cache 2023-10-24 18:03:03 +08:00
weishu
3cf5fc4c51 ci: ignore ksubot error 2023-10-24 18:00:45 +08:00
weishu
4e3cbf627a ci: fix secrets for release ci 2023-10-24 17:35:53 +08:00
weishu
72febb34c0 ci: Add Android 14 kernel build to release 2023-10-24 17:01:17 +08:00
weishu
03068f279d manager: fix clipboard toast 2023-10-24 15:59:30 +08:00
weishu
7371eae382 manager: template import/export 2023-10-24 15:24:32 +08:00
weishu
fae1fd9826 manager: make system and shell group conspicuously 2023-10-24 10:57:03 +08:00
weishu
ec5d9e6368 manager: sort groups and capabilities 2023-10-24 10:39:25 +08:00
weishu
64f849dc10 ci: fix build userspace su (#1079) 2023-10-24 10:19:08 +08:00
Js0n
d68fa5aed5 fix(ci): cast chat id and thread id into int (#1078) 2023-10-24 09:27:13 +08:00
4qwerty7
1b67c1b153 kernel: fix null pointer dereference for some case (#1075)
#973 __never_use_envp 被改名为 envp 并使用。

这导致 GKI 版本一旦代码运行到
[213](344c08bb79/kernel/ksud.c (L213))
行(或许只有 WSA 等类似情况会跑到这?),就会触发一个空指针解引用。

此PR意在修复此问题,且已在WSA上测试。
2023-10-24 07:00:52 +08:00
Js0n
f349507232 ci: replace python-telegram-bot with telethon (#1076) 2023-10-24 07:00:23 +08:00
weishu
bf823a29e8 kernel: fix incorrect strcmp 2023-10-23 22:22:47 +08:00
weishu
55f712d1b2 kernel: dirty fix for pixel8 wlan/bluetooth. close #1074
The wlan and bluetooth driver bcmdhd4398 cannot be loaded because cfg80211.ko has been converted to a vendor module. You can find more information about this conversion at: ee1e4b7c5e.

The reason why cfg80211.ko cannot be loaded is because the rfkill.ko module in system_dlkm has protected symbols. To fix this issue, we simply need to delete the protected symbol.

"There is no ABI stability between GKI and GKI modules. In order for modules to load correctly during runtime, GKI and GKI modules must be built and updated together."

We need to find a better solution to address this problem.

Co-authored-by: aviraxp <wanghan1995315@gmail.com>
2023-10-23 22:20:43 +08:00
weishu
ca10d7bcb9 manager: Add more info for logs 2023-10-23 17:25:39 +08:00
weishu
d24813b2c3 Merge pull request from GHSA-86cp-3prf-pwqq
* kernel: deny v2 signature blocks with incorrect number

* kernel: reject v1 signature

* kernel: enforce manager package name at compile time

* kernel: don't specific package name in source code, use it in ci
2023-10-23 12:59:30 +08:00
ZHANtech™
a6325193cf [CI] Update Android 13 sublevel and patch level (#1071)
android13-5.10-2023-10 :
https://android.googlesource.com/kernel/common/+/refs/heads/android13-5.10-2023-10

android13-5.15-2023-10 :
https://android.googlesource.com/kernel/common/+/refs/heads/android13-5.15-2023-10
2023-10-23 08:17:10 +08:00
kevios12
7a1767b4c9 kernel: fix Modules install stuck on kernel 4.4 (#1059) 2023-10-22 23:40:53 +08:00
github-actions[bot]
2d4d26c68e [add device]: (#1070)
has been added to the website.
Related issue: https://github.com/tiann/KernelSU/issues/1069

Co-authored-by: GitHub Actions <41898282+github-actions[bot]@users.noreply.github.com>
2023-10-22 23:39:11 +08:00
weishu
3f98493bb3 Add android14-6.1 (#1065) 2023-10-22 17:55:02 +08:00
sus
927f2a26bd 讓artifact可以正確導出 (#1064)
修正artifact無法被導出的問題
[action](https://github.com/tiann/KernelSU/actions/runs/6597355879)
Annotations
1 warning
upload-artifacts
No files were found with the provided path: Image-android13*/*.img.gz.
No artifacts will be uploaded.
2023-10-22 08:31:15 +08:00
weishu
344c08bb79 kernel: make compiler happy 2023-10-21 22:43:58 +08:00
weishu
84f16e4c82 assets: remove unused fields 2023-10-21 22:07:26 +08:00
weishu
4ff9dcaa17 assets: allow to use default uid, gid, groups, capabilities and context 2023-10-21 22:05:19 +08:00
weishu
34b64b8310 assets: remove CAP_DAC_READ_SEARCH 2023-10-21 20:41:30 +08:00
weishu
8f4e7f8a79 manager: remove default CAP_DAC_READ_SEARCH cap because we've processed it in kernel. 2023-10-21 20:39:30 +08:00
weishu
75b5fdfb9d kernel: make su without any capabilities possible 2023-10-21 20:32:28 +08:00
weishu
d4e19bb8fc manager: refresh template screen if needed. 2023-10-21 17:13:23 +08:00
weishu
571f89fac3 manager: Prioritize display of local templates 2023-10-21 16:52:37 +08:00
weishu
9e058c48a6 manager: support locales for online template(2) 2023-10-21 16:28:08 +08:00
weishu
e828053439 manager: support locales for online template 2023-10-21 16:23:33 +08:00
weishu
8a7d153b02 profile: Add incompetent.root profile template 2023-10-21 15:50:06 +08:00
weishu
06fdae18d2 manager: Fix missing template author 2023-10-21 15:38:17 +08:00
weishu
df8c91b306 profile: Add adb,system profile template 2023-10-21 15:33:10 +08:00
weishu
10b31bd09a manager: Fix remote template fetch error. 2023-10-21 15:29:26 +08:00
weishu
54a705d8dc profile: Add adb profile template 2023-10-21 14:25:08 +08:00
weishu
294caf3deb manager: show App Profile manage screen when empty 2023-10-21 14:02:00 +08:00
Weblate (bot)
a1f7d474f9 Translations update from Hosted Weblate (#1029)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[KernelSU/Manager](https://hosted.weblate.org/projects/kernelsu/manager/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/kernelsu/manager/horizontal-auto.svg)

---------

Co-authored-by: Ian Perdiansah <ianperdiansah05@gmail.com>
Co-authored-by: I g o r <igormczampola1@gmail.com>
Co-authored-by: Ali Beyaz <alipolatbeyaz@gmail.com>
Co-authored-by: Mix <3xh096xz4@mozmail.com>
Co-authored-by: Frankie McEyes <mceyes@protonmail.com>
Co-authored-by: wxt1221 <3264117476@qq.com>
Co-authored-by: Rex_sa <rex.sa@pm.me>
Co-authored-by: weishu tian <twsxtd@gmail.com>
2023-10-21 14:00:22 +08:00
weishu
1df5fec49b manager: use production template url 2023-10-21 13:24:20 +08:00
weishu
fd03626362 ksud: make cargo fmt happy 2023-10-21 13:21:33 +08:00
weishu
9b294682b0 manager: support App Profile template 2023-10-21 13:19:59 +08:00
weishu
a4fb9e4031 website: ensure templates dir exists 2023-10-21 10:33:39 +08:00
weishu
3ebee74efc website: Fix template index.json generate error 2023-10-21 10:28:23 +08:00
weishu
433627c82b website: Add placeholer for templates 2023-10-21 10:11:52 +08:00
weishu
6cce322107 website: Add profile template api 2023-10-21 10:01:02 +08:00
starmoe
906007a7b3 add ksu kernel for oneplus 5/5t (#1058) 2023-10-20 08:53:32 +08:00
weishu
583426ecc5 Add Android 14 kernel ci (#1057) 2023-10-20 08:53:08 +08:00
weishu
ce892bc439 kernel: don't umount for non zygote child process. fixes #1054,#1049,#1045 2023-10-19 17:29:10 +08:00
github-actions[bot]
1f1d4d454e [add device]: (#1047)
has been added to the website.
Related issue: https://github.com/tiann/KernelSU/issues/1046

Co-authored-by: GitHub Actions <41898282+github-actions[bot]@users.noreply.github.com>
2023-10-16 14:04:01 +08:00
wxt1221
4695b41f53 其他开发者适配的非GKI内核 (#1043)
[PR](https://github.com/tiann/KernelSU/pull/1024)
中删除了两个,实际上还在只是换名字了,希望加上:

https://github.com/Vincent4440/noxious_kernel_xiaomi_sm8250 ->
https://github.com/Vincent4440/android_kernel_xiaomi_sm8250

https://github.com/zharzinhoo/Kernel-Oriente-Cebu ->
https://github.com/zharzinhoo/android_kernel_motorola_cebu
2023-10-15 22:42:18 +08:00
Syuugo
52f17cde40 Optimize for build WSA kernels (#1025)
`5.15.104.4` will not be released, so commit internal changes first.
2023-10-13 19:51:25 +08:00
weishu
3408f944e6 kernel: use strncpy and strncmp 2023-10-12 15:52:10 +08:00
weishu
b1830049f1 kernel: prune allowlist with package name and uid 2023-10-12 15:44:43 +08:00
weishu
79951f06ed kernel: ignore path that's not mountpoint 2023-10-12 14:24:41 +08:00
weishu
8828939994 kernel: reject v3 and v3.1 signature scheme for manager verification 2023-10-11 17:06:14 +08:00
weishu
a3b92d6fee ksud: reject v3 and v3.1 signature scheme 2023-10-11 16:50:32 +08:00
weishu
a22959beae kernel: harden the signature check (#1027) 2023-10-11 02:53:11 -05:00
dabao1955
7753dc0987 repos.json: update source repo link (#1024)
https://github.com/Vincent4440/noxious_kernel_xiaomi_sm8250  404

https://github.com/SakuraNotStupid  301 > https://github.com/SakuraKyuo

https://github.com/Sanju0910  301 > https://github.com/sreeshankark

https://github.com/zharzinhoo/Kernel-Oriente-Cebu  404
2023-10-10 16:37:17 +08:00
igor
960c40129b fix typos in website (#1023) 2023-10-10 10:21:41 +08:00
weishu
f371d784ea Create SECURITY.md 2023-10-09 22:53:21 +08:00
github-actions[bot]
59b45ce822 [add device]: (#1021)
has been added to the website.
Related issue: https://github.com/tiann/KernelSU/issues/1020

Co-authored-by: GitHub Actions <41898282+github-actions[bot]@users.noreply.github.com>
2023-10-09 20:52:34 +08:00
weishu
340595276f kernel: Add selinux rules for module umount 2023-10-09 18:09:54 +08:00
Yu
72d756c9f2 fix typo in zh_CN guide (#1015) 2023-10-09 16:43:42 +08:00
github-actions[bot]
3d59071571 [add device]: a lineage kernel forked from LineageOS official repository, version 4.4.302, added ksu. (#1014)
a lineage kernel forked from LineageOS official repository, version
4.4.302, added ksu. has been added to the website.
Related issue: https://github.com/tiann/KernelSU/issues/1013

Co-authored-by: GitHub Actions <41898282+github-actions[bot]@users.noreply.github.com>
2023-10-09 14:35:59 +08:00
Yogesh
394cfe7516 Added Hindi translation to readme (#1009)
Co-authored-by: vibrantifix <92950980+vibrantifix@users.noreply.github.com>
2023-10-08 23:32:08 +08:00
weishu
0810db101e ci: Add android13-5.10-2023-09 2023-10-08 17:17:16 +08:00
weishu
ab0ae9d196 ci: Fix sublevel incorrect 2023-10-08 17:11:13 +08:00
weishu
13748300eb manager: update dependencies 2023-10-08 15:57:49 +08:00
weishu
c4db2bab4f manager: Fix changelog dialog, close #1005 2023-10-08 15:56:27 +08:00
weishu
e352ccc470 manager: Upgrade AGP to 8.1.0 2023-10-08 15:07:10 +08:00
weishu
7747c0e211 kernel: umount modules mnt when needed. fix #991 2023-10-08 14:17:33 +08:00
Weblate (bot)
2661a36375 Translations update from Hosted Weblate (#1000)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[KernelSU/Manager](https://hosted.weblate.org/projects/kernelsu/manager/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/kernelsu/manager/horizontal-auto.svg)

---------

Co-authored-by: I g o r <igormczampola1@gmail.com>
Co-authored-by: عَرَبَّآوٌىْ <arabawyc3@gmail.com>
Co-authored-by: Jen Kung-chih <Kaitul@outlook.com>
Co-authored-by: Rex_sa <rex.sa@pm.me>
Co-authored-by: HenRy <helge1o1o1@gmail.com>
Co-authored-by: zhar <cristofercamargo339@gmail.com>
Co-authored-by: Jakub Skorłutowski <jakub.skorlutowski@gmail.com>
Co-authored-by: Yogesh <ys76543210@gmail.com>
Co-authored-by: Szabolcs Hubai <szab.hu@gmail.com>
Co-authored-by: a0533057932 <a0533057932@gmail.com>
2023-10-08 12:15:10 +08:00
igor
1bdddb13ce fix website translations and improve grammar (#1004) 2023-10-07 11:56:15 +08:00
a0533057932
7d3c50ef0a Added Hebrew translation for readme (#1008) 2023-10-07 11:55:45 +08:00
orvit
2ee7696d67 enhance grammar and language in landing pages (en) (#1003)
Makes the project look considerably more professional and less like
you've just stumbled upon a phishing page.
2023-10-03 00:15:18 +08:00
longhuan1999
54ee400dc5 kernel: Adapt to low version Android init process (#973)
1. Adapt to low version Android init process
2. Add stop hook output
3. Fix output with missing line breaks
2023-10-02 12:00:24 +08:00
Weblate (bot)
945e2c3209 Translations update from Hosted Weblate (#980)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[KernelSU/Manager](https://hosted.weblate.org/projects/kernelsu/manager/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/kernelsu/manager/horizontal-auto.svg)

---------

Co-authored-by: I g o r <igormczampola1@gmail.com>
Co-authored-by: عَرَبَّآوٌىْ <arabawyc3@gmail.com>
Co-authored-by: Jen Kung-chih <Kaitul@outlook.com>
Co-authored-by: Rex_sa <rex.sa@pm.me>
Co-authored-by: HenRy <helge1o1o1@gmail.com>
Co-authored-by: zhar <cristofercamargo339@gmail.com>
Co-authored-by: Jakub Skorłutowski <jakub.skorlutowski@gmail.com>
2023-10-02 01:17:06 +08:00
github-actions[bot]
298e42cb42 [add device]: Moto g9 play (#995)
Moto g9 play has been added to the website.
Related issue: https://github.com/tiann/KernelSU/issues/994

Co-authored-by: GitHub Actions <41898282+github-actions[bot]@users.noreply.github.com>
2023-10-02 01:05:36 +08:00
Tuan Anh
3a657a9dbb Adding support for Nokia 8/8 Sirocco (#999)
... seems so. This include:
* Adding KernelSU support for Nokia 8/8 Sirocco (NB1/NLA/A1N)
2023-10-02 01:04:52 +08:00
huangsijun17
55aa54ca85 add a13-5.15.131 (#988)
add 131
2023-09-27 09:40:15 +08:00
igor
0b8359a2e2 fix translations from website (#989) 2023-09-26 10:45:51 +08:00
igor
afb04126f6 fix warning cards, tips and translation (#979) 2023-09-24 22:25:24 +08:00
Syuugo
98fae23864 Optimize for WSA (#975)
- Restore kernels
  - 5.15.**94.2**: WSA: **2305**.40000.(4~6).0
  - 5.15.**104.1**: WSA: **2306**.40000.4.0
  - 5.15.**104.2**: WSA: **2307**.40000.6.0
  
  This is because it is still being distributed by MS official.

- Optimize workflow
Unless there is a destructive update, all settings are the same, so
there are many unnecessary descriptions.
Therefore, the next time the device code is changed or the kernel
version is updated to higher than 5.15, the current configuration will
be restored again.
2023-09-22 10:12:42 +08:00
igor
23805d4784 update translation from website (#974) 2023-09-22 10:11:10 +08:00
github-actions[bot]
01bf24fa7b [add device]: Moto g9 play (#969)
Moto g9 play has been added to the website.
Related issue: https://github.com/tiann/KernelSU/issues/968

Co-authored-by: GitHub Actions <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: weishu <twsxtd@gmail.com>
2023-09-21 15:23:39 +08:00
Weblate (bot)
47f05a139d Translations update from Hosted Weblate (#960)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[KernelSU/Manager](https://hosted.weblate.org/projects/kernelsu/manager/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/kernelsu/manager/horizontal-auto.svg)

---------

Co-authored-by: Rex_sa <rex.sa@pm.me>
Co-authored-by: Julian Wu <juliancandra666@gmail.com>
Co-authored-by: Ali Beyaz <alipolatbeyaz@gmail.com>
Co-authored-by: weishu tian <twsxtd@gmail.com>
Co-authored-by: dabao1955 <dabao1955@163.com>
Co-authored-by: Igor Sorocean <sorocean.igor@gmail.com>
Co-authored-by: Syuugo <pub@s1204.me>
Co-authored-by: Jakub Skorłutowski <jakub.skorlutowski@gmail.com>
Co-authored-by: ANAND GOPAL YADAV <lsuwtlaq@telegmail.com>
Co-authored-by: I g o r <igormczampola1@gmail.com>
Co-authored-by: Kazuki Nakashima <flukfik41@gmail.com>
Co-authored-by: Justas <justasbaltiejus@gmail.com>
Co-authored-by: Artyom <akulasaur@yandex.ru>
2023-09-21 15:21:06 +08:00
github-actions[bot]
3c0c70ba7f [add device]: Moto g9 power (#971)
Moto g9 power has been added to the website.
Related issue: https://github.com/tiann/KernelSU/issues/970

Co-authored-by: GitHub Actions <41898282+github-actions[bot]@users.noreply.github.com>
2023-09-18 21:23:15 +08:00
igor
c19ba7fab0 Add Brazilian Portuguese language to the website (#965) 2023-09-18 17:22:17 +08:00
Weblate (bot)
1f42bbac5e Translations update from Hosted Weblate (#948)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[KernelSU/Manager](https://hosted.weblate.org/projects/kernelsu/manager/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/kernelsu/manager/horizontal-auto.svg)

---------

Co-authored-by: Rex_sa <rex.sa@pm.me>
Co-authored-by: Julian Wu <juliancandra666@gmail.com>
Co-authored-by: Ali Beyaz <alipolatbeyaz@gmail.com>
Co-authored-by: weishu tian <twsxtd@gmail.com>
Co-authored-by: dabao1955 <dabao1955@163.com>
Co-authored-by: Igor Sorocean <sorocean.igor@gmail.com>
Co-authored-by: Syuugo <pub@s1204.me>
Co-authored-by: Jakub Skorłutowski <jakub.skorlutowski@gmail.com>
2023-09-16 13:12:36 +08:00
Levi Zim
cbb98a1de9 Copy one extra byte from userspace filename (#958)
Otherwise we will rewrite paths for filenames that begins with
`/system/bin/su`.

This fix copies one extra byte from userspace filename so that when we
encounter filenames like `/system/bin/suasf`,
`/system/bin/su\0` gets compared with `/system/bin/sua`, which correctly
prevents the `su -> sh` path rewriting.

Close #957
2023-09-16 12:23:04 +08:00
weishu
08745664a6 manager: fix ascii art text of KernelSU. close #930 2023-09-16 12:22:44 +08:00
weishu
eac6fd0484 manager: show changelog when upgrade manager 2023-09-11 00:44:33 +08:00
Syuugo Mizoguchi
ad1dbf77a1 Move READMEs to docs (#940) 2023-09-11 00:06:35 +08:00
weishu
81bbb31098 manager: show changelog before update module 2023-09-11 00:03:21 +08:00
weishu
52234d040f manager: Fix incorrect version of downloaded module. 2023-09-10 18:16:44 +08:00
Weblate (bot)
1fb2aad893 Translations update from Hosted Weblate (#938)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[KernelSU/Manager](https://hosted.weblate.org/projects/kernelsu/manager/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/kernelsu/manager/horizontal-auto.svg)

Co-authored-by: Skallr2 <pm563838@gmail.com>
2023-09-09 23:40:01 +08:00
weishu
64744bb31d Revert "Fix the directory pathname while moving directories (#816)"
This reverts commit 983ad2c1fd.
2023-09-09 23:38:27 +08:00
Syuugo Mizoguchi
b9747fbe69 Upgrade Gradle (#937)
`8.1.1` -> `8.3`
2023-09-08 15:22:31 +08:00
ZHANtech™
85922946b7 [CI] Update Check Build Kernel (#936) 2023-09-07 23:33:55 +08:00
Syuugo Mizoguchi
40fc6d2163 Bump actions/checkout from 3 to 4 (#935)
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to
4.
- [Release notes](https://github.com/actions/checkout/releases)
-
[Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](actions/checkout@v3...v4)
2023-09-07 21:24:01 +08:00
Weblate (bot)
da662133ae Translations update from Hosted Weblate (#898)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[KernelSU/Manager](https://hosted.weblate.org/projects/kernelsu/manager/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/kernelsu/manager/horizontal-auto.svg)

---------

Co-authored-by: Reza Almanda <rezaalmanda27@gmail.com>
Co-authored-by: I g o r <igormczampola1@gmail.com>
Co-authored-by: Igor Sorocean <sorocean.igor@gmail.com>
Co-authored-by: Skallr2 <pm563838@gmail.com>
Co-authored-by: Szabolcs Hubai <szab.hu@gmail.com>
Co-authored-by: Pegioner <pegioner@yandex.ru>
Co-authored-by: Kazuki Nakashima <flukfik41@gmail.com>
Co-authored-by: Tushar Kumar <tushar8133@gmail.com>
Co-authored-by: Iksan Adi <iksanadisubekti@gmail.com>
Co-authored-by: Eryk Michalak <gnu.ewm@protonmail.com>
Co-authored-by: Kyle Brandon Sioson <siosonkylebrandon@gmail.com>
Co-authored-by: M4RZ3R0 <m4rz3r0.development@gmail.com>
2023-09-07 10:43:40 +08:00
Syuugo Mizoguchi
25592a0614 Fix WSA kernels (#925)
- WSA latest version: `2307.40000.6.0`
  -> Kernel version: `5.15.104.2`

- Next kernel version: `5.15.104.3`
  -> We haven't yet confirmed the release of this kernel.
2023-09-06 00:56:26 +08:00
weishu
2d96aaa28f ksud: don't clean update dir, only ensure it exists 2023-09-02 10:39:40 +08:00
Pa1NarK
64cf6eb8b9 feat(kernel): Add Kernel 5.10.187 (#866)
- Bluejay running GrapheneOS is on Kernel version `5.10.187`.  
- Tried to flash other versions `5.10.xxx` and all went into bootloop.
Unsure how this version would go
2023-09-01 23:30:16 +08:00
weishu
7e44765074 Fix build (#927) 2023-09-01 22:27:25 +08:00
hopez13
d84fdada31 workflow: update build tools branch (#926) 2023-09-01 14:30:12 +08:00
Nguyễn Viết Thắng
71c14d96ab Language Update (#924)
Update Vietnamese language for kernelsu.org and README_VI.md
2023-09-01 14:23:45 +08:00
ZHANtech™
5d988002c7 [CI] Update Android 13 5.15 sublevel and patch level (#921) 2023-09-01 06:49:10 +08:00
Azusachan
15ff9fbf41 [CI] Update Android 12 5.10 sublevel and patch level (#911)
For patch level 2023-07, sublevel is 177
https://android.googlesource.com/kernel/common/+/refs/heads/android12-5.10-2023-07/Makefile

For patch level 2023-09, sublevel is 185
https://android.googlesource.com/kernel/common/+/refs/heads/android12-5.10-2023-09/Makefile

Co-authored-by: weishu <twsxtd@gmail.com>
2023-08-31 22:23:52 +08:00
ISNing
542d3e40af manager: fix dependency version reference (#919)
This typo causes gradle sync failed
2023-08-31 21:39:16 +08:00
github-actions[bot]
7c4fb51b5c [add device]: (#908)
has been added to the website.
Related issue: https://github.com/tiann/KernelSU/issues/907

Co-authored-by: GitHub Actions <41898282+github-actions[bot]@users.noreply.github.com>
2023-08-31 20:46:52 +08:00
dabao1955
5b10d10b82 update repo kernel source link (#917)
https://github.com/GiovanYCringe-Experime/Kernel_m30s HTTP/2 404

https://github.com/Sr-Han/kernel_xiaomi_mojito.git HTTP/2 301 >
https://github.com/Sr-Han/kernel_xiaomi_mojito

https://github.com/SonalSingh18/android_kernel_xiaomi_sm6250.git HTTP/2
301 > https://github.com/SonalSingh18/android_kernel_xiaomi_sm6250

https://github.com/rxuglr/kernel_xiaomi_surya HTTP/2 404

https://github.com/LeviMarvin/kernel_xiaomi_alioth HTTP/2 301 >
https://github.com/LeviMarvin/android_kernel_xiaomi_alioth


https://github.com/Vincent4440/android_kernel_xiaomi_sm8250/tree/thirteen
HTTP/2 404 > https://github.com/Vincent4440/android_kernel_xiaomi_sm8250
2023-08-31 20:45:22 +08:00
Ali Beyaz
677d3357b9 Fixed "Discussion" titles on several languages (#900) 2023-08-28 01:15:02 +08:00
weishu
5e893e3d04 kernel: avoding select OVERLAY_FS becuase it may break GKI checks. fix 2023-08-28 01:06:44 +08:00
Fakhri
685cd75c99 Add Indonesian translation for README (#893) 2023-08-23 14:18:30 +08:00
github-actions[bot]
8354204c32 [add device]: (#895)
has been added to the website.
Related issue: https://github.com/tiann/KernelSU/issues/894

Co-authored-by: GitHub Actions <41898282+github-actions[bot]@users.noreply.github.com>
2023-08-23 14:17:48 +08:00
Weblate (bot)
d394fd2e01 Translations update from Hosted Weblate (#876)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[KernelSU/Manager](https://hosted.weblate.org/projects/kernelsu/manager/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/kernelsu/manager/horizontal-auto.svg)

---------

Co-authored-by: Re*Index. (ot_inc) <ot02092000@gmail.com>
Co-authored-by: AndroPlus <hosigumayuugi@gmail.com>
Co-authored-by: Nauru Toru <nyakori02@gmail.com>
Co-authored-by: Albert Castron <albertcastron65@gmail.com>
Co-authored-by: Issa1553 <fairfull.playing@gmail.com>
Co-authored-by: I g o r <igormczampola1@gmail.com>
Co-authored-by: Karl Schrader <pokemetti@gmail.com>
Co-authored-by: Francesco <ciccioinc@gmail.com>
Co-authored-by: Skallr2 <pm563838@gmail.com>
2023-08-20 23:43:49 +08:00
weishu
71799c7aed ksud: Fix module not showing when there is a module don't declare id in module.prop. fix #890 2023-08-20 23:35:09 +08:00
archandanime
76bdd12f73 Add Vietnamese translation for README (#884) 2023-08-19 10:12:46 +08:00
weishu
fb103472c6 Update custom.yml 2023-08-18 20:03:52 +08:00
weishu
9f17bafbf0 Update custom.yml 2023-08-18 20:03:16 +08:00
weishu
b2f9f3ade9 Update custom.yml 2023-08-18 20:01:42 +08:00
weishu
12a095fd1a Revert "ksud: Shrink image after module is updated. fix #855"
This reverts commit 7153336ad1.
2023-08-18 12:33:38 +08:00
weishu
7153336ad1 ksud: Shrink image after module is updated. fix #855 2023-08-17 23:57:51 +08:00
weishu
5f2566e478 ksud: No need to force e2fsck, fix #858,#879 2023-08-17 23:18:42 +08:00
weishu
0af25af1be ksud: exposed the command stdout/stderr to log 2023-08-17 22:05:49 +08:00
Weblate (bot)
ea3b397f34 Translations update from Hosted Weblate (#871)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[KernelSU/Manager](https://hosted.weblate.org/projects/kernelsu/manager/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/kernelsu/manager/horizontal-auto.svg)

---------

Co-authored-by: Re*Index. (ot_inc) <ot02092000@gmail.com>
Co-authored-by: AndroPlus <hosigumayuugi@gmail.com>
Co-authored-by: Nauru Toru <nyakori02@gmail.com>
2023-08-16 18:24:32 +08:00
rhjdvsgsgks
6aeb76a3ef kernel: fix build for gcc (#873)
current_cred() need this
2023-08-16 17:55:23 +08:00
Ylarod
ae9519de42 ksud: add post_mount stage (#864) 2023-08-16 11:39:32 +08:00
Weblate (bot)
8bf33e9aca Translations update from Hosted Weblate (#870)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[KernelSU/Manager](https://hosted.weblate.org/projects/kernelsu/manager/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/kernelsu/manager/horizontal-auto.svg)

Co-authored-by: Re*Index. (ot_inc) <ot02092000@gmail.com>
2023-08-16 09:18:46 +08:00
Syuugo Mizoguchi
b91a294138 Add WSA Kernel 5.15.104.2 (#827)
Remove `5.15.94.4` as soon as WSA 2306 is removed from the release.
2023-08-14 20:15:01 +08:00
YuSaki丶Kanade
d274a315b1 Added kernel 5.15.119 (#865) 2023-08-14 20:14:23 +08:00
Weblate (bot)
b0c3c3a9a2 Translations update from Hosted Weblate (#860) 2023-08-13 23:42:21 +08:00
diphons
1147eb205d [add device]: Xiaomi Poco F5 (Marble) - MI11T | Pro (Vili) (#857) 2023-08-12 14:27:33 +08:00
Wahid Khan
f160abf9ce [add device] Begonia and Marble (#856) 2023-08-11 12:57:55 +08:00
github-actions[bot]
61ad99dbe5 [add device]: Redmi Note 12 Pro / Pro+ For MIUI 14 (#848)
Redmi Note 12 Pro / Pro+ For MIUI 14 has been added to the website.
Related issue: https://github.com/tiann/KernelSU/issues/847

Co-authored-by: GitHub Actions <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: weishu <twsxtd@gmail.com>
2023-08-10 11:22:49 +08:00
github-actions[bot]
9a126645e8 [add device]: (#850)
has been added to the website.
Related issue: https://github.com/tiann/KernelSU/issues/849

Co-authored-by: GitHub Actions <41898282+github-actions[bot]@users.noreply.github.com>
2023-08-10 11:20:48 +08:00
Tejas Singh
21f39f6de8 Add Xiaomi Redmi Note 8/8T (#844)
Signed-off-by: tejas101k <tejassingh649@rediffmail.com>
2023-08-10 09:29:53 +08:00
weishu
0ddb8a4c89 ci: Maximize build space 2023-08-09 23:05:41 +08:00
Lakshay Choudhary
c9997b5ca9 Readme.md and Template changes for better readability (#842)
Files Changed:
README.md
add_device.yaml
Update bug_report.md

clarity, spelling, grammar and consistency changes.

open to suggestions.
2023-08-09 22:48:51 +08:00
Aquarius223
0b1bab5b01 kernel: Fix commit 7bdb8858 in Linux 4.9.y and Linux 4.4.y builds (#841)
* linux/uaccess.h is also required on 4.4 and 4.9

-- KernelSU version: 11184
-- KernelSU Manager signature size: 0x033b
-- KernelSU Manager signature hash: 0xb0b91415
  CC      drivers/kernelsu/kernel_compat.o
../drivers/kernelsu/kernel_compat.c:159:9: error: use of undeclared
identifier 'USER_DS'
        set_fs(USER_DS);
               ^
1 error generated.
make[4]: ***
[../scripts/Makefile.build:314:drivers/kernelsu/kernel_compat.o] 错误 1
make[3]: *** [../scripts/Makefile.build:599:drivers/kernelsu] 错误 2

Change-Id: I19598c62a3ae901049ea99ef878fa5c1a15201fd

Co-authored-by: stic-server-open <1138705738@qq.com>
2023-08-09 22:17:56 +08:00
weishu
676590be15 ci: Keep .repo becuase it contains all repo's .git 2023-08-09 22:07:14 +08:00
weishu
b52bf53d01 kernel: Fix compile err 2023-08-09 18:51:03 +08:00
weishu
7bdb885816 kernel: fix probe_kernel_read failed to read user addr 2023-08-09 18:37:30 +08:00
weishu
cde3e95180 kernel: Fix manager recognize err 2023-08-09 16:28:22 +08:00
Weblate (bot)
7ecb4b03ee Translations update from Hosted Weblate (#832)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[KernelSU/Manager](https://hosted.weblate.org/projects/kernelsu/manager/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widgets/kernelsu/-/manager/horizontal-auto.svg)

---------

Co-authored-by: weishu tian <twsxtd@gmail.com>
Co-authored-by: Rex_sa <rex.sa@pm.me>
Co-authored-by: cachiusa <nhat.dogpro@outlook.com>
Co-authored-by: dabao1955 <dabao1955@163.com>
2023-08-09 15:00:16 +08:00
weishu
e8a90aadb2 ci: Fix No space left on device (#833)
For android13 gki kernels, Google puts lots of unused file to kernel
source tree, while the Github Action only has 14G disk size and the ci
may fail because of "No space left on device". 

The `repo` tool will try pull all the refs and tags with depth=INT_MAX if it found the SHA1 hash doesn't exist on remote server even if you force it to fetch with `depth=1` and `--no-tags`. So we use the version `v2.16` which doesn't check it.

And also, using a fixed repo version can avoid randomly failure of building.
2023-08-09 13:32:48 +08:00
weishu
beaa048be3 kernel: don't trigger page fault when become manager. fix #836 2023-08-09 12:33:05 +08:00
Akari
936b650f12 update README_PT-BR.md (#835) 2023-08-09 11:16:56 +08:00
weishu
747c91d5c8 manager: remove require_kernel_version for re-translation. 2023-08-08 11:25:53 +08:00
Aquarius223
5023d0ab1d manager: Corrected "Kernel version" and "KernelSU version" string (#825)
* Avoid misunderstanding "The current kernel version %d is too low" Many
people misunderstand that the version of the Linux kernel is too low, so
the version of KernelSU is low and they go looking for a kernel with an
upgraded version of the Linux kernel.

 Correct the string of require_kernel_version to avoid misunderstanding,
 Now let them look for the updated KernelSU version of the kernel.

(cherry picked from commit dcc4ad10f81b1531b551b2b44a3b9cbdc0e489e9)
Change-Id: I4373b006d45ed98e02effa4556e8a9e8c0b70f14

Co-authored-by: admin <paper@localhost>
2023-08-08 11:21:40 +08:00
Weblate (bot)
5b638c876e Translations update from Hosted Weblate (#829)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[KernelSU/Manager](https://hosted.weblate.org/projects/kernelsu/manager/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widgets/kernelsu/-/manager/horizontal-auto.svg)

---------

Co-authored-by: Pierre GRASSER <piorrro33@outlook.com>
Co-authored-by: Kazuki Nakashima <flukfik41@gmail.com>
2023-08-08 10:32:34 +08:00
weishu
d6a7231fae manager: module description and name is optional. 2023-08-03 23:15:21 +08:00
weishu
06681a2490 ksud: restore selinux context for unlabeled module files on boot. fix #817 2023-08-03 12:00:28 +08:00
weishu
278cbef3ec ksud: don't follow link when restore file context 2023-08-03 12:00:28 +08:00
The_second_Tom
a83390b0ec Kernel: fix filp_open in kernel below 4.9 (#822)
Use current_cred()->session_keyring to check whether session_keyring
installed or not. close #814
2023-08-01 20:51:32 +08:00
weishu
907bcad1a7 kernel: use ordered work queue to avoid timing issues 2023-08-01 20:47:43 +08:00
Weblate (bot)
4c0a36785b Translations update from Hosted Weblate (#805)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[KernelSU/Manager](https://hosted.weblate.org/projects/kernelsu/manager/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widgets/kernelsu/-/manager/horizontal-auto.svg)

---------

Co-authored-by: Ali Beyaz <alipolatbeyaz@gmail.com>
Co-authored-by: dabao1955 <dabao1955@163.com>
Co-authored-by: Tian xiang <minepzh@outlook.com>
2023-08-01 17:02:43 +08:00
AzukiAtsui
983ad2c1fd Fix the directory pathname while moving directories (#816)
Fix the duplicate directory name error that occurs when the destination
directory already exists while moving folders.
2023-08-01 13:40:56 +08:00
hopez13
a3590b767e Docs: Fixed Word Repetition (#818) 2023-08-01 10:06:56 +08:00
DawfukFR
12e00dc717 [add device]: Oneplus8/8T/8P/9R (opkona) (#819)
Custom kernel for Oneplus SM8250 devices with support of KernelSU (using
the command : curl -LSs
"https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh"
| bash -)

Precompiled kernel can be found here : 
https://t.me/StellarisRelease (stable)
https://t.me/DawfukSpace (testing)

I have tested the KernelSU feature on this kernel, everything works
fine.
Current version used : 11165
KernelSU Manager signature size: 0x033b
KernelSU Manager signature hash: 0xb0b91415
2023-08-01 10:06:26 +08:00
weishu
e00a355fa8 website: Add docs for boot-completed stage 2023-07-31 19:58:45 +08:00
weishu
e95c5a9675 ksud: support common & module boot-completed.sh 2023-07-31 19:50:53 +08:00
weishu
d0b8144b96 manager: refresh module screen if it comes from install screen. fix #758 2023-07-31 16:15:42 +08:00
weishu
d16d3f87a6 manager: block vol up & down for module installation. fix #815 2023-07-31 15:27:53 +08:00
weishu
76decba8d9 manager: auto scroll for module installation. #815 2023-07-31 15:06:00 +08:00
dabao1955
d75678fca0 Update Custom issue temple (#811) 2023-07-28 22:27:52 +08:00
TinyHai
abe1fa471d manager: fix alignment and padding of some text in ModuleScreen (#812) 2023-07-28 22:27:03 +08:00
weishu
07a430aa5b ksud: re-enable lto 2023-07-28 22:23:03 +08:00
weishu
df9cf61575 ksud: fix su args parse error. close #736 2023-07-28 22:21:12 +08:00
TinyHai
bfe8c2eecd manager: a small fix to WarningCard (#809) 2023-07-28 17:34:57 +08:00
TinyHai
b732765811 manager: fix the text 'No module installed' is not centered (#803) 2023-07-25 18:47:09 +08:00
Weblate (bot)
a966252fa5 Translations update from Hosted Weblate (#783)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[KernelSU/Manager](https://hosted.weblate.org/projects/kernelsu/manager/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widgets/kernelsu/-/manager/horizontal-auto.svg)

---------

Co-authored-by: dabao1955 <dabao1955@163.com>
Co-authored-by: $D&fX!a&#YA6ZbJkZN$3 <mariusnnnn@gmail.com>
Co-authored-by: ia. Shovon <tecifac284@kameili.com>
Co-authored-by: Ruben Guerra <rubenguerrasr5870@gmail.com>
Co-authored-by: Fiqri Ardyansyah <fiqri0927936@gmail.com>
Co-authored-by: Kazuki Nakashima <flukfik41@gmail.com>
Co-authored-by: TheNoFace <fprhqkrtk303@naver.com>
Co-authored-by: Ali Beyaz <alipolatbeyaz@gmail.com>
Co-authored-by: Kirill Azimov <azimxv@yandex.ru>
2023-07-25 09:21:43 +08:00
weishu
3664003260 ksud: fix common post-fs-data.d may not execute if no modules are enabled 2023-07-24 13:39:51 +08:00
Flame
978178afc0 [add device]: POCO F3/Redmi K40/Mi 11X (alioth) (#799)
This pull request includes a modified LineageOS kernel with the
implementation of KernelSU for POCO F3/Redmi K40/Mi 11X (alioth), adding
them to the list of unofficially supported devices.
2023-07-23 10:44:30 +08:00
Asriadi Rahim
16f6f30eae Again add unofficial support Google Pixel 2/2XL (#797)
* i dont have any clue what i am doing...sory tian sur...hhh

Signed-off-by: Asriadi Rahim <asriadirahim03@gmail.com>
2023-07-22 00:22:11 +08:00
Akari
63851f8c88 Update README_PT-BR.md (#793)
Added information that was updated from
[README.md](https://github.com/tiann/KernelSU/blob/main/README.md) to
Brazilian Portuguese. some of this information:
- fixed some lines
- added information about Translate
- added information about the App Profile
2023-07-21 15:54:14 +08:00
Giovany
34c6765752 Support m30s (#791)
add , missing
2023-07-21 15:53:01 +08:00
Giovany
c23d1bcf58 Support Galaxy a50 (#790) 2023-07-21 10:08:23 +08:00
weishu
6ae7e1624f Merge pull request #788 from Sanju0910/patch-1
avicii: Update repository link
2023-07-21 00:10:07 +08:00
Sreeshankar K
ba4b014a99 Merge branch 'main' into patch-1 2023-07-20 19:42:16 +05:30
weishu
f192638943 Merge pull request #785 from dabao1955/main
README:Update Readme for Japanese Language
2023-07-20 22:05:23 +08:00
Sreeshankar K
0323ee7958 avicii: Update repository link 2023-07-20 19:34:30 +05:30
dabao1955
021ef521cb Update README_JP.md 2023-07-19 21:29:04 +08:00
dabao1955
34086cd445 Update README_JP.md 2023-07-19 21:26:26 +08:00
dabao1955
c306eddee8 Update README_JP.md 2023-07-19 21:21:07 +08:00
dabao1955
c72f7d750e Update README_JP.md 2023-07-19 21:19:37 +08:00
weishu
f9a91848ad Merge pull request #774 from tiann/translation
Translations update from Hosted Weblate
2023-07-19 09:40:08 +08:00
Mantas
cd8013a616 Translated using Weblate (Lithuanian)
Currently translated at 100.0% (81 of 81 strings)

Translation: KernelSU/Manager
Translate-URL: https://hosted.weblate.org/projects/kernelsu/manager/lt/
2023-07-18 15:30:09 +02:00
Rəşad Qasımlı
dc536d652a Translated using Weblate (Azerbaijani)
Currently translated at 100.0% (81 of 81 strings)

Translation: KernelSU/Manager
Translate-URL: https://hosted.weblate.org/projects/kernelsu/manager/az/
2023-07-18 15:30:08 +02:00
cachiusa
3114f6d7f6 Translated using Weblate (Vietnamese)
Currently translated at 100.0% (81 of 81 strings)

Translation: KernelSU/Manager
Translate-URL: https://hosted.weblate.org/projects/kernelsu/manager/vi/
2023-07-18 13:18:01 +02:00
Hosted Weblate
e2f5015107 Merge remote-tracking branch 'origin/main' 2023-07-18 11:46:39 +02:00
Ali Beyaz
884dd606eb Update README_TR.md (#779) 2023-07-18 17:46:33 +08:00
Hosted Weblate
8d246a6b9d Merge remote-tracking branch 'origin/main' 2023-07-18 10:08:32 +02:00
ia. Shovon
2ee3d55c88 Translated using Weblate (Bengali (Bangladesh))
Currently translated at 50.6% (41 of 81 strings)

Translation: KernelSU/Manager
Translate-URL: https://hosted.weblate.org/projects/kernelsu/manager/bn_BD/
2023-07-18 10:08:32 +02:00
dabao1955
55b540bf4c repos.json:Update repo info (#778)
Some changes to repos.json:
- Redirect android_kernel_xiaomi_surya to kernel_xiaomi_surya: Because
the original warehouse has changed android_kernel_xiaomi_surya to
kernel_xiaomi_surya, this time the original address is 404
- Removed kernel repository information maintained by AkariOficial #754
2023-07-18 16:08:26 +08:00
Hosted Weblate
c0d147dcad Merge remote-tracking branch 'origin/main' 2023-07-18 06:38:50 +02:00
セリカ・シルフィル
be413fd147 CI: Support set manager signature size and hash (#757)
close #739, close #745, close #752
2023-07-18 12:38:44 +08:00
weishu tian
786f3d6441 Added translation using Weblate (Bengali (Bangladesh)) 2023-07-18 06:34:32 +02:00
Hosted Weblate
8f50b5f6e5 Merge remote-tracking branch 'origin/main' 2023-07-18 04:16:19 +02:00
セリカ・シルフィル
90639fad6c Translated using Weblate (Russian)
Currently translated at 100.0% (81 of 81 strings)

Translation: KernelSU/Manager
Translate-URL: https://hosted.weblate.org/projects/kernelsu/manager/ru/
2023-07-18 04:16:19 +02:00
セリカ・シルフィル
2979434e2a Translated using Weblate (Indonesian)
Currently translated at 100.0% (81 of 81 strings)

Translation: KernelSU/Manager
Translate-URL: https://hosted.weblate.org/projects/kernelsu/manager/id/
2023-07-18 04:16:18 +02:00
weishu
56d145666c ksud: fix path env, close #775 2023-07-18 10:02:06 +08:00
weishu
db5f77aa96 docs: Update README 2023-07-18 09:45:42 +08:00
weishu
5fbce8ef07 docs: Add weblate to README 2023-07-18 09:39:37 +08:00
Hosted Weblate
4cc3644416 Merge remote-tracking branch 'origin/main' 2023-07-18 03:29:36 +02:00
Jen Kung-chih
01a7678a26 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (81 of 81 strings)

Translation: KernelSU/Manager
Translate-URL: https://hosted.weblate.org/projects/kernelsu/manager/zh_Hant/
2023-07-18 03:29:35 +02:00
Jen Kung-chih
95d22d2bb4 Translated using Weblate (Chinese (Traditional, Hong Kong))
Currently translated at 100.0% (81 of 81 strings)

Translation: KernelSU/Manager
Translate-URL: https://hosted.weblate.org/projects/kernelsu/manager/zh_Hant_HK/
2023-07-18 03:29:35 +02:00
Sreeshankar K
3efb2be456 avicii: Define Kernel Name & Update repository link (#777) 2023-07-18 09:29:28 +08:00
Rəşad Qasımlı
3b7ca2d7e8 Translated using Weblate (Azerbaijani)
Currently translated at 100.0% (81 of 81 strings)

Translation: KernelSU/Manager
Translate-URL: https://hosted.weblate.org/projects/kernelsu/manager/az/
2023-07-17 21:37:33 +02:00
cachiusa
7b45bc5aad Translated using Weblate (Vietnamese)
Currently translated at 100.0% (81 of 81 strings)

Translation: KernelSU/Manager
Translate-URL: https://hosted.weblate.org/projects/kernelsu/manager/vi/
2023-07-17 14:32:11 +02:00
ekotin
ed1e892600 Translated using Weblate (Turkish)
Currently translated at 98.7% (80 of 81 strings)

Translation: KernelSU/Manager
Translate-URL: https://hosted.weblate.org/projects/kernelsu/manager/tr/
2023-07-17 14:32:10 +02:00
Igor Sorocean
f188802044 Translated using Weblate (Romanian)
Currently translated at 100.0% (81 of 81 strings)

Translation: KernelSU/Manager
Translate-URL: https://hosted.weblate.org/projects/kernelsu/manager/ro/
2023-07-17 12:21:02 +02:00
Tian xiang
965c23867f Translated using Weblate (Japanese)
Currently translated at 86.4% (70 of 81 strings)

Translation: KernelSU/Manager
Translate-URL: https://hosted.weblate.org/projects/kernelsu/manager/ja/
2023-07-17 08:43:35 +02:00
Weblate (bot)
b271b2f587 Translations update from Hosted Weblate (#772)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[KernelSU/Manager](https://hosted.weblate.org/projects/kernelsu/manager/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widgets/kernelsu/-/manager/horizontal-auto.svg)

---------

Co-authored-by: Navin Holkar <fakeuser1693@gmail.com>
Co-authored-by: Cabrito <zrenzo81@gmail.com>
Co-authored-by: Fiqri Ardyansyah <fiqri0927936@gmail.com>
Co-authored-by: Yuttapong Paengsai <nuppyy400@gmail.com>
Co-authored-by: Rəşad Qasımlı <rashadgasimly2005@gmail.com>
Co-authored-by: Kazuki Nakashima <flukfik41@gmail.com>
Co-authored-by: Marvin Grasberger <marvingrasberger14@gmail.com>
Co-authored-by: Mantas <mantukasjolanta@gmail.com>
Co-authored-by: Sergio <sergta@live.com>
Co-authored-by: Melo Longo <melolongo87@gmail.com>
Co-authored-by: Igor Sorocean <sorocean.igor@gmail.com>
Co-authored-by: cachiusa <nhat.dogpro@outlook.com>
Co-authored-by: CakesTwix <cakestwix1@gmail.com>
Co-authored-by: SchweGELBin <abramjannikmichael06@gmail.com>
2023-07-17 08:57:39 +08:00
Weblate (bot)
0953f50e0c Translations update from Hosted Weblate (#771)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[KernelSU/Manager](https://hosted.weblate.org/projects/kernelsu/manager/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widgets/kernelsu/-/manager/horizontal-auto.svg)

---------

Co-authored-by: Karl Schrader <pokemetti@gmail.com>
Co-authored-by: weishu tian <twsxtd@gmail.com>
Co-authored-by: tcheral <lcockx@protonmail.com>
Co-authored-by: Тимур Муллаяров (Timur_23_1337) <mullaiarov2002@gmail.com>
2023-07-16 23:46:31 +08:00
Kirill
77ac974ce8 website: updated index.ts, ru_RU.ts, as well as some links (#763)
On the web page there is no link to the translation itself, I
familiarized myself with vitepress and edited the necessary configs
2023-07-13 20:59:38 +08:00
セリカ・シルフィル
d714ab0c5d CI: Add ARCVM release build (#762) 2023-07-13 20:58:45 +08:00
weishu
38eb93d5ca website: fix deploy 2023-07-13 20:11:37 +08:00
Kirill
080d5bd9e8 Translation of instructions into Russian (#761)
This project is quite extensive, decided to translate it into Russian
(further adjustments may be required)
2023-07-13 19:26:15 +08:00
weishu
d05ec41379 manager: show loading dialog when uninstall/enable/disable module. 2023-07-12 13:00:40 +08:00
weishu
d07956ead6 ksud: fix prune module 2023-07-11 22:00:50 +08:00
weishu
4e3af6dab3 ksud: refactor module iteration 2023-07-11 21:45:45 +08:00
weishu
45d96b98c5 ksud: remove update flag file before mount. if module installation is failed, the module.img will be reverted and the update flag file may exist 2023-07-11 21:28:56 +08:00
weishu
b554c66b46 ksud: uninstall module at next boot. close #740 2023-07-11 21:25:51 +08:00
Muhammed Ali
fb87d0f0f5 Support Xiaomi Redmi Note 8 and 8T (#750)
Updated

Signed-off-by: Muhammed Ali Simsek <malisimsek17@gmail.com>
2023-07-11 21:08:16 +08:00
weishu
37abe48702 manager: save stderr of installation to log file. fix #723 2023-07-11 20:10:12 +08:00
weishu
ec9babea76 ksud: Specify the block size of the ext4 image as 1K, because our subsequent size calculations are based on this; some phones such as the Samsung S23, if no default value is specified, will cause unexpected errors. close #721 2023-07-11 18:30:33 +08:00
Zackptg5
8a464ac7b2 Add boot script directory vars (#747)
Add back variable names for post-fs-data.d and service.d directories

Co-authored-by: weishu <twsxtd@gmail.com>
2023-07-11 12:39:56 +08:00
weishu
eb5a99e4b6 ci: fix rustfmt failed (#748) 2023-07-11 12:23:56 +08:00
weishu
047312e0e5 ci: fix rustfmt failed duplicated toml 2023-07-11 12:12:53 +08:00
weishu
45a25eda50 ci: fix rustfmt failed typo 2023-07-11 12:00:42 +08:00
weishu
120c2f43de ci: fix rustfmt failed 2023-07-11 11:59:58 +08:00
Gustavo Mendes
9deb820923 Update Portuguese brazilian translation (#741)
Signed-off-by: Gustavo Mendes <gusttavo.me@outlook.com>
2023-07-10 08:49:36 +08:00
Amicia De Rune
ae21d4c9fd manager: update translation Indonesian (#734)
Signed-off-by: RooGhz720 <rooghz720@gmail.com>
2023-07-09 17:02:00 +08:00
shìwēi nguyen
5381ceabae ksud: symlink by relative path when handle partitions (#737)
This allows the Magisk design-compliant module boot script to access
`$MODDIR/system/$part` while the mounted overlay still points to
`/$part`
Fix https://github.com/tiann/KernelSU/issues/726
2023-07-09 17:01:00 +08:00
Syuugo
5d07e1d392 Add WSA Kernel 5.15.104.1 (#704)
- Add `5.15.104.1`
- Delete `5.15.78.1`
2023-07-08 12:20:27 +08:00
weishu
d78f24098a Revert "manager: don't remember state when process died." close #728
This reverts commit 12761ee167.
2023-07-08 01:22:21 +08:00
dabao1955
cd952f5e45 kernel/ksu.c:Fix word mistakes when enabling CONFIG_KSU_DEBUG (#724)
According to the instructions in Kconfig, when the `CONFIG_KSU_DEBUG`
option is turned on, KernelSU will run in `debug mode` instead of the
`debug version` mentioned in kernel/ksu.c.
2023-07-08 01:22:06 +08:00
awakened
156b17f69d Support Samsung S10/N10 and Oneplus 9/9Pro (#725)
Co-authored-by: Phạm Tiên Sinh <song.long.dai.duong@gmail.com>
2023-07-06 13:25:28 +08:00
4qwerty7
f4d2b0feab Distinguish different PT_REGS_PARM4 under x86 (#711)
1. `PT_REGS_CCALL_PARM4` 表示存放C调用约定的第4个参数的寄存器
2. `PT_REGS_SYSCALL_PARM4` 表示存放linux syscall调用约定的第4个参数的寄存器
3. 将原有 `PT_REGS_PARM4` 改为上述之一
4. 将原有 `ksu_handle_execveat_ksud` 和 `ksu_handle_execveat_sucompat` 可能被
kprobe 传递错误实参、且不使用的形参标记为 never_used 并传递 `NULL`
5. 为 `ksu_handle_execveat_ksud` 提供正确的 argv 参数用以在 x86 下也能正确识别 `init
second_stage`

---------

Co-authored-by: weishu <twsxtd@gmail.com>
2023-07-06 09:01:35 +08:00
th1nhhdk
2c0a9cd64c repos.json: Updated repo link for Sony Xperia 1 II & Sony Xperia 5 II (#722)
The old one is outdated and unmaintained
2023-07-05 21:00:49 +08:00
Howard Wu
134507b928 ci: Fix checkout branch (#720)
Don't set ref branch for properly check PR
2023-07-05 08:03:27 +08:00
Howard Wu
2b42d14ef8 ci: Fix WSA build output path (#717) 2023-07-04 12:41:14 +08:00
Jakub Skorłutowski
e6071b5247 Add Polish language (#716) 2023-07-04 12:37:06 +08:00
dabao1955
f288cfccae update featrue_request issue temple (#715)
Compared with markdown, yaml may be more focused on the required
information, and will not easily destroy the content in the template.
And I think the "feature request" might not require users to upload
their logs.

It looks like this:


![Screenshot_2023-07-03-22-53-28-88_a252b927494330cdc2c8ba3b3f952e5e](https://github.com/tiann/KernelSU/assets/79307765/ef15e532-2d69-4dea-ba7a-326b7fa2e0ef)

Co-authored-by: dabao1955 <195328750@qq.com>
2023-07-03 23:05:19 +08:00
naxitoo
1cc9da5efe Update Spanish translations + Spanish README (#710) 2023-07-03 09:52:17 +08:00
longhuan1999
0aee64f339 Update app-profile.md and strings.xml (#712)
1. website: Correcting several errors in docs of App Profile
2. manager: Remove the 'app name' field except for the default
strings.xml file
2023-07-03 09:51:54 +08:00
Ali Beyaz
cbbdc665c8 Changed some Turkish translations (#707) 2023-07-02 19:42:58 +08:00
weishu
1b2635784f website: Add docs for App Profile 2023-07-02 19:07:09 +08:00
weishu
ee5d2f8c84 kernel: fix compile err in old kernel 2023-07-02 19:06:31 +08:00
weishu
dfc2a86e70 kernel: fix compile err and format code. close #706 2023-07-02 14:51:14 +08:00
4qwerty7
c0066b68f5 kernel: support the case that init_task.mnt_ns != zygote.mnt_ns(WSA) (#698)
Basic support for the case that init_task.mnt_ns != zygote.mnt_ns(WSA),
just copy nsproxy and fs pointers for solve #276.

Note the copy in `apk_sign.c` is not required but suggested for
secure(ensure the checked mnt_ns is what ns android running, not created
by user, although many distributions does not have user ns.).

Tested with latest release on Win10 19045.3086(with WSAPatch).

Further review required for:
- [x] Security of this operation (without locking).
- [x] The impact of these modifications on other Android distributions.
2023-07-02 00:20:01 +08:00
Ali Beyaz
6ef5e4ef76 Update Turkish strings.xml (#703) 2023-07-01 21:22:50 +08:00
weishu
e3e77fde78 kernel: authorize the newly type for all roles. refer: http://aospxref.com/kernel-android12-5.10-lts/xref/security/selinux/ss/policydb.c#950 2023-07-01 20:54:13 +08:00
weishu
8ea55c7f2f manager: bump minimal kernel version 2023-07-01 20:46:20 +08:00
raystef66
d2a976b3cc Update Flemish/Dutch translation (#702) 2023-07-01 20:14:51 +08:00
weishu
d675662862 kernel: add some log 2023-07-01 19:35:28 +08:00
weishu
839b318785 ksud: don't create dir when read 2023-07-01 19:01:09 +08:00
weishu
971f59c11e ksud: fix fmt 2023-07-01 18:59:41 +08:00
weishu
ab58808b64 ksud: fix compile err 2023-07-01 18:55:01 +08:00
weishu
9cbb7cb10e ksud: apply selinux rule when profile is set 2023-07-01 18:46:21 +08:00
weishu
70f2df11d1 manager: support setting selinux rules profile 2023-07-01 18:44:56 +08:00
weishu
827a2f2901 ksud: don't apply rule when check grammer 2023-07-01 17:43:40 +08:00
weishu
a9c33f6940 ksud: load profile sepolicy rules when boot 2023-07-01 16:50:10 +08:00
weishu
2bb73a2a92 ksud: support root profile's sepolicy 2023-07-01 16:34:43 +08:00
weishu
90407986be ksud: remove unused command 2023-07-01 15:31:53 +08:00
weishu
b85ece440b manager: show context menu on touch position 2023-07-01 12:13:30 +08:00
weishu
a10d2651c1 manager: Add context menu for app profile 2023-07-01 12:13:30 +08:00
SirRGB
b308a368d3 misc grammar and typo fixes (#699) 2023-06-30 23:54:15 +08:00
weishu
e6fea652de manager: only check update for enabled module 2023-06-30 23:49:11 +08:00
Aquarius223
0856b718de kernel: Modify KERNEL_SU_VERSION logic and behavior (#696)
This patch modifies the following:
- Move the version addition logic in ksu.h to Makefile processing
- Print the current version number of KernelSU during make build

build test (normal):
 buildlog:
HOSTCC scripts/basic/bin2c Using .. as source for kernel -- KernelSU
version: 11055
  CHK     include/generated/utsrelease.h
  UPD     include/generated/utsrelease.h

 KernelSU software:
  KernelSU Working Version: 11055 (v) Superusers: 0 Modules: 0


![11055](https://github.com/tiann/KernelSU/assets/47409494/10506289-04d2-41c0-bd48-bad9f0dbdec5)

build test (missing .git file):
 buildlog:
HOSTCC scripts/basic/bin2c Using .. as source for kernel
../drivers/kernelsu/Makefile:23: "KSU_GIT_VERSION not defined! It is
better to make KernelSU a git submodule!"
  CHK     include/generated/utsrelease.h
  CHK     scripts/mod/devicetable-offsets.h

 KernelSU software:
  KernelSU Working Version: 16 (v) Superusers: 0 Modules: 0

The current kernel version 16 is too low for the manager to function
properly. Please upgrade to version 10977 or higher!


![16](https://github.com/tiann/KernelSU/assets/47409494/9ea877a7-7b91-4a27-b6ab-58ce6e1b386f)

(cherry picked from commit 0c38a1614a77d80de752aba20908e3f9d21660a8)
Change-Id: I570f2ee33db224e1a36770f847137f290ba9bcfd

Co-authored-by: stic-server-open <1138705738@qq.com>
2023-06-28 21:45:36 +08:00
Zillion
6f1ccc5b3c Remove fontFamily from the Unsupported Warning (#694)
Just a small design fix, to make the Unsupported Warning text have the
same font as the Working text.

## Before

![before](https://github.com/tiann/KernelSU/assets/77107077/7e3f2382-446a-4039-8bec-d72c7e4471b3)

## After

![after](https://github.com/tiann/KernelSU/assets/77107077/31905aa3-a274-4289-b51b-0c45bbeee90e)
2023-06-27 21:17:48 +08:00
weishu
da959b4e17 kernel: fix compile err on lower kernel 2023-06-27 20:46:09 +08:00
likkai
0bfd6d9e30 Add device (lisa) (#691)
Co-authored-by: weishu <twsxtd@gmail.com>
2023-06-27 10:55:05 +08:00
weishu
980f1d09bc kernel: allow kernel to mount loop devices. close #514 2023-06-26 19:29:29 +08:00
weishu
b644c124e3 kernel: copy filename ourself instead of getname 2023-06-26 19:28:40 +08:00
weishu
65005131bd Create FUNDING.yml 2023-06-26 18:53:27 +08:00
syntaxticsugr
18aa7f2a17 Fixed Banner Art (#687)
Minor change (added spaces) to fix KSU Banner Art.
2023-06-26 18:22:56 +08:00
Zillion
cd5bc2efa9 Add Spanish Translation (#689) 2023-06-26 10:45:24 +08:00
Pegioner
477361f119 Update Russian translation (#681) 2023-06-24 20:17:51 +08:00
Gustavo Mendes
d3632e4b3b Update Portuguese brazilian translation (#682)
Signed-off-by: Gustavo Mendes <gusttavo.me@outlook.com>
2023-06-24 20:17:15 +08:00
SoDebug
0c2f90123b repos.json: Update the link of the KernelSU kernel release repo of the device I maintain (#686)
Update the link of the KernelSU kernel release repo of the device I
maintain
2023-06-24 20:16:25 +08:00
Howard Wu
09d90e1a0a ci: update gki version (#679)
Fix the version name of android13-5.15.74
Add android12-5.10.117
2023-06-23 17:48:18 +08:00
Trịnh Văn Lợi
4fe167c361 Update Vietnamese strings (#678) 2023-06-23 17:30:04 +08:00
294 changed files with 17804 additions and 4275 deletions

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
*.bat eol=crlf

5
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,5 @@
# These are supported funding model platforms
github: tiann
patreon: weishu
custom: https://vxposed.com/donate.html

View File

@@ -6,7 +6,7 @@ body:
- type: markdown - type: markdown
attributes: attributes:
value: | value: |
Thanks for supporting KernelSU ! Thanks for supporting KernelSU!
- type: input - type: input
id: repo-url id: repo-url
attributes: attributes:

View File

@@ -1,32 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.

72
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View File

@@ -0,0 +1,72 @@
name: Bug report
description: Create a report to help us improve KernelSU
labels: [Bug]
body:
- type: checkboxes
attributes:
label: Please check before submitting an issue
options:
- label: I have searched the issues and haven't found anything relevant
required: true
- label: I will upload bugreport file in KernelSU Manager - Settings - Report log
required: true
- label: I know how to reproduce the issue which may not be specific to my device
required: false
- type: textarea
attributes:
label: Describe the bug
description: A clear and concise description of what the bug is
validations:
required: true
- type: textarea
attributes:
label: To Reproduce
description: Steps to reproduce the behaviour
placeholder: |
- 1. Go to '...'
- 2. Click on '....'
- 3. Scroll down to '....'
- 4. See error
- type: textarea
attributes:
label: Expected behavior
description: A clear and concise description of what you expected to happen.
- type: textarea
attributes:
label: Screenshots
description: If applicable, add screenshots to help explain your problem.
- type: textarea
attributes:
label: Logs
description: If applicable, add crash or any other logs to help us figure out the problem.
- type: textarea
attributes:
label: Device info
value: |
- Device:
- OS Version:
- KernelSU Version:
- Kernel Version:
validations:
required: true
- type: textarea
attributes:
label: Additional context
description: Add any other context about the problem here.

View File

@@ -1,10 +0,0 @@
---
name: Custom issue template
about: Describe this issue template's purpose here.
title: ''
labels: ''
assignees: ''
---

11
.github/ISSUE_TEMPLATE/custom.yml vendored Normal file
View File

@@ -0,0 +1,11 @@
name: Custom issue template
description: WARNING! If you are reporting a bug but use this template, the issue will be closed directly.
title: '[Custom]'
body:
- type: textarea
id: description
attributes:
label: "Describe your problem."
validations:
required: true

View File

@@ -1,20 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@@ -0,0 +1,40 @@
name: Feature Request
description: "Suggest an idea for this project"
title: "[Feature]"
labels: "feature"
assignees: tiann
body:
- type: markdown
id: feature-info
attributes:
value: "## Feature Infomation"
- type: textarea
id: feature-main
validations:
required: true
attributes:
label: "Is your feature request related to a problem? Please describe."
description: "A clear and concise description of what the problem is."
placeholder: "I'm always frustrated when [...]"
- type: textarea
id: feature-solution
validations:
required: true
attributes:
label: "Describe the solution you'd like."
description: "A clear and concise description of what you want to happen."
- type: textarea
id: feature-describe
validations:
required: true
attributes:
label: "Describe alternatives you've considered."
description: "A clear and concise description of any alternative solutions or features you've considered."
- type: textarea
id: feature-extra
validations:
required: false
attributes:
label: "Additional context"
description: "Add any other context or screenshots about the feature request here."

View File

@@ -0,0 +1,71 @@
<?xml version='1.0' encoding='UTF-8'?>
<!--https://ci.android.com/builds/submitted/9964412/kernel_virt_x86_64/latest/manifest_9964412.xml-->
<manifest>
<remote name="aosp" fetch="https://android.googlesource.com/" review="https://android.googlesource.com/" />
<default revision="master" remote="aosp" sync-j="4" />
<superproject name="kernel/superproject" remote="aosp" revision="common-android14-6.1" />
<project path="build/kernel" name="kernel/build" revision="b0377a072bb3f78cdacfd6d809914a9d1b0c0148">
<linkfile dest="tools/bazel" src="kleaf/bazel.sh" />
<linkfile dest="WORKSPACE" src="kleaf/bazel.WORKSPACE" />
<linkfile dest="build/build.sh" src="build.sh" />
<linkfile dest="build/build_abi.sh" src="build_abi.sh" />
<linkfile dest="build/build_test.sh" src="build_test.sh" />
<linkfile dest="build/build_utils.sh" src="build_utils.sh" />
<linkfile dest="build/config.sh" src="config.sh" />
<linkfile dest="build/envsetup.sh" src="envsetup.sh" />
<linkfile dest="build/_setup_env.sh" src="_setup_env.sh" />
<linkfile dest="build/multi-switcher.sh" src="multi-switcher.sh" />
<linkfile dest="build/abi" src="abi" />
<linkfile dest="build/static_analysis" src="static_analysis" />
</project>
<project path="common" name="kernel/common" revision="7e35917775b8b3e3346a87f294e334e258bf15e6">
<linkfile dest=".source_date_epoch_dir" src="." />
</project>
<project path="kernel/tests" name="kernel/tests" revision="c90a1c1b226b975cc31e709fa96fc1c6ecdbe272" />
<project path="kernel/configs" name="kernel/configs" revision="52a7267d6a9f9efabf3cb43839bb5e7f7ff05be3" />
<project path="common-modules/virtual-device" name="kernel/common-modules/virtual-device" revision="0d03de3246301028775f05ea388c2c444344a268" />
<project path="prebuilts/clang/host/linux-x86" name="platform/prebuilts/clang/host/linux-x86" clone-depth="1" revision="4f7e5adc160ab726ac5bafb260de98e612904c50" />
<project path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.17-4.8" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.17-4.8" clone-depth="1" revision="f7b0d5b0ee369864d5ac3e96ae24ec9e2b6a52da" />
<project path="prebuilts/build-tools" name="platform/prebuilts/build-tools" clone-depth="1" revision="dc92e06585a7647bf739a2309a721b82fcfa01d4" />
<project path="prebuilts/clang-tools" name="platform/prebuilts/clang-tools" clone-depth="1" revision="5611871963f54c688d3ac49e527aecdef21e8567" />
<project path="prebuilts/kernel-build-tools" name="kernel/prebuilts/build-tools" clone-depth="1" revision="2597cb1b5525e419b7fa806373be673054a68d29" />
<project path="tools/mkbootimg" name="platform/system/tools/mkbootimg" revision="2680066d0844544b3e78d6022cd21321d31837c3" />
<project path="prebuilts/bazel/linux-x86_64" name="platform/prebuilts/bazel/linux-x86_64" clone-depth="1" revision="4fdb9395071ff22118311d434d697c2b6fd887b4" />
<project path="prebuilts/jdk/jdk11" name="platform/prebuilts/jdk/jdk11" clone-depth="1" revision="491e6aa056676f29c4541f71bd738e4e876e4ba2" />
<project path="prebuilts/ndk-r23" name="toolchain/prebuilts/ndk/r23" clone-depth="1" revision="19ac7e4eded12adb99d4f613490dde6dd0e72664" />
<project path="external/bazel-skylib" name="platform/external/bazel-skylib" revision="f998e5dc13c03f0eae9e373263d3afff0932c738" />
<project path="build/bazel_common_rules" name="platform/build/bazel_common_rules" revision="707b2c5fe3d0d7d934a93e00a8a4062e83557831" />
<project path="external/stardoc" name="platform/external/stardoc" revision="e83f522ee95419e55d2c5654aa6e0143beeef595" />
<project path="external/python/absl-py" name="platform/external/python/absl-py" revision="393d0b1e3f0fea3e95944a2fd3282cc9f76d4f14" />
</manifest>

View File

@@ -0,0 +1,37 @@
<manifest>
<!-- https://ci.android.com/builds/submitted/11275718/kernel_virt_aarch64/latest/manifest_11275718.xml -->
<remote name="aosp" fetch="https://android.googlesource.com/" review="https://android.googlesource.com/"/>
<default revision="main" remote="aosp" sync-j="4"/>
<superproject name="kernel/superproject" remote="aosp" revision="common-android15-6.6"/>
<project path="build/kernel" name="kernel/build" groups="ddk" revision="43337ece156eabd735426a0b007637bb52fa7339">
<linkfile dest="tools/bazel" src="kleaf/bazel.sh"/>
<linkfile dest="WORKSPACE" src="kleaf/bazel.WORKSPACE"/>
</project>
<project path="common" name="kernel/common" revision="515a956763d8c874d9a7e23528332bf907b31748"/>
<project path="kernel/common-patches" name="kernel/common-patches" revision="495419530db8761a40f8db9fb734a9be78fa25fd">
<linkfile dest="common/patches" src="android-mainline"/>
</project>
<project path="kernel/tests" name="kernel/tests" revision="99abfd276063ab3a7748939aa55e107aaca903f6"/>
<project path="kernel/configs" name="kernel/configs" revision="786dab5f2f49b983b7c448d45a50c62d36e9f7f9"/>
<project path="common-modules/virtual-device" name="kernel/common-modules/virtual-device" revision="5c7466d6fc47f7ee2245f9ee6471cd78e6ff82f0"/>
<project path="prebuilts/clang/host/linux-x86" name="platform/prebuilts/clang/host/linux-x86" revision="1400cf7d2f0d28c425737d7b58c1f67c52db087f" clone-depth="1" groups="ddk"/>
<project path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.17-4.8" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.17-4.8" clone-depth="1" groups="ddk" revision="99e41849eb3895574b1dc7e854ca15cb3fb11a71"/>
<project path="prebuilts/build-tools" name="platform/prebuilts/build-tools" clone-depth="1" groups="ddk" revision="93e69718fd53f0c3dd7f0087657dfe2e78926830"/>
<project path="prebuilts/clang-tools" name="platform/prebuilts/clang-tools" clone-depth="1" revision="bf33473342630944198190ff74e6ca09a9bcfdeb"/>
<project path="prebuilts/kernel-build-tools" name="kernel/prebuilts/build-tools" clone-depth="1" groups="ddk" revision="4b68c02455e6ce5c87ccf8e09e629f0177771a8c"/>
<project path="prebuilts/rust" name="platform/prebuilts/rust" revision="7e636e2a1b7cf415c3c01981e439d98843dc4973" clone-depth="1"/>
<project path="prebuilts/tradefed" name="platform/tools/tradefederation/prebuilts" clone-depth="1" revision="79d9ec16c1e4e747b0bfad9a80a1665080c42d7b"/>
<project path="prebuilts/asuite" name="platform/prebuilts/asuite" clone-depth="1" revision="9e2738f6242785a3b2096010ce63363a160c122f"/>
<project path="tools/mkbootimg" name="platform/system/tools/mkbootimg" revision="722e6fa37d508b190fafa9a8ce9f6d571fad3a8c"/>
<project path="prebuilts/jdk/jdk11" name="platform/prebuilts/jdk/jdk11" revision="06351a976e772d8a9cdb133bb982032c64ee9e53" clone-depth="1" groups="ddk"/>
<project path="prebuilts/ndk-r26" name="toolchain/prebuilts/ndk/r26" clone-depth="1" groups="ddk" revision="e87abe7cbe9143d239ba54f32c64ca697adcba75"/>
<project path="external/bazel-skylib" name="platform/external/bazel-skylib" groups="ddk" revision="930baaa09975eb3809629a72806acbe9494dd224"/>
<project path="build/bazel_common_rules" name="platform/build/bazel_common_rules" groups="ddk" revision="5fb8d26dfb2565e0e2d8b6630d241b5f5675e0b1"/>
<project path="external/libcap-ng" name="platform/external/libcap-ng" revision="2bcc92ae19481dd2b8d3ce3abdfbbee49261abe6"/>
<project path="external/libcap" name="platform/external/libcap" revision="9577b17009379649c9220edca7d0077311445b95"/>
<project path="external/stardoc" name="platform/external/stardoc" groups="ddk" revision="85b0f239303220d902ad919ff27d2da475fc12e2"/>
<project path="external/python/absl-py" name="platform/external/python/absl-py" groups="ddk" revision="8cc5fc4798ef442b0c5b70c1ecc7e45a8f6eb2f8"/>
<project path="external/bazelbuild-rules_cc" name="platform/external/bazelbuild-rules_cc" groups="ddk" revision="9a4853f0327e0266818c8d6b4967e2e8f36b1a88"/>
<project path="external/bazelbuild-rules_python" name="platform/external/bazelbuild-rules_python" groups="ddk" revision="3e21f23d9400ba51f10e9b76016ff6d472829b4e"/>
<project path="external/bazelbuild-rules_rust" name="platform/external/bazelbuild-rules_rust" revision="bdd24099a80555ff8a4441e8bb47f4c7cfe413f8"/>
</manifest>

View File

@@ -1,48 +0,0 @@
From f1e398602b989ac197cdd0fda4a7c4c323b03eb9 Mon Sep 17 00:00:00 2001
From: DozNaka <dozdguide@gmail.com>
Date: Mon, 11 Apr 2022 20:43:45 -0400
Subject: [PATCH] Makefile: Use CCACHE for faster compilation
---
Makefile | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/Makefile b/Makefile
index e8b8d5894..51e8aac6e 100644
--- a/Makefile
+++ b/Makefile
@@ -442,21 +442,21 @@ KBUILD_HOSTLDLIBS := $(HOST_LFS_LIBS) $(HOSTLDLIBS)
# Make variables (CC, etc...)
CPP = $(CC) -E
ifneq ($(LLVM),)
-CC = clang
-LD = ld.lld
-AR = llvm-ar
+CC = $(CCACHE) clang
+LD = $(CCACHE) ld.lld
+AR = $(CCACHE) llvm-ar
NM = llvm-nm
-OBJCOPY = llvm-objcopy
-OBJDUMP = llvm-objdump
+OBJCOPY = $(CCACHE) llvm-objcopy
+OBJDUMP = $(CCACHE) llvm-objdump
READELF = llvm-readelf
STRIP = llvm-strip
else
-CC = $(CROSS_COMPILE)gcc
-LD = $(CROSS_COMPILE)ld
-AR = $(CROSS_COMPILE)ar
+CC = $(CCACHE) $(CROSS_COMPILE)gcc
+LD = $(CCACHE) $(CROSS_COMPILE)ld
+AR = $(CCACHE) $(CROSS_COMPILE)ar
NM = $(CROSS_COMPILE)nm
-OBJCOPY = $(CROSS_COMPILE)objcopy
-OBJDUMP = $(CROSS_COMPILE)objdump
+OBJCOPY = $(CCACHE) $(CROSS_COMPILE)objcopy
+OBJDUMP = $(CCACHE) $(CROSS_COMPILE)objdump
READELF = $(CROSS_COMPILE)readelf
STRIP = $(CROSS_COMPILE)strip
endif
--
2.37.2

View File

@@ -1,48 +0,0 @@
From f1e398602b989ac197cdd0fda4a7c4c323b03eb9 Mon Sep 17 00:00:00 2001
From: DozNaka <dozdguide@gmail.com>
Date: Mon, 11 Apr 2022 20:43:45 -0400
Subject: [PATCH] Makefile: Use CCACHE for faster compilation
---
Makefile | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/Makefile b/Makefile
index e8b8d5894..51e8aac6e 100644
--- a/Makefile
+++ b/Makefile
@@ -442,21 +442,21 @@ KBUILD_HOSTLDLIBS := $(HOST_LFS_LIBS) $(HOSTLDLIBS)
# Make variables (CC, etc...)
CPP = $(CC) -E
ifneq ($(LLVM),)
-CC = clang
-LD = ld.lld
-AR = llvm-ar
+CC = $(CCACHE) clang
+LD = $(CCACHE) ld.lld
+AR = $(CCACHE) llvm-ar
NM = llvm-nm
-OBJCOPY = llvm-objcopy
-OBJDUMP = llvm-objdump
+OBJCOPY = $(CCACHE) llvm-objcopy
+OBJDUMP = $(CCACHE) llvm-objdump
READELF = llvm-readelf
STRIP = llvm-strip
else
-CC = $(CROSS_COMPILE)gcc
-LD = $(CROSS_COMPILE)ld
-AR = $(CROSS_COMPILE)ar
+CC = $(CCACHE) $(CROSS_COMPILE)gcc
+LD = $(CCACHE) $(CROSS_COMPILE)ld
+AR = $(CCACHE) $(CROSS_COMPILE)ar
NM = $(CROSS_COMPILE)nm
-OBJCOPY = $(CROSS_COMPILE)objcopy
-OBJDUMP = $(CROSS_COMPILE)objdump
+OBJCOPY = $(CCACHE) $(CROSS_COMPILE)objcopy
+OBJDUMP = $(CCACHE) $(CROSS_COMPILE)objdump
READELF = $(CROSS_COMPILE)readelf
STRIP = $(CROSS_COMPILE)strip
endif
--
2.37.2

View File

@@ -11,7 +11,7 @@ jobs:
env: env:
ISSUE_CONTENT: ${{ github.event.issue.body }} ISSUE_CONTENT: ${{ github.event.issue.body }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Parse issue body - name: Parse issue body
id: handle-add-device id: handle-add-device
run: | run: |

164
.github/workflows/avd-kernel.yml vendored Normal file
View File

@@ -0,0 +1,164 @@
name: GKI Kernel Build
on:
workflow_call:
inputs:
version_name:
required: true
type: string
description: >
With SUBLEVEL of kernel,
for example: android12-5.10.66
arch:
required: true
type: string
description: >
Build arch: aarch64/x86_64
debug:
required: false
type: boolean
default: true
manifest_name:
required: false
type: string
description: >
Local repo manifest xml path,
typically for AVD kernel build.
secrets:
BOOT_SIGN_KEY:
required: false
CHAT_ID:
required: false
BOT_TOKEN:
required: false
MESSAGE_THREAD_ID:
required: false
jobs:
build:
name: Build ${{ inputs.version_name }}
runs-on: ubuntu-latest
steps:
- name: Maximize build space
uses: easimon/maximize-build-space@master
with:
root-reserve-mb: 8192
temp-reserve-mb: 2048
remove-dotnet: 'true'
remove-android: 'true'
remove-haskell: 'true'
remove-codeql: 'true'
- uses: actions/checkout@v4
with:
path: KernelSU
fetch-depth: 0
- name: Setup need_upload
id: need_upload
run: |
if [ ! -z "${{ secrets.BOT_TOKEN }}" ]; then
echo "UPLOAD=true" >> $GITHUB_OUTPUT
else
echo "UPLOAD=false" >> $GITHUB_OUTPUT
fi
- name: Setup kernel source
run: |
echo "Free space:"
df -h
cd $GITHUB_WORKSPACE
sudo apt-get install repo -y
mkdir android-kernel && cd android-kernel
repo init --depth=1 -u https://android.googlesource.com/kernel/manifest -m "$GITHUB_WORKSPACE/KernelSU/.github/manifests/${{ inputs.manifest_name }}" --repo-rev=v2.16
repo --version
repo --trace sync -c -j$(nproc --all) --no-tags
df -h
- name: Setup KernelSU
env:
PATCH_PATH: ${{ inputs.patch_path }}
IS_DEBUG_KERNEL: ${{ inputs.debug }}
run: |
cd $GITHUB_WORKSPACE/android-kernel
echo "[+] KernelSU setup"
GKI_ROOT=$(pwd)
echo "[+] GKI_ROOT: $GKI_ROOT"
echo "[+] Copy KernelSU driver to $GKI_ROOT/common/drivers"
ln -sf $GITHUB_WORKSPACE/KernelSU/kernel $GKI_ROOT/common/drivers/kernelsu
echo "[+] Add KernelSU driver to Makefile"
DRIVER_MAKEFILE=$GKI_ROOT/common/drivers/Makefile
grep -q "kernelsu" "$DRIVER_MAKEFILE" || printf "\nobj-y += kernelsu/\n" >> "$DRIVER_MAKEFILE"
echo "[+] Apply KernelSU patches"
cd $GKI_ROOT/common/ && git apply $GITHUB_WORKSPACE/KernelSU/.github/patches/$PATCH_PATH/*.patch || echo "[-] No patch found"
if [ "$IS_DEBUG_KERNEL" = "true" ]; then
echo "[+] Enable debug features for kernel"
printf "\nccflags-y += -DCONFIG_KSU_DEBUG\n" >> $GITHUB_WORKSPACE/KernelSU/kernel/Makefile
fi
repo status
echo "[+] KernelSU setup done."
cd $GITHUB_WORKSPACE/KernelSU
VERSION=$(($(git rev-list --count HEAD) + 10200))
echo "VERSION: $VERSION"
echo "kernelsu_version=$VERSION" >> $GITHUB_ENV
- name: Make working directory clean to avoid dirty
working-directory: android-kernel
run: |
rm common/android/abi_gki_protected_exports_* || echo "No protected exports!"
git config --global user.email "bot@kernelsu.org"
git config --global user.name "KernelSUBot"
cd common/ && git add -A && git commit -a -m "Add KernelSU"
repo status
- name: Build kernel
working-directory: android-kernel
run: |
if [ ! -z ${{ vars.EXPECTED_SIZE }} ] && [ ! -z ${{ vars.EXPECTED_HASH }} ]; then
export KSU_EXPECTED_SIZE=${{ vars.EXPECTED_SIZE }}
export KSU_EXPECTED_HASH=${{ vars.EXPECTED_HASH }}
fi
tools/bazel run --config=android_ci --config=stamp --lto=thin //common-modules/virtual-device:virtual_device_${{ inputs.arch }}_dist -- --dist_dir=dist
NAME=kernel-${{ inputs.arch }}-avd-${{ inputs.version_name }}-${{ env.kernelsu_version }}
TARGET_IMAGE=dist/bzImage
if [ ! -e $TARGET_IMAGE ]; then
TARGET_IMAGE=dist/Image
fi
mv $TARGET_IMAGE $NAME
echo "file_path=android-kernel/$NAME" >> $GITHUB_ENV
- name: Upload Kernel
uses: actions/upload-artifact@v4
with:
name: kernel-${{ inputs.arch }}-avd-${{ inputs.version_name }}-${{ env.kernelsu_version }}
path: "${{ env.file_path }}"
- name: Bot session cache
if: github.event_name == 'push' && github.ref == 'refs/heads/main' || github.ref_type == 'tag'
id: bot_session_cache
uses: actions/cache@v3
with:
path: scripts/ksubot.session
key: ${{ runner.os }}-bot-session
- name: Post to Telegram
if: github.event_name == 'push' && github.ref == 'refs/heads/main' || github.ref_type == 'tag'
env:
CHAT_ID: ${{ secrets.CHAT_ID }}
BOT_TOKEN: ${{ secrets.BOT_TOKEN }}
MESSAGE_THREAD_ID: ${{ secrets.MESSAGE_THREAD_ID }}
COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
COMMIT_URL: ${{ github.event.head_commit.url }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
run: |
TITLE=kernel-${{ inputs.arch }}-avd-${{ inputs.version_name }}
echo "[+] title: $TITLE"
export TITLE
export VERSION="${{ env.kernelsu_version }}"
echo "[+] Image to upload"
ls -l "${{ env.file_path }}"
if [ -n "${{ secrets.BOT_TOKEN }}" ]; then
pip3 install telethon==1.31.1
python3 "$GITHUB_WORKSPACE/KernelSU/scripts/ksubot.py" "${{ env.file_path }}"
fi

View File

@@ -7,9 +7,9 @@ jobs:
uses: ./.github/workflows/gki-kernel.yml uses: ./.github/workflows/gki-kernel.yml
with: with:
version: android12-5.10 version: android12-5.10
version_name: android12-5.10.177 version_name: android12-5.10.185
tag: android12-5.10-2023-06 tag: android12-5.10-2023-09
os_patch_level: 2023-06 os_patch_level: 2023-09
patch_path: "5.10" patch_path: "5.10"
debug: true debug: true
build-debug-kernel-a13: build-debug-kernel-a13:
@@ -17,15 +17,15 @@ jobs:
matrix: matrix:
include: include:
- version: "5.10" - version: "5.10"
sub_level: 177 sub_level: 187
os_patch_level: 2023-06 os_patch_level: 2023-08
- version: "5.15" - version: "5.15"
sub_level: 94 sub_level: 119
os_patch_level: 2023-06 os_patch_level: 2023-09
uses: ./.github/workflows/gki-kernel.yml uses: ./.github/workflows/gki-kernel.yml
with: with:
version: android13-${{ matrix.version }} version: android13-${{ matrix.version }}
version_name: android13-${{ matrix.version }}.${{ matrix.sub_level }} version_name: android13-${{ matrix.version }}.${{ matrix.sub_level }}
tag: android13-${{ matrix.version }}-${{ matrix.os_patch_level }} tag: android13-${{ matrix.version }}-${{ matrix.os_patch_level }}
patch_path: ${{ matrix.version }} patch_path: ${{ matrix.version }}
debug: true debug: true

View File

@@ -1,7 +1,7 @@
name: Build Kernel - Android 12 name: Build Kernel - Android 12
on: on:
push: push:
branches: ["main", "ci"] branches: ["main", "ci", "checkci"]
paths: paths:
- ".github/workflows/build-kernel-a12.yml" - ".github/workflows/build-kernel-a12.yml"
- ".github/workflows/gki-kernel.yml" - ".github/workflows/gki-kernel.yml"
@@ -17,18 +17,20 @@ on:
workflow_call: workflow_call:
jobs: jobs:
build-kernel: build-kernel:
if: github.event_name != 'pull_request' if: github.event_name != 'pull_request' && github.ref != 'refs/heads/checkci'
strategy: strategy:
matrix: matrix:
include: include:
- sub_level: 66 - sub_level: 66
os_patch_level: 2021-11 os_patch_level: 2022-01
- sub_level: 81 - sub_level: 81
os_patch_level: 2022-03 os_patch_level: 2022-03
- sub_level: 101 - sub_level: 101
os_patch_level: 2022-05 os_patch_level: 2022-05
- sub_level: 110 - sub_level: 110
os_patch_level: 2022-07 os_patch_level: 2022-07
- sub_level: 117
os_patch_level: 2022-09
- sub_level: 136 - sub_level: 136
os_patch_level: 2022-11 os_patch_level: 2022-11
- sub_level: 149 - sub_level: 149
@@ -38,7 +40,13 @@ jobs:
- sub_level: 168 - sub_level: 168
os_patch_level: 2023-05 os_patch_level: 2023-05
- sub_level: 177 - sub_level: 177
os_patch_level: 2023-06 os_patch_level: 2023-07
- sub_level: 185
os_patch_level: 2023-09
- sub_level: 198
os_patch_level: 2024-01
- sub_level: 205
os_patch_level: 2024-03
uses: ./.github/workflows/gki-kernel.yml uses: ./.github/workflows/gki-kernel.yml
secrets: inherit secrets: inherit
with: with:
@@ -47,13 +55,13 @@ jobs:
tag: android12-5.10-${{ matrix.os_patch_level }} tag: android12-5.10-${{ matrix.os_patch_level }}
os_patch_level: ${{ matrix.os_patch_level }} os_patch_level: ${{ matrix.os_patch_level }}
patch_path: "5.10" patch_path: "5.10"
upload-artifacts: upload-artifacts:
needs: build-kernel needs: build-kernel
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: ${{ ( github.event_name != 'pull_request' && github.ref == 'refs/heads/main' ) || github.ref_type == 'tag' || github.ref == 'refs/heads/ci' }} if: ${{ ( github.event_name != 'pull_request' && github.ref == 'refs/heads/main' ) || github.ref_type == 'tag' || github.ref == 'refs/heads/ci' }}
env: env:
CHAT_ID: ${{ secrets.CHAT_ID }} CHAT_ID: ${{ secrets.CHAT_ID }}
CACHE_CHAT_ID: ${{ secrets.CACHE_CHAT_ID }}
BOT_TOKEN: ${{ secrets.BOT_TOKEN }} BOT_TOKEN: ${{ secrets.BOT_TOKEN }}
MESSAGE_THREAD_ID: ${{ secrets.MESSAGE_THREAD_ID }} MESSAGE_THREAD_ID: ${{ secrets.MESSAGE_THREAD_ID }}
COMMIT_MESSAGE: ${{ github.event.head_commit.message }} COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
@@ -61,9 +69,9 @@ jobs:
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
steps: steps:
- name: Download artifacts - name: Download artifacts
uses: actions/download-artifact@v3 uses: actions/download-artifact@v4
- uses: actions/checkout@v3 - uses: actions/checkout@v4
with: with:
path: KernelSU path: KernelSU
fetch-depth: 0 fetch-depth: 0
@@ -75,11 +83,11 @@ jobs:
- name: Download prebuilt toolchain - name: Download prebuilt toolchain
run: | run: |
AOSP_MIRROR=https://android.googlesource.com AOSP_MIRROR=https://android.googlesource.com
BRANCH=master-kernel-build-2022 BRANCH=main-kernel-build-2023
git clone $AOSP_MIRROR/platform/prebuilts/build-tools -b $BRANCH --depth 1 build-tools git clone $AOSP_MIRROR/platform/prebuilts/build-tools -b $BRANCH --depth 1 build-tools
git clone $AOSP_MIRROR/kernel/prebuilts/build-tools -b $BRANCH --depth 1 kernel-build-tools git clone $AOSP_MIRROR/kernel/prebuilts/build-tools -b $BRANCH --depth 1 kernel-build-tools
git clone $AOSP_MIRROR/platform/system/tools/mkbootimg -b $BRANCH --depth 1 git clone $AOSP_MIRROR/platform/system/tools/mkbootimg -b $BRANCH --depth 1
pip3 install python-telegram-bot pip3 install telethon==1.31.1
- name: Set boot sign key - name: Set boot sign key
env: env:
@@ -89,8 +97,12 @@ jobs:
echo "$BOOT_SIGN_KEY" > ./kernel-build-tools/linux-x86/share/avb/testkey_rsa2048.pem echo "$BOOT_SIGN_KEY" > ./kernel-build-tools/linux-x86/share/avb/testkey_rsa2048.pem
fi fi
- name: Setup mutex for uploading - name: Bot session cache
uses: ben-z/gh-action-mutex@v1.0-alpha-7 id: bot_session_cache
uses: actions/cache@v3
with:
path: scripts/ksubot.session
key: ${{ runner.os }}-bot-session
- name: Build boot images - name: Build boot images
run: | run: |
@@ -109,17 +121,17 @@ jobs:
run: ls -R run: ls -R
- name: Upload images artifact - name: Upload images artifact
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: boot-images-android12 name: boot-images-android12
path: Image-android12*/*.img.gz path: Image-android12*/*.img.gz
check-build-kernel: check-build-kernel:
if: github.event_name == 'pull_request' if: (github.event_name == 'pull_request' && !github.event.pull_request.draft) || github.ref == 'refs/heads/checkci'
uses: ./.github/workflows/gki-kernel.yml uses: ./.github/workflows/gki-kernel.yml
with: with:
version: android12-5.10 version: android12-5.10
version_name: android12-5.10.177 version_name: android12-5.10.177
tag: android12-5.10-2023-06 tag: android12-5.10-2023-06
os_patch_level: 2023-06 os_patch_level: 2023-06
patch_path: "5.10" patch_path: "5.10"

View File

@@ -1,7 +1,7 @@
name: Build Kernel - Android 13 name: Build Kernel - Android 13
on: on:
push: push:
branches: ["main", "ci"] branches: ["main", "ci", "checkci"]
paths: paths:
- ".github/workflows/build-kernel-a13.yml" - ".github/workflows/build-kernel-a13.yml"
- ".github/workflows/gki-kernel.yml" - ".github/workflows/gki-kernel.yml"
@@ -17,7 +17,7 @@ on:
workflow_call: workflow_call:
jobs: jobs:
build-kernel: build-kernel:
if: github.event_name != 'pull_request' if: github.event_name != 'pull_request' && github.ref != 'refs/heads/checkci'
strategy: strategy:
matrix: matrix:
include: include:
@@ -35,13 +35,31 @@ jobs:
os_patch_level: 2023-05 os_patch_level: 2023-05
- version: "5.10" - version: "5.10"
sub_level: 177 sub_level: 177
os_patch_level: 2023-06 os_patch_level: 2023-07
- version: "5.10"
sub_level: 177
os_patch_level: 2024-02
- version: "5.10"
sub_level: 186
os_patch_level: 2023-08
- version: "5.10"
sub_level: 186
os_patch_level: 2023-09
- version: "5.10"
sub_level: 189
os_patch_level: 2023-11
- version: "5.10"
sub_level: 198
os_patch_level: 2023-12
- version: "5.10"
sub_level: 205
os_patch_level: 2024-02
- version: "5.15" - version: "5.15"
sub_level: 41 sub_level: 41
os_patch_level: 2022-11 os_patch_level: 2022-11
- version: "5.15" - version: "5.15"
sub_level: 74 sub_level: 74
os_patch_level: 2023-02 os_patch_level: 2023-01
- version: "5.15" - version: "5.15"
sub_level: 78 sub_level: 78
os_patch_level: 2023-03 os_patch_level: 2023-03
@@ -50,7 +68,19 @@ jobs:
os_patch_level: 2023-05 os_patch_level: 2023-05
- version: "5.15" - version: "5.15"
sub_level: 104 sub_level: 104
os_patch_level: 2023-06 os_patch_level: 2023-07
- version: "5.15"
sub_level: 119
os_patch_level: 2023-09
- version: "5.15"
sub_level: 123
os_patch_level: 2023-11
- version: "5.15"
sub_level: 137
os_patch_level: 2023-12
- version: "5.15"
sub_level: 144
os_patch_level: 2024-02
uses: ./.github/workflows/gki-kernel.yml uses: ./.github/workflows/gki-kernel.yml
secrets: inherit secrets: inherit
with: with:
@@ -59,13 +89,13 @@ jobs:
tag: android13-${{ matrix.version }}-${{ matrix.os_patch_level }} tag: android13-${{ matrix.version }}-${{ matrix.os_patch_level }}
os_patch_level: ${{ matrix.os_patch_level }} os_patch_level: ${{ matrix.os_patch_level }}
patch_path: ${{ matrix.version }} patch_path: ${{ matrix.version }}
upload-artifacts: upload-artifacts:
needs: build-kernel needs: build-kernel
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: ${{ ( github.event_name != 'pull_request' && github.ref == 'refs/heads/main' ) || github.ref_type == 'tag' || github.ref == 'refs/heads/ci' }} if: ${{ ( github.event_name != 'pull_request' && github.ref == 'refs/heads/main' ) || github.ref_type == 'tag' || github.ref == 'refs/heads/ci' }}
env: env:
CHAT_ID: ${{ secrets.CHAT_ID }} CHAT_ID: ${{ secrets.CHAT_ID }}
CACHE_CHAT_ID: ${{ secrets.CACHE_CHAT_ID }}
BOT_TOKEN: ${{ secrets.BOT_TOKEN }} BOT_TOKEN: ${{ secrets.BOT_TOKEN }}
MESSAGE_THREAD_ID: ${{ secrets.MESSAGE_THREAD_ID }} MESSAGE_THREAD_ID: ${{ secrets.MESSAGE_THREAD_ID }}
COMMIT_MESSAGE: ${{ github.event.head_commit.message }} COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
@@ -73,9 +103,9 @@ jobs:
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
steps: steps:
- name: Download artifacts - name: Download artifacts
uses: actions/download-artifact@v3 uses: actions/download-artifact@v4
- uses: actions/checkout@v3 - uses: actions/checkout@v4
with: with:
path: KernelSU path: KernelSU
fetch-depth: 0 fetch-depth: 0
@@ -87,11 +117,11 @@ jobs:
- name: Download prebuilt toolchain - name: Download prebuilt toolchain
run: | run: |
AOSP_MIRROR=https://android.googlesource.com AOSP_MIRROR=https://android.googlesource.com
BRANCH=master-kernel-build-2022 BRANCH=main-kernel-build-2023
git clone $AOSP_MIRROR/platform/prebuilts/build-tools -b $BRANCH --depth 1 build-tools git clone $AOSP_MIRROR/platform/prebuilts/build-tools -b $BRANCH --depth 1 build-tools
git clone $AOSP_MIRROR/kernel/prebuilts/build-tools -b $BRANCH --depth 1 kernel-build-tools git clone $AOSP_MIRROR/kernel/prebuilts/build-tools -b $BRANCH --depth 1 kernel-build-tools
git clone $AOSP_MIRROR/platform/system/tools/mkbootimg -b $BRANCH --depth 1 git clone $AOSP_MIRROR/platform/system/tools/mkbootimg -b $BRANCH --depth 1
pip3 install python-telegram-bot pip3 install telethon==1.31.1
- name: Set boot sign key - name: Set boot sign key
env: env:
@@ -101,8 +131,12 @@ jobs:
echo "$BOOT_SIGN_KEY" > ./kernel-build-tools/linux-x86/share/avb/testkey_rsa2048.pem echo "$BOOT_SIGN_KEY" > ./kernel-build-tools/linux-x86/share/avb/testkey_rsa2048.pem
fi fi
- name: Setup mutex for uploading - name: Bot session cache
uses: ben-z/gh-action-mutex@v1.0-alpha-7 id: bot_session_cache
uses: actions/cache@v3
with:
path: scripts/ksubot.session
key: ${{ runner.os }}-bot-session
- name: Build boot images - name: Build boot images
run: | run: |
@@ -116,30 +150,31 @@ jobs:
echo "VERSION: $VERSION" echo "VERSION: $VERSION"
cd - cd -
bash $GITHUB_WORKSPACE/KernelSU/.github/scripts/build_a13.sh bash $GITHUB_WORKSPACE/KernelSU/.github/scripts/build_a13.sh
- name: Display structure of boot files - name: Display structure of boot files
run: ls -R run: ls -R
- name: Upload images artifact - name: Upload images artifact
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: boot-images-android13 name: boot-images-android13
path: Image-android13*/*.img.gz path: Image-android13*/*.img.gz
check-build-kernel: check-build-kernel:
if: github.event_name == 'pull_request' if: (github.event_name == 'pull_request' && !github.event.pull_request.draft) || github.ref == 'refs/heads/checkci'
strategy: strategy:
matrix: matrix:
include: include:
- version: "5.10" - version: "5.10"
sub_level: 177 sub_level: 189
os_patch_level: 2023-06 os_patch_level: 2023-10
- version: "5.15" - version: "5.15"
sub_level: 104 sub_level: 123
os_patch_level: 2023-06 os_patch_level: 2023-10
uses: ./.github/workflows/gki-kernel.yml uses: ./.github/workflows/gki-kernel.yml
with: with:
version: android13-${{ matrix.version }} version: android13-${{ matrix.version }}
version_name: android13-${{ matrix.version }}.${{ matrix.sub_level }} version_name: android13-${{ matrix.version }}.${{ matrix.sub_level }}
tag: android13-${{ matrix.version }}-${{ matrix.os_patch_level }} tag: android13-${{ matrix.version }}-${{ matrix.os_patch_level }}
patch_path: ${{ matrix.version }} os_patch_level: ${{ matrix.os_patch_level }}
patch_path: ${{ matrix.version }}

144
.github/workflows/build-kernel-a14.yml vendored Normal file
View File

@@ -0,0 +1,144 @@
name: Build Kernel - Android 14
on:
push:
branches: ["main", "ci", "checkci"]
paths:
- ".github/workflows/build-kernel-a14.yml"
- ".github/workflows/gki-kernel.yml"
- ".github/scripts/build_a13.sh"
- "kernel/**"
pull_request:
branches: ["main"]
paths:
- ".github/workflows/build-kernel-a14.yml"
- ".github/workflows/gki-kernel.yml"
- ".github/scripts/build-a13.sh"
- "kernel/**"
workflow_call:
jobs:
build-kernel:
if: github.event_name != 'pull_request' && github.ref != 'refs/heads/checkci'
strategy:
matrix:
include:
- version: "5.15"
sub_level: 110
os_patch_level: 2023-09
- version: "5.15"
sub_level: 131
os_patch_level: 2023-11
- version: "5.15"
sub_level: 137
os_patch_level: 2024-01
- version: "5.15"
sub_level: 144
os_patch_level: 2024-03
- version: "6.1"
sub_level: 25
os_patch_level: 2023-10
- version: "6.1"
sub_level: 43
os_patch_level: 2023-11
- version: "6.1"
sub_level: 57
os_patch_level: 2024-01
- version: "6.1"
sub_level: 68
os_patch_level: 2024-02
uses: ./.github/workflows/gki-kernel.yml
secrets: inherit
with:
version: android14-${{ matrix.version }}
version_name: android14-${{ matrix.version }}.${{ matrix.sub_level }}
tag: android14-${{ matrix.version }}-${{ matrix.os_patch_level }}
os_patch_level: ${{ matrix.os_patch_level }}
patch_path: ${{ matrix.version }}
upload-artifacts:
needs: build-kernel
runs-on: ubuntu-latest
if: ${{ ( github.event_name != 'pull_request' && github.ref == 'refs/heads/main' ) || github.ref_type == 'tag' || github.ref == 'refs/heads/ci' }}
env:
CHAT_ID: ${{ secrets.CHAT_ID }}
BOT_TOKEN: ${{ secrets.BOT_TOKEN }}
MESSAGE_THREAD_ID: ${{ secrets.MESSAGE_THREAD_ID }}
COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
COMMIT_URL: ${{ github.event.head_commit.url }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
steps:
- name: Download artifacts
uses: actions/download-artifact@v4
- uses: actions/checkout@v4
with:
path: KernelSU
fetch-depth: 0
- name: List artifacts
run: |
tree
- name: Download prebuilt toolchain
run: |
AOSP_MIRROR=https://android.googlesource.com
BRANCH=main-kernel-build-2023
git clone $AOSP_MIRROR/platform/prebuilts/build-tools -b $BRANCH --depth 1 build-tools
git clone $AOSP_MIRROR/kernel/prebuilts/build-tools -b $BRANCH --depth 1 kernel-build-tools
git clone $AOSP_MIRROR/platform/system/tools/mkbootimg -b $BRANCH --depth 1
pip3 install telethon==1.31.1
- name: Set boot sign key
env:
BOOT_SIGN_KEY: ${{ secrets.BOOT_SIGN_KEY }}
run: |
if [ ! -z "$BOOT_SIGN_KEY" ]; then
echo "$BOOT_SIGN_KEY" > ./kernel-build-tools/linux-x86/share/avb/testkey_rsa2048.pem
fi
- name: Bot session cache
id: bot_session_cache
uses: actions/cache@v3
with:
path: scripts/ksubot.session
key: ${{ runner.os }}-bot-session
- name: Build boot images
run: |
export AVBTOOL=$GITHUB_WORKSPACE/kernel-build-tools/linux-x86/bin/avbtool
export GZIP=$GITHUB_WORKSPACE/build-tools/path/linux-x86/gzip
export LZ4=$GITHUB_WORKSPACE/build-tools/path/linux-x86/lz4
export MKBOOTIMG=$GITHUB_WORKSPACE/mkbootimg/mkbootimg.py
export UNPACK_BOOTIMG=$GITHUB_WORKSPACE/mkbootimg/unpack_bootimg.py
cd $GITHUB_WORKSPACE/KernelSU
export VERSION=$(($(git rev-list --count HEAD) + 10200))
echo "VERSION: $VERSION"
cd -
bash $GITHUB_WORKSPACE/KernelSU/.github/scripts/build_a13.sh
- name: Display structure of boot files
run: ls -R
- name: Upload images artifact
uses: actions/upload-artifact@v4
with:
name: boot-images-android14
path: Image-android14*/*.img.gz
check-build-kernel:
if: (github.event_name == 'pull_request' && !github.event.pull_request.draft) || github.ref == 'refs/heads/checkci'
strategy:
matrix:
include:
- version: "5.15"
sub_level: 110
os_patch_level: 2023-09
- version: "6.1"
sub_level: 68
os_patch_level: 2024-02
uses: ./.github/workflows/gki-kernel.yml
with:
version: android14-${{ matrix.version }}
version_name: android14-${{ matrix.version }}.${{ matrix.sub_level }}
tag: android14-${{ matrix.version }}-${{ matrix.os_patch_level }}
os_patch_level: ${{ matrix.os_patch_level }}
patch_path: ${{ matrix.version }}

View File

@@ -1,7 +1,7 @@
name: Build Kernel - ChromeOS ARCVM name: Build Kernel - ChromeOS ARCVM
on: on:
push: push:
branches: ["main"] branches: ["main", "ci", "checkci"]
paths: paths:
- ".github/workflows/build-kernel-arcvm.yml" - ".github/workflows/build-kernel-arcvm.yml"
- "kernel/**" - "kernel/**"
@@ -15,6 +15,7 @@ on:
jobs: jobs:
build: build:
if: github.event_name != 'pull_request' || (github.event_name == 'pull_request' && !github.event.pull_request.draft)
strategy: strategy:
matrix: matrix:
arch: [x86_64] arch: [x86_64]
@@ -59,10 +60,9 @@ jobs:
sudo ln -s --force /usr/bin/clang++-$LLVM_VERSION /usr/bin/clang++ sudo ln -s --force /usr/bin/clang++-$LLVM_VERSION /usr/bin/clang++
- name: Checkout KernelSU - name: Checkout KernelSU
uses: actions/checkout@v3 uses: actions/checkout@v4
with: with:
path: KernelSU path: KernelSU
ref: main
fetch-depth: 0 fetch-depth: 0
- name: Setup kernel source - name: Setup kernel source
@@ -82,7 +82,7 @@ jobs:
grep -q "kernelsu" $DRIVER_MAKEFILE || echo "obj-y += kernelsu/" >> $DRIVER_MAKEFILE grep -q "kernelsu" $DRIVER_MAKEFILE || echo "obj-y += kernelsu/" >> $DRIVER_MAKEFILE
echo "[+] Apply KernelSU patches" echo "[+] Apply KernelSU patches"
cd $KERNEL_ROOT && git apply $GITHUB_WORKSPACE/KernelSU/.github/patches/5.10/*.patch cd $KERNEL_ROOT && git apply $GITHUB_WORKSPACE/KernelSU/.github/patches/5.10/*.patch || echo "[-] No patch found"
echo "[+] Patch script/setlocalversion" echo "[+] Patch script/setlocalversion"
sed -i 's/-dirty//g' $KERNEL_ROOT/scripts/setlocalversion sed -i 's/-dirty//g' $KERNEL_ROOT/scripts/setlocalversion
@@ -98,6 +98,10 @@ jobs:
run: | run: |
set -a && . build.config.gki.x86_64; set +a set -a && . build.config.gki.x86_64; set +a
export DEFCONFIG=x86_64_arcvm_defconfig export DEFCONFIG=x86_64_arcvm_defconfig
if [ ! -z ${{ vars.EXPECTED_SIZE }} ] && [ ! -z ${{ vars.EXPECTED_HASH }} ]; then
export KSU_EXPECTED_SIZE=${{ vars.EXPECTED_SIZE }}
export KSU_EXPECTED_HASH=${{ vars.EXPECTED_HASH }}
fi
make LLVM=1 LLVM_IAS=1 DEPMOD=depmod DTC=dtc O=${PWD} mrproper make LLVM=1 LLVM_IAS=1 DEPMOD=depmod DTC=dtc O=${PWD} mrproper
make LLVM=1 LLVM_IAS=1 DEPMOD=depmod DTC=dtc O=${PWD} ${DEFCONFIG} < /dev/null make LLVM=1 LLVM_IAS=1 DEPMOD=depmod DTC=dtc O=${PWD} ${DEFCONFIG} < /dev/null
@@ -107,16 +111,23 @@ jobs:
echo "file_path=${PWD}/arch/x86/boot/bzImage" >> $GITHUB_ENV echo "file_path=${PWD}/arch/x86/boot/bzImage" >> $GITHUB_ENV
- name: Upload kernel-ARCVM-${{ matrix.arch }}-${{ matrix.version }} - name: Upload kernel-ARCVM-${{ matrix.arch }}-${{ matrix.version }}
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: kernel-ARCVM-${{ matrix.arch }}-${{ matrix.version }} name: kernel-ARCVM-${{ matrix.arch }}-${{ matrix.version }}
path: "${{ env.file_path }}" path: "${{ env.file_path }}"
- name: Bot session cache
if: ${{ ( github.event_name == 'push' && github.ref == 'refs/heads/main' ) || github.ref_type == 'tag' }}
id: bot_session_cache
uses: actions/cache@v3
with:
path: scripts/ksubot.session
key: ${{ runner.os }}-bot-session
- name: Post to Telegram - name: Post to Telegram
if: ${{ ( github.event_name == 'push' && github.ref == 'refs/heads/main' ) || github.ref_type == 'tag' }} if: ${{ ( github.event_name == 'push' && github.ref == 'refs/heads/main' ) || github.ref_type == 'tag' }}
env: env:
CHAT_ID: ${{ secrets.CHAT_ID }} CHAT_ID: ${{ secrets.CHAT_ID }}
CACHE_CHAT_ID: ${{ secrets.CACHE_CHAT_ID }}
BOT_TOKEN: ${{ secrets.BOT_TOKEN }} BOT_TOKEN: ${{ secrets.BOT_TOKEN }}
MESSAGE_THREAD_ID: ${{ secrets.MESSAGE_THREAD_ID }} MESSAGE_THREAD_ID: ${{ secrets.MESSAGE_THREAD_ID }}
COMMIT_MESSAGE: ${{ github.event.head_commit.message }} COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
@@ -132,6 +143,6 @@ jobs:
echo "[+] Image to upload" echo "[+] Image to upload"
ls -l "${{ env.file_path }}.gz" ls -l "${{ env.file_path }}.gz"
if [ -n "${{ secrets.BOT_TOKEN }}" ]; then if [ -n "${{ secrets.BOT_TOKEN }}" ]; then
pip3 install python-telegram-bot pip3 install telethon==1.31.1
python3 "$GITHUB_WORKSPACE/KernelSU/scripts/ksubot.py" "${{ env.file_path }}.gz" python3 "$GITHUB_WORKSPACE/KernelSU/scripts/ksubot.py" "${{ env.file_path }}.gz"
fi fi

37
.github/workflows/build-kernel-avd.yml vendored Normal file
View File

@@ -0,0 +1,37 @@
name: Build Kernel - AVD
on:
push:
branches: ["main", "ci", "checkci"]
paths:
- ".github/workflows/build-kernel-avd.yml"
- ".github/workflows/avd-kernel.yml"
- ".github/workflows/manifests/*xml"
- "kernel/**"
pull_request:
branches: ["main"]
paths:
- ".github/workflows/build-kernel-avd.yml"
- ".github/workflows/avd-kernel.yml"
- ".github/workflows/manifests/*.xml"
- "kernel/**"
workflow_call:
workflow_dispatch:
jobs:
build-kernel:
if: github.event_name != 'pull_request' && github.ref != 'refs/heads/checkci'
uses: ./.github/workflows/avd-kernel.yml
secrets: inherit
strategy:
matrix:
include:
- version: "android-14-avd_x86_64"
manifest: "android-14-avd_x86_64.xml"
arch: "x86_64"
- version: "android-15-avd_aarch64"
manifest: "android-15-avd_aarch64.xml"
arch: "aarch64"
with:
version_name: ${{ matrix.version }}
manifest_name: ${{ matrix.manifest }}
arch: ${{ matrix.arch }}
debug: true

View File

@@ -1,151 +1,38 @@
name: Build Kernel - WSA name: Build Kernel - WSA
on: on:
push: push:
branches: ["main"] branches: ["main", "ci", "checkci"]
paths: paths:
- ".github/workflows/build-kernel-wsa.yml" - ".github/workflows/build-kernel-wsa.yml"
- ".github/workflows/wsa-kernel.yml"
- "kernel/**" - "kernel/**"
pull_request: pull_request:
branches: ["main"] branches: ["main"]
paths: paths:
- ".github/workflows/build-kernel-wsa.yml" - ".github/workflows/build-kernel-wsa.yml"
- ".github/workflows/wsa-kernel.yml"
- "kernel/**" - "kernel/**"
workflow_call: workflow_call:
workflow_dispatch: workflow_dispatch:
jobs: jobs:
build: build:
if: github.event_name != 'pull_request' && github.ref != 'refs/heads/checkci'
strategy: strategy:
matrix: matrix:
arch: [x86_64, arm64] arch: [x86_64, arm64]
version: ["5.15.78.1", "5.15.94.4"] version: ["5.15.94.2", "5.15.104.1", "5.15.104.2", "5.15.104.3", "5.15.104.4"]
include: uses: ./.github/workflows/wsa-kernel.yml
- arch: x86_64 with:
file_name: "bzImage" arch: ${{ matrix.arch }}
- arch: arm64 version: ${{ matrix.version }}
file_name: "Image"
cross_compile: "aarch64-linux-gnu"
- version: "5.15.78.1"
arch: x86_64
make_config: config-wsa-x64
- version: "5.15.78.1"
arch: arm64
make_config: config-wsa-arm64
- version: "5.15.94.4"
arch: x86_64
make_config: config-wsa-x64
- version: "5.15.94.4"
arch: arm64
make_config: config-wsa-arm64
- version: "5.15.78.1"
device_code: latte-2
kernel_version: "5.15"
- version: "5.15.94.4"
device_code: latte-2
kernel_version: "5.15"
check_build:
name: Build WSA-Kernel-${{ matrix.version }}-${{ matrix.arch }} if: (github.event_name == 'pull_request' && !github.event.pull_request.draft) || github.ref == 'refs/heads/checkci'
runs-on: ubuntu-20.04 uses: ./.github/workflows/wsa-kernel.yml
env: strategy:
CCACHE_COMPILERCHECK: "%compiler% -dumpmachine; %compiler% -dumpversion" matrix:
CCACHE_NOHASHDIR: "true" arch: [x86_64, arm64]
CCACHE_HARDLINK: "true" with:
arch: ${{ matrix.arch }}
steps: version: "5.15.104.4"
- name: Install Build Tools
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends bc bison build-essential ca-certificates flex git gnupg libelf-dev libssl-dev lsb-release software-properties-common wget libncurses-dev binutils-aarch64-linux-gnu gcc-aarch64-linux-gnu nuget gzip
export LLVM_VERSION=12
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh $LLVM_VERSION
rm ./llvm.sh
sudo ln -s --force /usr/bin/clang-$LLVM_VERSION /usr/bin/clang
sudo ln -s --force /usr/bin/ld.lld-$LLVM_VERSION /usr/bin/ld.lld
sudo ln -s --force /usr/bin/llvm-objdump-$LLVM_VERSION /usr/bin/llvm-objdump
sudo ln -s --force /usr/bin/llvm-ar-$LLVM_VERSION /usr/bin/llvm-ar
sudo ln -s --force /usr/bin/llvm-nm-$LLVM_VERSION /usr/bin/llvm-nm
sudo ln -s --force /usr/bin/llvm-strip-$LLVM_VERSION /usr/bin/llvm-strip
sudo ln -s --force /usr/bin/llvm-objcopy-$LLVM_VERSION /usr/bin/llvm-objcopy
sudo ln -s --force /usr/bin/llvm-readelf-$LLVM_VERSION /usr/bin/llvm-readelf
sudo ln -s --force /usr/bin/clang++-$LLVM_VERSION /usr/bin/clang++
- name: Checkout KernelSU
uses: actions/checkout@v3
with:
path: KernelSU
ref: main
fetch-depth: 0
- name: Setup kernel source
uses: actions/checkout@v3
with:
repository: microsoft/WSA-Linux-Kernel
ref: android-lts/${{ matrix.device_code }}/${{ matrix.version }}
path: WSA-Linux-Kernel
- name: Setup Ccache
uses: hendrikmuhs/ccache-action@v1.2
with:
key: WSA-Kernel-${{ matrix.version }}-${{ matrix.arch }}
save: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
max-size: 2G
- name: Setup KernelSU
working-directory: WSA-Linux-Kernel
run: |
echo "[+] KernelSU setup"
KERNEL_ROOT=$GITHUB_WORKSPACE/WSA-Linux-Kernel
echo "[+] KERNEL_ROOT: $KERNEL_ROOT"
echo "[+] Copy KernelSU driver to $KERNEL_ROOT/drivers"
ln -sf $GITHUB_WORKSPACE/KernelSU/kernel $KERNEL_ROOT/drivers/kernelsu
echo "[+] Add KernelSU driver to Makefile"
DRIVER_MAKEFILE=$KERNEL_ROOT/drivers/Makefile
grep -q "kernelsu" $DRIVER_MAKEFILE || echo "obj-y += kernelsu/" >> $DRIVER_MAKEFILE
echo "[+] Apply KernelSU patches"
cd $KERNEL_ROOT && git apply $GITHUB_WORKSPACE/KernelSU/.github/patches/${{ matrix.kernel_version }}/*.patch
echo "[+] KernelSU setup done."
cd $GITHUB_WORKSPACE/KernelSU
VERSION=$(($(git rev-list --count HEAD) + 10200))
echo "VERSION: $VERSION"
echo "kernelsu_version=$VERSION" >> $GITHUB_ENV
- name: Build Kernel
working-directory: WSA-Linux-Kernel
run: |
cp configs/wsa/${{ matrix.make_config }} .config
make olddefconfig
make -j`nproc` LLVM=1 ARCH=${{ matrix.arch }} CROSS_COMPILE=${{ matrix.cross_compile }} ${{ matrix.file_name }} CCACHE="/usr/bin/ccache"
echo "file_path=WSA-Linux-Kernel/arch/${{ matrix.arch }}/boot/${{ matrix.file_name }}" >> $GITHUB_ENV
- name: Upload kernel-${{ matrix.arch }}-${{ matrix.version }}
uses: actions/upload-artifact@v3
with:
name: kernel-WSA-${{ matrix.arch }}-${{ matrix.version }}
path: "${{ env.file_path }}"
- name: Post to Telegram
if: ${{ ( github.event_name == 'push' && github.ref == 'refs/heads/main' ) || github.ref_type == 'tag' }}
env:
CHAT_ID: ${{ secrets.CHAT_ID }}
CACHE_CHAT_ID: ${{ secrets.CACHE_CHAT_ID }}
BOT_TOKEN: ${{ secrets.BOT_TOKEN }}
MESSAGE_THREAD_ID: ${{ secrets.MESSAGE_THREAD_ID }}
COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
COMMIT_URL: ${{ github.event.head_commit.url }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
run: |
TITLE=kernel-${{ matrix.arch }}-WSA-${{ matrix.version }}
echo "[+] title: $TITLE"
export TITLE
export VERSION="${{ env.kernelsu_version }}"
echo "[+] Compress images"
gzip -n -f -9 "${{ env.file_path }}"
echo "[+] Image to upload"
ls -l "${{ env.file_path }}.gz"
if [ -n "${{ secrets.BOT_TOKEN }}" ]; then
pip3 install python-telegram-bot
python3 "$GITHUB_WORKSPACE/KernelSU/scripts/ksubot.py" "${{ env.file_path }}.gz"
fi

View File

@@ -2,13 +2,13 @@ name: Build KSUD
on: on:
push: push:
branches: [ "main", "ci" ] branches: [ "main", "ci" ]
paths: paths:
- '.github/workflows/build-ksud.yml' - '.github/workflows/build-ksud.yml'
- '.github/workflows/ksud.yml' - '.github/workflows/ksud.yml'
- 'userspace/ksud/**' - 'userspace/ksud/**'
pull_request: pull_request:
branches: [ "main" ] branches: [ "main" ]
paths: paths:
- '.github/workflows/build-ksud.yml' - '.github/workflows/build-ksud.yml'
- '.github/workflows/ksud.yml' - '.github/workflows/ksud.yml'
- 'userspace/ksud/**' - 'userspace/ksud/**'
@@ -18,8 +18,20 @@ jobs:
matrix: matrix:
include: include:
- target: aarch64-linux-android - target: aarch64-linux-android
os: ubuntu-latest
- target: x86_64-linux-android - target: x86_64-linux-android
- target: x86_64-pc-windows-gnu # only for build os: ubuntu-latest
- target: x86_64-pc-windows-gnu # windows pc
os: ubuntu-latest
- target: x86_64-apple-darwin # Intel mac
os: macos-latest
- target: aarch64-apple-darwin # M chip mac
os: macos-latest
- target: aarch64-unknown-linux-musl # arm64 Linux
os: ubuntu-latest
- target: x86_64-unknown-linux-musl # x86 Linux
os: ubuntu-latest
uses: ./.github/workflows/ksud.yml uses: ./.github/workflows/ksud.yml
with: with:
target: ${{ matrix.target }} target: ${{ matrix.target }}
os: ${{ matrix.os }}

42
.github/workflows/build-lkm.yml vendored Normal file
View File

@@ -0,0 +1,42 @@
name: Build LKM for KernelSU
on:
push:
branches: ["main", "ci", "checkci"]
paths:
- ".github/workflows/gki-kernel.yml"
- ".github/workflows/build-lkm.yml"
- "kernel/**"
pull_request:
branches: ["main"]
paths:
- ".github/workflows/gki-kernel.yml"
- ".github/workflows/build-lkm.yml"
- "kernel/**"
workflow_call:
jobs:
build-lkm:
strategy:
matrix:
include:
- version: "android12-5.10"
sub_level: 198
os_patch_level: "2024-01"
- version: "android13-5.10"
sub_level: 198
os_patch_level: 2023-12
- version: "android13-5.15"
sub_level: 137
os_patch_level: 2023-12
- version: "android14-5.15"
sub_level: 110
os_patch_level: 2023-09
- version: "android14-6.1"
sub_level: 43
os_patch_level: 2023-11
uses: ./.github/workflows/gki-kernel.yml
with:
version: ${{ matrix.version }}
version_name: ${{ matrix.version }}.${{ matrix.sub_level }}
tag: ${{ matrix.version }}-${{ matrix.os_patch_level }}
os_patch_level: ${{ matrix.os_patch_level }}
build_lkm: true

View File

@@ -33,7 +33,7 @@ jobs:
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
@@ -50,15 +50,17 @@ jobs:
if: ${{ ( github.event_name != 'pull_request' && github.ref == 'refs/heads/main' ) || github.ref_type == 'tag' }} if: ${{ ( github.event_name != 'pull_request' && github.ref == 'refs/heads/main' ) || github.ref_type == 'tag' }}
run: | run: |
if [ ! -z "${{ secrets.KEYSTORE }}" ]; then if [ ! -z "${{ secrets.KEYSTORE }}" ]; then
echo KEYSTORE_PASSWORD='${{ secrets.KEYSTORE_PASSWORD }}' >> gradle.properties {
echo KEY_ALIAS='${{ secrets.KEY_ALIAS }}' >> gradle.properties echo KEYSTORE_PASSWORD='${{ secrets.KEYSTORE_PASSWORD }}'
echo KEY_PASSWORD='${{ secrets.KEY_PASSWORD }}' >> gradle.properties echo KEY_ALIAS='${{ secrets.KEY_ALIAS }}'
echo KEYSTORE_FILE='../key.jks' >> gradle.properties echo KEY_PASSWORD='${{ secrets.KEY_PASSWORD }}'
echo ${{ secrets.KEYSTORE }} | base64 --decode > key.jks echo KEYSTORE_FILE='../key.jks'
} >> gradle.properties
echo ${{ secrets.KEYSTORE }} | base64 -d > key.jks
fi fi
- name: Setup Java - name: Setup Java
uses: actions/setup-java@v3 uses: actions/setup-java@v4
with: with:
distribution: "temurin" distribution: "temurin"
java-version: "17" java-version: "17"
@@ -69,13 +71,13 @@ jobs:
gradle-home-cache-cleanup: true gradle-home-cache-cleanup: true
- name: Download arm64 ksud - name: Download arm64 ksud
uses: actions/download-artifact@v3 uses: actions/download-artifact@v4
with: with:
name: ksud-aarch64-linux-android name: ksud-aarch64-linux-android
path: . path: .
- name: Download x86_64 ksud - name: Download x86_64 ksud
uses: actions/download-artifact@v3 uses: actions/download-artifact@v4
with: with:
name: ksud-x86_64-linux-android name: ksud-x86_64-linux-android
path: . path: .
@@ -89,28 +91,39 @@ jobs:
- name: Build with Gradle - name: Build with Gradle
run: | run: |
echo 'org.gradle.parallel=true' >> gradle.properties {
echo 'org.gradle.vfs.watch=true' >> gradle.properties echo 'org.gradle.parallel=true'
echo 'org.gradle.jvmargs=-Xmx2048m' >> gradle.properties echo 'org.gradle.vfs.watch=true'
echo 'android.native.buildOutput=verbose' >> gradle.properties echo 'org.gradle.jvmargs=-Xmx2048m'
echo 'android.native.buildOutput=verbose'
} >> gradle.properties
sed -i 's/org.gradle.configuration-cache=true//g' gradle.properties sed -i 's/org.gradle.configuration-cache=true//g' gradle.properties
./gradlew clean assembleRelease ./gradlew clean assembleRelease
- name: Upload build artifact - name: Upload build artifact
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: manager name: manager
path: manager/app/build/outputs/apk/release/*.apk path: manager/app/build/outputs/apk/release/*.apk
- name: Setup mutex for uploading - name: Upload mappings
uses: ben-z/gh-action-mutex@v1.0-alpha-7 uses: actions/upload-artifact@v4
with:
name: "mappings"
path: "manager/app/build/outputs/mapping/release/"
- name: Bot session cache
if: github.event_name != 'pull_request' && steps.need_upload.outputs.UPLOAD == 'true' if: github.event_name != 'pull_request' && steps.need_upload.outputs.UPLOAD == 'true'
id: bot_session_cache
uses: actions/cache@v4
with:
path: scripts/ksubot.session
key: ${{ runner.os }}-bot-session
- name: Upload to telegram - name: Upload to telegram
if: github.event_name != 'pull_request' && steps.need_upload.outputs.UPLOAD == 'true' if: github.event_name != 'pull_request' && steps.need_upload.outputs.UPLOAD == 'true'
env: env:
CHAT_ID: ${{ secrets.CHAT_ID }} CHAT_ID: ${{ secrets.CHAT_ID }}
CACHE_CHAT_ID: ${{ secrets.CACHE_CHAT_ID }}
BOT_TOKEN: ${{ secrets.BOT_TOKEN }} BOT_TOKEN: ${{ secrets.BOT_TOKEN }}
MESSAGE_THREAD_ID: ${{ secrets.MESSAGE_THREAD_ID }} MESSAGE_THREAD_ID: ${{ secrets.MESSAGE_THREAD_ID }}
COMMIT_MESSAGE: ${{ github.event.head_commit.message }} COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
@@ -121,6 +134,6 @@ jobs:
if [ ! -z "${{ secrets.BOT_TOKEN }}" ]; then if [ ! -z "${{ secrets.BOT_TOKEN }}" ]; then
export VERSION=$(git rev-list --count HEAD) export VERSION=$(git rev-list --count HEAD)
APK=$(find ./app/build/outputs/apk/release -name "*.apk") APK=$(find ./app/build/outputs/apk/release -name "*.apk")
pip3 install python-telegram-bot pip3 install telethon==1.31.1
python3 $GITHUB_WORKSPACE/scripts/ksubot.py $APK python3 $GITHUB_WORKSPACE/scripts/ksubot.py $APK
fi fi

View File

@@ -1,21 +1,21 @@
name: Build SU name: Build SU
on: on:
push: push:
branches: [ "main" ] branches: [ "main", "ci" ]
paths: paths:
- '.github/workflows/build-su.yml' - '.github/workflows/build-su.yml'
- 'userspace/su/**' - 'userspace/su/**'
- 'scripts/ksubot.py' - 'scripts/ksubot.py'
pull_request: pull_request:
branches: [ "main" ] branches: [ "main" ]
paths: paths:
- 'userspace/su/**' - 'userspace/su/**'
jobs: jobs:
build-su: build-su:
name: Build userspace su name: Build userspace su
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Setup need_upload - name: Setup need_upload
@@ -28,24 +28,26 @@ jobs:
fi fi
- uses: nttld/setup-ndk@v1 - uses: nttld/setup-ndk@v1
with: with:
ndk-version: r25b ndk-version: r25c
local-cache: true
- name: Build su - name: Build su
working-directory: ./userspace/su working-directory: ./userspace/su
run: ndk-build run: ndk-build
- name: Upload a Build Artifact - name: Upload a Build Artifact
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: su name: su
path: ./userspace/su/libs path: ./userspace/su/libs
- name: Setup mutex for uploading - name: Bot session cache
uses: ben-z/gh-action-mutex@v1.0-alpha-7
if: github.event_name != 'pull_request' && steps.need_upload.outputs.UPLOAD == 'true' if: github.event_name != 'pull_request' && steps.need_upload.outputs.UPLOAD == 'true'
id: bot_session_cache
uses: actions/cache@v3
with:
path: scripts/ksubot.session
key: ${{ runner.os }}-bot-session
- name: Upload to telegram - name: Upload to telegram
if: github.event_name != 'pull_request' && steps.need_upload.outputs.UPLOAD == 'true' if: github.event_name != 'pull_request' && steps.need_upload.outputs.UPLOAD == 'true'
env: env:
CHAT_ID: ${{ secrets.CHAT_ID }} CHAT_ID: ${{ secrets.CHAT_ID }}
CACHE_CHAT_ID: ${{ secrets.CACHE_CHAT_ID }}
BOT_TOKEN: ${{ secrets.BOT_TOKEN }} BOT_TOKEN: ${{ secrets.BOT_TOKEN }}
MESSAGE_THREAD_ID: ${{ secrets.MESSAGE_THREAD_ID }} MESSAGE_THREAD_ID: ${{ secrets.MESSAGE_THREAD_ID }}
COMMIT_MESSAGE: ${{ github.event.head_commit.message }} COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
@@ -55,7 +57,7 @@ jobs:
run: | run: |
if [ ! -z "${{ secrets.BOT_TOKEN }}" ]; then if [ ! -z "${{ secrets.BOT_TOKEN }}" ]; then
export VERSION=$(git rev-list --count HEAD) export VERSION=$(git rev-list --count HEAD)
pip3 install python-telegram-bot pip3 install telethon==1.31.1
mv ./userspace/su/libs/arm64-v8a/su su-arm64 mv ./userspace/su/libs/arm64-v8a/su su-arm64
mv ./userspace/su/libs/x86_64/su su-x86_64 mv ./userspace/su/libs/x86_64/su su-x86_64
python3 scripts/ksubot.py su-arm64 su-x86_64 python3 scripts/ksubot.py su-arm64 su-x86_64

View File

@@ -21,7 +21,7 @@ jobs:
clippy: clippy:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
# cross build failed after Rust 1.68, see https://github.com/cross-rs/cross/issues/1222 # cross build failed after Rust 1.68, see https://github.com/cross-rs/cross/issues/1222
- run: rustup default 1.67.0 - run: rustup default 1.67.0
- uses: Swatinem/rust-cache@v2 - uses: Swatinem/rust-cache@v2
@@ -29,7 +29,7 @@ jobs:
workspaces: userspace/ksud workspaces: userspace/ksud
- name: Install cross - name: Install cross
run: cargo install cross run: cargo install cross --locked
- name: Run clippy - name: Run clippy
run: | run: |

View File

@@ -8,30 +8,60 @@ on:
paths: paths:
- '.github/workflows/deploy-website.yml' - '.github/workflows/deploy-website.yml'
- 'website/**' - 'website/**'
workflow_dispatch:
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: pages
cancel-in-progress: false
jobs: jobs:
deploy: # Build job
build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
defaults: defaults:
run: run:
working-directory: ./website working-directory: ./website
steps: steps:
- uses: actions/checkout@v3 - name: Checkout
uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0 # Not needed if lastUpdated is not enabled
- uses: actions/setup-node@v3 - name: Setup Node
uses: actions/setup-node@v4
with: with:
node-version: 16 node-version: 18
cache: yarn cache: yarn # or pnpm / yarn
cache-dependency-path: website/yarn.lock cache-dependency-path: website/yarn.lock
- run: yarn install --frozen-lockfile - name: Setup Pages
uses: actions/configure-pages@v4
- name: Build - name: Install dependencies
run: yarn docs:build run: yarn install --frozen-lockfile
- name: Build with VitePress
- name: Deploy run: |
uses: peaceiris/actions-gh-pages@v3 yarn docs:build
touch docs/.vitepress/dist/.nojekyll
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with: with:
github_token: ${{ secrets.GITHUB_TOKEN }} path: website/docs/.vitepress/dist
publish_dir: website/docs/.vitepress/dist
cname: kernelsu.org # if wanna deploy to custom domain # Deployment job
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
needs: build
runs-on: ubuntu-latest
name: Deploy
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4

View File

@@ -29,7 +29,7 @@ on:
for example: 2021-11 for example: 2021-11
default: 2022-05 default: 2022-05
patch_path: patch_path:
required: true required: false
type: string type: string
description: > description: >
Directory name of .github/patches/<patch_path> Directory name of .github/patches/<patch_path>
@@ -49,13 +49,15 @@ on:
required: false required: false
type: boolean type: boolean
default: false default: false
build_lkm:
required: false
type: boolean
default: false
secrets: secrets:
BOOT_SIGN_KEY: BOOT_SIGN_KEY:
required: false required: false
CHAT_ID: CHAT_ID:
required: false required: false
CACHE_CHAT_ID:
required: false
BOT_TOKEN: BOT_TOKEN:
required: false required: false
MESSAGE_THREAD_ID: MESSAGE_THREAD_ID:
@@ -70,7 +72,17 @@ jobs:
CCACHE_NOHASHDIR: "true" CCACHE_NOHASHDIR: "true"
CCACHE_HARDLINK: "true" CCACHE_HARDLINK: "true"
steps: steps:
- uses: actions/checkout@v3 - name: Maximize build space
uses: easimon/maximize-build-space@master
with:
root-reserve-mb: 8192
temp-reserve-mb: 2048
remove-dotnet: 'true'
remove-android: 'true'
remove-haskell: 'true'
remove-codeql: 'true'
- uses: actions/checkout@v4
with: with:
path: KernelSU path: KernelSU
fetch-depth: 0 fetch-depth: 0
@@ -86,17 +98,22 @@ jobs:
- name: Setup kernel source - name: Setup kernel source
run: | run: |
echo "Free space:"
df -h
cd $GITHUB_WORKSPACE cd $GITHUB_WORKSPACE
git clone https://gerrit.googlesource.com/git-repo sudo apt-get install repo -y
mkdir android-kernel && cd android-kernel mkdir android-kernel && cd android-kernel
../git-repo/repo init --depth=1 --u https://android.googlesource.com/kernel/manifest -b common-${{ inputs.tag }} repo init --depth=1 --u https://android.googlesource.com/kernel/manifest -b common-${{ inputs.tag }} --repo-rev=v2.16
REMOTE_BRANCH=$(git ls-remote https://android.googlesource.com/kernel/common ${{ inputs.tag }}) REMOTE_BRANCH=$(git ls-remote https://android.googlesource.com/kernel/common ${{ inputs.tag }})
DEFAULT_MANIFEST_PATH=.repo/manifests/default.xml
if grep -q deprecated <<< $REMOTE_BRANCH; then if grep -q deprecated <<< $REMOTE_BRANCH; then
echo "Found deprecated branch: ${{ inputs.tag }}" echo "Found deprecated branch: ${{ inputs.tag }}"
sed -i 's/"${{ inputs.tag }}"/"deprecated\/${{ inputs.tag }}"/g' .repo/manifests/default.xml sed -i 's/"${{ inputs.tag }}"/"deprecated\/${{ inputs.tag }}"/g' $DEFAULT_MANIFEST_PATH
cat .repo/manifests/default.xml cat $DEFAULT_MANIFEST_PATH
fi fi
../git-repo/repo sync -j$(nproc --all) repo --version
repo --trace sync -c -j$(nproc --all) --no-tags
df -h
- name: Setup KernelSU - name: Setup KernelSU
env: env:
@@ -111,16 +128,15 @@ jobs:
ln -sf $GITHUB_WORKSPACE/KernelSU/kernel $GKI_ROOT/common/drivers/kernelsu ln -sf $GITHUB_WORKSPACE/KernelSU/kernel $GKI_ROOT/common/drivers/kernelsu
echo "[+] Add KernelSU driver to Makefile" echo "[+] Add KernelSU driver to Makefile"
DRIVER_MAKEFILE=$GKI_ROOT/common/drivers/Makefile DRIVER_MAKEFILE=$GKI_ROOT/common/drivers/Makefile
grep -q "kernelsu" $DRIVER_MAKEFILE || echo "obj-y += kernelsu/" >> $DRIVER_MAKEFILE grep -q "kernelsu" $DRIVER_MAKEFILE || printf "\nobj-y += kernelsu/\n" >> $DRIVER_MAKEFILE
echo "[+] Apply KernelSU patches" echo "[+] Apply KernelSU patches"
cd $GKI_ROOT/common/ && git apply $GITHUB_WORKSPACE/KernelSU/.github/patches/$PATCH_PATH/*.patch cd $GKI_ROOT/common/ && git apply $GITHUB_WORKSPACE/KernelSU/.github/patches/$PATCH_PATH/*.patch || echo "[-] No patch found"
echo "[+] Patch script/setlocalversion"
sed -i 's/-dirty//g' $GKI_ROOT/common/scripts/setlocalversion
if [ "$IS_DEBUG_KERNEL" = "true" ]; then if [ "$IS_DEBUG_KERNEL" = "true" ]; then
echo "[+] Enable debug features for kernel" echo "[+] Enable debug features for kernel"
echo "ccflags-y += -DCONFIG_KSU_DEBUG" >> $GITHUB_WORKSPACE/KernelSU/kernel/Makefile printf "\nccflags-y += -DCONFIG_KSU_DEBUG\n" >> $GITHUB_WORKSPACE/KernelSU/kernel/Makefile
fi fi
repo status
echo "[+] KernelSU setup done." echo "[+] KernelSU setup done."
- name: Symbol magic - name: Symbol magic
@@ -142,29 +158,92 @@ jobs:
max-size: 2G max-size: 2G
save: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} save: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
- name: Build boot.img - name: Setup for LKM
if: ${{ inputs.build_lkm == true }}
working-directory: android-kernel working-directory: android-kernel
run: CCACHE="/usr/bin/ccache" LTO=thin BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh run: |
pip install ast-grep-cli
sudo apt-get install llvm-15 -y
ast-grep -U -p '$$$ check_exports($$$) {$$$}' -r '' common/scripts/mod/modpost.c
ast-grep -U -p 'check_exports($$$);' -r '' common/scripts/mod/modpost.c
sed -i '1i KSU_MODULE := 1' $GITHUB_WORKSPACE/KernelSU/kernel/Makefile
echo "drivers/kernelsu/kernelsu.ko" >> common/android/gki_aarch64_modules
# bazel build, android14-5.15, android14-6.1 use bazel
if [ ! -e build/build.sh ]; then
sed -i 's/needs unknown symbol/Dont abort when unknown symbol/g' build/kernel/*.sh || echo "No unknown symbol scripts found"
if [ -e common/modules.bzl ]; then
sed -i 's/_COMMON_GKI_MODULES_LIST = \[/_COMMON_GKI_MODULES_LIST = \[ "drivers\/kernelsu\/kernelsu.ko",/g' common/modules.bzl
fi
else
TARGET_FILE="build/kernel/build.sh"
if [ ! -e "$TARGET_FILE" ]; then
TARGET_FILE="build/build.sh"
fi
sed -i 's/needs unknown symbol/Dont abort when unknown symbol/g' $TARGET_FILE || echo "No unknown symbol in $TARGET_FILE"
sed -i 's/if ! diff -u "\${KERNEL_DIR}\/\${MODULES_ORDER}" "\${OUT_DIR}\/modules\.order"; then/if false; then/g' $TARGET_FILE
sed -i 's@${ROOT_DIR}/build/abi/compare_to_symbol_list@echo@g' $TARGET_FILE
sed -i 's/needs unknown symbol/Dont abort when unknown symbol/g' build/kernel/*.sh || echo "No unknown symbol scripts found"
fi
- name: Make working directory clean to avoid dirty
working-directory: android-kernel
run: |
rm common/android/abi_gki_protected_exports_* || echo "No protected exports!"
git config --global user.email "bot@kernelsu.org"
git config --global user.name "KernelSUBot"
cd common/ && git add -A && git commit -a -m "Add KernelSU"
repo status
- name: Build Kernel/LKM
working-directory: android-kernel
run: |
if [ ! -z ${{ vars.EXPECTED_SIZE }} ] && [ ! -z ${{ vars.EXPECTED_HASH }} ]; then
export KSU_EXPECTED_SIZE=${{ vars.EXPECTED_SIZE }}
export KSU_EXPECTED_HASH=${{ vars.EXPECTED_HASH }}
fi
if [ -e build/build.sh ]; then
LTO=thin BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh CC="/usr/bin/ccache clang"
else
tools/bazel run --disk_cache=/home/runner/.cache/bazel --config=fast --config=stamp --lto=thin //common:kernel_aarch64_dist -- --dist_dir=dist
fi
- name: Prepare artifacts - name: Prepare artifacts
id: prepareArtifacts id: prepareArtifacts
run: | run: |
OUTDIR=android-kernel/out/${{ inputs.version }}/dist OUTDIR=android-kernel/out/${{ inputs.version }}/dist
if [ ! -e $OUTDIR ]; then
OUTDIR=android-kernel/dist
fi
mkdir output mkdir output
cp $OUTDIR/Image ./output/ if [ "${{ inputs.build_lkm}}" = "true" ]; then
cp $OUTDIR/Image.lz4 ./output/ llvm-strip-15 -d $OUTDIR/kernelsu.ko
git clone https://github.com/Kernel-SU/AnyKernel3 mv $OUTDIR/kernelsu.ko ./output/${{ inputs.version }}_kernelsu.ko
rm -rf ./AnyKernel3/.git else
cp $OUTDIR/Image ./AnyKernel3/ cp $OUTDIR/Image ./output/
cp $OUTDIR/Image.lz4 ./output/
git clone https://github.com/Kernel-SU/AnyKernel3
rm -rf ./AnyKernel3/.git
cp $OUTDIR/Image ./AnyKernel3/
fi
- name: Upload Image and Image.gz - name: Upload Image and Image.gz
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
if: ${{ inputs.build_lkm == false }}
with: with:
name: Image-${{ inputs.version_name }}_${{ inputs.os_patch_level }} name: Image-${{ inputs.version_name }}_${{ inputs.os_patch_level }}
path: ./output/* path: ./output/*
- name: Upload AnyKernel3 - name: Upload AnyKernel3
uses: actions/upload-artifact@v3 if: ${{ inputs.build_lkm == false }}
uses: actions/upload-artifact@v4
with: with:
name: AnyKernel3-${{ inputs.version_name }}_${{ inputs.os_patch_level }} name: AnyKernel3-${{ inputs.version_name }}_${{ inputs.os_patch_level }}
path: ./AnyKernel3/* path: ./AnyKernel3/*
- name: Upload LKM
uses: actions/upload-artifact@v4
if: ${{ inputs.build_lkm == true }}
with:
name: ${{ inputs.version }}_lkm
path: ./output/*_kernelsu.ko

View File

@@ -5,32 +5,40 @@ on:
target: target:
required: true required: true
type: string type: string
os:
required: false
type: string
default: ubuntu-latest
use_cache: use_cache:
required: false required: false
type: boolean type: boolean
default: true default: true
jobs: jobs:
build: build:
runs-on: ubuntu-latest runs-on: ${{ inputs.os }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
# cross build failed after Rust 1.68, see https://github.com/cross-rs/cross/issues/1222 # cross build failed after Rust 1.68, see https://github.com/cross-rs/cross/issues/1222
- run: rustup default 1.67.0 - name: Setup rustup
run: |
rustup default 1.67.0
rustup target add x86_64-apple-darwin
rustup target add aarch64-apple-darwin
- uses: Swatinem/rust-cache@v2 - uses: Swatinem/rust-cache@v2
with: with:
workspaces: userspace/ksud workspaces: userspace/ksud
cache-targets: false cache-targets: false
- name: Install cross - name: Install cross
run: cargo install cross run: cargo install cross --locked
- name: Build ksud - name: Build ksud
run: cross build --target ${{ inputs.target }} --release --manifest-path ./userspace/ksud/Cargo.toml run: cross build --target ${{ inputs.target }} --release --manifest-path ./userspace/ksud/Cargo.toml
- name: Upload ksud artifact - name: Upload ksud artifact
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: ksud-${{ inputs.target }} name: ksud-${{ inputs.target }}
path: userspace/ksud/target/**/release/ksud path: userspace/ksud/target/**/release/ksud*

View File

@@ -9,22 +9,37 @@ jobs:
build-manager: build-manager:
uses: ./.github/workflows/build-manager.yml uses: ./.github/workflows/build-manager.yml
secrets: inherit secrets: inherit
build-lkm:
uses: ./.github/workflows/build-lkm.yml
secrets: inherit
build-a12-kernel: build-a12-kernel:
uses: ./.github/workflows/build-kernel-a12.yml uses: ./.github/workflows/build-kernel-a12.yml
secrets: inherit
build-a13-kernel: build-a13-kernel:
uses: ./.github/workflows/build-kernel-a13.yml uses: ./.github/workflows/build-kernel-a13.yml
secrets: inherit
build-a14-kernel:
uses: ./.github/workflows/build-kernel-a14.yml
secrets: inherit
build-wsa-kernel: build-wsa-kernel:
uses: ./.github/workflows/build-kernel-wsa.yml uses: ./.github/workflows/build-kernel-wsa.yml
secrets: inherit
build-arcvm-kernel:
uses: ./.github/workflows/build-kernel-arcvm.yml
secrets: inherit
release: release:
needs: needs:
- build-manager - build-manager
- build-lkm
- build-a12-kernel - build-a12-kernel
- build-a13-kernel - build-a13-kernel
- build-a14-kernel
- build-wsa-kernel - build-wsa-kernel
- build-arcvm-kernel
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Download artifacts - name: Download artifacts
uses: actions/download-artifact@v3 uses: actions/download-artifact@v4
- name: Zip AnyKernel3 - name: Zip AnyKernel3
run: | run: |
for dir in AnyKernel3-*; do for dir in AnyKernel3-*; do
@@ -43,6 +58,15 @@ jobs:
fi fi
done done
- name: Zip ChromeOS ARCVM kernel
run: |
for dir in kernel-ARCVM-*; do
if [ -d "$dir" ]; then
echo "------ Zip $dir ----------"
(cd $dir && zip -r9 "$dir".zip ./* -x .git .gitignore ./*.zip && mv *.zip ..)
fi
done
- name: Display structure of downloaded files - name: Display structure of downloaded files
run: ls -R run: ls -R
@@ -51,6 +75,8 @@ jobs:
with: with:
files: | files: |
manager/*.apk manager/*.apk
*-lkm/*_kernelsu.ko
AnyKernel3-*.zip AnyKernel3-*.zip
boot-images-*/Image-*/*.img.gz boot-images-*/Image-*/*.img.gz
kernel-WSA*.zip kernel-WSA*.zip
kernel-ARCVM*.zip

View File

@@ -21,13 +21,13 @@ jobs:
format: format:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly - uses: dtolnay/rust-toolchain@nightly
with: with:
components: rustfmt components: rustfmt
- uses: LoliGothick/rustfmt-check@v0.3.1 - uses: LoliGothick/rustfmt-check@master
with: with:
token: ${{ github.token }} token: ${{ github.token }}
options: --manifest-path userspace/ksud/Cargo.toml working-directory: userspace/ksud

View File

@@ -18,7 +18,7 @@ jobs:
shellcheck: shellcheck:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Run ShellCheck - name: Run ShellCheck
uses: ludeeus/action-shellcheck@2.0.0 uses: ludeeus/action-shellcheck@2.0.0

135
.github/workflows/wsa-kernel.yml vendored Normal file
View File

@@ -0,0 +1,135 @@
name: Build Kernel - WSA
on:
workflow_call:
inputs:
arch:
required: true
type: string
description: >
Build arch: x86_64 / arm64
version:
required: true
type: string
description: >
Build version
jobs:
build:
name: Build WSA-Kernel-${{ inputs.version }}-${{ inputs.arch }}
runs-on: ubuntu-20.04
env:
CCACHE_COMPILERCHECK: "%compiler% -dumpmachine; %compiler% -dumpversion"
CCACHE_NOHASHDIR: "true"
CCACHE_HARDLINK: "true"
steps:
- name: Install Build Tools
uses: awalsh128/cache-apt-pkgs-action@v1
with:
packages: bc bison build-essential flex libelf-dev binutils-aarch64-linux-gnu gcc-aarch64-linux-gnu gzip ccache
version: 1.0
- name: Cache LLVM
id: cache-llvm
uses: actions/cache@v3
with:
path: ./llvm
key: llvm-12.0.1
- name: Setup LLVM
uses: KyleMayes/install-llvm-action@v1
with:
version: "12.0.1"
force-version: true
ubuntu-version: "16.04"
cached: ${{ steps.cache-llvm.outputs.cache-hit }}
- name: Checkout KernelSU
uses: actions/checkout@v4
with:
path: KernelSU
fetch-depth: 0
- name: Setup kernel source
uses: actions/checkout@v4
with:
repository: microsoft/WSA-Linux-Kernel
ref: android-lts/latte-2/${{ inputs.version }}
path: WSA-Linux-Kernel
- name: Setup Ccache
uses: hendrikmuhs/ccache-action@v1.2
with:
key: WSA-Kernel-${{ inputs.version }}-${{ inputs.arch }}
save: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
max-size: 2G
- name: Setup KernelSU
working-directory: WSA-Linux-Kernel
run: |
echo "[+] KernelSU setup"
KERNEL_ROOT=$GITHUB_WORKSPACE/WSA-Linux-Kernel
echo "[+] KERNEL_ROOT: $KERNEL_ROOT"
echo "[+] Copy KernelSU driver to $KERNEL_ROOT/drivers"
ln -sf $GITHUB_WORKSPACE/KernelSU/kernel $KERNEL_ROOT/drivers/kernelsu
echo "[+] Add KernelSU driver to Makefile"
DRIVER_MAKEFILE=$KERNEL_ROOT/drivers/Makefile
grep -q "kernelsu" $DRIVER_MAKEFILE || echo "obj-y += kernelsu/" >> $DRIVER_MAKEFILE
echo "[+] Apply KernelSU patches"
cd $KERNEL_ROOT && git apply $GITHUB_WORKSPACE/KernelSU/.github/patches/5.15/*.patch || echo "[-] No patch found"
echo "[+] KernelSU setup done."
cd $GITHUB_WORKSPACE/KernelSU
VERSION=$(($(git rev-list --count HEAD) + 10200))
echo "VERSION: $VERSION"
echo "kernelsu_version=$VERSION" >> $GITHUB_ENV
- name: Build Kernel
working-directory: WSA-Linux-Kernel
run: |
if [ ! -z ${{ vars.EXPECTED_SIZE }} ] && [ ! -z ${{ vars.EXPECTED_HASH }} ]; then
export KSU_EXPECTED_SIZE=${{ vars.EXPECTED_SIZE }}
export KSU_EXPECTED_HASH=${{ vars.EXPECTED_HASH }}
fi
declare -A ARCH_MAP=(["x86_64"]="x64" ["arm64"]="arm64")
cp configs/wsa/config-wsa-${ARCH_MAP[${{ inputs.arch }}]} .config
make olddefconfig
declare -A FILE_NAME=(["x86_64"]="bzImage" ["arm64"]="Image")
make -j`nproc` LLVM=1 ARCH=${{ inputs.arch }} $(if [ "${{ inputs.arch }}" == "arm64" ]; then echo CROSS_COMPILE=aarch64-linux-gnu; fi) ${FILE_NAME[${{ inputs.arch }}]} CCACHE="/usr/bin/ccache"
declare -A ARCH_MAP_FILE=(["x86_64"]="x86" ["arm64"]="arm64")
echo "file_path=WSA-Linux-Kernel/arch/${ARCH_MAP_FILE[${{ inputs.arch }}]}/boot/${FILE_NAME[${{ inputs.arch }}]}" >> $GITHUB_ENV
- name: Upload kernel-${{ inputs.arch }}-${{ inputs.version }}
uses: actions/upload-artifact@v4
with:
name: kernel-WSA-${{ inputs.arch }}-${{ inputs.version }}
path: "${{ env.file_path }}"
- name: Bot session cache
if: github.event_name == 'push' && github.ref == 'refs/heads/main' || github.ref_type == 'tag'
id: bot_session_cache
uses: actions/cache@v3
with:
path: scripts/ksubot.session
key: ${{ runner.os }}-bot-session
- name: Post to Telegram
if: github.event_name == 'push' && github.ref == 'refs/heads/main' || github.ref_type == 'tag'
env:
CHAT_ID: ${{ secrets.CHAT_ID }}
BOT_TOKEN: ${{ secrets.BOT_TOKEN }}
MESSAGE_THREAD_ID: ${{ secrets.MESSAGE_THREAD_ID }}
COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
COMMIT_URL: ${{ github.event.head_commit.url }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
run: |
TITLE=kernel-${{ inputs.arch }}-WSA-${{ inputs.version }}
echo "[+] title: $TITLE"
export TITLE
export VERSION="${{ env.kernelsu_version }}"
echo "[+] Compress images"
gzip -n -f -9 "${{ env.file_path }}"
echo "[+] Image to upload"
ls -l "${{ env.file_path }}.gz"
if [ -n "${{ secrets.BOT_TOKEN }}" ]; then
pip3 install telethon==1.31.1
python3 "$GITHUB_WORKSPACE/KernelSU/scripts/ksubot.py" "${{ env.file_path }}.gz"
fi

View File

@@ -1,42 +0,0 @@
**English** | [简体中文](README_CN.md) | [繁體中文](README_TW.md) | [日本語](README_JP.md) | [Portuguese-Brazil](README_PT-BR.md) | [Türkçe](README_TR.md)
# KernelSU
A Kernel based root solution for Android devices.
## Features
1. Kernel-based `su` and root access management.
2. Module system based on overlayfs.
## Compatibility State
KernelSU officially supports Android GKI 2.0 devices(with kernel 5.10+), old kernels(4.14+) is also compatible, but you need to build kernel yourself.
WSA and containter-based Android should also work with KernelSU integrated.
And the current supported ABIs are : `arm64-v8a` and `x86_64`
## Usage
[Installation](https://kernelsu.org/guide/installation.html)
## Build
[How to build?](https://kernelsu.org/guide/how-to-build.html)
### Discussion
- Telegram: [@KernelSU](https://t.me/KernelSU)
## License
- Files under `kernel` directory are [GPL-2](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
- All other parts except `kernel` directory are [GPL-3](https://www.gnu.org/licenses/gpl-3.0.html)
## Credits
- [kernel-assisted-superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/): the KernelSU idea.
- [genuine](https://github.com/brevent/genuine/): apk v2 signature validation.
- [Diamorphine](https://github.com/m0nad/Diamorphine): some rootkit skills.
- [Magisk](https://github.com/topjohnwu/Magisk): the sepolicy implementation.

View File

@@ -1,42 +0,0 @@
[English](README.md) | **简体中文** | [繁體中文](README_TW.md) | [日本語](README_JP.md) | [Portuguese-Brazil](README_PT-BR.md) | [Türkçe](README_TR.md)
# KernelSU
一个 Android 上基于内核的 root 方案。
## 特性
- 基于内核的 su 和权限管理。
- 基于 overlayfs 的模块系统。
## 兼容状态
KernelSU 官方支持 GKI 2.0 的设备内核版本5.10以上旧内核也是兼容的最低4.14+),不过需要自己编译内核。
WSA 和运行在容器上的 Android 也可以与 KernelSU 一起工作。
目前支持架构 : `arm64-v8a``x86_64`
## 使用方法
[安装教程](https://kernelsu.org/zh_CN/guide/installation.html)
## 构建
[如何构建?](https://kernelsu.org/zh_CN/guide/how-to-build.html)
### 讨论
- Telegram: [@KernelSU](https://t.me/KernelSU)
## 许可证
- 目录 `kernel` 下所有文件为 [GPL-2](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
-`kernel` 目录的其他部分均为 [GPL-3](https://www.gnu.org/licenses/gpl-3.0.html)
## 鸣谢
- [kernel-assisted-superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/)KernelSU 的灵感。
- [genuine](https://github.com/brevent/genuine/)apk v2 签名验证。
- [Diamorphine](https://github.com/m0nad/Diamorphine):一些 rootkit 技巧。
- [Magisk](https://github.com/topjohnwu/Magisk)sepolicy 的实现。

View File

@@ -1,42 +0,0 @@
[English](README.md) | [简体中文](README_CN.md) | [繁體中文](README_TW.md) | **日本語** | [Portuguese-Brazil](README_PT-BR.md) | [Türkçe](README_TR.md)
# KernelSU
Android におけるカーネルベースの root ソリューションです。
## 特徴
1. カーネルベースの `su` と権限管理
2. OverlayFS に基づくモジュールシステム
## 対応状況
KernelSU は GKI 2.0 デバイス(カーネルバージョン 5.10 以上を公式にサポートしています。古いカーネル4.14以上)とも互換性がありますが、自分でカーネルをビルドする必要があります。
WSA とコンテナ上で動作する Android でも KernelSU を統合して動かせます。
現在サポートしているアーキテクチャは `arm64-v8a` および `x86_64` です。
## 使用方法
[インストール方法はこちら](https://kernelsu.org/ja_JP/guide/installation.html)
## ビルド
[ビルド方法はこちら](https://kernelsu.org/guide/how-to-build.html)
### ディスカッション
- Telegram: [@KernelSU](https://t.me/KernelSU)
## ライセンス
- `kernel` ディレクトリの下にあるすべてのファイル: [GPL-2](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
- `kernel` ディレクトリ以外のすべてのファイル: [GPL-3](https://www.gnu.org/licenses/gpl-3.0.html)
## クレジット
- [kernel-assisted-superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/)KernelSU のアイデア元
- [genuine](https://github.com/brevent/genuine/)apk v2 の署名検証
- [Diamorphine](https://github.com/m0nad/Diamorphine): rootkit のスキル
- [Magisk](https://github.com/topjohnwu/Magisk)sepolicy の実装

View File

@@ -1,47 +0,0 @@
[English](README.md) | [简体中文](README_CN.md) | [繁體中文](README_TW.md) | [日本語](README_JP.md) | **Portuguese-Brazil** | [Türkçe](README_TR.md)
# KernelSU
Uma solução raiz baseada em Kernel para dispositivos Android.
## Características
1. `su` baseado em kernel e gerenciamento de acesso root.
2. Sistema modular baseado em overlayfs.
## Estado de compatibilidade
O KernelSU suporta oficialmente dispositivos Android GKI 2.0 (com kernel 5.10+), kernels antigos (4.14+) também são compatíveis, mas você mesmo precisa construir o kernel.
O Android baseado em WSA e contêiner também deve funcionar com o KernelSU integrado.
E os ABIs atualmente suportados são: `arm64-v8a` e `x86_64`
## Uso
[Instalação](https://kernelsu.org/guide/installation.html)
## Construir
[Como construir?](https://kernelsu.org/guide/how-to-build.html)
### Discussão
- Telegram: [@KernelSU](https://t.me/KernelSU)
## Licença
- Os arquivos no diretório `kernel` são [GPL-2](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
- Todas as outras partes, exceto o diretório `kernel`, são [GPL-3](https://www.gnu.org/licenses/gpl-3.0.html)
## Créditos
- [kernel-assisted-superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/): a ideia do KernelSU.
- [genuine](https://github.com/brevent/genuine/): validação de assinatura apk v2.
- [Diamorphine](https://github.com/m0nad/Diamorphine): algumas habilidades de rootkit.
- [Magisk](https://github.com/topjohnwu/Magisk): a implementação da sepolicy.

View File

@@ -1,42 +0,0 @@
[English](README.md) | [简体中文](README_CN.md) | [繁體中文](README_TW.md) | [日本語](README_JP.md) | [Portuguese-Brazil](README_PT-BR.md) | **Türkçe**
# KernelSU
Android cihazlar için kernel tabanlı bir root çözümü.
## Özellikler
1. Kernel-tabanlı `su` ve root erişimi yönetimi.
2. Overlayfs'ye dayalı modül sistemi.
## Uyumluluk Durumu
KernelSU resmi olarak Android GKI 2.0 cihazlarını ( 5.10+ kernelli) destekler, eski kernellerle de (4.14+) uyumludur, ancak kerneli kendinizin inşaa etmesi gerekir.
WSA ve konteyner tabanlı Android'in de, KernelSU ile entegre olarak da çalışması gerekmektedir.
Ve desteklenen mevcut ABI'ler : `arm64-v8a` ve `x86_64`
## Kullanım
[Yükleme](https://kernelsu.org/guide/installation.html)
## İnşaa
[Nasıl inşa edilir?](https://kernelsu.org/guide/how-to-build.html)
### Tartışma
- Telegram: [@KernelSU](https://t.me/KernelSU)
## Lisans
- `kernel` klasöründeki dosyalar [GPL-2](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html) lisansı altındadır.
- `kernel` klasörü dışındaki bütün diğer bölümler [GPL-3](https://www.gnu.org/licenses/gpl-3.0.html) lisansı altındadır.
## Krediler
- [kernel-assisted-superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/): KernelSU fikri.
- [genuine](https://github.com/brevent/genuine/): apk v2 imza doğrulama.
- [Diamorphine](https://github.com/m0nad/Diamorphine): bazı rootkit becerileri.
- [Magisk](https://github.com/topjohnwu/Magisk): sepolicy uygulaması.

View File

@@ -1,42 +0,0 @@
[English](README.md) | [简体中文](README_CN.md) | **繁體中文** | [日本語](README_JP.md) | [Portuguese-Brazil](README_PT-BR.md) | [Türkçe](README_TR.md)
# KernelSU
一個基於核心的 Android 裝置 Root 解決方案
## 功能
- 基於核心的 Su 和 Root 存取權管理。
- 基於 Overlayfs 的模組系統。
## 相容性狀態
KernelSU 官方支援 Android GKI 2.0 的裝置 (核心版本 5.10+);舊版核心同樣相容 (最低 4.14+),但需要自行編譯核心。
WSA 和執行在容器中的 Android 也可以與 KernelSU 一同運作。
目前支援架構:`arm64-v8a``x86_64`
## 使用方法
[安裝教學](https://kernelsu.org/zh_TW/guide/installation.html)
## 建置
[如何建置?](https://kernelsu.org/zh_TW/guide/how-to-build.html)
### 討論
- Telegram[@KernelSU](https://t.me/KernelSU)
## 授權
- 目錄 `kernel` 下所有檔案為 [GPL-2](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
-`kernel` 目錄的其他部分均為 [GPL-3](https://www.gnu.org/licenses/gpl-3.0.html)
## 致謝
- [kernel-assisted-superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/)KernelSU 的靈感。
- [genuine](https://github.com/brevent/genuine/)apk v2 簽章驗證。
- [Diamorphine](https://github.com/m0nad/Diamorphine):一些 rootkit 技巧。
- [Magisk](https://github.com/topjohnwu/Magisk)sepolicy 實作。

7
SECURITY.md Normal file
View File

@@ -0,0 +1,7 @@
# Reporting Security Issues
The KernelSU team and community take security bugs in KernelSU seriously. We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions.
To report a security issue, please use the GitHub Security Advisory ["Report a Vulnerability"](https://github.com/tiann/KernelSU/security/advisories/new) tab, or you can mailto [weishu](mailto:twsxtd@gmail.com) directly.
The KernelSU team will send a response indicating the next steps in handling your report. After the initial reply to your report, the security team will keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance.

57
docs/README.md Normal file
View File

@@ -0,0 +1,57 @@
**English** | [Español](README_ES.md) | [简体中文](README_CN.md) | [繁體中文](README_TW.md) | [日本語](README_JP.md) | [Polski](README_PL.md) | [Português (Brasil)](README_PT-BR.md) | [Türkçe](README_TR.md) | [Русский](README_RU.md) | [Tiếng Việt](README_VI.md) | [Indonesia](README_ID.md) | [עברית](README_IW.md) | [हिंदी](README_IN.md)
# KernelSU
<img src="https://kernelsu.org/logo.png" style="width: 96px;" alt="logo">
A Kernel-based root solution for Android devices.
[![Latest release](https://img.shields.io/github/v/release/tiann/KernelSU?label=Release&logo=github)](https://github.com/tiann/KernelSU/releases/latest)
[![Weblate](https://img.shields.io/badge/Localization-Weblate-teal?logo=weblate)](https://hosted.weblate.org/engage/kernelsu)
[![Channel](https://img.shields.io/badge/Follow-Telegram-blue.svg?logo=telegram)](https://t.me/KernelSU)
[![License: GPL v2](https://img.shields.io/badge/License-GPL%20v2-orange.svg?logo=gnu)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
[![GitHub License](https://img.shields.io/github/license/tiann/KernelSU?logo=gnu)](/LICENSE)
## Features
1. Kernel-based `su` and root access management.
2. Module system based on [OverlayFS](https://en.wikipedia.org/wiki/OverlayFS).
3. [App Profile](https://kernelsu.org/guide/app-profile.html): Lock up the root power in a cage.
## Compatibility State
KernelSU officially supports Android GKI 2.0 devices (kernel 5.10+). Older kernels (4.14+) are also compatible, but the kernel will have to be built manually.
With this, WSA, ChromeOS, and container-based Android are all supported.
Currently, only `arm64-v8a` and `x86_64` are supported.
## Usage
- [Installation Instruction](https://kernelsu.org/guide/installation.html)
- [How to build?](https://kernelsu.org/guide/how-to-build.html)
- [Official Website](https://kernelsu.org/)
## Translation
To help translate KernelSU or improve existing translations, please use [Weblate](https://hosted.weblate.org/engage/kernelsu/). PR of Manager's translation is no longer accepted, because it will conflict with Weblate.
## Discussion
- Telegram: [@KernelSU](https://t.me/KernelSU)
## Security
For information on reporting security vulnerabilities in KernelSU, see [SECURITY.md](/SECURITY.md).
## License
- Files under the `kernel` directory are [GPL-2.0-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html).
- All other parts except the `kernel` directory are [GPL-3.0-or-later](https://www.gnu.org/licenses/gpl-3.0.html).
## Credits
- [kernel-assisted-superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/): the KernelSU idea.
- [Magisk](https://github.com/topjohnwu/Magisk): the powerful root tool.
- [genuine](https://github.com/brevent/genuine/): apk v2 signature validation.
- [Diamorphine](https://github.com/m0nad/Diamorphine): some rootkit skills.

57
docs/README_CN.md Normal file
View File

@@ -0,0 +1,57 @@
[English](README.md) | [Español](README_ES.md) | **简体中文** | [繁體中文](README_TW.md) | [日本語](README_JP.md) | [Polski](README_PL.md) | [Português (Brasil)](README_PT-BR.md) | [Türkçe](README_TR.md) | [Русский](README_RU.md) | [Tiếng Việt](README_VI.md) | [Indonesia](README_ID.md) | [עברית](README_IW.md) | [हिंदी](README_IN.md)
# KernelSU
<img src="https://kernelsu.org/logo.png" style="width: 96px;" alt="logo">
一个 Android 上基于内核的 root 方案。
[![Latest release](https://img.shields.io/github/v/release/tiann/KernelSU?label=Release&logo=github)](https://github.com/tiann/KernelSU/releases/latest)
[![Weblate](https://img.shields.io/badge/Localization-Weblate-teal?logo=weblate)](https://hosted.weblate.org/engage/kernelsu)
[![Channel](https://img.shields.io/badge/Follow-Telegram-blue.svg?logo=telegram)](https://t.me/KernelSU)
[![License: GPL v2](https://img.shields.io/badge/License-GPL%20v2-orange.svg?logo=gnu)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
[![GitHub License](https://img.shields.io/github/license/tiann/KernelSU?logo=gnu)](/LICENSE)
## 特性
- 基于内核的 `su` 和权限管理。
- 基于 [OverlayFS](https://en.wikipedia.org/wiki/OverlayFS) 的模块系统。
- [App Profile](https://kernelsu.org/zh_CN/guide/app-profile.html): 把 Root 权限关进笼子里。
## 兼容状态
KernelSU 官方支持 GKI 2.0 的设备内核版本5.10以上旧内核也是兼容的最低4.14+),不过需要自己编译内核。
WSA, ChromeOS 和运行在容器上的 Android 也可以与 KernelSU 一起工作。
目前支持架构 : `arm64-v8a``x86_64`
## 使用方法
- [安装教程](https://kernelsu.org/zh_CN/guide/installation.html)
- [如何构建?](https://kernelsu.org/zh_CN/guide/how-to-build.html)
- [官方网站](https://kernelsu.org/zh_CN/)
## 参与翻译
要将 KernelSU 翻译成您的语言,或完善现有的翻译,请使用 [Weblate](https://hosted.weblate.org/engage/kernelsu/)。现已不再接受有关管理器翻译的PR因为这会与Weblate冲突。
## 讨论
- Telegram: [@KernelSU](https://t.me/KernelSU)
## 安全性
有关报告 KernelSU 安全漏洞的信息,请参阅 [SECURITY.md](/SECURITY.md)。
## 许可证
- 目录 `kernel` 下所有文件为 [GPL-2.0-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)。
-`kernel` 目录的其他部分均为 [GPL-3.0-or-later](https://www.gnu.org/licenses/gpl-3.0.html)。
## 鸣谢
- [kernel-assisted-superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/)KernelSU 的灵感。
- [Magisk](https://github.com/topjohnwu/Magisk):强大的 root 工具箱。
- [genuine](https://github.com/brevent/genuine/)apk v2 签名验证。
- [Diamorphine](https://github.com/m0nad/Diamorphine):一些 rootkit 技巧。

56
docs/README_ES.md Normal file
View File

@@ -0,0 +1,56 @@
[English](README.md) | **Español** | [简体中文](README_CN.md) | [繁體中文](README_TW.md) | [日本語](README_JP.md) | [Polski](README_PL.md) | [Português (Brasil)](README_PT-BR.md) | [Türkçe](README_TR.md) | [Русский](README_RU.md) | [Tiếng Việt](README_VI.md) | [Indonesia](README_ID.md) | [עברית](README_IW.md) | [हिंदी](README_IN.md)
# KernelSU
<img src="https://kernelsu.org/logo.png" style="width: 96px;" alt="logo">
Una solución root basada en el kernel para dispositivos Android.
[![Latest release](https://img.shields.io/github/v/release/tiann/KernelSU?label=Release&logo=github)](https://github.com/tiann/KernelSU/releases/latest)
[![Weblate](https://img.shields.io/badge/Localización-Weblate-teal?logo=weblate)](https://hosted.weblate.org/engage/kernelsu)
[![Channel](https://img.shields.io/badge/Seguir-Telegram-blue.svg?logo=telegram)](https://t.me/KernelSU)
[![License: GPL v2](https://img.shields.io/badge/Licencia-GPL%20v2-orange.svg?logo=gnu)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
[![GitHub License](https://img.shields.io/github/license/tiann/KernelSU?logo=gnu)](/LICENSE)
## Características
1. Binario `su` basado en el kernel y gestión de acceso root.
2. Sistema de módulos basado en [OverlayFS](https://en.wikipedia.org/wiki/OverlayFS).
## Estado de compatibilidad
**KernelSU** soporta de forma oficial dispositivos Android con **GKI 2.0** (a partir de la versión **5.10** del kernel). Los kernels antiguos (a partir de la versión **4.14**) también son compatibles, pero necesitas compilarlos por tu cuenta.
Con esto, WSA, ChromeOS y Android basado en contenedores están todos compatibles.
Actualmente, solo se admiten las arquitecturas `arm64-v8a` y `x86_64`.
## Uso
- [¿Cómo instalarlo?](https://kernelsu.org/guide/installation.html)
- [¿Cómo compilarlo?](https://kernelsu.org/guide/how-to-build.html)
- [Site oficial](https://kernelsu.org/)
## Traducción
Para ayudar a traducir KernelSU o mejorar las traducciones existentes, utilice [Weblate](https://hosted.weblate.org/engage/kernelsu/). Ya no se aceptan PR de la traducción de Manager porque entrará en conflicto con Weblate.
## Discusión
- Telegram: [@KernelSU](https://t.me/KernelSU)
## Seguridad
Para obtener información sobre cómo informar vulnerabilidades de seguridad en KernelSU, consulte [SECURITY.md](/SECURITY.md).
## Licencia
- Los archivos bajo el directorio `kernel` están licenciados bajo [GPL-2-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html).
- Todas las demás partes, a excepción del directorio `kernel`, están licenciados bajo [GPL-3-or-later](https://www.gnu.org/licenses/gpl-3.0.html).
## Créditos
- [kernel-assisted-superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/): la idea de KernelSU.
- [Magisk](https://github.com/topjohnwu/Magisk): la poderosa herramienta root.
- [genuine](https://github.com/brevent/genuine/): validación de firma apk v2.
- [Diamorphine](https://github.com/m0nad/Diamorphine): algunas habilidades de rootkit.

53
docs/README_ID.md Normal file
View File

@@ -0,0 +1,53 @@
[English](README.md) | [Español](README_ES.md) | [简体中文](README_CN.md) | [繁體中文](README_TW.md) | [日本語](README_JP.md) | [Polski](README_PL.md) | [Português (Brasil)](README_PT-BR.md) | [Türkçe](README_TR.md) | [Русский](README_RU.md) | [Tiếng Việt](README_VI.md) | **Indonesia** | [עברית](README_IW.md) | [हिंदी](README_IN.md)
# KernelSU
<img src="https://kernelsu.org/logo.png" style="width: 96px;" alt="logo">
Solusi root berbasis Kernel untuk perangkat Android.
[![Latest release](https://img.shields.io/github/v/release/tiann/KernelSU?label=Release&logo=github)](https://github.com/tiann/KernelSU/releases/latest)
[![Weblate](https://img.shields.io/badge/Localization-Weblate-teal?logo=weblate)](https://hosted.weblate.org/engage/kernelsu)
[![Channel](https://img.shields.io/badge/Follow-Telegram-blue.svg?logo=telegram)](https://t.me/KernelSU)
[![License: GPL v2](https://img.shields.io/badge/License-GPL%20v2-orange.svg?logo=gnu)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
[![GitHub License](https://img.shields.io/github/license/tiann/KernelSU?logo=gnu)](/LICENSE)
## Fitur
1. Manajemen akses root dan `su` berbasis kernel.
2. Sistem modul berdasarkan [OverlayFS](https://en.wikipedia.org/wiki/OverlayFS).
3. [Profil Aplikasi](https://kernelsu.org/guide/app-profile.html): Kunci daya root di dalam sangkar.
## Status Kompatibilitas
KernelSU secara resmi mendukung perangkat Android GKI 2.0 (dengan kernel 5.10+), kernel lama (4.14+) juga kompatibel, tetapi Anda perlu membuat kernel sendiri.
WSA, ChromeOS, dan Android berbasis wadah juga dapat bekerja dengan KernelSU terintegrasi.
Dan ABI yang didukung saat ini adalah: `arm64-v8a` dan `x86_64`
## Penggunaan
- [Petunjuk Instalasi](https://kernelsu.org/id_ID/guide/installation.html)
- [Bagaimana cara membuat?](https://kernelsu.org/id_ID/guide/how-to-build.html)
- [Situs Web Resmi](https://kernelsu.org/id_ID/)
## Terjemahan
Untuk menerjemahkan KernelSU ke dalam bahasa Anda atau menyempurnakan terjemahan yang sudah ada, harap gunakan [Weblat](https://hosted.weblate.org/engage/kernelsu/).
## Diskusi
- Telegram: [@KernelSU](https://t.me/KernelSU)
## Lisensi
- File di bawah direktori `kernel` adalah [GPL-2-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html).
- Semua bagian lain kecuali direktori `kernel` adalah [GPL-3.0-or-later](https://www.gnu.org/licenses/gpl-3.0.html).
## Kredit
- [kernel-assisted-superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/): ide KernelSU.
- [Magisk](https://github.com/topjohnwu/Magisk): alat root yang ampuh.
- [genuine](https://github.com/brevent/genuine/): validasi tanda tangan apk v2.
- [Diamorphine](https://github.com/m0nad/Diamorphine): beberapa keterampilan rootkit.

53
docs/README_IN.md Normal file
View File

@@ -0,0 +1,53 @@
[English](README.md) | [Español](README_ES.md) | [简体中文](README_CN.md) | [繁體中文](README_TW.md) | [日本語](README_JP.md) | [Polski](README_PL.md) | [Português (Brasil)](README_PT-BR.md) | [Türkçe](README_TR.md) | [Русский](README_RU.md) | [Tiếng Việt](README_VI.md) | [Indonesia](README_ID.md) | [עברית](README_IW.md) | **हिंदी**
# KernelSU
<img src="https://kernelsu.org/logo.png" style="width: 96px;" alt="logo">
Android उपकरणों के लिए कर्नेल-आधारित रूट समाधान।
[![Latest release](https://img.shields.io/github/v/release/tiann/KernelSU?label=Release&logo=github)](https://github.com/tiann/KernelSU/releases/latest)
[![Weblate](https://img.shields.io/badge/Localization-Weblate-teal?logo=weblate)](https://hosted.weblate.org/engage/kernelsu)
[![Channel](https://img.shields.io/badge/Follow-Telegram-blue.svg?logo=telegram)](https://t.me/KernelSU)
[![License: GPL v2](https://img.shields.io/badge/License-GPL%20v2-orange.svg?logo=gnu)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
[![GitHub License](https://img.shields.io/github/license/tiann/KernelSU?logo=gnu)](/LICENSE)
## विशेषताएँ
1. कर्नेल-आधारित `su` और रूट एक्सेस प्रबंधन।
2. [OverlayFS](https://en.wikipedia.org/wiki/OverlayFS) पर आधारित मॉड्यूल प्रणाली।
3. [App Profile](https://kernelsu.org/guide/app-profile.html): Root शक्ति को पिंजरे में बंद कर दो।
## अनुकूलता अवस्था
KernelSU आधिकारिक तौर पर Android GKI 2.0 डिवाइस (कर्नेल 5.10+) का समर्थन करता है। पुराने कर्नेल (4.14+) भी संगत हैं, लेकिन कर्नेल को मैन्युअल रूप से बनाना होगा।
इसके साथ, WSA, ChromeOS और कंटेनर-आधारित Android सभी समर्थित हैं।
वर्तमान में, केवल `arm64-v8a` और `x86_64` समर्थित हैं।
## प्रयोग
- [स्थापना निर्देश](https://kernelsu.org/guide/installation.html)
- [कैसे बनाना है ?](https://kernelsu.org/guide/how-to-build.html)
- [आधिकारिक वेबसाइट](https://kernelsu.org/)
## अनुवाद करना
KernelSU का अनुवाद करने या मौजूदा अनुवादों को बेहतर बनाने में सहायता के लिए, कृपया इसका उपयोग करें [Weblate](https://hosted.weblate.org/engage/kernelsu/).
## बहस
- Telegram: [@KernelSU](https://t.me/KernelSU)
## लाइसेंस
- `Kernel` निर्देशिका के अंतर्गत फ़ाइलें हैं [GPL-2-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
- `Kernel` निर्देशिका को छोड़कर अन्य सभी भाग हैं [GPL-3.0-or-later](https://www.gnu.org/licenses/gpl-3.0.html)
## आभार सूची
- [kernel-assisted-superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/): KernelSU विचार।
- [Magisk](https://github.com/topjohnwu/Magisk): शक्तिशाली root उपकरण।
- [genuine](https://github.com/brevent/genuine/): apk v2 हस्ताक्षर सत्यापन।
- [Diamorphine](https://github.com/m0nad/Diamorphine): कुछ रूटकिट कौशल।

53
docs/README_IW.md Normal file
View File

@@ -0,0 +1,53 @@
[English](README.md) | [Español](README_ES.md) | [简体中文](README_CN.md) | [繁體中文](README_TW.md) | [日本語](README_JP.md) | [Polski](README_PL.md) | [Português (Brasil)](README_PT-BR.md) | [Türkçe](README_TR.md) | [Русский](README_RU.md) | [Tiếng Việt](README_VI.md) | [Indonesia](README_ID.md) | **עברית** | [हिंदी](README_IN.md)
# KernelSU
<img src="https://kernelsu.org/logo.png" style="width: 96px;" alt="logo">
פתרון לניהול root מבוסס על Kernel עבור מכשירי Android.
[![Latest release](https://img.shields.io/github/v/release/tiann/KernelSU?label=Release&logo=github)](https://github.com/tiann/KernelSU/releases/latest)
[![Weblate](https://img.shields.io/badge/Localization-Weblate-teal?logo=weblate)](https://hosted.weblate.org/engage/kernelsu)
[![Channel](https://img.shields.io/badge/Follow-Telegram-blue.svg?logo=telegram)](https://t.me/KernelSU)
[![License: GPL v2](https://img.shields.io/badge/License-GPL%20v2-orange.svg?logo=gnu)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
[![GitHub License](https://img.shields.io/github/license/tiann/KernelSU?logo=gnu)](/LICENSE)
## תכונות
1. ניהול root ו־`su` מבוססים על Kernel.
2. מערכת מודולים מבוססת [OverlayFS](https://en.wikipedia.org/wiki/OverlayFS).
3. [פרופיל אפליקציה](https://kernelsu.org/guide/app-profile.html): נעילת גישת root בכלוב.
## מצב תאימות
KernelSU תומך במכשירי Android GKI 2.0 (kernel 5.10+) באופן רשמי. לליבות ישנות (4.14+) יש גם תאימות, אך יידרש לבנות את הליבה באופן ידני.
באמצעות זה, תמיכה זמינה גם ל-WSA, ChromeOS ומכשירי Android המבוססים על מיכלים.
כרגע, רק `arm64-v8a` ו־`x86_64` נתמכים.
## שימוש
- [הוראות התקנה](https://kernelsu.org/guide/installation.html)
- [איך לבנות?](https://kernelsu.org/guide/how-to-build.html)
- [האתר רשמי](https://kernelsu.org/)
## תרגום
כדי לעזור בתרגום של KernelSU או לשפר תרגומים קיימים, יש להשתמש ב-[Weblate](https://hosted.weblate.org/engage/kernelsu/).
## דיון
- Telegram: [@KernelSU](https://t.me/KernelSU)
## רשיון
- קבצים תחת הספרייה `kernel` מוגנים על פי [GPL-2.0-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html).
- כל החלקים האחרים, למעט הספרייה `kernel`, מוגנים על פי [GPL-3.0-or-later](https://www.gnu.org/licenses/gpl-3.0.html).
## קרדיטים
- [kernel-assisted-superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/): הרעיון של KernelSU.
- [Magisk](https://github.com/topjohnwu/Magisk): הכלי הסופר חזק לניהול root.
- [genuine](https://github.com/brevent/genuine/): אימות חתימת apk v2.
- [Diamorphine](https://github.com/m0nad/Diamorphine): כמה יכולות רוט.

53
docs/README_JP.md Normal file
View File

@@ -0,0 +1,53 @@
[English](README.md) | [Español](README_ES.md) | [简体中文](README_CN.md) | [繁體中文](README_TW.md) | **日本語** | [Polski](README_PL.md) | [Português (Brasil)](README_PT-BR.md) | [Türkçe](README_TR.md) | [Русский](README_RU.md) | [Tiếng Việt](README_VI.md) | [Indonesia](README_ID.md) | [עברית](README_IW.md) | [हिंदी](README_IN.md)
# KernelSU
<img src="https://kernelsu.org/logo.png" style="width: 96px;" alt="logo">
Android におけるカーネルベースの root ソリューションです。
[![Latest release](https://img.shields.io/github/v/release/tiann/KernelSU?label=Release&logo=github)](https://github.com/tiann/KernelSU/releases/latest)
[![Weblate](https://img.shields.io/badge/Localization-Weblate-teal?logo=weblate)](https://hosted.weblate.org/engage/kernelsu)
[![Channel](https://img.shields.io/badge/Follow-Telegram-blue.svg?logo=telegram)](https://t.me/KernelSU)
[![License: GPL v2](https://img.shields.io/badge/License-GPL%20v2-orange.svg?logo=gnu)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
[![GitHub License](https://img.shields.io/github/license/tiann/KernelSU?logo=gnu)](/LICENSE)
## 特徴
1. カーネルベースの `su` と権限管理。
2. [OverlayFS](https://en.wikipedia.org/wiki/OverlayFS) に基づくモジュールシステム。
3. [アプリのプロファイル](https://kernelsu.org/guide/app-profile.html): root の権限をケージ内に閉じ込めます。
## 対応状況
KernelSU は GKI 2.0 デバイス(カーネルバージョン 5.10 以上を公式にサポートしています。古いカーネル4.14以上)とも互換性がありますが、自分でカーネルをビルドする必要があります。
WSA 、ChromeOS とコンテナ上で動作する Android でも KernelSU を統合して動かせます。
現在サポートしているアーキテクチャは `arm64-v8a` および `x86_64` です。
## 使用方法
- [インストール方法はこちら](https://kernelsu.org/ja_JP/guide/installation.html)
- [ビルド方法はこちら](https://kernelsu.org/guide/how-to-build.html)
- [公式サイト](https://kernelsu.org/ja_JP/)
## 翻訳
KernelSU をあなたの言語に翻訳するか、既存の翻訳を改善するには、[Weblate](https://hosted.weblate.org/engage/kernelsu/) を使用してください。Manager翻訳した PR は、Weblate と競合するため受け入れられなくなりました。
## ディスカッション
- Telegram: [@KernelSU](https://t.me/KernelSU)
## ライセンス
- `kernel` ディレクトリの下にあるすべてのファイル: [GPL-2-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)。
- `kernel` ディレクトリ以外のすべてのファイル: [GPL-3.0-or-later](https://www.gnu.org/licenses/gpl-3.0.html)。
## クレジット
- [kernel-assisted-superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/)KernelSU のアイデア元。
- [Magisk](https://github.com/topjohnwu/Magisk):強力な root ツール。
- [genuine](https://github.com/brevent/genuine/)apk v2 の署名検証。
- [Diamorphine](https://github.com/m0nad/Diamorphine): rootkit のスキル。

55
docs/README_PL.md Normal file
View File

@@ -0,0 +1,55 @@
[English](README.md) | [Español](README_ES.md) | [简体中文](README_CN.md) | [繁體中文](README_TW.md) | [日本語](README_JP.md) | **Polski** | [Português (Brasil)](README_PT-BR.md) | [Türkçe](README_TR.md) | [Русский](README_RU.md) | [Tiếng Việt](README_VI.md) | [Indonesia](README_ID.md) | [עברית](README_IW.md) | [हिंदी](README_IN.md)
# KernelSU
<img src="https://kernelsu.org/logo.png" style="width: 96px;" alt="logo">
Rozwiązanie root oparte na jądrze dla urządzeń z systemem Android.
[![Latest release](https://img.shields.io/github/v/release/tiann/KernelSU?label=Release&logo=github)](https://github.com/tiann/KernelSU/releases/latest)
[![Weblate](https://img.shields.io/badge/Localization-Weblate-teal?logo=weblate)](https://hosted.weblate.org/engage/kernelsu)
[![Channel](https://img.shields.io/badge/Follow-Telegram-blue.svg?logo=telegram)](https://t.me/KernelSU)
[![License: GPL v2](https://img.shields.io/badge/License-GPL%20v2-orange.svg?logo=gnu)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
[![GitHub License](https://img.shields.io/github/license/tiann/KernelSU?logo=gnu)](/LICENSE)
## Cechy
1. Oparte na jądrze `su` i zarządzanie dostępem roota.
2. System modułów oparty na [OverlayFS](https://en.wikipedia.org/wiki/OverlayFS).
## Kompatybilność
KernelSU oficjalnie obsługuje urządzenia z Androidem GKI 2.0 (z jądrem 5.10+), starsze jądra (4.14+) są również kompatybilne, ale musisz sam skompilować jądro.
WSA i Android oparty na kontenerach również powinny działać ze zintegrowanym KernelSU.
Aktualnie obsługiwane ABI to : `arm64-v8a` i `x86_64`.
## Użycie
- [Instalacja](https://kernelsu.org/guide/installation.html)
- [Jak skompilować?](https://kernelsu.org/guide/how-to-build.html)
## Tłumaczenie
Aby pomóc w tłumaczeniu KernelSU lub ulepszyć istniejące tłumaczenia, użyj [Weblate](https://hosted.weblate.org/engage/kernelsu/). PR tłumaczenia Managera nie jest już akceptowany, ponieważ będzie kolidował z Weblate.
## Dyskusja
- Telegram: [@KernelSU](https://t.me/KernelSU)
## Bezpieczeństwo
Informacje na temat zgłaszania luk w zabezpieczeniach w KernelSU można znaleźć w pliku [SECURITY.md](/SECURITY.md).
## Licencja
- Pliki w katalogu `kernel` są na licencji [GPL-2-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html).
- Wszystkie inne części poza katalogiem `kernel` są na licencji [GPL-3-or-later](https://www.gnu.org/licenses/gpl-3.0.html).
## Podziękowania
- [kernel-assisted-superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/): pomysłodawca KernelSU.
- [Magisk](https://github.com/topjohnwu/Magisk): implementacja sepolicy.
- [genuine](https://github.com/brevent/genuine/): walidacja podpisu apk v2.
- [Diamorphine](https://github.com/m0nad/Diamorphine): cenna znajomość rootkitów.

57
docs/README_PT-BR.md Normal file
View File

@@ -0,0 +1,57 @@
[English](README.md) | [Español](README_ES.md) | [简体中文](README_CN.md) | [繁體中文](README_TW.md) | [日本語](README_JP.md) | [Polski](README_PL.md) | **Português (Brasil)** | [Türkçe](README_TR.md) | [Русский](README_RU.md) | [Tiếng Việt](README_VI.md) | [Indonesia](README_ID.md) | [עברית](README_IW.md) | [हिंदी](README_IN.md)
# KernelSU
<img src="https://kernelsu.org/logo.png" style="width: 96px;" alt="logo">
Uma solução root baseada em kernel para dispositivos Android.
[![Latest release](https://img.shields.io/github/v/release/tiann/KernelSU?label=Release&logo=github)](https://github.com/tiann/KernelSU/releases/latest)
[![Weblate](https://img.shields.io/badge/Localização-Weblate-teal?logo=weblate)](https://hosted.weblate.org/engage/kernelsu)
[![Channel](https://img.shields.io/badge/Seguir-Telegram-blue.svg?logo=telegram)](https://t.me/KernelSU)
[![License: GPL v2](https://img.shields.io/badge/Licença-GPL%20v2-orange.svg?logo=gnu)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
[![GitHub License](https://img.shields.io/github/license/tiann/KernelSU?logo=gnu)](/LICENSE)
## Características
1. `su` e gerenciamento de acesso root baseado em kernel.
2. Sistema modular baseado em [OverlayFS](https://en.wikipedia.org/wiki/OverlayFS).
3. [Perfil do Aplicativo](https://kernelsu.org/pt_BR/guide/app-profile.html): Tranque o poder root em uma gaiola.
## Estado de compatibilidade
O KernelSU oferece suporte oficial a dispositivos Android GKI 2.0 (kernel 5.10+). Kernels mais antigos (4.14+) também são compatíveis, mas o kernel terá que ser construído manualmente.
Com isso, WSA, ChromeOS e Android baseado em contêiner são todos suportados.
Atualmente, apenas `arm64-v8a` e `x86_64` são suportados.
## Uso
- [Instalação](https://kernelsu.org/pt_BR/guide/installation.html)
- [Como construir o KernelSU?](https://kernelsu.org/pt_BR/guide/how-to-build.html)
- [Site oficial](https://kernelsu.org/pt_BR/)
## Tradução
Para contribuir com a tradução do KernelSU ou aprimorar traduções existentes, por favor, utilize o [Weblate](https://hosted.weblate.org/engage/kernelsu/). PR para a tradução do Gerenciador não são mais aceitas, pois podem entrar em conflito com o Weblate.
## Discussão
- Telegram: [@KernelSU](https://t.me/KernelSU)
## Segurança
Para obter informações sobre como relatar vulnerabilidades de segurança do KernelSU, consulte [SECURITY.md](/SECURITY.md).
## Licença
- Os arquivos no diretório `kernel` são [GPL-2.0-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html).
- Todas as outras partes, exceto o diretório `kernel` são [GPL-3.0-or-later](https://www.gnu.org/licenses/gpl-3.0.html).
## Créditos
- [kernel-assisted-superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/): a ideia do KernelSU.
- [Magisk](https://github.com/topjohnwu/Magisk): a poderosa ferramenta root.
- [genuine](https://github.com/brevent/genuine/): validação de assinatura apk v2.
- [Diamorphine](https://github.com/m0nad/Diamorphine): algumas habilidades de rootkit.

49
docs/README_RU.md Normal file
View File

@@ -0,0 +1,49 @@
[English](README.md) | [Español](README_ES.md) | [简体中文](README_CN.md) | [繁體中文](README_TW.md) | [日本語](README_JP.md) | [Polski](README_PL.md) | [Português (Brasil)](README_PT-BR.md) | [Türkçe](README_TR.md) | **Русский** | [Tiếng Việt](README_VI.md) | [Indonesia](README_ID.md) | [עברית](README_IW.md) | [हिंदी](README_IN.md)
# KernelSU
<img src="https://kernelsu.org/logo.png" style="width: 96px;" alt="logo">
Решение на основе ядра root для Android-устройств.
[![Latest release](https://img.shields.io/github/v/release/tiann/KernelSU?label=Release&logo=github)](https://github.com/tiann/KernelSU/releases/latest)
[![Weblate](https://img.shields.io/badge/Localization-Weblate-teal?logo=weblate)](https://hosted.weblate.org/engage/kernelsu)
[![Channel](https://img.shields.io/badge/Follow-Telegram-blue.svg?logo=telegram)](https://t.me/KernelSU)
[![License: GPL v2](https://img.shields.io/badge/License-GPL%20v2-orange.svg?logo=gnu)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
[![GitHub License](https://img.shields.io/github/license/tiann/KernelSU?logo=gnu)](/LICENSE)
## Особенности
1. Управление `su` и root-доступом на основе ядра.
2. Система модулей на основе [OverlayFS](https://en.wikipedia.org/wiki/OverlayFS).
3. [Профиль приложений](https://kernelsu.org/ru_RU/guide/app-profile.html): Запри корневую силу в клетке.
## Совместимость
KernelSU официально поддерживает устройства на базе Android GKI 2.0 (с ядром 5.10+), старые ядра (4.14+) также совместимы, но для этого необходимо собрать ядро самостоятельно.
WSA и Android на основе контейнеров также должны работать с интегрированным KernelSU.
В настоящее время поддерживаются следующие ABI: `arm64-v8a` и `x86_64`.
## Использование
- [Установка](https://kernelsu.org/ru_RU/guide/installation.html)
- [Как собрать?](https://kernelsu.org/ru_RU/guide/how-to-build.html)
- [официальный сайт](https://kernelsu.org/ru_RU/)
## Обсуждение
- Telegram: [@KernelSU](https://t.me/KernelSU)
## Лицензия
- Файлы в директории `kernel` [GPL-2-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html).
- Все остальные части, кроме директории `kernel` [GPL-3-or-later](https://www.gnu.org/licenses/gpl-3.0.html).
## Благодарности
- [kernel-assisted-superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/): идея KernelSU.
- [Magisk](https://github.com/topjohnwu/Magisk): реализация sepolicy.
- [genuine](https://github.com/brevent/genuine/): проверка подписи apk v2.
- [Diamorphine](https://github.com/m0nad/Diamorphine): некоторые навыки руткита.

57
docs/README_TR.md Normal file
View File

@@ -0,0 +1,57 @@
[English](README.md) | [Español](README_ES.md) | [简体中文](README_CN.md) | [繁體中文](README_TW.md) | [日本語](README_JP.md) | [Polski](README_PL.md) | [Português (Brasil)](README_PT-BR.md) | **Türkçe** | [Русский](README_RU.md) | [Tiếng Việt](README_VI.md) | [Indonesia](README_ID.md) | [עברית](README_IW.md) | [हिंदी](README_IN.md)
# KernelSU
<img src="https://kernelsu.org/logo.png" style="width: 96px;" alt="logo">
Android cihazlar için kernel tabanlı root çözümü.
[![Latest release](https://img.shields.io/github/v/release/tiann/KernelSU?label=Release&logo=github)](https://github.com/tiann/KernelSU/releases/latest)
[![Weblate](https://img.shields.io/badge/Localization-Weblate-teal?logo=weblate)](https://hosted.weblate.org/engage/kernelsu)
[![Channel](https://img.shields.io/badge/Follow-Telegram-blue.svg?logo=telegram)](https://t.me/KernelSU)
[![License: GPL v2](https://img.shields.io/badge/License-GPL%20v2-orange.svg?logo=gnu)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
[![GitHub License](https://img.shields.io/github/license/tiann/KernelSU?logo=gnu)](/LICENSE)
## Özellikler
1. Kernel-tabanlı `su` ve root erişimi yönetimi.
2. [OverlayFS](https://en.wikipedia.org/wiki/OverlayFS)'ye dayalı modül sistemi.
3. [Uygulama profili](https://kernelsu.org/guide/app-profile.html): Root gücünü bir kafese kapatın.
## Uyumluluk Durumu
KernelSU resmi olarak Android GKI 2.0 cihazlarını (5.10+ kernelli) destekler, eski kernellerle de (4.14+) uyumludur, ancak kerneli kendinizin derlemeniz gerekir.
Bununla birlikte; WSA, ChromeOS ve konteyner tabanlı Android'in tamamı desteklenmektedir.
Şimdilik sadece `arm64-v8a` ve `x86_64` desteklenmektedir.
## Kullanım
- [Yükleme yönergeleri](https://kernelsu.org/guide/installation.html)
- [Nasıl derlenir?](https://kernelsu.org/guide/how-to-build.html)
- [Resmi WEB sitesi](https://kernelsu.org/)
## Çeviri
KernelSU'nun çevirisine veya mevcut çevirilerin iyileştirilmesine yardımcı olmak için lütfen [Weblate](https://hosted.weblate.org/engage/kernelsu/) kullanın. Yönetici uygulamasının PR ile çevirisi, Weblate ile çakışacağından artık kabul edilmeyecektir.
## Tartışma
- Telegram: [@KernelSU](https://t.me/KernelSU)
## Güvenlik
KernelSU'daki güvenlik açıklarını bildirme hakkında bilgi için, bkz [SECURITY.md](/SECURITY.md).
## Lisans
- `kernel` klasöründeki dosyalar [GPL-2-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html) lisansı altındadır.
- `kernel` klasörü dışındaki bütün diğer bölümler [GPL-3-veya-sonraki](https://www.gnu.org/licenses/gpl-3.0.html) lisansı altındadır.
## Krediler
- [kernel-assisted-superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/): KernelSU fikri.
- [Magisk](https://github.com/topjohnwu/Magisk): güçlü root aracı.
- [genuine](https://github.com/brevent/genuine/): apk v2 imza doğrulaması.
- [Diamorphine](https://github.com/m0nad/Diamorphine): bazı rootkit becerileri.

47
docs/README_TW.md Normal file
View File

@@ -0,0 +1,47 @@
[English](README.md) | [Español](README_ES.md) | [简体中文](README_CN.md) | **繁體中文** | [日本語](README_JP.md) | [Polski](README_PL.md) | [Português (Brasil)](README_PT-BR.md) | [Türkçe](README_TR.md) | [Русский](README_RU.md) | [Tiếng Việt](README_VI.md) | [Indonesia](README_ID.md) | [עברית](README_IW.md) | [हिंदी](README_IN.md)
# KernelSU
<img src="https://kernelsu.org/logo.png" style="width: 96px;" alt="logo">
一個基於核心的 Android 裝置 Root 解決方案
[![Latest release](https://img.shields.io/github/v/release/tiann/KernelSU?label=Release&logo=github)](https://github.com/tiann/KernelSU/releases/latest)
[![Weblate](https://img.shields.io/badge/Localization-Weblate-teal?logo=weblate)](https://hosted.weblate.org/engage/kernelsu)
[![Channel](https://img.shields.io/badge/Follow-Telegram-blue.svg?logo=telegram)](https://t.me/KernelSU)
[![License: GPL v2](https://img.shields.io/badge/License-GPL%20v2-orange.svg?logo=gnu)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
[![GitHub License](https://img.shields.io/github/license/tiann/KernelSU?logo=gnu)](/LICENSE)
## 功能
- 基於核心的 `su` 和 Root 存取權管理。
- 基於 [OverlayFS](https://en.wikipedia.org/wiki/OverlayFS) 的模組系統。
## 相容性狀態
KernelSU 官方支援 Android GKI 2.0 的裝置 (核心版本 5.10+);舊版核心同樣相容 (最低 4.14+),但需要自行編譯核心。
WSA 和執行在容器中的 Android 也可以與 KernelSU 一同運作。
目前支援架構:`arm64-v8a``x86_64`
## 使用方法
- [安裝教學](https://kernelsu.org/zh_TW/guide/installation.html)
- [如何建置?](https://kernelsu.org/zh_TW/guide/how-to-build.html)
### 討論
- Telegram[@KernelSU](https://t.me/KernelSU)
## 授權
- 目錄 `kernel` 下所有檔案為 [GPL-2-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)。
-`kernel` 目錄的其他部分均為 [GPL-3-or-later](https://www.gnu.org/licenses/gpl-3.0.html)。
## 致謝
- [kernel-assisted-superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/)KernelSU 的靈感。
- [Magisk](https://github.com/topjohnwu/Magisk)sepolicy 實作。
- [genuine](https://github.com/brevent/genuine/)apk v2 簽章驗證。
- [Diamorphine](https://github.com/m0nad/Diamorphine):一些 rootkit 技巧。

53
docs/README_VI.md Normal file
View File

@@ -0,0 +1,53 @@
[English](README.md) | [Español](README_ES.md) | [简体中文](README_CN.md) | [繁體中文](README_TW.md) | [日本語](README_JP.md) | [Polski](README_PL.md) | [Português (Brasil)](README_PT-BR.md) | [Türkçe](README_TR.md) | [Русский](README_RU.md) | **Tiếng Việt** | [Indonesia](README_ID.md) | [עברית](README_IW.md) | [हिंदी](README_IN.md)
# KernelSU
<img src="https://kernelsu.org/logo.png" style="width: 96px;" alt="logo">
Giải pháp root thông qua thay đổi trên Kernel hệ điều hành cho các thiết bị Android.
[![Latest release](https://img.shields.io/github/v/release/tiann/KernelSU?label=Release&logo=github)](https://github.com/tiann/KernelSU/releases/latest)
[![Weblate](https://img.shields.io/badge/Localization-Weblate-teal?logo=weblate)](https://hosted.weblate.org/engage/kernelsu)
[![Channel](https://img.shields.io/badge/Follow-Telegram-blue.svg?logo=telegram)](https://t.me/KernelSU)
[![License: GPL v2](https://img.shields.io/badge/License-GPL%20v2-orange.svg?logo=gnu)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
[![GitHub License](https://img.shields.io/github/license/tiann/KernelSU?logo=gnu)](/LICENSE)
## Tính năng
1. Hỗ trợ gói thực thi `su` và quản lý quyền root.
2. Hệ thống mô-đun thông qua [OverlayFS](https://en.wikipedia.org/wiki/OverlayFS).
3. [App Profile](https://kernelsu.org/guide/app-profile.html): Hạn chế quyền root của ứng dụng.
## Tình trạng tương thích
KernelSU chính thức hỗ trợ các thiết bị Android với kernel GKI 2.0 (phiên bản kernel 5.10+), các phiên bản kernel cũ hơn (4.14+) cũng tương thích, nhưng bạn cần phải tự biên dịch.
WSA, ChromeOS và Android dựa trên container(container-based) cũng được hỗ trợ bởi KernelSU.
Hiên tại Giao diện nhị phân của ứng dụng (ABI) được hỗ trợ bao gồm `arm64-v8a``x86_64`.
## Sử dụng
- [Hướng dẫn cài đặt](https://kernelsu.org/vi_VN/guide/installation.html)
- [Cách để build?](https://kernelsu.org/vi_VN/guide/how-to-build.html)
- [Website Chính Thức](https://kernelsu.org/vi_VN/)
## Hỗ trợ dịch
Nếu bạn muốn hỗ trợ dịch KernelSU sang một ngôn ngữ khác hoặc cải thiện các bản dịch trước, vui lòng sử dụng [Weblate](https://hosted.weblate.org/engage/kernelsu/).
## Thảo luận
- Telegram: [@KernelSU](https://t.me/KernelSU)
## Giấy phép
- Tất cả các file trong thư mục `kernel` dùng giấy phép [GPL-2-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html).
- Tất cả các thành phần khác ngoại trừ thư mục `kernel` dùng giấy phép [GPL-3-or-later](https://www.gnu.org/licenses/gpl-3.0.html).
## Lời cảm ơn
- [kernel-assisted-superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/): ý tưởng cho KernelSU.
- [Magisk](https://github.com/topjohnwu/Magisk): công cụ root mạnh mẽ.
- [genuine](https://github.com/brevent/genuine/): phương pháp xác thực apk v2.
- [Diamorphine](https://github.com/m0nad/Diamorphine): các phương pháp ẩn của rootkit.

111
js/README.md Normal file
View File

@@ -0,0 +1,111 @@
# Library for KernelSU's module WebUI
## Install
```sh
yarn add kernelsu
```
## API
### exec
Spawns a **root** shell and runs a command within that shell, passing the `stdout` and `stderr` to a Promise when complete.
- `command` `<string>` The command to run, with space-separated arguments.
- `options` `<Object>`
- `cwd` - Current working directory of the child process
- `env` - Environment key-value pairs
```javascript
import { exec } from 'kernelsu';
const { errno, stdout, stderr } = await exec('ls -l', { cwd: '/tmp' });
if (errno === 0) {
// success
console.log(stdout);
}
```
### spawn
Spawns a new process using the given `command` in **root** shell, with command-line arguments in `args`. If omitted, `args` defaults to an empty array.
Returns a `ChildProcess`, Instances of the ChildProcess represent spawned child processes.
- `command` `<string>` The command to run.
- `args` `<string[]>` List of string arguments.
- `options` `<Object>`:
- `cwd` `<string>` - Current working directory of the child process
- `env` `<Object>` - Environment key-value pairs
Example of running `ls -lh /data`, capturing `stdout`, `stderr`, and the exit code:
```javascript
import { spawn } from 'kernelsu';
const ls = spawn('ls', ['-lh', '/data']);
ls.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
ls.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
});
ls.on('exit', (code) => {
console.log(`child process exited with code ${code}`);
});
```
#### ChildProcess
##### Event 'exit'
- `code` `<number>` The exit code if the child exited on its own.
The `'exit'` event is emitted after the child process ends. If the process exited, `code` is the final exit code of the process, otherwise null
##### Event 'error'
- `err` `<Error>` The error.
The `'error'` event is emitted whenever:
- The process could not be spawned.
- The process could not be killed.
##### `stdout`
A `Readable Stream` that represents the child process's `stdout`.
```javascript
const subprocess = spawn('ls');
subprocess.stdout.on('data', (data) => {
console.log(`Received chunk ${data}`);
});
```
#### `stderr`
A `Readable Stream` that represents the child process's `stderr`.
### fullScreen
Request the WebView enter/exit full screen.
```javascript
import { fullScreen } from 'kernelsu';
fullScreen(true);
```
### toast
Show a toast message.
```javascript
import { toast } from 'kernelsu';
toast('Hello, world!');
```

45
js/index.d.ts vendored Normal file
View File

@@ -0,0 +1,45 @@
interface ExecOptions {
cwd?: string,
env?: { [key: string]: string }
}
interface ExecResults {
errno: number,
stdout: string,
stderr: string
}
declare function exec(command: string): Promise<ExecResults>;
declare function exec(command: string, options: ExecOptions): Promise<ExecResults>;
interface SpawnOptions {
cwd?: string,
env?: { [key: string]: string }
}
interface Stdio {
on(event: 'data', callback: (data: string) => void)
}
interface ChildProcess {
stdout: Stdio,
stderr: Stdio,
on(event: 'exit', callback: (code: number) => void)
on(event: 'error', callback: (err: any) => void)
}
declare function spawn(command: string): ChildProcess;
declare function spawn(command: string, args: string[]): ChildProcess;
declare function spawn(command: string, options: SpawnOptions): ChildProcess;
declare function spawn(command: string, args: string[], options: SpawnOptions): ChildProcess;
declare function fullScreen(isFullScreen: boolean);
declare function toast(message: string);
export {
exec,
spawn,
fullScreen,
toast
}

115
js/index.js Normal file
View File

@@ -0,0 +1,115 @@
let callbackCounter = 0;
function getUniqueCallbackName(prefix) {
return `${prefix}_callback_${Date.now()}_${callbackCounter++}`;
}
export function exec(command, options) {
if (typeof options === "undefined") {
options = {};
}
return new Promise((resolve, reject) => {
// Generate a unique callback function name
const callbackFuncName = getUniqueCallbackName("exec");
// Define the success callback function
window[callbackFuncName] = (errno, stdout, stderr) => {
resolve({ errno, stdout, stderr });
cleanup(callbackFuncName);
};
function cleanup(successName) {
delete window[successName];
}
try {
ksu.exec(command, JSON.stringify(options), callbackFuncName);
} catch (error) {
reject(error);
cleanup(callbackFuncName);
}
});
}
function Stdio() {
this.listeners = {};
}
Stdio.prototype.on = function (event, listener) {
if (!this.listeners[event]) {
this.listeners[event] = [];
}
this.listeners[event].push(listener);
};
Stdio.prototype.emit = function (event, ...args) {
if (this.listeners[event]) {
this.listeners[event].forEach((listener) => listener(...args));
}
};
function ChildProcess() {
this.listeners = {};
this.stdin = new Stdio();
this.stdout = new Stdio();
this.stderr = new Stdio();
}
ChildProcess.prototype.on = function (event, listener) {
if (!this.listeners[event]) {
this.listeners[event] = [];
}
this.listeners[event].push(listener);
};
ChildProcess.prototype.emit = function (event, ...args) {
if (this.listeners[event]) {
this.listeners[event].forEach((listener) => listener(...args));
}
};
export function spawn(command, args, options) {
if (typeof args === "undefined") {
args = [];
} else if (!(args instanceof Array)) {
// allow for (command, options) signature
options = args;
}
if (typeof options === "undefined") {
options = {};
}
const child = new ChildProcess();
const childCallbackName = getUniqueCallbackName("spawn");
window[childCallbackName] = child;
function cleanup(name) {
delete window[name];
}
child.on("exit", code => {
cleanup(childCallbackName);
});
try {
ksu.spawn(
command,
JSON.stringify(args),
JSON.stringify(options),
childCallbackName
);
} catch (error) {
child.emit("error", error);
cleanup(childCallbackName);
}
return child;
}
export function fullScreen(isFullScreen) {
ksu.fullScreen(isFullScreen);
}
export function toast(message) {
ksu.toast(message);
}

26
js/package.json Normal file
View File

@@ -0,0 +1,26 @@
{
"name": "kernelsu",
"version": "1.0.6",
"description": "Library for KernelSU's module WebUI",
"main": "index.js",
"types": "index.d.ts",
"scripts": {
"test": "npm run test"
},
"repository": {
"type": "git",
"url": "git+https://github.com/tiann/KernelSU.git"
},
"keywords": [
"su",
"kernelsu",
"module",
"webui"
],
"author": "weishu",
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/tiann/KernelSU/issues"
},
"homepage": "https://github.com/tiann/KernelSU#readme"
}

14
justfile Normal file
View File

@@ -0,0 +1,14 @@
alias bk := build_ksud
alias bm := build_manager
build_ksud:
cross build --target aarch64-linux-android --release --manifest-path ./userspace/ksud/Cargo.toml
build_manager: build_ksud
cp userspace/ksud/target/aarch64-linux-android/release/ksud manager/app/src/main/jniLibs/arm64-v8a/libksud.so
cd manager && ./gradlew aDebug
clippy:
cargo fmt --manifest-path ./userspace/ksud/Cargo.toml
cross clippy --target x86_64-pc-windows-gnu --release --manifest-path ./userspace/ksud/Cargo.toml
cross clippy --target aarch64-linux-android --release --manifest-path ./userspace/ksud/Cargo.toml

View File

@@ -2,7 +2,7 @@ menu "KernelSU"
config KSU config KSU
tristate "KernelSU function support" tristate "KernelSU function support"
select OVERLAY_FS depends on OVERLAY_FS
default y default y
help help
Enable kernel-level root privileges on Android System. Enable kernel-level root privileges on Android System.
@@ -14,4 +14,11 @@ config KSU_DEBUG
help help
Enable KernelSU debug mode Enable KernelSU debug mode
config KSU_MODULE
bool "Build KernelSU as a module"
depends on KSU
default n
help
Build KernelSU as a loadable kernel module
endmenu endmenu

View File

@@ -1,32 +1,68 @@
obj-y += ksu.o kernelsu-objs := ksu.o
obj-y += allowlist.o kernelsu-objs += allowlist.o
kernelsu-objs := apk_sign.o kernelsu-objs += apk_sign.o
obj-y += kernelsu.o kernelsu-objs += module_api.o
obj-y += module_api.o kernelsu-objs += sucompat.o
obj-y += sucompat.o kernelsu-objs += uid_observer.o
obj-y += uid_observer.o kernelsu-objs += manager.o
obj-y += manager.o kernelsu-objs += core_hook.o
obj-y += core_hook.o kernelsu-objs += ksud.o
obj-y += ksud.o kernelsu-objs += embed_ksud.o
obj-y += embed_ksud.o kernelsu-objs += kernel_compat.o
obj-y += kernel_compat.o
kernelsu-objs += selinux/selinux.o
kernelsu-objs += selinux/sepolicy.o
kernelsu-objs += selinux/rules.o
ccflags-y += -I$(srctree)/security/selinux -I$(srctree)/security/selinux/include
ccflags-y += -I$(objtree)/security/selinux -include $(srctree)/include/uapi/asm-generic/errno.h
ifndef KSU_MODULE
obj-y += kernelsu.o
else
obj-m += kernelsu.o
endif
obj-y += selinux/
# .git is a text file while the module is imported by 'git submodule add'. # .git is a text file while the module is imported by 'git submodule add'.
ifeq ($(shell test -e $(srctree)/$(src)/../.git; echo $$?),0) ifeq ($(shell test -e $(srctree)/$(src)/../.git; echo $$?),0)
$(shell cd $(srctree)/$(src); /usr/bin/env PATH="$$PATH":/usr/bin:/usr/local/bin [ -f ../.git/shallow ] && git fetch --unshallow)
KSU_GIT_VERSION := $(shell cd $(srctree)/$(src); /usr/bin/env PATH="$$PATH":/usr/bin:/usr/local/bin git rev-list --count HEAD) KSU_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) # ksu_version: major * 10000 + git version + 200 for historical reasons
$(eval KSU_VERSION=$(shell expr 10000 + $(KSU_GIT_VERSION) + 200))
$(info -- KernelSU version: $(KSU_VERSION))
ccflags-y += -DKSU_VERSION=$(KSU_VERSION)
else # If there is no .git file, the default version will be passed.
$(warning "KSU_GIT_VERSION not defined! It is better to make KernelSU a git submodule!")
ccflags-y += -DKSU_VERSION=16
endif endif
ifndef EXPECTED_SIZE ifeq ($(shell grep -q " current_sid(void)" $(srctree)/security/selinux/include/objsec.h; echo $$?),0)
EXPECTED_SIZE := 0x033b ccflags-y += -DKSU_COMPAT_HAS_CURRENT_SID
endif endif
ifndef EXPECTED_HASH ifeq ($(shell grep -q "struct selinux_state " $(srctree)/security/selinux/include/security.h; echo $$?),0)
EXPECTED_HASH := 0xb0b91415 ccflags-y += -DKSU_COMPAT_HAS_SELINUX_STATE
endif endif
ccflags-y += -DEXPECTED_SIZE=$(EXPECTED_SIZE) ifndef KSU_EXPECTED_SIZE
ccflags-y += -DEXPECTED_HASH=$(EXPECTED_HASH) KSU_EXPECTED_SIZE := 0x033b
endif
ifndef KSU_EXPECTED_HASH
KSU_EXPECTED_HASH := c371061b19d8c7d7d6133c6a9bafe198fa944e50c1b31c9d8daa8d7f1fc2d2d6
endif
ifdef KSU_MANAGER_PACKAGE
ccflags-y += -DKSU_MANAGER_PACKAGE=\"$(KSU_MANAGER_PACKAGE)\"
$(info -- KernelSU Manager package name: $(KSU_MANAGER_PACKAGE))
endif
$(info -- KernelSU Manager signature size: $(KSU_EXPECTED_SIZE))
$(info -- KernelSU Manager signature hash: $(KSU_EXPECTED_HASH))
ccflags-y += -DEXPECTED_SIZE=$(KSU_EXPECTED_SIZE)
ccflags-y += -DEXPECTED_HASH=\"$(KSU_EXPECTED_HASH)\"
ccflags-y += -Wno-implicit-function-declaration -Wno-strict-prototypes -Wno-int-conversion -Wno-gcc-compat ccflags-y += -Wno-implicit-function-declaration -Wno-strict-prototypes -Wno-int-conversion -Wno-gcc-compat
ccflags-y += -Wno-declaration-after-statement ccflags-y += -Wno-declaration-after-statement -Wno-unused-function
# Keep a new line here!! Because someone may append config

View File

@@ -97,7 +97,7 @@ void ksu_show_allow_list(void)
{ {
struct perm_data *p = NULL; struct perm_data *p = NULL;
struct list_head *pos = NULL; struct list_head *pos = NULL;
pr_info("ksu_show_allow_list"); pr_info("ksu_show_allow_list\n");
list_for_each (pos, &allow_list) { list_for_each (pos, &allow_list) {
p = list_entry(pos, struct perm_data, list); p = list_entry(pos, struct perm_data, list);
pr_info("uid :%d, allow: %d\n", p->profile.current_uid, pr_info("uid :%d, allow: %d\n", p->profile.current_uid,
@@ -349,10 +349,9 @@ void do_save_allow_list(struct work_struct *work)
struct perm_data *p = NULL; struct perm_data *p = NULL;
struct list_head *pos = NULL; struct list_head *pos = NULL;
loff_t off = 0; loff_t off = 0;
KWORKER_INSTALL_KEYRING();
struct file *fp =
filp_open(KERNEL_SU_ALLOWLIST, O_WRONLY | O_CREAT, 0644);
struct file *fp =
ksu_filp_open_compat(KERNEL_SU_ALLOWLIST, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (IS_ERR(fp)) { if (IS_ERR(fp)) {
pr_err("save_allow_list create file failed: %ld\n", PTR_ERR(fp)); pr_err("save_allow_list create file failed: %ld\n", PTR_ERR(fp));
return; return;
@@ -392,15 +391,14 @@ void do_load_allow_list(struct work_struct *work)
struct file *fp = NULL; struct file *fp = NULL;
u32 magic; u32 magic;
u32 version; u32 version;
KWORKER_INSTALL_KEYRING();
#ifdef CONFIG_KSU_DEBUG #ifdef CONFIG_KSU_DEBUG
// always allow adb shell by default // always allow adb shell by default
ksu_grant_root_to_shell(); ksu_grant_root_to_shell();
#endif #endif
// load allowlist now!
fp = filp_open(KERNEL_SU_ALLOWLIST, O_RDONLY, 0);
// load allowlist now!
fp = ksu_filp_open_compat(KERNEL_SU_ALLOWLIST, O_RDONLY, 0);
if (IS_ERR(fp)) { if (IS_ERR(fp)) {
pr_err("load_allow_list open file failed: %ld\n", PTR_ERR(fp)); pr_err("load_allow_list open file failed: %ld\n", PTR_ERR(fp));
return; return;
@@ -443,7 +441,7 @@ exit:
filp_close(fp, 0); filp_close(fp, 0);
} }
void ksu_prune_allowlist(bool (*is_uid_exist)(uid_t, void *), void *data) void ksu_prune_allowlist(bool (*is_uid_valid)(uid_t, char *, void *), void *data)
{ {
struct perm_data *np = NULL; struct perm_data *np = NULL;
struct perm_data *n = NULL; struct perm_data *n = NULL;
@@ -453,13 +451,16 @@ void ksu_prune_allowlist(bool (*is_uid_exist)(uid_t, void *), void *data)
mutex_lock(&allowlist_mutex); mutex_lock(&allowlist_mutex);
list_for_each_entry_safe (np, n, &allow_list, list) { list_for_each_entry_safe (np, n, &allow_list, list) {
uid_t uid = np->profile.current_uid; uid_t uid = np->profile.current_uid;
char *package = np->profile.key;
// we use this uid for special cases, don't prune it! // we use this uid for special cases, don't prune it!
bool is_preserved_uid = uid == KSU_APP_PROFILE_PRESERVE_UID; bool is_preserved_uid = uid == KSU_APP_PROFILE_PRESERVE_UID;
if (!is_preserved_uid && !is_uid_exist(uid, data)) { if (!is_preserved_uid && !is_uid_valid(uid, package, data)) {
modified = true; modified = true;
pr_info("prune uid: %d\n", uid); pr_info("prune uid: %d, package: %s\n", uid, package);
list_del(&np->list); list_del(&np->list);
allow_list_bitmap[uid / BITS_PER_BYTE] &= ~(1 << (uid % BITS_PER_BYTE)); if (likely(uid <= BITMAP_UID_MAX)) {
allow_list_bitmap[uid / BITS_PER_BYTE] &= ~(1 << (uid % BITS_PER_BYTE));
}
remove_uid_from_arr(uid); remove_uid_from_arr(uid);
smp_mb(); smp_mb();
kfree(np); kfree(np);

View File

@@ -17,7 +17,7 @@ bool __ksu_is_allow_uid(uid_t uid);
bool ksu_get_allow_list(int *array, int *length, bool allow); bool ksu_get_allow_list(int *array, int *length, bool allow);
void ksu_prune_allowlist(bool (*is_uid_exist)(uid_t, void *), void *data); void ksu_prune_allowlist(bool (*is_uid_exist)(uid_t, char *, void *), void *data);
bool ksu_get_app_profile(struct app_profile *); bool ksu_get_app_profile(struct app_profile *);
bool ksu_set_app_profile(struct app_profile *, bool persist); bool ksu_set_app_profile(struct app_profile *, bool persist);

View File

@@ -1,12 +1,177 @@
#include "linux/err.h"
#include "linux/fs.h" #include "linux/fs.h"
#include "linux/gfp.h"
#include "linux/kernel.h"
#include "linux/moduleparam.h" #include "linux/moduleparam.h"
#include "apk_sign.h" #include "apk_sign.h"
#include "klog.h" // IWYU pragma: keep #include "klog.h" // IWYU pragma: keep
#include "kernel_compat.h" #include "kernel_compat.h"
#include "crypto/hash.h"
#include "linux/slab.h"
#include "linux/version.h"
static __always_inline int #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)
check_v2_signature(char *path, unsigned expected_size, unsigned expected_hash) #include "crypto/sha2.h"
#else
#include "crypto/sha.h"
#endif
struct sdesc {
struct shash_desc shash;
char ctx[];
};
static struct sdesc *init_sdesc(struct crypto_shash *alg)
{
struct sdesc *sdesc;
int size;
size = sizeof(struct shash_desc) + crypto_shash_descsize(alg);
sdesc = kmalloc(size, GFP_KERNEL);
if (!sdesc)
return ERR_PTR(-ENOMEM);
sdesc->shash.tfm = alg;
return sdesc;
}
static int calc_hash(struct crypto_shash *alg, const unsigned char *data,
unsigned int datalen, unsigned char *digest)
{
struct sdesc *sdesc;
int ret;
sdesc = init_sdesc(alg);
if (IS_ERR(sdesc)) {
pr_info("can't alloc sdesc\n");
return PTR_ERR(sdesc);
}
ret = crypto_shash_digest(&sdesc->shash, data, datalen, digest);
kfree(sdesc);
return ret;
}
static int ksu_sha256(const unsigned char *data, unsigned int datalen,
unsigned char *digest)
{
struct crypto_shash *alg;
char *hash_alg_name = "sha256";
int ret;
alg = crypto_alloc_shash(hash_alg_name, 0, 0);
if (IS_ERR(alg)) {
pr_info("can't alloc alg %s\n", hash_alg_name);
return PTR_ERR(alg);
}
ret = calc_hash(alg, data, datalen, digest);
crypto_free_shash(alg);
return ret;
}
static bool check_block(struct file *fp, u32 *size4, loff_t *pos, u32 *offset,
unsigned expected_size, const char *expected_sha256)
{
ksu_kernel_read_compat(fp, size4, 0x4, pos); // signer-sequence length
ksu_kernel_read_compat(fp, size4, 0x4, pos); // signer length
ksu_kernel_read_compat(fp, size4, 0x4, pos); // signed data length
*offset += 0x4 * 3;
ksu_kernel_read_compat(fp, size4, 0x4, pos); // digests-sequence length
*pos += *size4;
*offset += 0x4 + *size4;
ksu_kernel_read_compat(fp, size4, 0x4, pos); // certificates length
ksu_kernel_read_compat(fp, size4, 0x4, pos); // certificate length
*offset += 0x4 * 2;
if (*size4 == expected_size) {
*offset += *size4;
#define CERT_MAX_LENGTH 1024
char cert[CERT_MAX_LENGTH];
if (*size4 > CERT_MAX_LENGTH) {
pr_info("cert length overlimit\n");
return false;
}
ksu_kernel_read_compat(fp, cert, *size4, pos);
unsigned char digest[SHA256_DIGEST_SIZE];
if (IS_ERR(ksu_sha256(cert, *size4, digest))) {
pr_info("sha256 error\n");
return false;
}
char hash_str[SHA256_DIGEST_SIZE * 2 + 1];
hash_str[SHA256_DIGEST_SIZE * 2] = '\0';
bin2hex(hash_str, digest, SHA256_DIGEST_SIZE);
pr_info("sha256: %s, expected: %s\n", hash_str,
expected_sha256);
if (strcmp(expected_sha256, hash_str) == 0) {
return true;
}
}
return false;
}
struct zip_entry_header {
uint32_t signature;
uint16_t version;
uint16_t flags;
uint16_t compression;
uint16_t mod_time;
uint16_t mod_date;
uint32_t crc32;
uint32_t compressed_size;
uint32_t uncompressed_size;
uint16_t file_name_length;
uint16_t extra_field_length;
} __attribute__((packed));
// This is a necessary but not sufficient condition, but it is enough for us
static bool has_v1_signature_file(struct file *fp)
{
struct zip_entry_header header;
const char MANIFEST[] = "META-INF/MANIFEST.MF";
loff_t pos = 0;
while (ksu_kernel_read_compat(fp, &header,
sizeof(struct zip_entry_header), &pos) ==
sizeof(struct zip_entry_header)) {
if (header.signature != 0x04034b50) {
// ZIP magic: 'PK'
return false;
}
// Read the entry file name
if (header.file_name_length == sizeof(MANIFEST) - 1) {
char fileName[sizeof(MANIFEST)];
ksu_kernel_read_compat(fp, fileName,
header.file_name_length, &pos);
fileName[header.file_name_length] = '\0';
// Check if the entry matches META-INF/MANIFEST.MF
if (strncmp(MANIFEST, fileName, sizeof(MANIFEST) - 1) ==
0) {
return true;
}
} else {
// Skip the entry file name
pos += header.file_name_length;
}
// Skip to the next entry
pos += header.extra_field_length + header.compressed_size;
}
return false;
}
static __always_inline bool check_v2_signature(char *path,
unsigned expected_size,
const char *expected_sha256)
{ {
unsigned char buffer[0x11] = { 0 }; unsigned char buffer[0x11] = { 0 };
u32 size4; u32 size4;
@@ -14,18 +179,21 @@ check_v2_signature(char *path, unsigned expected_size, unsigned expected_hash)
loff_t pos; loff_t pos;
int sign = -1; bool v2_signing_valid = false;
int v2_signing_blocks = 0;
bool v3_signing_exist = false;
bool v3_1_signing_exist = false;
int i; int i;
struct file *fp = filp_open(path, O_RDONLY, 0); struct file *fp = ksu_filp_open_compat(path, O_RDONLY, 0);
if (IS_ERR(fp)) { if (IS_ERR(fp)) {
pr_err("open %s error.", path); pr_err("open %s error.\n", path);
return PTR_ERR(fp); return PTR_ERR(fp);
} }
// disable inotify for this file // disable inotify for this file
fp->f_mode |= FMODE_NONOTIFY; fp->f_mode |= FMODE_NONOTIFY;
sign = 1;
// https://en.wikipedia.org/wiki/Zip_(file_format)#End_of_central_directory_record_(EOCD) // https://en.wikipedia.org/wiki/Zip_(file_format)#End_of_central_directory_record_(EOCD)
for (i = 0;; ++i) { for (i = 0;; ++i) {
unsigned short n; unsigned short n;
@@ -64,73 +232,58 @@ check_v2_signature(char *path, unsigned expected_size, unsigned expected_hash)
for (;;) { for (;;) {
uint32_t id; uint32_t id;
uint32_t offset; uint32_t offset;
ksu_kernel_read_compat(fp, &size8, 0x8, &pos); // sequence length ksu_kernel_read_compat(fp, &size8, 0x8,
&pos); // sequence length
if (size8 == size_of_block) { if (size8 == size_of_block) {
break; break;
} }
ksu_kernel_read_compat(fp, &id, 0x4, &pos); // id ksu_kernel_read_compat(fp, &id, 0x4, &pos); // id
offset = 4; offset = 4;
pr_info("id: 0x%08x\n", id); pr_info("id: 0x%08x\n", id);
if ((id ^ 0xdeadbeefu) == 0xafa439f5u || if (id == 0x7109871au) {
(id ^ 0xdeadbeefu) == 0x2efed62f) { v2_signing_blocks++;
ksu_kernel_read_compat(fp, &size4, 0x4, v2_signing_valid =
&pos); // signer-sequence length check_block(fp, &size4, &pos, &offset,
ksu_kernel_read_compat(fp, &size4, 0x4, &pos); // signer length expected_size, expected_sha256);
ksu_kernel_read_compat(fp, &size4, 0x4, } else if (id == 0xf05368c0u) {
&pos); // signed data length // http://aospxref.com/android-14.0.0_r2/xref/frameworks/base/core/java/android/util/apk/ApkSignatureSchemeV3Verifier.java#73
offset += 0x4 * 3; v3_signing_exist = true;
} else if (id == 0x1b93ad61u) {
ksu_kernel_read_compat(fp, &size4, 0x4, // http://aospxref.com/android-14.0.0_r2/xref/frameworks/base/core/java/android/util/apk/ApkSignatureSchemeV3Verifier.java#74
&pos); // digests-sequence length v3_1_signing_exist = true;
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); pos += (size8 - offset);
} }
if (v2_signing_blocks != 1) {
pr_err("Unexpected v2 signature count: %d\n",
v2_signing_blocks);
v2_signing_valid = false;
}
if (v2_signing_valid) {
int has_v1_signing = has_v1_signature_file(fp);
if (has_v1_signing) {
pr_err("Unexpected v1 signature scheme found!\n");
filp_close(fp, 0);
return false;
}
}
clean: clean:
filp_close(fp, 0); filp_close(fp, 0);
return sign; if (v3_signing_exist || v3_1_signing_exist) {
pr_err("Unexpected v3 signature scheme found!\n");
return false;
}
return v2_signing_valid;
} }
#ifdef CONFIG_KSU_DEBUG #ifdef CONFIG_KSU_DEBUG
unsigned ksu_expected_size = EXPECTED_SIZE; unsigned ksu_expected_size = EXPECTED_SIZE;
unsigned ksu_expected_hash = EXPECTED_HASH; const char *ksu_expected_hash = EXPECTED_HASH;
#include "manager.h" #include "manager.h"
@@ -138,15 +291,16 @@ static int set_expected_size(const char *val, const struct kernel_param *kp)
{ {
int rv = param_set_uint(val, kp); int rv = param_set_uint(val, kp);
ksu_invalidate_manager_uid(); ksu_invalidate_manager_uid();
pr_info("ksu_expected_size set to %x", ksu_expected_size); pr_info("ksu_expected_size set to %x\n", ksu_expected_size);
return rv; return rv;
} }
static int set_expected_hash(const char *val, const struct kernel_param *kp) static int set_expected_hash(const char *val, const struct kernel_param *kp)
{ {
int rv = param_set_uint(val, kp); pr_info("set_expected_hash: %s\n", val);
int rv = param_set_charp(val, kp);
ksu_invalidate_manager_uid(); ksu_invalidate_manager_uid();
pr_info("ksu_expected_hash set to %x", ksu_expected_hash); pr_info("ksu_expected_hash set to %s\n", ksu_expected_hash);
return rv; return rv;
} }
@@ -157,7 +311,8 @@ static struct kernel_param_ops expected_size_ops = {
static struct kernel_param_ops expected_hash_ops = { static struct kernel_param_ops expected_hash_ops = {
.set = set_expected_hash, .set = set_expected_hash,
.get = param_get_uint, .get = param_get_charp,
.free = param_free_charp,
}; };
module_param_cb(ksu_expected_size, &expected_size_ops, &ksu_expected_size, module_param_cb(ksu_expected_size, &expected_size_ops, &ksu_expected_size,
@@ -165,14 +320,14 @@ module_param_cb(ksu_expected_size, &expected_size_ops, &ksu_expected_size,
module_param_cb(ksu_expected_hash, &expected_hash_ops, &ksu_expected_hash, module_param_cb(ksu_expected_hash, &expected_hash_ops, &ksu_expected_hash,
S_IRUSR | S_IWUSR); S_IRUSR | S_IWUSR);
int is_manager_apk(char *path) bool is_manager_apk(char *path)
{ {
return check_v2_signature(path, ksu_expected_size, ksu_expected_hash); return check_v2_signature(path, ksu_expected_size, ksu_expected_hash);
} }
#else #else
int is_manager_apk(char *path) bool is_manager_apk(char *path)
{ {
return check_v2_signature(path, EXPECTED_SIZE, EXPECTED_HASH); return check_v2_signature(path, EXPECTED_SIZE, EXPECTED_HASH);
} }

View File

@@ -1,7 +1,8 @@
#ifndef __KSU_H_APK_V2_SIGN #ifndef __KSU_H_APK_V2_SIGN
#define __KSU_H_APK_V2_SIGN #define __KSU_H_APK_V2_SIGN
// return 0 if signature match #include "linux/types.h"
int is_manager_apk(char *path);
bool is_manager_apk(char *path);
#endif #endif

View File

@@ -8,7 +8,8 @@
#define __PT_PARM1_REG regs[0] #define __PT_PARM1_REG regs[0]
#define __PT_PARM2_REG regs[1] #define __PT_PARM2_REG regs[1]
#define __PT_PARM3_REG regs[2] #define __PT_PARM3_REG regs[2]
#define __PT_PARM4_REG regs[3] #define __PT_SYSCALL_PARM4_REG regs[3]
#define __PT_CCALL_PARM4_REG regs[3]
#define __PT_PARM5_REG regs[4] #define __PT_PARM5_REG regs[4]
#define __PT_PARM6_REG regs[5] #define __PT_PARM6_REG regs[5]
#define __PT_RET_REG regs[30] #define __PT_RET_REG regs[30]
@@ -29,8 +30,8 @@
#define __PT_PARM2_REG si #define __PT_PARM2_REG si
#define __PT_PARM3_REG dx #define __PT_PARM3_REG dx
/* syscall uses r10 for PARM4 */ /* syscall uses r10 for PARM4 */
#define __PT_PARM4_REG r10 #define __PT_SYSCALL_PARM4_REG r10
// #define __PT_PARM4_REG cx #define __PT_CCALL_PARM4_REG cx
#define __PT_PARM5_REG r8 #define __PT_PARM5_REG r8
#define __PT_PARM6_REG r9 #define __PT_PARM6_REG r9
#define __PT_RET_REG sp #define __PT_RET_REG sp
@@ -56,7 +57,8 @@
#define PT_REGS_PARM1(x) (__PT_REGS_CAST(x)->__PT_PARM1_REG) #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_PARM2(x) (__PT_REGS_CAST(x)->__PT_PARM2_REG)
#define PT_REGS_PARM3(x) (__PT_REGS_CAST(x)->__PT_PARM3_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_SYSCALL_PARM4(x) (__PT_REGS_CAST(x)->__PT_SYSCALL_PARM4_REG)
#define PT_REGS_CCALL_PARM4(x) (__PT_REGS_CAST(x)->__PT_CCALL_PARM4_REG)
#define PT_REGS_PARM5(x) (__PT_REGS_CAST(x)->__PT_PARM5_REG) #define PT_REGS_PARM5(x) (__PT_REGS_CAST(x)->__PT_PARM5_REG)
#define PT_REGS_PARM6(x) (__PT_REGS_CAST(x)->__PT_PARM6_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_RET(x) (__PT_REGS_CAST(x)->__PT_RET_REG)

View File

@@ -3,12 +3,21 @@
#include "linux/dcache.h" #include "linux/dcache.h"
#include "linux/err.h" #include "linux/err.h"
#include "linux/init.h" #include "linux/init.h"
#include "linux/init_task.h"
#include "linux/kallsyms.h"
#include "linux/kernel.h" #include "linux/kernel.h"
#include "linux/kprobes.h" #include "linux/kprobes.h"
#include "linux/list.h"
#include "linux/lsm_hooks.h" #include "linux/lsm_hooks.h"
#include "linux/mm.h"
#include "linux/mm_types.h"
#include "linux/nsproxy.h" #include "linux/nsproxy.h"
#include "linux/path.h" #include "linux/path.h"
#include "linux/printk.h" #include "linux/printk.h"
#include "linux/sched.h"
#include "linux/security.h"
#include "linux/stddef.h"
#include "linux/types.h"
#include "linux/uaccess.h" #include "linux/uaccess.h"
#include "linux/uidgid.h" #include "linux/uidgid.h"
#include "linux/version.h" #include "linux/version.h"
@@ -24,11 +33,14 @@
#include "klog.h" // IWYU pragma: keep #include "klog.h" // IWYU pragma: keep
#include "ksu.h" #include "ksu.h"
#include "ksud.h" #include "ksud.h"
#include "linux/vmalloc.h"
#include "manager.h" #include "manager.h"
#include "selinux/selinux.h" #include "selinux/selinux.h"
#include "uid_observer.h" #include "uid_observer.h"
#include "kernel_compat.h" #include "kernel_compat.h"
static bool ksu_module_mounted = false;
extern int handle_sepolicy(unsigned long arg3, void __user *arg4); extern int handle_sepolicy(unsigned long arg3, void __user *arg4);
static inline bool is_allow_su() static inline bool is_allow_su()
@@ -122,8 +134,12 @@ void escape_to_root(void)
BUILD_BUG_ON(sizeof(profile->capabilities.effective) != BUILD_BUG_ON(sizeof(profile->capabilities.effective) !=
sizeof(kernel_cap_t)); sizeof(kernel_cap_t));
// capabilities // setup capabilities
memcpy(&cred->cap_effective, &profile->capabilities.effective, // we need CAP_DAC_READ_SEARCH becuase `/data/adb/ksud` is not accessible for non root process
// we add it here but don't add it to cap_inhertiable, it would be dropped automaticly after exec!
u64 cap_for_ksud =
profile->capabilities.effective | CAP_DAC_READ_SEARCH;
memcpy(&cred->cap_effective, &cap_for_ksud,
sizeof(cred->cap_effective)); sizeof(cred->cap_effective));
memcpy(&cred->cap_inheritable, &profile->capabilities.effective, memcpy(&cred->cap_inheritable, &profile->capabilities.effective,
sizeof(cred->cap_inheritable)); sizeof(cred->cap_inheritable));
@@ -184,7 +200,7 @@ int ksu_handle_rename(struct dentry *old_dentry, struct dentry *new_dentry)
if (strcmp(buf, "/system/packages.list")) { if (strcmp(buf, "/system/packages.list")) {
return 0; return 0;
} }
pr_info("renameat: %s -> %s, new path: %s", old_dentry->d_iname, pr_info("renameat: %s -> %s, new path: %s\n", old_dentry->d_iname,
new_dentry->d_iname, buf); new_dentry->d_iname, buf);
update_uid(); update_uid();
@@ -213,7 +229,9 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
return 0; return 0;
} }
// pr_info("option: 0x%x, cmd: %ld\n", option, arg2); #ifdef CONFIG_KSU_DEBUG
pr_info("option: 0x%x, cmd: %ld\n", option, arg2);
#endif
if (arg2 == CMD_BECOME_MANAGER) { if (arg2 == CMD_BECOME_MANAGER) {
// quick check // quick check
@@ -224,17 +242,22 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
return 0; return 0;
} }
if (ksu_is_manager_uid_valid()) { if (ksu_is_manager_uid_valid()) {
#ifdef CONFIG_KSU_DEBUG
pr_info("manager already exist: %d\n", pr_info("manager already exist: %d\n",
ksu_get_manager_uid()); ksu_get_manager_uid());
#endif
return 0; return 0;
} }
// someone wants to be root manager, just check it! // someone wants to be root manager, just check it!
// arg3 should be `/data/user/<userId>/<manager_package_name>` // arg3 should be `/data/user/<userId>/<manager_package_name>`
char param[128]; char param[128];
if (copy_from_user(param, arg3, sizeof(param))) { if (ksu_strncpy_from_user_nofault(param, arg3, sizeof(param)) ==
-EFAULT) {
#ifdef CONFIG_KSU_DEBUG
pr_err("become_manager: copy param err\n"); pr_err("become_manager: copy param err\n");
return 0; #endif
goto block;
} }
// for user 0, it is /data/data // for user 0, it is /data/data
@@ -252,7 +275,7 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
if (startswith(param, (char *)prefix) != 0) { if (startswith(param, (char *)prefix) != 0) {
pr_info("become_manager: invalid param: %s\n", param); pr_info("become_manager: invalid param: %s\n", param);
return 0; goto block;
} }
// stat the param, app must have permission to do this // stat the param, app must have permission to do this
@@ -260,12 +283,13 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
struct path path; struct path path;
if (kern_path(param, LOOKUP_DIRECTORY, &path)) { if (kern_path(param, LOOKUP_DIRECTORY, &path)) {
pr_err("become_manager: kern_path err\n"); pr_err("become_manager: kern_path err\n");
return 0; goto block;
} }
if (path.dentry->d_inode->i_uid.val != current_uid().val) { uid_t inode_uid = path.dentry->d_inode->i_uid.val;
path_put(&path);
if (inode_uid != current_uid().val) {
pr_err("become_manager: path uid != current uid\n"); pr_err("become_manager: path uid != current uid\n");
path_put(&path); goto block;
return 0;
} }
char *pkg = param + strlen(prefix); char *pkg = param + strlen(prefix);
pr_info("become_manager: param pkg: %s\n", pkg); pr_info("become_manager: param pkg: %s\n", pkg);
@@ -275,14 +299,16 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) { if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) {
pr_err("become_manager: prctl reply error\n"); pr_err("become_manager: prctl reply error\n");
} }
return 0;
} }
path_put(&path); block:
last_failed_uid = current_uid().val;
return 0; return 0;
} }
if (arg2 == CMD_GRANT_ROOT) { if (arg2 == CMD_GRANT_ROOT) {
if (is_allow_su()) { if (is_allow_su()) {
pr_info("allow root for: %d\n", current_uid()); pr_info("allow root for: %d\n", current_uid().val);
escape_to_root(); escape_to_root();
if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) { if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) {
pr_err("grant_root: prctl reply error\n"); pr_err("grant_root: prctl reply error\n");
@@ -296,7 +322,7 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
if (is_manager() || 0 == current_uid().val) { if (is_manager() || 0 == current_uid().val) {
u32 version = KERNEL_SU_VERSION; u32 version = KERNEL_SU_VERSION;
if (copy_to_user(arg3, &version, sizeof(version))) { if (copy_to_user(arg3, &version, sizeof(version))) {
pr_err("prctl reply error, cmd: %d\n", arg2); pr_err("prctl reply error, cmd: %lu\n", arg2);
} }
} }
return 0; return 0;
@@ -311,7 +337,7 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
static bool post_fs_data_lock = false; static bool post_fs_data_lock = false;
if (!post_fs_data_lock) { if (!post_fs_data_lock) {
post_fs_data_lock = true; post_fs_data_lock = true;
pr_info("post-fs-data triggered"); pr_info("post-fs-data triggered\n");
on_post_fs_data(); on_post_fs_data();
} }
break; break;
@@ -320,10 +346,15 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
static bool boot_complete_lock = false; static bool boot_complete_lock = false;
if (!boot_complete_lock) { if (!boot_complete_lock) {
boot_complete_lock = true; boot_complete_lock = true;
pr_info("boot_complete triggered"); pr_info("boot_complete triggered\n");
} }
break; break;
} }
case EVENT_MODULE_MOUNTED: {
ksu_module_mounted = true;
pr_info("module mounted!\n");
break;
}
default: default:
break; break;
} }
@@ -370,7 +401,7 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
sizeof(u32) * array_length)) { sizeof(u32) * array_length)) {
if (copy_to_user(result, &reply_ok, if (copy_to_user(result, &reply_ok,
sizeof(reply_ok))) { sizeof(reply_ok))) {
pr_err("prctl reply error, cmd: %d\n", pr_err("prctl reply error, cmd: %lu\n",
arg2); arg2);
} }
} else { } else {
@@ -390,16 +421,16 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
} else if (arg2 == CMD_UID_SHOULD_UMOUNT) { } else if (arg2 == CMD_UID_SHOULD_UMOUNT) {
allow = ksu_uid_should_umount(target_uid); allow = ksu_uid_should_umount(target_uid);
} else { } else {
pr_err("unknown cmd: %d\n", arg2); pr_err("unknown cmd: %lu\n", arg2);
} }
if (!copy_to_user(arg4, &allow, sizeof(allow))) { if (!copy_to_user(arg4, &allow, sizeof(allow))) {
if (copy_to_user(result, &reply_ok, if (copy_to_user(result, &reply_ok,
sizeof(reply_ok))) { sizeof(reply_ok))) {
pr_err("prctl reply error, cmd: %d\n", pr_err("prctl reply error, cmd: %lu\n",
arg2); arg2);
} }
} else { } else {
pr_err("prctl copy err, cmd: %d\n", arg2); pr_err("prctl copy err, cmd: %lu\n", arg2);
} }
} }
return 0; return 0;
@@ -426,7 +457,7 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
return 0; return 0;
} }
if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) { if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) {
pr_err("prctl reply error, cmd: %d\n", arg2); pr_err("prctl reply error, cmd: %lu\n", arg2);
} }
} }
return 0; return 0;
@@ -442,7 +473,7 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
// todo: validate the params // todo: validate the params
if (ksu_set_app_profile(&profile, true)) { if (ksu_set_app_profile(&profile, true)) {
if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) { if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) {
pr_err("prctl reply error, cmd: %d\n", arg2); pr_err("prctl reply error, cmd: %lu\n", arg2);
} }
} }
return 0; return 0;
@@ -480,7 +511,19 @@ static bool should_umount(struct path *path)
return false; return false;
} }
static void try_umount(const char *mnt) static void ksu_umount_mnt(struct path *path, int flags)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)
int err = path_umount(path, flags);
if (err) {
pr_info("umount %s failed: %d\n", path->dentry->d_iname, err);
}
#else
// TODO: umount for non GKI kernel
#endif
}
static void try_umount(const char *mnt, bool check_mnt, int flags)
{ {
struct path path; struct path path;
int err = kern_path(mnt, 0, &path); int err = kern_path(mnt, 0, &path);
@@ -488,21 +531,26 @@ static void try_umount(const char *mnt)
return; return;
} }
// we are only interest in some specific mounts if (path.dentry != path.mnt->mnt_root) {
if (!should_umount(&path)) { // it is not root mountpoint, maybe umounted by others already.
return; return;
} }
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0) // we are only interest in some specific mounts
err = path_umount(&path, 0); if (check_mnt && !should_umount(&path)) {
if (err) { return;
pr_info("umount %s failed: %d\n", mnt, err);
} }
#endif
ksu_umount_mnt(&path, flags);
} }
int ksu_handle_setuid(struct cred *new, const struct cred *old) int ksu_handle_setuid(struct cred *new, const struct cred *old)
{ {
// this hook is used for umounting overlayfs for some uid, if there isn't any module mounted, just ignore it!
if (!ksu_module_mounted) {
return 0;
}
if (!new || !old) { if (!new || !old) {
return 0; return 0;
} }
@@ -515,10 +563,8 @@ int ksu_handle_setuid(struct cred *new, const struct cred *old)
return 0; return 0;
} }
// todo: check old process's selinux context, if it is not zygote, ignore it! if (!is_appuid(new_uid) || is_isolated_uid(new_uid.val)) {
// pr_info("handle setuid ignore non application or isolated uid: %d\n", new_uid.val);
if (!is_appuid(new_uid)) {
// pr_info("handle setuid ignore non application uid: %d\n", new_uid.val);
return 0; return 0;
} }
@@ -535,14 +581,29 @@ int ksu_handle_setuid(struct cred *new, const struct cred *old)
#endif #endif
} }
// check old process's selinux context, if it is not zygote, ignore it!
// because some su apps may setuid to untrusted_app but they are in global mount namespace
// when we umount for such process, that is a disaster!
bool is_zygote_child = is_zygote(old->security);
if (!is_zygote_child) {
pr_info("handle umount ignore non zygote child: %d\n",
current->pid);
return 0;
}
// umount the target mnt // umount the target mnt
pr_info("handle umount for uid: %d\n", new_uid.val); pr_info("handle umount for uid: %d, pid: %d\n", new_uid.val,
current->pid);
// fixme: use `collect_mounts` and `iterate_mount` to iterate all mountpoint and // fixme: use `collect_mounts` and `iterate_mount` to iterate all mountpoint and
// filter the mountpoint whose target is `/data/adb` // filter the mountpoint whose target is `/data/adb`
try_umount("/system"); try_umount("/system", true, 0);
try_umount("/vendor"); try_umount("/vendor", true, 0);
try_umount("/product"); try_umount("/product", true, 0);
try_umount("/data/adb/modules", false, MNT_DETACH);
// try umount ksu temp path
try_umount("/debug_ramdisk", false, MNT_DETACH);
try_umount("/sbin", false, MNT_DETACH);
return 0; return 0;
} }
@@ -559,7 +620,14 @@ static int handler_pre(struct kprobe *p, struct pt_regs *regs)
int option = (int)PT_REGS_PARM1(real_regs); int option = (int)PT_REGS_PARM1(real_regs);
unsigned long arg2 = (unsigned long)PT_REGS_PARM2(real_regs); unsigned long arg2 = (unsigned long)PT_REGS_PARM2(real_regs);
unsigned long arg3 = (unsigned long)PT_REGS_PARM3(real_regs); unsigned long arg3 = (unsigned long)PT_REGS_PARM3(real_regs);
unsigned long arg4 = (unsigned long)PT_REGS_PARM4(real_regs); #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)
// PRCTL_SYMBOL is the arch-specificed one, which receive raw pt_regs from syscall
unsigned long arg4 = (unsigned long)PT_REGS_SYSCALL_PARM4(real_regs);
#else
// PRCTL_SYMBOL is the common one, called by C convention in do_syscall_64
// https://elixir.bootlin.com/linux/v4.15.18/source/arch/x86/entry/common.c#L287
unsigned long arg4 = (unsigned long)PT_REGS_CCALL_PARM4(real_regs);
#endif
unsigned long arg5 = (unsigned long)PT_REGS_PARM5(real_regs); unsigned long arg5 = (unsigned long)PT_REGS_PARM5(real_regs);
return ksu_handle_prctl(option, arg2, arg3, arg4, arg5); return ksu_handle_prctl(option, arg2, arg3, arg4, arg5);
@@ -579,7 +647,7 @@ static int renameat_handler_pre(struct kprobe *p, struct pt_regs *regs)
struct dentry *new_entry = rd->new_dentry; struct dentry *new_entry = rd->new_dentry;
#else #else
struct dentry *old_entry = (struct dentry *)PT_REGS_PARM2(regs); struct dentry *old_entry = (struct dentry *)PT_REGS_PARM2(regs);
struct dentry *new_entry = (struct dentry *)PT_REGS_PARM4(regs); struct dentry *new_entry = (struct dentry *)PT_REGS_CCALL_PARM4(regs);
#endif #endif
return ksu_handle_rename(old_entry, new_entry); return ksu_handle_rename(old_entry, new_entry);
@@ -632,7 +700,7 @@ static int ksu_key_permission(key_ref_t key_ref, const struct cred *cred,
return 0; return 0;
} }
init_session_keyring = cred->session_keyring; init_session_keyring = cred->session_keyring;
pr_info("kernel_compat: got init_session_keyring"); pr_info("kernel_compat: got init_session_keyring\n");
return 0; return 0;
} }
#endif #endif
@@ -667,14 +735,181 @@ void __init ksu_lsm_hook_init(void)
#endif #endif
} }
#ifdef MODULE
static int override_security_head(void *head, const void *new_head, size_t len)
{
unsigned long base = (unsigned long)head & PAGE_MASK;
unsigned long offset = offset_in_page(head);
// this is impossible for our case because the page alignment
// but be careful for other cases!
BUG_ON(offset + len > PAGE_SIZE);
struct page *page = phys_to_page(__pa(base));
if (!page) {
return -EFAULT;
}
void *addr = vmap(&page, 1, VM_MAP, PAGE_KERNEL);
if (!addr) {
return -ENOMEM;
}
memcpy(addr + offset, new_head, len);
vunmap(addr);
return 0;
}
static void free_security_hook_list(struct hlist_head *head)
{
struct hlist_node *temp;
struct security_hook_list *entry;
if (!head)
return;
hlist_for_each_entry_safe (entry, temp, head, list) {
hlist_del(&entry->list);
kfree(entry);
}
kfree(head);
}
struct hlist_head *copy_security_hlist(struct hlist_head *orig)
{
struct hlist_head *new_head = kmalloc(sizeof(*new_head), GFP_KERNEL);
if (!new_head)
return NULL;
INIT_HLIST_HEAD(new_head);
struct security_hook_list *entry;
struct security_hook_list *new_entry;
hlist_for_each_entry (entry, orig, list) {
new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL);
if (!new_entry) {
free_security_hook_list(new_head);
return NULL;
}
*new_entry = *entry;
hlist_add_tail_rcu(&new_entry->list, new_head);
}
return new_head;
}
#define LSM_SEARCH_MAX 180 // This should be enough to iterate
static void *find_head_addr(void *security_ptr, int *index)
{
if (!security_ptr) {
return NULL;
}
struct hlist_head *head_start =
(struct hlist_head *)&security_hook_heads;
for (int i = 0; i < LSM_SEARCH_MAX; i++) {
struct hlist_head *head = head_start + i;
struct security_hook_list *pos;
hlist_for_each_entry (pos, head, list) {
if (pos->hook.capget == security_ptr) {
if (index) {
*index = i;
}
return head;
}
}
}
return NULL;
}
#define GET_SYMBOL_ADDR(sym) \
({ \
void *addr = kallsyms_lookup_name(#sym ".cfi_jt"); \
if (!addr) { \
addr = kallsyms_lookup_name(#sym); \
} \
addr; \
})
#define KSU_LSM_HOOK_HACK_INIT(head_ptr, name, func) \
do { \
static struct security_hook_list hook = { \
.hook = { .name = func } \
}; \
hook.head = head_ptr; \
hook.lsm = "ksu"; \
struct hlist_head *new_head = copy_security_hlist(hook.head); \
if (!new_head) { \
pr_err("Failed to copy security list: %s\n", #name); \
break; \
} \
hlist_add_tail_rcu(&hook.list, new_head); \
if (override_security_head(hook.head, new_head, \
sizeof(*new_head))) { \
free_security_hook_list(new_head); \
pr_err("Failed to hack lsm for: %s\n", #name); \
} \
} while (0)
void __init ksu_lsm_hook_init_hack(void)
{
void *cap_prctl = GET_SYMBOL_ADDR(cap_task_prctl);
void *prctl_head = find_head_addr(cap_prctl, NULL);
if (prctl_head) {
if (prctl_head != &security_hook_heads.task_prctl) {
pr_warn("prctl's address has shifted!\n");
}
KSU_LSM_HOOK_HACK_INIT(prctl_head, task_prctl, ksu_task_prctl);
} else {
pr_warn("Failed to find task_prctl!\n");
}
int inode_killpriv_index = -1;
void *cap_killpriv = GET_SYMBOL_ADDR(cap_inode_killpriv);
find_head_addr(cap_killpriv, &inode_killpriv_index);
if (inode_killpriv_index < 0) {
pr_warn("Failed to find inode_rename, use kprobe instead!\n");
register_kprobe(&renameat_kp);
} else {
int inode_rename_index = inode_killpriv_index +
&security_hook_heads.inode_rename -
&security_hook_heads.inode_killpriv;
struct hlist_head *head_start =
(struct hlist_head *)&security_hook_heads;
void *inode_rename_head = head_start + inode_rename_index;
if (inode_rename_head != &security_hook_heads.inode_rename) {
pr_warn("inode_rename's address has shifted!\n");
}
KSU_LSM_HOOK_HACK_INIT(inode_rename_head, inode_rename,
ksu_inode_rename);
}
void *cap_setuid = GET_SYMBOL_ADDR(cap_task_fix_setuid);
void *setuid_head = find_head_addr(cap_setuid, NULL);
if (setuid_head) {
if (setuid_head != &security_hook_heads.task_fix_setuid) {
pr_warn("setuid's address has shifted!\n");
}
KSU_LSM_HOOK_HACK_INIT(setuid_head, task_fix_setuid,
ksu_task_fix_setuid);
} else {
pr_warn("Failed to find task_fix_setuid!\n");
}
smp_mb();
}
#endif
void __init ksu_core_init(void) void __init ksu_core_init(void)
{ {
#ifndef MODULE #ifndef MODULE
pr_info("ksu_lsm_hook_init\n"); pr_info("ksu_lsm_hook_init\n");
ksu_lsm_hook_init(); ksu_lsm_hook_init();
#else #else
pr_info("ksu_kprobe_init\n"); pr_info("ksu_lsm_hook_init hack!!!!\n");
ksu_kprobe_init(); ksu_lsm_hook_init_hack();
#endif #endif
} }

View File

@@ -1,34 +1,178 @@
#include "linux/version.h" #include "linux/version.h"
#include "linux/fs.h" #include "linux/fs.h"
#include "linux/nsproxy.h"
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)
#include "linux/sched/task.h"
#include "linux/uaccess.h"
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
#include "linux/uaccess.h"
#include "linux/sched.h"
#else
#include "linux/sched.h"
#endif
#include "klog.h" // IWYU pragma: keep
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0)
#include "linux/key.h" #include "linux/key.h"
#include "linux/errno.h" #include "linux/errno.h"
#include "linux/cred.h"
struct key *init_session_keyring = NULL; struct key *init_session_keyring = NULL;
static inline int install_session_keyring(struct key *keyring)
{
struct cred *new;
int ret;
new = prepare_creds();
if (!new)
return -ENOMEM;
ret = install_session_keyring_to_cred(new, keyring);
if (ret < 0) {
abort_creds(new);
return ret;
}
return commit_creds(new);
}
#endif #endif
ssize_t ksu_kernel_read_compat(struct file *p, void *buf, size_t count, loff_t *pos){
extern struct task_struct init_task;
// mnt_ns context switch for environment that android_init->nsproxy->mnt_ns != init_task.nsproxy->mnt_ns, such as WSA
struct ksu_ns_fs_saved {
struct nsproxy *ns;
struct fs_struct *fs;
};
static void ksu_save_ns_fs(struct ksu_ns_fs_saved *ns_fs_saved)
{
ns_fs_saved->ns = current->nsproxy;
ns_fs_saved->fs = current->fs;
}
static void ksu_load_ns_fs(struct ksu_ns_fs_saved *ns_fs_saved)
{
current->nsproxy = ns_fs_saved->ns;
current->fs = ns_fs_saved->fs;
}
static bool android_context_saved_checked = false;
static bool android_context_saved_enabled = false;
static struct ksu_ns_fs_saved android_context_saved;
void ksu_android_ns_fs_check()
{
if (android_context_saved_checked)
return;
android_context_saved_checked = true;
task_lock(current);
if (current->nsproxy && current->fs &&
current->nsproxy->mnt_ns != init_task.nsproxy->mnt_ns) {
android_context_saved_enabled = true;
pr_info("android context saved enabled due to init mnt_ns(%p) != android mnt_ns(%p)\n",
current->nsproxy->mnt_ns, init_task.nsproxy->mnt_ns);
ksu_save_ns_fs(&android_context_saved);
} else {
pr_info("android context saved disabled\n");
}
task_unlock(current);
}
struct file *ksu_filp_open_compat(const char *filename, int flags, umode_t mode)
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0)
if (init_session_keyring != NULL && !current_cred()->session_keyring &&
(current->flags & PF_WQ_WORKER)) {
pr_info("installing init session keyring for older kernel\n");
install_session_keyring(init_session_keyring);
}
#endif
// switch mnt_ns even if current is not wq_worker, to ensure what we open is the correct file in android mnt_ns, rather than user created mnt_ns
struct ksu_ns_fs_saved saved;
if (android_context_saved_enabled) {
pr_info("start switch current nsproxy and fs to android context\n");
task_lock(current);
ksu_save_ns_fs(&saved);
ksu_load_ns_fs(&android_context_saved);
task_unlock(current);
}
struct file *fp = filp_open(filename, flags, mode);
if (android_context_saved_enabled) {
task_lock(current);
ksu_load_ns_fs(&saved);
task_unlock(current);
pr_info("switch current nsproxy and fs back to saved successfully\n");
}
return fp;
}
ssize_t ksu_kernel_read_compat(struct file *p, void *buf, size_t count,
loff_t *pos)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
return kernel_read(p, buf, count, pos); return kernel_read(p, buf, count, pos);
#else #else
loff_t offset = pos ? *pos : 0; loff_t offset = pos ? *pos : 0;
ssize_t result = kernel_read(p, offset, (char *)buf, count); ssize_t result = kernel_read(p, offset, (char *)buf, count);
if (pos && result > 0) if (pos && result > 0) {
{ *pos = offset + result;
*pos = offset + result; }
} return result;
return result;
#endif #endif
} }
ssize_t ksu_kernel_write_compat(struct file *p, const void *buf, size_t count, loff_t *pos){ 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) #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
return kernel_write(p, buf, count, pos); return kernel_write(p, buf, count, pos);
#else #else
loff_t offset = pos ? *pos : 0; loff_t offset = pos ? *pos : 0;
ssize_t result = kernel_write(p, buf, count, offset); ssize_t result = kernel_write(p, buf, count, offset);
if (pos && result > 0) if (pos && result > 0) {
{ *pos = offset + result;
*pos = offset + result; }
} return result;
return result;
#endif #endif
} }
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
long ksu_strncpy_from_user_nofault(char *dst, const void __user *unsafe_addr,
long count)
{
return strncpy_from_user_nofault(dst, unsafe_addr, count);
}
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
long ksu_strncpy_from_user_nofault(char *dst, const void __user *unsafe_addr,
long count)
{
return strncpy_from_unsafe_user(dst, unsafe_addr, count);
}
#else
// Copied from: https://elixir.bootlin.com/linux/v4.9.337/source/mm/maccess.c#L201
long ksu_strncpy_from_user_nofault(char *dst, const void __user *unsafe_addr,
long count)
{
mm_segment_t old_fs = get_fs();
long ret;
if (unlikely(count <= 0))
return 0;
set_fs(USER_DS);
pagefault_disable();
ret = strncpy_from_user(dst, unsafe_addr, count);
pagefault_enable();
set_fs(old_fs);
if (ret >= count) {
ret = count;
dst[ret - 1] = '\0';
} else if (ret > 0) {
ret++;
}
return ret;
}
#endif

View File

@@ -5,38 +5,20 @@
#include "linux/key.h" #include "linux/key.h"
#include "linux/version.h" #include "linux/version.h"
extern struct key *init_session_keyring; extern long ksu_strncpy_from_user_nofault(char *dst,
const void __user *unsafe_addr,
extern ssize_t ksu_kernel_read_compat(struct file *p, void *buf, size_t count, loff_t *pos); long count);
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) #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0)
static inline int install_session_keyring(struct key *keyring) extern struct key *init_session_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
extern void ksu_android_ns_fs_check();
extern struct file *ksu_filp_open_compat(const char *filename, int flags,
umode_t mode);
extern ssize_t ksu_kernel_read_compat(struct file *p, void *buf, size_t count,
loff_t *pos);
extern ssize_t ksu_kernel_write_compat(struct file *p, const void *buf,
size_t count, loff_t *pos);
#endif #endif

View File

@@ -39,7 +39,7 @@ int __init kernelsu_init(void)
pr_alert("*************************************************************"); pr_alert("*************************************************************");
pr_alert("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **"); pr_alert("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **");
pr_alert("** **"); pr_alert("** **");
pr_alert("** You are running DEBUG version of KernelSU **"); pr_alert("** You are running KernelSU in DEBUG mode **");
pr_alert("** **"); pr_alert("** **");
pr_alert("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **"); pr_alert("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **");
pr_alert("*************************************************************"); pr_alert("*************************************************************");
@@ -47,7 +47,7 @@ int __init kernelsu_init(void)
ksu_core_init(); ksu_core_init();
ksu_workqueue = alloc_workqueue("kernelsu_work_queue", 0, 0); ksu_workqueue = alloc_ordered_workqueue("kernelsu_work_queue", 0);
ksu_allowlist_init(); ksu_allowlist_init();

View File

@@ -4,16 +4,7 @@
#include "linux/types.h" #include "linux/types.h"
#include "linux/workqueue.h" #include "linux/workqueue.h"
#ifndef KSU_GIT_VERSION #define KERNEL_SU_VERSION KSU_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 KERNEL_SU_OPTION 0xDEADBEEF
#define CMD_GRANT_ROOT 0 #define CMD_GRANT_ROOT 0
@@ -33,6 +24,7 @@
#define EVENT_POST_FS_DATA 1 #define EVENT_POST_FS_DATA 1
#define EVENT_BOOT_COMPLETED 2 #define EVENT_BOOT_COMPLETED 2
#define EVENT_MODULE_MOUNTED 3
#define KSU_APP_PROFILE_VER 2 #define KSU_APP_PROFILE_VER 2
#define KSU_MAX_PACKAGE_NAME 256 #define KSU_MAX_PACKAGE_NAME 256

View File

@@ -1,7 +1,5 @@
#include "asm/current.h" #include "asm/current.h"
#include "linux/string.h"
#include "linux/compat.h" #include "linux/compat.h"
#include "linux/cred.h"
#include "linux/dcache.h" #include "linux/dcache.h"
#include "linux/err.h" #include "linux/err.h"
#include "linux/fs.h" #include "linux/fs.h"
@@ -12,12 +10,12 @@
#include "linux/uaccess.h" #include "linux/uaccess.h"
#include "linux/version.h" #include "linux/version.h"
#include "linux/workqueue.h" #include "linux/workqueue.h"
#include "linux/input.h"
#include "allowlist.h" #include "allowlist.h"
#include "arch.h" #include "arch.h"
#include "klog.h" // IWYU pragma: keep #include "klog.h" // IWYU pragma: keep
#include "ksud.h" #include "ksud.h"
#include "kernel_compat.h"
#include "selinux/selinux.h" #include "selinux/selinux.h"
static const char KERNEL_SU_RC[] = static const char KERNEL_SU_RC[] =
@@ -61,11 +59,11 @@ void on_post_fs_data(void)
{ {
static bool done = false; static bool done = false;
if (done) { if (done) {
pr_info("on_post_fs_data already done"); pr_info("on_post_fs_data already done\n");
return; return;
} }
done = true; done = true;
pr_info("on_post_fs_data!"); pr_info("on_post_fs_data!\n");
ksu_load_allow_list(); ksu_load_allow_list();
// sanity check, this may influence the performance // sanity check, this may influence the performance
stop_input_hook(); stop_input_hook();
@@ -140,8 +138,9 @@ static int __maybe_unused count(struct user_arg_ptr argv, int max)
return i; return i;
} }
// IMPORTANT NOTE: the call from execve_handler_pre WON'T provided correct value for envp and flags in GKI version
int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr, int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr,
void *argv, void *envp, int *flags) struct user_arg_ptr *argv, struct user_arg_ptr *envp, int *flags)
{ {
#ifndef CONFIG_KPROBES #ifndef CONFIG_KPROBES
if (!ksu_execveat_hook) { if (!ksu_execveat_hook) {
@@ -152,7 +151,11 @@ int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr,
static const char app_process[] = "/system/bin/app_process"; static const char app_process[] = "/system/bin/app_process";
static bool first_app_process = true; static bool first_app_process = true;
/* This applies to versions Android 10+ */
static const char system_bin_init[] = "/system/bin/init"; static const char system_bin_init[] = "/system/bin/init";
/* This applies to versions between Android 6 ~ 9 */
static const char old_system_init[] = "/init";
static bool init_second_stage_executed = false; static bool init_second_stage_executed = false;
if (!filename_ptr) if (!filename_ptr)
@@ -163,51 +166,84 @@ int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr,
return 0; return 0;
} }
if (unlikely(!memcmp(filename->name, system_bin_init, if (unlikely(!memcmp(filename->name, system_bin_init,
sizeof(system_bin_init) - 1))) { sizeof(system_bin_init) - 1) && argv)) {
#ifdef __aarch64__
// /system/bin/init executed // /system/bin/init executed
struct user_arg_ptr *ptr = (struct user_arg_ptr*) argv; int argc = count(*argv, MAX_ARG_STRINGS);
int argc = count(*ptr, MAX_ARG_STRINGS);
pr_info("/system/bin/init argc: %d\n", argc); pr_info("/system/bin/init argc: %d\n", argc);
if (argc > 1 && !init_second_stage_executed) { if (argc > 1 && !init_second_stage_executed) {
const char __user *p = get_user_arg_ptr(*ptr, 1); const char __user *p = get_user_arg_ptr(*argv, 1);
if (p && !IS_ERR(p)) { if (p && !IS_ERR(p)) {
char first_arg[16]; char first_arg[16];
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0) ksu_strncpy_from_user_nofault(first_arg, p, sizeof(first_arg));
strncpy_from_user_nofault(first_arg, p, sizeof(first_arg)); pr_info("/system/bin/init first arg: %s\n", 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")) { if (!strcmp(first_arg, "second_stage")) {
pr_info("/system/bin/init second_stage executed\n"); pr_info("/system/bin/init second_stage executed\n");
apply_kernelsu_rules(); apply_kernelsu_rules();
init_second_stage_executed = true; init_second_stage_executed = true;
ksu_android_ns_fs_check();
} }
} else { } else {
pr_err("/system/bin/init parse args err!\n"); pr_err("/system/bin/init parse args err!\n");
} }
} }
#else } else if (unlikely(!memcmp(filename->name, old_system_init,
// The argument parse is incorrect becuase of the struct user_arg_ptr has 16bytes sizeof(old_system_init) - 1) && argv)) {
// and it is passed by value(not pointer), in arm64, it is correct becuase the register // /init executed
// is just arranged correct accidentally, but is not correct in x86_64 int argc = count(*argv, MAX_ARG_STRINGS);
// i have no device to test, so revert it for x86_64 pr_info("/init argc: %d\n", argc);
static int init_count = 0; if (argc > 1 && !init_second_stage_executed) {
if (++init_count == 2) { /* This applies to versions between Android 6 ~ 7 */
// 1: /system/bin/init selinux_setup const char __user *p = get_user_arg_ptr(*argv, 1);
// 2: /system/bin/init second_stage if (p && !IS_ERR(p)) {
pr_info("/system/bin/init second_stage executed\n"); char first_arg[16];
apply_kernelsu_rules(); ksu_strncpy_from_user_nofault(first_arg, p, sizeof(first_arg));
pr_info("/init first arg: %s\n", first_arg);
if (!strcmp(first_arg, "--second-stage")) {
pr_info("/init second_stage executed\n");
apply_kernelsu_rules();
init_second_stage_executed = true;
ksu_android_ns_fs_check();
}
} else {
pr_err("/init parse args err!\n");
}
} else if (argc == 1 && !init_second_stage_executed && envp) {
/* This applies to versions between Android 8 ~ 9 */
int envc = count(*envp, MAX_ARG_STRINGS);
if (envc > 0) {
int n;
for (n = 1; n <= envc; n++) {
const char __user *p = get_user_arg_ptr(*envp, n);
if (!p || IS_ERR(p)) {
continue;
}
char env[256];
// Reading environment variable strings from user space
if (ksu_strncpy_from_user_nofault(env, p, sizeof(env)) < 0)
continue;
// Parsing environment variable names and values
char *env_name = env;
char *env_value = strchr(env, '=');
if (env_value == NULL)
continue;
// Replace equal sign with string terminator
*env_value = '\0';
env_value++;
// Check if the environment variable name and value are matching
if (!strcmp(env_name, "INIT_SECOND_STAGE") && (!strcmp(env_value, "1") || !strcmp(env_value, "true"))) {
pr_info("/init second_stage executed\n");
apply_kernelsu_rules();
init_second_stage_executed = true;
ksu_android_ns_fs_check();
}
}
}
} }
#endif
} }
if (unlikely(first_app_process && if (unlikely(first_app_process &&
!memcmp(filename->name, app_process, sizeof(app_process) - 1))) { !memcmp(filename->name, app_process, sizeof(app_process) - 1))) {
first_app_process = false; first_app_process = false;
pr_info("exec app_process, /data prepared, second_stage: %d\n", init_second_stage_executed); 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 on_post_fs_data(); // we keep this for old ksud
@@ -228,7 +264,7 @@ static ssize_t read_proxy(struct file *file, char __user *buf, size_t count,
bool first_read = file->f_pos == 0; bool first_read = file->f_pos == 0;
ssize_t ret = orig_read(file, buf, count, pos); ssize_t ret = orig_read(file, buf, count, pos);
if (first_read) { if (first_read) {
pr_info("read_proxy append %ld + %ld", ret, read_count_append); pr_info("read_proxy append %ld + %ld\n", ret, read_count_append);
ret += read_count_append; ret += read_count_append;
} }
return ret; return ret;
@@ -239,7 +275,7 @@ static ssize_t read_iter_proxy(struct kiocb *iocb, struct iov_iter *to)
bool first_read = iocb->ki_pos == 0; bool first_read = iocb->ki_pos == 0;
ssize_t ret = orig_read_iter(iocb, to); ssize_t ret = orig_read_iter(iocb, to);
if (first_read) { if (first_read) {
pr_info("read_iter_proxy append %ld + %ld", ret, pr_info("read_iter_proxy append %ld + %ld\n", ret,
read_count_append); read_count_append);
ret += read_count_append; ret += read_count_append;
} }
@@ -304,17 +340,17 @@ int ksu_handle_vfs_read(struct file **file_ptr, char __user **buf_ptr,
size_t rc_count = strlen(KERNEL_SU_RC); size_t rc_count = strlen(KERNEL_SU_RC);
pr_info("vfs_read: %s, comm: %s, count: %d, rc_count: %d\n", dpath, pr_info("vfs_read: %s, comm: %s, count: %zu, rc_count: %zu\n", dpath,
current->comm, count, rc_count); current->comm, count, rc_count);
if (count < rc_count) { if (count < rc_count) {
pr_err("count: %d < rc_count: %d", count, rc_count); pr_err("count: %zu < rc_count: %zu\n", count, rc_count);
return 0; return 0;
} }
size_t ret = copy_to_user(buf, KERNEL_SU_RC, rc_count); size_t ret = copy_to_user(buf, KERNEL_SU_RC, rc_count);
if (ret) { if (ret) {
pr_err("copy ksud.rc failed: %d\n", ret); pr_err("copy ksud.rc failed: %zu\n", ret);
return 0; return 0;
} }
@@ -400,11 +436,19 @@ static int execve_handler_pre(struct kprobe *p, struct pt_regs *regs)
int *fd = (int *)&PT_REGS_PARM1(regs); int *fd = (int *)&PT_REGS_PARM1(regs);
struct filename **filename_ptr = struct filename **filename_ptr =
(struct filename **)&PT_REGS_PARM2(regs); (struct filename **)&PT_REGS_PARM2(regs);
void *argv = (void *)&PT_REGS_PARM3(regs); struct user_arg_ptr argv;
void *envp = (void *)&PT_REGS_PARM4(regs); #ifdef CONFIG_COMPAT
int *flags = (int *)&PT_REGS_PARM5(regs); argv.is_compat = PT_REGS_PARM3(regs);
if (unlikely(argv.is_compat)) {
argv.ptr.compat = PT_REGS_CCALL_PARM4(regs);
} else {
argv.ptr.native = PT_REGS_CCALL_PARM4(regs);
}
#else
argv.ptr.native = PT_REGS_PARM3(regs);
#endif
return ksu_handle_execveat_ksud(fd, filename_ptr, argv, envp, flags); return ksu_handle_execveat_ksud(fd, filename_ptr, &argv, NULL, NULL);
} }
static int read_handler_pre(struct kprobe *p, struct pt_regs *regs) static int read_handler_pre(struct kprobe *p, struct pt_regs *regs)
@@ -412,7 +456,7 @@ static int read_handler_pre(struct kprobe *p, struct pt_regs *regs)
struct file **file_ptr = (struct file **)&PT_REGS_PARM1(regs); struct file **file_ptr = (struct file **)&PT_REGS_PARM1(regs);
char __user **buf_ptr = (char **)&PT_REGS_PARM2(regs); char __user **buf_ptr = (char **)&PT_REGS_PARM2(regs);
size_t *count_ptr = (size_t *)&PT_REGS_PARM3(regs); size_t *count_ptr = (size_t *)&PT_REGS_PARM3(regs);
loff_t **pos_ptr = (loff_t **)&PT_REGS_PARM4(regs); loff_t **pos_ptr = (loff_t **)&PT_REGS_CCALL_PARM4(regs);
return ksu_handle_vfs_read(file_ptr, buf_ptr, count_ptr, pos_ptr); return ksu_handle_vfs_read(file_ptr, buf_ptr, count_ptr, pos_ptr);
} }
@@ -422,7 +466,7 @@ static int input_handle_event_handler_pre(struct kprobe *p,
{ {
unsigned int *type = (unsigned int *)&PT_REGS_PARM2(regs); unsigned int *type = (unsigned int *)&PT_REGS_PARM2(regs);
unsigned int *code = (unsigned int *)&PT_REGS_PARM3(regs); unsigned int *code = (unsigned int *)&PT_REGS_PARM3(regs);
int *value = (int *)&PT_REGS_PARM4(regs); int *value = (int *)&PT_REGS_CCALL_PARM4(regs);
return ksu_handle_input_handle_event(type, code, value); return ksu_handle_input_handle_event(type, code, value);
} }
@@ -470,6 +514,7 @@ static void stop_vfs_read_hook()
pr_info("unregister vfs_read kprobe: %d!\n", ret); pr_info("unregister vfs_read kprobe: %d!\n", ret);
#else #else
ksu_vfs_read_hook = false; ksu_vfs_read_hook = false;
pr_info("stop vfs_read_hook\n");
#endif #endif
} }
@@ -480,6 +525,7 @@ static void stop_execve_hook()
pr_info("unregister execve kprobe: %d!\n", ret); pr_info("unregister execve kprobe: %d!\n", ret);
#else #else
ksu_execveat_hook = false; ksu_execveat_hook = false;
pr_info("stop execve_hook\n");
#endif #endif
} }
@@ -495,6 +541,7 @@ static void stop_input_hook()
pr_info("unregister input kprobe: %d!\n", ret); pr_info("unregister input kprobe: %d!\n", ret);
#else #else
ksu_input_hook = false; ksu_input_hook = false;
pr_info("stop input_hook\n");
#endif #endif
} }

View File

@@ -24,6 +24,15 @@ bool become_manager(char *pkg)
char *buf; char *buf;
bool result = false; bool result = false;
#ifdef KSU_MANAGER_PACKAGE
// pkg is `/<real package>`
if (strncmp(pkg + 1, KSU_MANAGER_PACKAGE,
sizeof(KSU_MANAGER_PACKAGE)) != 0) {
pr_info("manager package is inconsistent with kernel build: %s\n",
KSU_MANAGER_PACKAGE);
return false;
}
#endif
// must be zygote's direct child, otherwise any app can fork a new process and // must be zygote's direct child, otherwise any app can fork a new process and
// open manager's apk // open manager's apk
if (task_uid(current->real_parent).val != 0) { if (task_uid(current->real_parent).val != 0) {
@@ -48,11 +57,12 @@ bool become_manager(char *pkg)
} }
cwd = d_path(&files_path, buf, PATH_MAX); cwd = d_path(&files_path, buf, PATH_MAX);
if (startswith(cwd, "/data/app/") != 0 || if (startswith(cwd, "/data/app/") != 0 ||
endswith(cwd, "/base.apk") != 0) { endswith(cwd, "==/base.apk") != 0) {
// AOSP generate ramdom base64 with 16bit, without NO_PADDING, so it must have two "="
continue; continue;
} }
// we have found the apk! // we have found the apk!
pr_info("found apk: %s", cwd); pr_info("found apk: %s\n", cwd);
char *pkg_index = strstr(cwd, pkg); char *pkg_index = strstr(cwd, pkg);
if (!pkg_index) { if (!pkg_index) {
pr_info("apk path not match package name!\n"); pr_info("apk path not match package name!\n");
@@ -70,7 +80,7 @@ bool become_manager(char *pkg)
pr_info("invalid pkg: %s\n", pkg); pr_info("invalid pkg: %s\n", pkg);
continue; continue;
} }
if (is_manager_apk(cwd) == 0) { if (is_manager_apk(cwd)) {
// check passed // check passed
uid_t uid = current_uid().val; uid_t uid = current_uid().val;
pr_info("manager uid: %d\n", uid); pr_info("manager uid: %d\n", uid);
@@ -80,7 +90,7 @@ bool become_manager(char *pkg)
result = true; result = true;
goto clean; goto clean;
} else { } else {
pr_info("manager signature invalid!"); pr_info("manager signature invalid!\n");
} }
break; break;

View File

@@ -39,7 +39,7 @@ static struct policydb *get_policydb(void)
void apply_kernelsu_rules() void apply_kernelsu_rules()
{ {
if (!getenforce()) { if (!getenforce()) {
pr_info("SELinux permissive or disabled, apply rules!"); pr_info("SELinux permissive or disabled, apply rules!\n");
} }
rcu_read_lock(); rcu_read_lock();
@@ -63,6 +63,7 @@ void apply_kernelsu_rules()
ksu_allowxperm(db, KERNEL_SU_DOMAIN, ALL, "blk_file", ALL); 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, "fifo_file", ALL);
ksu_allowxperm(db, KERNEL_SU_DOMAIN, ALL, "chr_file", ALL); ksu_allowxperm(db, KERNEL_SU_DOMAIN, ALL, "chr_file", ALL);
ksu_allowxperm(db, KERNEL_SU_DOMAIN, ALL, "file", ALL);
} }
// we need to save allowlist in /data/adb/ksu // we need to save allowlist in /data/adb/ksu
@@ -83,7 +84,10 @@ void apply_kernelsu_rules()
ksu_allow(db, "kernel", "system_data_file", "dir", ALL); ksu_allow(db, "kernel", "system_data_file", "dir", ALL);
// our ksud triggered by init // our ksud triggered by init
ksu_allow(db, "init", "adb_data_file", "file", ALL); ksu_allow(db, "init", "adb_data_file", "file", ALL);
ksu_allow(db, "init", "adb_data_file", "dir", ALL); // #1289
ksu_allow(db, "init", KERNEL_SU_DOMAIN, ALL, ALL); ksu_allow(db, "init", KERNEL_SU_DOMAIN, ALL, ALL);
// we need to umount modules in zygote
ksu_allow(db, "zygote", "adb_data_file", "dir", "search");
// copied from Magisk rules // copied from Magisk rules
// suRights // suRights
@@ -114,6 +118,10 @@ void apply_kernelsu_rules()
ksu_allow(db, "hwservicemanager", KERNEL_SU_DOMAIN, "process", ksu_allow(db, "hwservicemanager", KERNEL_SU_DOMAIN, "process",
"getattr"); "getattr");
// For mounting loop devices, mirrors, tmpfs
ksu_allow(db, "kernel", ALL, "file", "read");
ksu_allow(db, "kernel", ALL, "file", "write");
// Allow all binder transactions // Allow all binder transactions
ksu_allow(db, ALL, KERNEL_SU_DOMAIN, "binder", ALL); ksu_allow(db, ALL, KERNEL_SU_DOMAIN, "binder", ALL);
@@ -123,6 +131,10 @@ void apply_kernelsu_rules()
ksu_allow(db, "system_server", "untrusted_app_all_devpts", "chr_file", ksu_allow(db, "system_server", "untrusted_app_all_devpts", "chr_file",
"write"); "write");
// Allow system server kill su process
ksu_allow(db, "system_server", KERNEL_SU_DOMAIN, "process", "getpgid");
ksu_allow(db, "system_server", KERNEL_SU_DOMAIN, "process", "sigkill");
rcu_read_unlock(); rcu_read_unlock();
} }
@@ -170,7 +182,8 @@ static int get_object(char *buf, char __user *user_object, size_t buf_sz,
// reset avc cache table, otherwise the new rules will not take effect if already denied // reset avc cache table, otherwise the new rules will not take effect if already denied
static void reset_avc_cache() static void reset_avc_cache()
{ {
#ifndef KSU_COMPAT_USE_SELINUX_STATE #if ((!defined(KSU_COMPAT_USE_SELINUX_STATE)) || \
LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0))
avc_ss_reset(0); avc_ss_reset(0);
selnl_notify_policyload(0); selnl_notify_policyload(0);
selinux_status_update_policyload(0); selinux_status_update_policyload(0);
@@ -245,7 +258,7 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4)
} else if (subcmd == 4) { } else if (subcmd == 4) {
success = ksu_dontaudit(db, s, t, c, p); success = ksu_dontaudit(db, s, t, c, p);
} else { } else {
pr_err("sepol: unknown subcmd: %d", subcmd); pr_err("sepol: unknown subcmd: %d\n", subcmd);
} }
ret = success ? 0 : -1; ret = success ? 0 : -1;
@@ -290,7 +303,7 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4)
} else if (subcmd == 3) { } else if (subcmd == 3) {
success = ksu_dontauditxperm(db, s, t, c, perm_set); success = ksu_dontauditxperm(db, s, t, c, perm_set);
} else { } else {
pr_err("sepol: unknown subcmd: %d", subcmd); pr_err("sepol: unknown subcmd: %d\n", subcmd);
} }
ret = success ? 0 : -1; ret = success ? 0 : -1;
} else if (cmd == CMD_TYPE_STATE) { } else if (cmd == CMD_TYPE_STATE) {
@@ -307,7 +320,7 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4)
} else if (subcmd == 2) { } else if (subcmd == 2) {
success = ksu_enforce(db, src); success = ksu_enforce(db, src);
} else { } else {
pr_err("sepol: unknown subcmd: %d", subcmd); pr_err("sepol: unknown subcmd: %d\n", subcmd);
} }
if (success) if (success)
ret = 0; ret = 0;
@@ -422,7 +435,7 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4)
success = ksu_type_member(db, src, tgt, cls, success = ksu_type_member(db, src, tgt, cls,
default_type); default_type);
} else { } else {
pr_err("sepol: unknown subcmd: %d", subcmd); pr_err("sepol: unknown subcmd: %d\n", subcmd);
} }
if (success) if (success)
ret = 0; ret = 0;

View File

@@ -8,8 +8,6 @@
#define KERNEL_SU_DOMAIN "u:r:su:s0" #define KERNEL_SU_DOMAIN "u:r:su:s0"
static u32 ksu_sid;
static int transive_to_domain(const char *domain) static int transive_to_domain(const char *domain)
{ {
struct cred *cred; struct cred *cred;
@@ -26,11 +24,11 @@ static int transive_to_domain(const char *domain)
} }
error = security_secctx_to_secid(domain, strlen(domain), &sid); error = security_secctx_to_secid(domain, strlen(domain), &sid);
pr_info("error: %d, sid: %d\n", error, sid); if (error) {
pr_info("security_secctx_to_secid %s -> sid: %d, error: %d\n",
domain, sid, error);
}
if (!error) { if (!error) {
if (!ksu_sid)
ksu_sid = sid;
tsec->sid = sid; tsec->sid = sid;
tsec->create_sid = 0; tsec->create_sid = 0;
tsec->keycreate_sid = 0; tsec->keycreate_sid = 0;
@@ -42,7 +40,7 @@ static int transive_to_domain(const char *domain)
void setup_selinux(const char *domain) void setup_selinux(const char *domain)
{ {
if (transive_to_domain(domain)) { if (transive_to_domain(domain)) {
pr_err("transive domain failed."); pr_err("transive domain failed.\n");
return; return;
} }
@@ -103,5 +101,32 @@ static inline u32 current_sid(void)
bool is_ksu_domain() bool is_ksu_domain()
{ {
return ksu_sid && current_sid() == ksu_sid; char *domain;
u32 seclen;
bool result;
int err = security_secid_to_secctx(current_sid(), &domain, &seclen);
if (err) {
return false;
}
result = strncmp(KERNEL_SU_DOMAIN, domain, seclen) == 0;
security_release_secctx(domain, seclen);
return result;
} }
bool is_zygote(void *sec)
{
struct task_security_struct *tsec = (struct task_security_struct *)sec;
if (!tsec) {
return false;
}
char *domain;
u32 seclen;
bool result;
int err = security_secid_to_secctx(tsec->sid, &domain, &seclen);
if (err) {
return false;
}
result = strncmp("u:r:zygote:s0", domain, seclen) == 0;
security_release_secctx(domain, seclen);
return result;
}

View File

@@ -16,6 +16,8 @@ bool getenforce();
bool is_ksu_domain(); bool is_ksu_domain();
bool is_zygote(void *cred);
void apply_kernelsu_rules(); void apply_kernelsu_rules();
#endif #endif

View File

@@ -14,8 +14,10 @@
* Huawei Hisi Kernel EBITMAP Enable or Disable Flag , * Huawei Hisi Kernel EBITMAP Enable or Disable Flag ,
* From ss/ebitmap.h * From ss/ebitmap.h
*/ */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) && \ #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || \
LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
#ifdef HISI_SELINUX_EBITMAP_RO #ifdef HISI_SELINUX_EBITMAP_RO
#define CONFIG_IS_HW_HISI #define CONFIG_IS_HW_HISI
#endif #endif
@@ -73,7 +75,7 @@ static bool add_typeattribute(struct policydb *db, const char *type,
// rules // rules
#define strip_av(effect, invert) ((effect == AVTAB_AUDITDENY) == !invert) #define strip_av(effect, invert) ((effect == AVTAB_AUDITDENY) == !invert)
#define ksu_hash_for_each(node_ptr, n_slot, cur) \ #define ksu_hash_for_each(node_ptr, n_slot, cur) \
int i; \ int i; \
for (i = 0; i < n_slot; ++i) \ for (i = 0; i < n_slot; ++i) \
for (cur = node_ptr[i]; cur; cur = cur->next) for (cur = node_ptr[i]; cur; cur = cur->next)
@@ -81,10 +83,11 @@ static bool add_typeattribute(struct policydb *db, const char *type,
// htable is a struct instead of pointer above 5.8.0: // 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 // https://elixir.bootlin.com/linux/v5.8-rc1/source/security/selinux/ss/symtab.h
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
#define ksu_hashtab_for_each(htab, cur) ksu_hash_for_each (htab.htable, htab.size, cur) #define ksu_hashtab_for_each(htab, cur) \
ksu_hash_for_each(htab.htable, htab.size, cur)
#else #else
#define ksu_hashtab_for_each(htab, cur) \ #define ksu_hashtab_for_each(htab, cur) \
ksu_hash_for_each (htab->htable, htab->size, cur) ksu_hash_for_each(htab->htable, htab->size, cur)
#endif #endif
// symtab_search is introduced on 5.9.0: // symtab_search is introduced on 5.9.0:
@@ -95,8 +98,7 @@ static bool add_typeattribute(struct policydb *db, const char *type,
#endif #endif
#define avtab_for_each(avtab, cur) \ #define avtab_for_each(avtab, cur) \
ksu_hash_for_each (avtab.htable, avtab.nslot, cur) \ ksu_hash_for_each(avtab.htable, avtab.nslot, cur);
;
static struct avtab_node *get_avtab_node(struct policydb *db, static struct avtab_node *get_avtab_node(struct policydb *db,
struct avtab_key *key, struct avtab_key *key,
@@ -592,14 +594,14 @@ static bool add_filename_trans(struct policydb *db, const char *s,
trans = (struct filename_trans_datum *)kcalloc(sizeof(*trans), trans = (struct filename_trans_datum *)kcalloc(sizeof(*trans),
1, GFP_ATOMIC); 1, GFP_ATOMIC);
if (!trans) { if (!trans) {
pr_err("add_filename_trans: Failed to alloc datum"); pr_err("add_filename_trans: Failed to alloc datum\n");
return false; return false;
} }
struct filename_trans *new_key = struct filename_trans *new_key =
(struct filename_trans *)kmalloc(sizeof(*new_key), (struct filename_trans *)kmalloc(sizeof(*new_key),
GFP_ATOMIC); GFP_ATOMIC);
if (!new_key) { if (!new_key) {
pr_err("add_filename_trans: Failed to alloc new_key"); pr_err("add_filename_trans: Failed to alloc new_key\n");
return false; return false;
} }
*new_key = key; *new_key = key;
@@ -693,7 +695,7 @@ static bool add_type(struct policydb *db, const char *type_name, bool attr)
int i; int i;
for (i = 0; i < db->p_roles.nprim; ++i) { for (i = 0; i < db->p_roles.nprim; ++i) {
ebitmap_set_bit(&db->role_val_to_struct[i]->types, value - 1, ebitmap_set_bit(&db->role_val_to_struct[i]->types, value - 1,
0); 1);
} }
return true; return true;
@@ -743,7 +745,7 @@ static bool add_type(struct policydb *db, const char *type_name, bool attr)
int i; int i;
for (i = 0; i < db->p_roles.nprim; ++i) { for (i = 0; i < db->p_roles.nprim; ++i) {
ebitmap_set_bit(&db->role_val_to_struct[i]->types, value - 1, ebitmap_set_bit(&db->role_val_to_struct[i]->types, value - 1,
0); 1);
} }
return true; return true;
@@ -854,7 +856,7 @@ static bool add_type(struct policydb *db, const char *type_name, bool attr)
int i; int i;
for (i = 0; i < db->p_roles.nprim; ++i) { for (i = 0; i < db->p_roles.nprim; ++i) {
ebitmap_set_bit(&db->role_val_to_struct[i]->types, value - 1, ebitmap_set_bit(&db->role_val_to_struct[i]->types, value - 1,
0); 1);
} }
return true; return true;
#endif #endif

View File

@@ -44,7 +44,7 @@ echo '[+] Add kernel su driver to Makefile'
DRIVER_MAKEFILE=$DRIVER_DIR/Makefile DRIVER_MAKEFILE=$DRIVER_DIR/Makefile
DRIVER_KCONFIG=$DRIVER_DIR/Kconfig DRIVER_KCONFIG=$DRIVER_DIR/Kconfig
grep -q "kernelsu" "$DRIVER_MAKEFILE" || printf "obj-\$(CONFIG_KSU) += kernelsu/\n" >> "$DRIVER_MAKEFILE" grep -q "kernelsu" "$DRIVER_MAKEFILE" || printf "\nobj-\$(CONFIG_KSU) += kernelsu/\n" >> "$DRIVER_MAKEFILE"
grep -q "kernelsu" "$DRIVER_KCONFIG" || sed -i "/endmenu/i\\source \"drivers/kernelsu/Kconfig\"" "$DRIVER_KCONFIG" grep -q "kernelsu" "$DRIVER_KCONFIG" || sed -i "/endmenu/i\\source \"drivers/kernelsu/Kconfig\"" "$DRIVER_KCONFIG"
echo '[+] Done.' echo '[+] Done.'

View File

@@ -16,6 +16,7 @@
#include "arch.h" #include "arch.h"
#include "klog.h" // IWYU pragma: keep #include "klog.h" // IWYU pragma: keep
#include "ksud.h" #include "ksud.h"
#include "kernel_compat.h"
#define SU_PATH "/system/bin/su" #define SU_PATH "/system/bin/su"
#define SH_PATH "/system/bin/sh" #define SH_PATH "/system/bin/sh"
@@ -41,32 +42,27 @@ static char __user *sh_user_path(void)
int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode, int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode,
int *flags) int *flags)
{ {
struct filename *filename;
const char su[] = SU_PATH; const char su[] = SU_PATH;
if (!ksu_is_allow_uid(current_uid().val)) { if (!ksu_is_allow_uid(current_uid().val)) {
return 0; return 0;
} }
filename = getname(*filename_user); char path[sizeof(su) + 1];
memset(path, 0, sizeof(path));
ksu_strncpy_from_user_nofault(path, *filename_user, sizeof(path));
if (IS_ERR(filename)) { if (unlikely(!memcmp(path, su, sizeof(su)))) {
return 0;
}
if (unlikely(!memcmp(filename->name, su, sizeof(su)))) {
pr_info("faccessat su->sh!\n"); pr_info("faccessat su->sh!\n");
*filename_user = sh_user_path(); *filename_user = sh_user_path();
} }
putname(filename);
return 0; return 0;
} }
int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags) int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags)
{ {
// const char sh[] = SH_PATH; // const char sh[] = SH_PATH;
struct filename *filename;
const char su[] = SU_PATH; const char su[] = SU_PATH;
if (!ksu_is_allow_uid(current_uid().val)) { if (!ksu_is_allow_uid(current_uid().val)) {
@@ -77,23 +73,35 @@ int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags)
return 0; return 0;
} }
filename = getname(*filename_user); char path[sizeof(su) + 1];
memset(path, 0, sizeof(path));
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0)
// it becomes a `struct filename *` after 5.18
// https://elixir.bootlin.com/linux/v5.18/source/fs/stat.c#L216
const char sh[] = SH_PATH;
struct filename *filename = * ((struct filename **) filename_user);
if (IS_ERR(filename)) { if (IS_ERR(filename)) {
return 0; return 0;
} }
if (unlikely(!memcmp(filename->name, su, sizeof(su)))) { if (likely(memcmp(filename->name, su, sizeof(su))))
return 0;
pr_info("vfs_statx su->sh!\n");
memcpy((void *)filename->name, sh, sizeof(sh));
#else
ksu_strncpy_from_user_nofault(path, *filename_user, sizeof(path));
if (unlikely(!memcmp(path, su, sizeof(su)))) {
pr_info("newfstatat su->sh!\n"); pr_info("newfstatat su->sh!\n");
*filename_user = sh_user_path(); *filename_user = sh_user_path();
} }
#endif
putname(filename);
return 0; return 0;
} }
// the call from execve_handler_pre won't provided correct value for __never_use_argument, use them after fix execve_handler_pre, keeping them for consistence for manually patched code
int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr, int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr,
void *argv, void *envp, int *flags) void *__never_use_argv, void *__never_use_envp, int *__never_use_flags)
{ {
struct filename *filename; struct filename *filename;
const char sh[] = KSUD_PATH; const char sh[] = KSUD_PATH;
@@ -128,7 +136,8 @@ static int faccessat_handler_pre(struct kprobe *p, struct pt_regs *regs)
int *dfd = (int *)PT_REGS_PARM1(regs); int *dfd = (int *)PT_REGS_PARM1(regs);
const char __user **filename_user = (const char **)&PT_REGS_PARM2(regs); const char __user **filename_user = (const char **)&PT_REGS_PARM2(regs);
int *mode = (int *)&PT_REGS_PARM3(regs); int *mode = (int *)&PT_REGS_PARM3(regs);
int *flags = (int *)&PT_REGS_PARM4(regs); // Both sys_ and do_ is C function
int *flags = (int *)&PT_REGS_CCALL_PARM4(regs);
return ksu_handle_faccessat(dfd, filename_user, mode, flags); return ksu_handle_faccessat(dfd, filename_user, mode, flags);
} }
@@ -142,7 +151,7 @@ static int newfstatat_handler_pre(struct kprobe *p, struct pt_regs *regs)
int *flags = (int *)&PT_REGS_PARM3(regs); int *flags = (int *)&PT_REGS_PARM3(regs);
#else #else
// int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,int flag) // int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,int flag)
int *flags = (int *)&PT_REGS_PARM4(regs); int *flags = (int *)&PT_REGS_CCALL_PARM4(regs);
#endif #endif
return ksu_handle_stat(dfd, filename_user, flags); return ksu_handle_stat(dfd, filename_user, flags);
@@ -154,12 +163,8 @@ static int execve_handler_pre(struct kprobe *p, struct pt_regs *regs)
int *fd = (int *)&PT_REGS_PARM1(regs); int *fd = (int *)&PT_REGS_PARM1(regs);
struct filename **filename_ptr = struct filename **filename_ptr =
(struct filename **)&PT_REGS_PARM2(regs); (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, return ksu_handle_execveat_sucompat(fd, filename_ptr, NULL, NULL, NULL);
flags);
} }
static struct kprobe faccessat_kp = { static struct kprobe faccessat_kp = {

View File

@@ -20,16 +20,18 @@ static struct work_struct ksu_update_uid_work;
struct uid_data { struct uid_data {
struct list_head list; struct list_head list;
u32 uid; u32 uid;
char package[KSU_MAX_PACKAGE_NAME];
}; };
static bool is_uid_exist(uid_t uid, void *data) static bool is_uid_exist(uid_t uid, char *package, void *data)
{ {
struct list_head *list = (struct list_head *)data; struct list_head *list = (struct list_head *)data;
struct uid_data *np; struct uid_data *np;
bool exist = false; bool exist = false;
list_for_each_entry (np, list, list) { list_for_each_entry (np, list, list) {
if (np->uid == uid % 100000) { if (np->uid == uid % 100000 &&
strncmp(np->package, package, KSU_MAX_PACKAGE_NAME) == 0) {
exist = true; exist = true;
break; break;
} }
@@ -39,11 +41,11 @@ static bool is_uid_exist(uid_t uid, void *data)
static void do_update_uid(struct work_struct *work) static void do_update_uid(struct work_struct *work)
{ {
KWORKER_INSTALL_KEYRING(); struct file *fp =
struct file *fp = filp_open(SYSTEM_PACKAGES_LIST_PATH, O_RDONLY, 0); ksu_filp_open_compat(SYSTEM_PACKAGES_LIST_PATH, O_RDONLY, 0);
if (IS_ERR(fp)) { if (IS_ERR(fp)) {
pr_err("do_update_uid, open " SYSTEM_PACKAGES_LIST_PATH pr_err("do_update_uid, open " SYSTEM_PACKAGES_LIST_PATH
" failed: %d\n", " failed: %ld\n",
PTR_ERR(fp)); PTR_ERR(fp));
return; return;
} }
@@ -54,7 +56,7 @@ static void do_update_uid(struct work_struct *work)
char chr = 0; char chr = 0;
loff_t pos = 0; loff_t pos = 0;
loff_t line_start = 0; loff_t line_start = 0;
char buf[128]; char buf[KSU_MAX_PACKAGE_NAME];
for (;;) { for (;;) {
ssize_t count = ssize_t count =
ksu_kernel_read_compat(fp, &chr, sizeof(chr), &pos); ksu_kernel_read_compat(fp, &chr, sizeof(chr), &pos);
@@ -67,26 +69,27 @@ static void do_update_uid(struct work_struct *work)
&line_start); &line_start);
struct uid_data *data = struct uid_data *data =
kmalloc(sizeof(struct uid_data), GFP_ATOMIC); kzalloc(sizeof(struct uid_data), GFP_ATOMIC);
if (!data) { if (!data) {
goto out; goto out;
} }
char *tmp = buf; char *tmp = buf;
const char *delim = " "; const char *delim = " ";
strsep(&tmp, delim); // skip package char *package = strsep(&tmp, delim);
char *uid = strsep(&tmp, delim); char *uid = strsep(&tmp, delim);
if (!uid) { if (!uid || !package) {
pr_err("update_uid: uid is NULL!\n"); pr_err("update_uid: package or uid is NULL!\n");
continue; break;
} }
u32 res; u32 res;
if (kstrtou32(uid, 10, &res)) { if (kstrtou32(uid, 10, &res)) {
pr_err("update_uid: uid parse err\n"); pr_err("update_uid: uid parse err\n");
continue; break;
} }
data->uid = res; data->uid = res;
strncpy(data->package, package, KSU_MAX_PACKAGE_NAME);
list_add_tail(&data->list, &uid_list); list_add_tail(&data->list, &uid_list);
// reset line start // reset line start
line_start = pos; line_start = pos;

View File

@@ -93,12 +93,14 @@ dependencies {
implementation(libs.com.google.accompanist.drawablepainter) implementation(libs.com.google.accompanist.drawablepainter)
implementation(libs.com.google.accompanist.navigation.animation) implementation(libs.com.google.accompanist.navigation.animation)
implementation(libs.com.google.accompanist.systemuicontroller) implementation(libs.com.google.accompanist.systemuicontroller)
implementation(libs.com.google.accompanist.webview)
implementation(libs.compose.destinations.animations.core) implementation(libs.compose.destinations.animations.core)
ksp(libs.compose.destinations.ksp) ksp(libs.compose.destinations.ksp)
implementation(libs.com.github.topjohnwu.libsu.core) implementation(libs.com.github.topjohnwu.libsu.core)
implementation(libs.com.github.topjohnwu.libsu.service) implementation(libs.com.github.topjohnwu.libsu.service)
implementation(libs.com.github.topjohnwu.libsu.io)
implementation(libs.dev.rikka.rikkax.parcelablelist) implementation(libs.dev.rikka.rikkax.parcelablelist)
@@ -111,4 +113,7 @@ dependencies {
implementation(libs.sheet.compose.dialogs.core) implementation(libs.sheet.compose.dialogs.core)
implementation(libs.sheet.compose.dialogs.list) implementation(libs.sheet.compose.dialogs.list)
implementation(libs.sheet.compose.dialogs.input) implementation(libs.sheet.compose.dialogs.input)
implementation(libs.markdown)
implementation(libs.androidx.webkit)
} }

View File

@@ -13,6 +13,7 @@
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"
android:supportsRtl="true" android:supportsRtl="true"
android:networkSecurityConfig="@xml/network_security_config"
android:theme="@style/Theme.KernelSU" android:theme="@style/Theme.KernelSU"
tools:targetApi="33"> tools:targetApi="33">
<activity <activity

View File

@@ -156,13 +156,6 @@ Java_me_weishu_kernelsu_Natives_getAppProfile(JNIEnv *env, jobject, jstring pkg,
env->SetBooleanField(obj, allowSuField, false); env->SetBooleanField(obj, allowSuField, false);
env->SetBooleanField(obj, nonRootUseDefaultField, true); env->SetBooleanField(obj, nonRootUseDefaultField, true);
jobject capList = env->GetObjectField(obj, capabilitiesField);
int DEFAULT_CAPS[] = {CAP_DAC_READ_SEARCH};
for (auto i: DEFAULT_CAPS) {
addIntToList(env, capList, i);
}
return obj; return obj;
} }

View File

@@ -5,6 +5,7 @@ import coil.Coil
import coil.ImageLoader import coil.ImageLoader
import me.zhanghai.android.appiconloader.coil.AppIconFetcher import me.zhanghai.android.appiconloader.coil.AppIconFetcher
import me.zhanghai.android.appiconloader.coil.AppIconKeyer import me.zhanghai.android.appiconloader.coil.AppIconKeyer
import java.io.File
lateinit var ksuApp: KernelSUApplication lateinit var ksuApp: KernelSUApplication
@@ -24,6 +25,11 @@ class KernelSUApplication : Application() {
} }
.build() .build()
) )
val webroot = File(dataDir, "webroot")
if (!webroot.exists()) {
webroot.mkdir()
}
} }

View File

@@ -37,6 +37,23 @@ fun parseKernelVersion(version: String): KernelVersion {
} }
} }
fun parseKMI(input: String): String? {
val regex = Regex("(.* )?(\\d+\\.\\d+)(\\S+)?(android\\d+)(.*)")
val result = regex.find(input)
return result?.let {
val androidVersion = it.groups[4]?.value ?: ""
val kernelVersion = it.groups[2]?.value ?: ""
"$androidVersion-$kernelVersion"
}
}
fun getKMI(): String? {
Os.uname().release.let {
return parseKMI(it)
}
}
fun getKernelVersion(): KernelVersion { fun getKernelVersion(): KernelVersion {
Os.uname().release.let { Os.uname().release.let {
return parseKernelVersion(it) return parseKernelVersion(it)

View File

@@ -15,7 +15,13 @@ object Natives {
// 10931: app profile struct add 'version' field // 10931: app profile struct add 'version' field
// 10946: add capabilities // 10946: add capabilities
// 10977: change groups_count and groups to avoid overflow write // 10977: change groups_count and groups to avoid overflow write
const val MINIMAL_SUPPORTED_KERNEL = 10977 // 11071: Fix the issue of failing to set a custom SELinux type.
const val MINIMAL_SUPPORTED_KERNEL = 11071
const val KERNEL_SU_DOMAIN = "u:r:su:s0"
const val ROOT_UID = 0
const val ROOT_GID = 0
init { init {
System.loadLibrary("kernelsu") System.loadLibrary("kernelsu")
@@ -44,7 +50,6 @@ object Natives {
external fun setAppProfile(profile: Profile?): Boolean external fun setAppProfile(profile: Profile?): Boolean
private const val NON_ROOT_DEFAULT_PROFILE_KEY = "$" private const val NON_ROOT_DEFAULT_PROFILE_KEY = "$"
private const val ROOT_DEFAULT_PROFILE_KEY = "#"
private const val NOBODY_UID = 9999 private const val NOBODY_UID = 9999
fun setDefaultUmountModules(umountModules: Boolean): Boolean { fun setDefaultUmountModules(umountModules: Boolean): Boolean {
@@ -84,20 +89,21 @@ object Natives {
// these are used for root profile // these are used for root profile
val rootUseDefault: Boolean = true, val rootUseDefault: Boolean = true,
val rootTemplate: String? = null, val rootTemplate: String? = null,
val uid: Int = 0, val uid: Int = ROOT_UID,
val gid: Int = 0, val gid: Int = ROOT_GID,
val groups: List<Int> = mutableListOf(), val groups: List<Int> = mutableListOf(),
val capabilities: List<Int> = mutableListOf(), val capabilities: List<Int> = mutableListOf(),
val context: String = "u:r:su:s0", val context: String = KERNEL_SU_DOMAIN,
val namespace: Int = Namespace.Inherited.ordinal, val namespace: Int = Namespace.INHERITED.ordinal,
val nonRootUseDefault: Boolean = true, val nonRootUseDefault: Boolean = true,
val umountModules: Boolean = true, val umountModules: Boolean = true,
var rules: String = "", // this field is save in ksud!!
) : Parcelable { ) : Parcelable {
enum class Namespace { enum class Namespace {
Inherited, INHERITED,
Global, GLOBAL,
Individual, INDIVIDUAL,
} }
constructor() : this("") constructor() : this("")

View File

@@ -1,6 +1,7 @@
package me.weishu.kernelsu.profile package me.weishu.kernelsu.profile
/** /**
* https://cs.android.com/android/platform/superproject/main/+/main:system/core/libcutils/include/private/android_filesystem_config.h
* @author weishu * @author weishu
* @date 2023/6/3. * @date 2023/6/3.
*/ */
@@ -60,17 +61,55 @@ enum class Groups(val gid: Int, val display: String, val desc: String) {
FIREWALL(1048, "firewall", "firewall process"), FIREWALL(1048, "firewall", "firewall process"),
TRUNKS(1049, "trunks", "trunksd process"), TRUNKS(1049, "trunks", "trunksd process"),
NVRAM(1050, "nvram", "nvram daemon"), NVRAM(1050, "nvram", "nvram daemon"),
DNS_TETHER(1051, "dns_tether", "dns_tether device"), DNS(1051, "dns", "DNS resolution daemon (system: netd)"),
DNS_TETHER_RESERVED(1052, "dns_tether_reserved", "Reserved range for dns_tether"), DNS_TETHER(1052, "dns_tether", "DNS resolution daemon (tether: dnsmasq)"),
WEBVIEW_ZYGOTE(1053, "webview_zygote", "zygote process"), WEBVIEW_ZYGOTE(1053, "webview_zygote", "WebView zygote process"),
WEBVIEW_USER(1054, "webview_user", "webview chromium user"), VEHICLE_NETWORK(1054, "vehicle_network", "Vehicle network service"),
ETHERNET(1055, "ethernet", "Ethernet"), MEDIA_AUDIO(1055, "media_audio", "GID for audio files on internal media storage"),
TOMBSTONED(1056, "tombstoned", "tombstoned process"), MEDIA_VIDEO(1056, "media_video", "GID for video files on internal media storage"),
GRAPHICS_RW(1057, "graphics_rw", "graphics devices"), MEDIA_IMAGE(1057, "media_image", "GID for image files on internal media storage"),
TOMBSTONED(1058, "tombstoned", "tombstoned user"),
MEDIA_OBB(1059, "media_obb", "GID for OBB files on internal media storage"),
ESE(1060, "ese", "embedded secure element (eSE) subsystem"),
OTA_UPDATE(1061, "ota_update", "resource tracking UID for OTA updates"),
AUTOMOTIVE_EVS(1062, "automotive_evs", "Automotive rear and surround view system"),
LOWPAN(1063, "lowpan", "LoWPAN subsystem"),
HSM(1064, "lowpan", "hardware security module subsystem"),
RESERVED_DISK(1065, "reserved_disk", "GID that has access to reserved disk space"),
STATSD(1066, "statsd", "statsd daemon"),
INCIDENTD(1067, "incidentd", "incidentd daemon"),
SECURE_ELEMENT(1068, "secure_element", "secure element subsystem"),
LMKD(1069, "lmkd", "low memory killer daemon"),
LLKD(1070, "llkd", "live lock daemon"),
IORAPD(1071, "iorapd", "input/output readahead and pin daemon"),
GPU_SERVICE(1072, "gpu_service", "GPU service daemon"),
NETWORK_STACK(1073, "network_stack", "network stack service"),
GSID(1074, "GSID", "GSI service daemon"),
FSVERITY_CERT(1075, "fsverity_cert", "fs-verity key ownership in keystore"),
CREDSTORE(1076, "credstore", "identity credential manager service"),
EXTERNAL_STORAGE(1077, "external_storage", "Full external storage access including USB OTG volumes"),
EXT_DATA_RW(1078, "ext_data_rw", "GID for app-private data directories on external storage"),
EXT_OBB_RW(1079, "ext_obb_rw", "GID for OBB directories on external storage"),
CONTEXT_HUB(1080, "context_hub", "GID for access to the Context Hub"),
VIRTUALIZATIONSERVICE(1081, "virtualizationservice", "VirtualizationService daemon"),
ARTD(1082, "artd", "ART Service daemon"),
UWB(1083, "uwb", "UWB subsystem"),
THREAD_NETWORK(1084, "thread_network", "Thread Network subsystem"),
DICED(1085, "diced", "Android's DICE daemon"),
DMESGD(1086, "dmesgd", "dmesg parsing daemon for kernel report collection"),
JC_WEAVER(1087, "jc_weaver", "Javacard Weaver HAL - to manage omapi ARA rules"),
JC_STRONGBOX(1088, "jc_strongbox", "Javacard Strongbox HAL - to manage omapi ARA rules"),
JC_IDENTITYCRED(1089, "jc_identitycred", "Javacard Identity Cred HAL - to manage omapi ARA rules"),
SDK_SANDBOX(1090, "sdk_sandbox", "SDK sandbox virtual UID"),
SECURITY_LOG_WRITER(1091, "security_log_writer", "write to security log"),
PRNG_SEEDER(1092, "prng_seeder", "PRNG seeder daemon"),
SHELL(2000, "shell", "adb and debug shell user"), SHELL(2000, "shell", "adb and debug shell user"),
CACHE(2001, "cache", "cache access"), CACHE(2001, "cache", "cache access"),
DIAG(2002, "diag", "diagnostics"), DIAG(2002, "diag", "access to diagnostic resources"),
/* The 3000 series are intended for use as supplemental group id's only.
* They indicate special Android capabilities that the kernel is aware of. */
NET_BT_ADMIN(3001, "net_bt_admin", "bluetooth: create any socket"), NET_BT_ADMIN(3001, "net_bt_admin", "bluetooth: create any socket"),
NET_BT(3002, "net_bt", "bluetooth: create sco, rfcomm or l2cap sockets"), NET_BT(3002, "net_bt", "bluetooth: create sco, rfcomm or l2cap sockets"),
INET(3003, "inet", "can create AF_INET and AF_INET6 sockets"), INET(3003, "inet", "can create AF_INET and AF_INET6 sockets"),
@@ -79,7 +118,11 @@ enum class Groups(val gid: Int, val display: String, val desc: String) {
NET_BW_STATS(3006, "net_bw_stats", "read bandwidth statistics"), NET_BW_STATS(3006, "net_bw_stats", "read bandwidth statistics"),
NET_BW_ACCT(3007, "net_bw_acct", "change bandwidth statistics accounting"), NET_BW_ACCT(3007, "net_bw_acct", "change bandwidth statistics accounting"),
NET_BT_STACK(3008, "net_bt_stack", "access to various bluetooth management functions"), NET_BT_STACK(3008, "net_bt_stack", "access to various bluetooth management functions"),
QCOM_DIAG(3009, "qcom_diag", "allow msm specific diag commands"), READPROC(3009, "readproc", "Allow /proc read access"),
WAKELOCK(3010, "wakelock", "Allow system wakelock read/write access"),
UHID(3011, "uhid", "Allow read/write to /dev/uhid node"),
READTRACEFS(3012, "readtracefs", "Allow tracefs read"),
EVERYBODY(9997, "everybody", "Shared external storage read/write"), EVERYBODY(9997, "everybody", "Shared external storage read/write"),
MISC(9998, "misc", "Access to misc storage"), MISC(9998, "misc", "Access to misc storage"),
NOBODY(9999, "nobody", "Reserved"), NOBODY(9999, "nobody", "Reserved"),

View File

@@ -5,13 +5,7 @@ import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Icon import androidx.compose.material3.*
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
@@ -20,18 +14,18 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import androidx.navigation.compose.currentBackStackEntryAsState
import com.google.accompanist.navigation.animation.rememberAnimatedNavController import com.google.accompanist.navigation.animation.rememberAnimatedNavController
import com.ramcosta.composedestinations.DestinationsNavHost import com.ramcosta.composedestinations.DestinationsNavHost
import com.ramcosta.composedestinations.navigation.popBackStack import com.ramcosta.composedestinations.navigation.popBackStack
import com.ramcosta.composedestinations.utils.isRouteOnBackStackAsState import com.ramcosta.composedestinations.utils.isRouteOnBackStackAsState
import me.weishu.kernelsu.Natives import me.weishu.kernelsu.Natives
import me.weishu.kernelsu.ksuApp import me.weishu.kernelsu.ksuApp
import me.weishu.kernelsu.ui.component.rememberDialogHostState
import me.weishu.kernelsu.ui.screen.BottomBarDestination import me.weishu.kernelsu.ui.screen.BottomBarDestination
import me.weishu.kernelsu.ui.screen.NavGraphs import me.weishu.kernelsu.ui.screen.NavGraphs
import me.weishu.kernelsu.ui.theme.KernelSUTheme import me.weishu.kernelsu.ui.theme.KernelSUTheme
import me.weishu.kernelsu.ui.util.LocalDialogHost
import me.weishu.kernelsu.ui.util.LocalSnackbarHost import me.weishu.kernelsu.ui.util.LocalSnackbarHost
import me.weishu.kernelsu.ui.util.rootAvailable
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity() {
@@ -43,13 +37,15 @@ class MainActivity : ComponentActivity() {
KernelSUTheme { KernelSUTheme {
val navController = rememberAnimatedNavController() val navController = rememberAnimatedNavController()
val snackbarHostState = remember { SnackbarHostState() } val snackbarHostState = remember { SnackbarHostState() }
val navBackStackEntry by navController.currentBackStackEntryAsState()
val route = navBackStackEntry?.destination?.route
val showBottomBar = route == null || !route.startsWith("web_screen")
Scaffold( Scaffold(
bottomBar = { BottomBar(navController) }, bottomBar = { if (showBottomBar) BottomBar(navController) },
snackbarHost = { SnackbarHost(snackbarHostState) } snackbarHost = { SnackbarHost(snackbarHostState) }
) { innerPadding -> ) { innerPadding ->
CompositionLocalProvider( CompositionLocalProvider(
LocalSnackbarHost provides snackbarHostState, LocalSnackbarHost provides snackbarHostState,
LocalDialogHost provides rememberDialogHostState(),
) { ) {
DestinationsNavHost( DestinationsNavHost(
modifier = Modifier.padding(innerPadding), modifier = Modifier.padding(innerPadding),
@@ -66,7 +62,7 @@ class MainActivity : ComponentActivity() {
@Composable @Composable
private fun BottomBar(navController: NavHostController) { private fun BottomBar(navController: NavHostController) {
val isManager = Natives.becomeManager(ksuApp.packageName) val isManager = Natives.becomeManager(ksuApp.packageName)
val fullFeatured = isManager && !Natives.requireNewKernel() val fullFeatured = isManager && !Natives.requireNewKernel() && rootAvailable()
NavigationBar(tonalElevation = 8.dp) { NavigationBar(tonalElevation = 8.dp) {
BottomBarDestination.values().forEach { destination -> BottomBarDestination.values().forEach { destination ->
if (!fullFeatured && destination.rootRequired) return@forEach if (!fullFeatured && destination.rootRequired) return@forEach

View File

@@ -12,6 +12,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.ElevatedCard import androidx.compose.material3.ElevatedCard
import androidx.compose.material3.LocalContentColor import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
@@ -52,11 +53,9 @@ fun AboutCard() {
} }
@Composable @Composable
fun AboutDialog(showAboutDialog: MutableState<Boolean>) { fun AboutDialog(dismiss: () -> Unit) {
if (showAboutDialog.value) { Dialog(onDismissRequest = { dismiss() }) {
Dialog(onDismissRequest = { showAboutDialog.value = false }) { AboutCard()
AboutCard()
}
} }
} }

View File

@@ -1,61 +1,73 @@
package me.weishu.kernelsu.ui.component package me.weishu.kernelsu.ui.component
import android.graphics.text.LineBreaker
import android.os.Parcelable
import android.text.Layout
import android.text.method.LinkMovementMethod
import android.util.Log
import android.view.ViewGroup
import android.widget.TextView
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.AlertDialog import androidx.compose.material3.*
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.Saver
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties import androidx.compose.ui.window.DialogProperties
import kotlinx.coroutines.CancellableContinuation import io.noties.markwon.Markwon
import kotlinx.coroutines.coroutineScope import io.noties.markwon.utils.NoCopySpannableFactory
import kotlinx.coroutines.launch import kotlinx.coroutines.*
import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.channels.ReceiveChannel
import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.flow.FlowCollector
import me.weishu.kernelsu.ui.util.LocalDialogHost import kotlinx.coroutines.flow.consumeAsFlow
import kotlinx.coroutines.flow.onEach
import kotlinx.parcelize.Parcelize
import kotlin.coroutines.resume import kotlin.coroutines.resume
interface DialogVisuals private const val TAG = "DialogComponent"
interface LoadingDialogVisuals : DialogVisuals interface ConfirmDialogVisuals : Parcelable {
interface PromptDialogVisuals : DialogVisuals {
val title: String val title: String
val content: String val content: String
} val isMarkdown: Boolean
interface ConfirmDialogVisuals : PromptDialogVisuals {
val confirm: String? val confirm: String?
val dismiss: String? val dismiss: String?
} }
@Parcelize
sealed interface DialogData { private data class ConfirmDialogVisualsImpl(
val visuals: DialogVisuals override val title: String,
override val content: String,
override val isMarkdown: Boolean,
override val confirm: String?,
override val dismiss: String?,
) : ConfirmDialogVisuals {
companion object {
val Empty: ConfirmDialogVisuals = ConfirmDialogVisualsImpl("", "", false, null, null)
}
} }
interface LoadingDialogData : DialogData { interface DialogHandle {
override val visuals: LoadingDialogVisuals val isShown: Boolean
fun dismiss() val dialogType: String
fun show()
fun hide()
} }
interface PromptDialogData : DialogData { interface LoadingDialogHandle : DialogHandle {
override val visuals: PromptDialogVisuals suspend fun <R> withLoading(block: suspend () -> R): R
fun dismiss() fun showLoading()
}
interface ConfirmDialogData : PromptDialogData {
override val visuals: ConfirmDialogVisuals
fun confirm()
} }
sealed interface ConfirmResult { sealed interface ConfirmResult {
@@ -63,147 +75,315 @@ sealed interface ConfirmResult {
object Canceled : ConfirmResult object Canceled : ConfirmResult
} }
class DialogHostState { interface ConfirmDialogHandle : DialogHandle {
val visuals: ConfirmDialogVisuals
private object LoadingDialogVisualsImpl : LoadingDialogVisuals fun showConfirm(
private data class PromptDialogVisualsImpl(
override val title: String,
override val content: String
) : PromptDialogVisuals
private data class ConfirmDialogVisualsImpl(
override val title: String,
override val content: String,
override val confirm: String?,
override val dismiss: String?
) : ConfirmDialogVisuals
private data class LoadingDialogDataImpl(
override val visuals: LoadingDialogVisuals,
private val continuation: CancellableContinuation<Unit>,
) : LoadingDialogData {
override fun dismiss() {
if (continuation.isActive) continuation.resume(Unit)
}
}
private data class PromptDialogDataImpl(
override val visuals: PromptDialogVisuals,
private val continuation: CancellableContinuation<Unit>,
) : PromptDialogData {
override fun dismiss() {
if (continuation.isActive) continuation.resume(Unit)
}
}
private data class ConfirmDialogDataImpl(
override val visuals: ConfirmDialogVisuals,
private val continuation: CancellableContinuation<ConfirmResult>
) : ConfirmDialogData {
override fun confirm() {
if (continuation.isActive) continuation.resume(ConfirmResult.Confirmed)
}
override fun dismiss() {
if (continuation.isActive) continuation.resume(ConfirmResult.Canceled)
}
}
private val mutex = Mutex()
var currentDialogData by mutableStateOf<DialogData?>(null)
private set
suspend fun showLoading() {
try {
mutex.withLock {
suspendCancellableCoroutine { continuation ->
currentDialogData = LoadingDialogDataImpl(
visuals = LoadingDialogVisualsImpl,
continuation = continuation
)
}
}
} finally {
currentDialogData = null
}
}
suspend fun <R> withLoading(block: suspend () -> R) = coroutineScope {
val showLoading = launch {
showLoading()
}
val result = block()
showLoading.cancel()
result
}
suspend fun showPrompt(title: String, content: String) {
try {
mutex.withLock {
suspendCancellableCoroutine { continuation ->
currentDialogData = PromptDialogDataImpl(
visuals = PromptDialogVisualsImpl(title, content),
continuation = continuation
)
}
}
} finally {
currentDialogData = null
}
}
suspend fun showConfirm(
title: String, title: String,
content: String, content: String,
markdown: Boolean = false,
confirm: String? = null, confirm: String? = null,
dismiss: String? = null dismiss: String? = null
): ConfirmResult = mutex.withLock { )
try {
return@withLock suspendCancellableCoroutine { continuation -> suspend fun awaitConfirm(
currentDialogData = ConfirmDialogDataImpl( title: String,
visuals = ConfirmDialogVisualsImpl(title, content, confirm, dismiss), content: String,
continuation = continuation markdown: Boolean = false,
) confirm: String? = null,
dismiss: String? = null
): ConfirmResult
}
private abstract class DialogHandleBase(
protected val visible: MutableState<Boolean>,
protected val coroutineScope: CoroutineScope
) : DialogHandle {
override val isShown: Boolean
get() = visible.value
override fun show() {
coroutineScope.launch {
visible.value = true
}
}
final override fun hide() {
coroutineScope.launch {
visible.value = false
}
}
override fun toString(): String {
return dialogType
}
}
private class LoadingDialogHandleImpl(
visible: MutableState<Boolean>,
coroutineScope: CoroutineScope
) : LoadingDialogHandle, DialogHandleBase(visible, coroutineScope) {
override suspend fun <R> withLoading(block: suspend () -> R): R {
return coroutineScope.async {
try {
visible.value = true
block()
} finally {
visible.value = false
}
}.await()
}
override fun showLoading() {
show()
}
override val dialogType: String get() = "LoadingDialog"
}
typealias NullableCallback = (() -> Unit)?
interface ConfirmCallback {
val onConfirm: NullableCallback
val onDismiss: NullableCallback
val isEmpty: Boolean get() = onConfirm == null && onDismiss == null
companion object {
operator fun invoke(onConfirmProvider: () -> NullableCallback, onDismissProvider: () -> NullableCallback): ConfirmCallback {
return object : ConfirmCallback {
override val onConfirm: NullableCallback
get() = onConfirmProvider()
override val onDismiss: NullableCallback
get() = onDismissProvider()
} }
} finally {
currentDialogData = null
} }
} }
} }
private class ConfirmDialogHandleImpl(
visible: MutableState<Boolean>,
coroutineScope: CoroutineScope,
callback: ConfirmCallback,
override var visuals: ConfirmDialogVisuals = ConfirmDialogVisualsImpl.Empty,
private val resultFlow: ReceiveChannel<ConfirmResult>
) : ConfirmDialogHandle, DialogHandleBase(visible, coroutineScope) {
private class ResultCollector(
private val callback: ConfirmCallback
) : FlowCollector<ConfirmResult> {
fun handleResult(result: ConfirmResult) {
Log.d(TAG, "handleResult: ${result.javaClass.simpleName}")
when (result) {
ConfirmResult.Confirmed -> onConfirm()
ConfirmResult.Canceled -> onDismiss()
}
}
fun onConfirm() {
callback.onConfirm?.invoke()
}
fun onDismiss() {
callback.onDismiss?.invoke()
}
override suspend fun emit(value: ConfirmResult) {
handleResult(value)
}
}
private val resultCollector = ResultCollector(callback)
private var awaitContinuation: CancellableContinuation<ConfirmResult>? = null
private val isCallbackEmpty = callback.isEmpty
init {
coroutineScope.launch {
resultFlow
.consumeAsFlow()
.onEach { result ->
awaitContinuation?.let {
awaitContinuation = null
if (it.isActive) {
it.resume(result)
}
}
}
.onEach { hide() }
.collect(resultCollector)
}
}
private suspend fun awaitResult(): ConfirmResult {
return suspendCancellableCoroutine {
awaitContinuation = it.apply {
if (isCallbackEmpty) {
invokeOnCancellation {
visible.value = false
}
}
}
}
}
fun updateVisuals(visuals: ConfirmDialogVisuals) {
this.visuals = visuals
}
override fun show() {
if (visuals !== ConfirmDialogVisualsImpl.Empty) {
super.show()
} else {
throw UnsupportedOperationException("can't show confirm dialog with the Empty visuals")
}
}
override fun showConfirm(
title: String,
content: String,
markdown: Boolean,
confirm: String?,
dismiss: String?
) {
coroutineScope.launch {
updateVisuals(ConfirmDialogVisualsImpl(title, content, markdown, confirm, dismiss))
show()
}
}
override suspend fun awaitConfirm(
title: String,
content: String,
markdown: Boolean,
confirm: String?,
dismiss: String?
): ConfirmResult {
coroutineScope.launch {
updateVisuals(ConfirmDialogVisualsImpl(title, content, markdown, confirm, dismiss))
show()
}
return awaitResult()
}
override val dialogType: String get() = "ConfirmDialog"
override fun toString(): String {
return "${super.toString()}(visuals: $visuals)"
}
companion object {
fun Saver(
visible: MutableState<Boolean>,
coroutineScope: CoroutineScope,
callback: ConfirmCallback,
resultChannel: ReceiveChannel<ConfirmResult>
) = Saver<ConfirmDialogHandle, ConfirmDialogVisuals>(
save = {
it.visuals
},
restore = {
Log.d(TAG, "ConfirmDialog restore, visuals: $it")
ConfirmDialogHandleImpl(visible, coroutineScope, callback, it, resultChannel)
}
)
}
}
private class CustomDialogHandleImpl(
visible: MutableState<Boolean>,
coroutineScope: CoroutineScope
) : DialogHandleBase(visible, coroutineScope) {
override val dialogType: String get() = "CustomDialog"
}
@Composable @Composable
fun rememberDialogHostState(): DialogHostState { fun rememberLoadingDialog(): LoadingDialogHandle {
val visible = remember {
mutableStateOf(false)
}
val coroutineScope = rememberCoroutineScope()
if (visible.value) {
LoadingDialog()
}
return remember { return remember {
DialogHostState() LoadingDialogHandleImpl(visible, coroutineScope)
}
}
private inline fun <reified T : DialogData> DialogData?.tryInto(): T? {
return when (this) {
is T -> this
else -> null
} }
} }
@Composable @Composable
fun LoadingDialog( private fun rememberConfirmDialog(visuals: ConfirmDialogVisuals, callback: ConfirmCallback): ConfirmDialogHandle {
state: DialogHostState = LocalDialogHost.current, val visible = rememberSaveable {
) { mutableStateOf(false)
state.currentDialogData.tryInto<LoadingDialogData>() ?: return
val dialogProperties = remember {
DialogProperties(dismissOnClickOutside = false, dismissOnBackPress = false)
} }
Dialog(onDismissRequest = {}, properties = dialogProperties) { val coroutineScope = rememberCoroutineScope()
val resultChannel = remember {
Channel<ConfirmResult>()
}
val handle = rememberSaveable(
saver = ConfirmDialogHandleImpl.Saver(visible, coroutineScope, callback, resultChannel),
init = {
ConfirmDialogHandleImpl(visible, coroutineScope, callback, visuals, resultChannel)
}
)
if (visible.value) {
ConfirmDialog(
handle.visuals,
confirm = { coroutineScope.launch { resultChannel.send(ConfirmResult.Confirmed) } },
dismiss = { coroutineScope.launch { resultChannel.send(ConfirmResult.Canceled) } }
)
}
return handle
}
@Composable
fun rememberConfirmCallback(onConfirm: NullableCallback, onDismiss: NullableCallback): ConfirmCallback {
val currentOnConfirm by rememberUpdatedState(newValue = onConfirm)
val currentOnDismiss by rememberUpdatedState(newValue = onDismiss)
return remember {
ConfirmCallback({ currentOnConfirm }, { currentOnDismiss })
}
}
@Composable
fun rememberConfirmDialog(onConfirm: NullableCallback = null, onDismiss: NullableCallback = null): ConfirmDialogHandle {
return rememberConfirmDialog(rememberConfirmCallback(onConfirm, onDismiss))
}
@Composable
fun rememberConfirmDialog(callback: ConfirmCallback): ConfirmDialogHandle {
return rememberConfirmDialog(ConfirmDialogVisualsImpl.Empty, callback)
}
@Composable
fun rememberCustomDialog(composable: @Composable (dismiss: () -> Unit) -> Unit): DialogHandle {
val visible = rememberSaveable {
mutableStateOf(false)
}
val coroutineScope = rememberCoroutineScope()
if (visible.value) {
composable { visible.value = false }
}
return remember {
CustomDialogHandleImpl(visible, coroutineScope)
}
}
@Composable
private fun LoadingDialog() {
Dialog(
onDismissRequest = {},
properties = DialogProperties(dismissOnClickOutside = false, dismissOnBackPress = false)
) {
Surface( Surface(
modifier = Modifier modifier = Modifier.size(100.dp), shape = RoundedCornerShape(8.dp)
.size(100.dp),
shape = RoundedCornerShape(8.dp)
) { ) {
Box( Box(
contentAlignment = Alignment.Center, contentAlignment = Alignment.Center,
@@ -215,55 +395,56 @@ fun LoadingDialog(
} }
@Composable @Composable
fun PromptDialog( private fun ConfirmDialog(visuals: ConfirmDialogVisuals, confirm: () -> Unit, dismiss: () -> Unit) {
state: DialogHostState = LocalDialogHost.current,
) {
val promptDialogData = state.currentDialogData.tryInto<PromptDialogData>() ?: return
val visuals = promptDialogData.visuals
AlertDialog( AlertDialog(
onDismissRequest = { onDismissRequest = {
promptDialogData.dismiss() dismiss()
}, },
title = { title = {
Text(text = visuals.title) Text(text = visuals.title)
}, },
text = { text = {
Text(text = visuals.content) if (visuals.isMarkdown) {
}, MarkdownContent(content = visuals.content)
confirmButton = { } else {
TextButton(onClick = { promptDialogData.dismiss() }) { Text(text = visuals.content)
Text(text = stringResource(id = android.R.string.ok))
} }
}, },
dismissButton = null,
)
}
@Composable
fun ConfirmDialog(state: DialogHostState = LocalDialogHost.current) {
val confirmDialogData = state.currentDialogData.tryInto<ConfirmDialogData>() ?: return
val visuals = confirmDialogData.visuals
AlertDialog(
onDismissRequest = {
confirmDialogData.dismiss()
},
title = {
Text(text = visuals.title)
},
text = {
Text(text = visuals.content)
},
confirmButton = { confirmButton = {
TextButton(onClick = { confirmDialogData.confirm() }) { TextButton(onClick = confirm) {
Text(text = visuals.confirm ?: stringResource(id = android.R.string.ok)) Text(text = visuals.confirm ?: stringResource(id = android.R.string.ok))
} }
}, },
dismissButton = { dismissButton = {
TextButton(onClick = { confirmDialogData.dismiss() }) { TextButton(onClick = dismiss) {
Text(text = visuals.dismiss ?: stringResource(id = android.R.string.cancel)) Text(text = visuals.dismiss ?: stringResource(id = android.R.string.cancel))
} }
}, },
) )
}
@Composable
private fun MarkdownContent(content: String) {
val contentColor = LocalContentColor.current
AndroidView(
factory = { context ->
TextView(context).apply {
movementMethod = LinkMovementMethod.getInstance()
setSpannableFactory(NoCopySpannableFactory.getInstance())
breakStrategy = LineBreaker.BREAK_STRATEGY_SIMPLE
hyphenationFrequency = Layout.HYPHENATION_FREQUENCY_NONE
layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT
)
}
},
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight(),
update = {
Markwon.create(it.context).setMarkdown(it, content)
it.setTextColor(contentColor.toArgb())
}
)
} }

View File

@@ -0,0 +1,28 @@
package me.weishu.kernelsu.ui.component
import androidx.compose.foundation.focusable
import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.input.key.KeyEvent
import androidx.compose.ui.input.key.onKeyEvent
@Composable
fun KeyEventBlocker(predicate: (KeyEvent) -> Boolean) {
val requester = remember { FocusRequester() }
Box(
Modifier
.onKeyEvent {
predicate(it)
}
.focusRequester(requester)
.focusable()
)
LaunchedEffect(Unit) {
requester.requestFocus()
}
}

View File

@@ -28,6 +28,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@@ -53,6 +54,7 @@ import me.weishu.kernelsu.Natives
import me.weishu.kernelsu.R import me.weishu.kernelsu.R
import me.weishu.kernelsu.profile.Capabilities import me.weishu.kernelsu.profile.Capabilities
import me.weishu.kernelsu.profile.Groups import me.weishu.kernelsu.profile.Groups
import me.weishu.kernelsu.ui.component.rememberCustomDialog
import me.weishu.kernelsu.ui.util.isSepolicyValid import me.weishu.kernelsu.ui.util.isSepolicyValid
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@@ -74,9 +76,9 @@ fun RootProfileConfig(
var expanded by remember { mutableStateOf(false) } var expanded by remember { mutableStateOf(false) }
val currentNamespace = when (profile.namespace) { val currentNamespace = when (profile.namespace) {
Natives.Profile.Namespace.Inherited.ordinal -> stringResource(R.string.profile_namespace_inherited) Natives.Profile.Namespace.INHERITED.ordinal -> stringResource(R.string.profile_namespace_inherited)
Natives.Profile.Namespace.Global.ordinal -> stringResource(R.string.profile_namespace_global) Natives.Profile.Namespace.GLOBAL.ordinal -> stringResource(R.string.profile_namespace_global)
Natives.Profile.Namespace.Individual.ordinal -> stringResource(R.string.profile_namespace_individual) Natives.Profile.Namespace.INDIVIDUAL.ordinal -> stringResource(R.string.profile_namespace_individual)
else -> stringResource(R.string.profile_namespace_inherited) else -> stringResource(R.string.profile_namespace_inherited)
} }
ListItem(headlineContent = { ListItem(headlineContent = {
@@ -104,21 +106,21 @@ fun RootProfileConfig(
DropdownMenuItem( DropdownMenuItem(
text = { Text(stringResource(R.string.profile_namespace_inherited)) }, text = { Text(stringResource(R.string.profile_namespace_inherited)) },
onClick = { onClick = {
onProfileChange(profile.copy(namespace = Natives.Profile.Namespace.Inherited.ordinal)) onProfileChange(profile.copy(namespace = Natives.Profile.Namespace.INHERITED.ordinal))
expanded = false expanded = false
}, },
) )
DropdownMenuItem( DropdownMenuItem(
text = { Text(stringResource(R.string.profile_namespace_global)) }, text = { Text(stringResource(R.string.profile_namespace_global)) },
onClick = { onClick = {
onProfileChange(profile.copy(namespace = Natives.Profile.Namespace.Global.ordinal)) onProfileChange(profile.copy(namespace = Natives.Profile.Namespace.GLOBAL.ordinal))
expanded = false expanded = false
}, },
) )
DropdownMenuItem( DropdownMenuItem(
text = { Text(stringResource(R.string.profile_namespace_individual)) }, text = { Text(stringResource(R.string.profile_namespace_individual)) },
onClick = { onClick = {
onProfileChange(profile.copy(namespace = Natives.Profile.Namespace.Individual.ordinal)) onProfileChange(profile.copy(namespace = Natives.Profile.Namespace.INDIVIDUAL.ordinal))
expanded = false expanded = false
}, },
) )
@@ -175,6 +177,7 @@ fun RootProfileConfig(
onProfileChange( onProfileChange(
profile.copy( profile.copy(
context = domain, context = domain,
rules = rules,
rootUseDefault = false rootUseDefault = false
) )
) )
@@ -186,11 +189,20 @@ fun RootProfileConfig(
@OptIn(ExperimentalLayoutApi::class) @OptIn(ExperimentalLayoutApi::class)
@Composable @Composable
fun GroupsPanel(selected: List<Groups>, closeSelection: (selection: Set<Groups>) -> Unit) { fun GroupsPanel(selected: List<Groups>, closeSelection: (selection: Set<Groups>) -> Unit) {
val selectGroupsDialog = rememberCustomDialog { dismiss: () -> Unit ->
val groups = Groups.values().sortedWith(
compareBy<Groups> { if (selected.contains(it)) 0 else 1 }
.then(compareBy {
when (it) {
Groups.ROOT -> 0
Groups.SYSTEM -> 1
Groups.SHELL -> 2
else -> Int.MAX_VALUE
}
})
.then(compareBy { it.name })
var showDialog by remember { mutableStateOf(false) } )
if (showDialog) {
val groups = Groups.values()
val options = groups.map { value -> val options = groups.map { value ->
ListOption( ListOption(
titleText = value.display, titleText = value.display,
@@ -204,7 +216,7 @@ fun GroupsPanel(selected: List<Groups>, closeSelection: (selection: Set<Groups>)
state = rememberUseCaseState(visible = true, onFinishedRequest = { state = rememberUseCaseState(visible = true, onFinishedRequest = {
closeSelection(selection) closeSelection(selection)
}, onCloseRequest = { }, onCloseRequest = {
showDialog = false dismiss()
}), }),
header = Header.Default( header = Header.Default(
title = stringResource(R.string.profile_groups), title = stringResource(R.string.profile_groups),
@@ -228,7 +240,7 @@ fun GroupsPanel(selected: List<Groups>, closeSelection: (selection: Set<Groups>)
.fillMaxWidth() .fillMaxWidth()
.padding(16.dp) .padding(16.dp)
.clickable { .clickable {
showDialog = true selectGroupsDialog.show()
}) { }) {
Column(modifier = Modifier.padding(16.dp)) { Column(modifier = Modifier.padding(16.dp)) {
@@ -252,11 +264,11 @@ fun CapsPanel(
selected: Collection<Capabilities>, selected: Collection<Capabilities>,
closeSelection: (selection: Set<Capabilities>) -> Unit closeSelection: (selection: Set<Capabilities>) -> Unit
) { ) {
val selectCapabilitiesDialog = rememberCustomDialog { dismiss ->
var showDialog by remember { mutableStateOf(false) } val caps = Capabilities.values().sortedWith(
compareBy<Capabilities> { if (selected.contains(it)) 0 else 1 }
if (showDialog) { .then(compareBy { it.name })
val caps = Capabilities.values() )
val options = caps.map { value -> val options = caps.map { value ->
ListOption( ListOption(
titleText = value.display, titleText = value.display,
@@ -270,7 +282,7 @@ fun CapsPanel(
state = rememberUseCaseState(visible = true, onFinishedRequest = { state = rememberUseCaseState(visible = true, onFinishedRequest = {
closeSelection(selection) closeSelection(selection)
}, onCloseRequest = { }, onCloseRequest = {
showDialog = false dismiss()
}), }),
header = Header.Default( header = Header.Default(
title = stringResource(R.string.profile_capabilities), title = stringResource(R.string.profile_capabilities),
@@ -293,7 +305,7 @@ fun CapsPanel(
.fillMaxWidth() .fillMaxWidth()
.padding(16.dp) .padding(16.dp)
.clickable { .clickable {
showDialog = true selectCapabilitiesDialog.show()
}) { }) {
Column(modifier = Modifier.padding(16.dp)) { Column(modifier = Modifier.padding(16.dp)) {
@@ -357,11 +369,13 @@ private fun UidPanel(uid: Int, label: String, onUidChange: (Int) -> Unit) {
} }
@Composable @Composable
private fun SELinuxPanel(profile: Natives.Profile, onSELinuxChange: (domain: String, rules: String) -> Unit) { private fun SELinuxPanel(
var showDialog by remember { mutableStateOf(false) } profile: Natives.Profile,
if (showDialog) { onSELinuxChange: (domain: String, rules: String) -> Unit
) {
val editSELinuxDialog = rememberCustomDialog { dismiss ->
var domain by remember { mutableStateOf(profile.context) } var domain by remember { mutableStateOf(profile.context) }
var rules by remember { mutableStateOf("") } var rules by remember { mutableStateOf(profile.rules) }
val inputOptions = listOf( val inputOptions = listOf(
InputTextField( InputTextField(
@@ -382,7 +396,7 @@ private fun SELinuxPanel(profile: Natives.Profile, onSELinuxChange: (domain: Str
// value can be a-zA-Z0-9_ // value can be a-zA-Z0-9_
val regex = Regex("^[a-z_]+:[a-z0-9_]+:[a-z0-9_]+(:[a-z0-9_]+)?$") val regex = Regex("^[a-z_]+:[a-z0-9_]+:[a-z0-9_]+(:[a-z0-9_]+)?$")
if (value?.matches(regex) == true) ValidationResult.Valid if (value?.matches(regex) == true) ValidationResult.Valid
else ValidationResult.Invalid("Domain must be valid sepolicy") else ValidationResult.Invalid("Domain must be in the format of \"user:role:type:level\"")
} }
), ),
InputTextField( InputTextField(
@@ -393,7 +407,6 @@ private fun SELinuxPanel(profile: Natives.Profile, onSELinuxChange: (domain: Str
type = InputTextFieldType.OUTLINED, type = InputTextFieldType.OUTLINED,
keyboardOptions = KeyboardOptions( keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Ascii, keyboardType = KeyboardType.Ascii,
imeAction = ImeAction.Done
), ),
singleLine = false, singleLine = false,
resultListener = { resultListener = {
@@ -401,8 +414,8 @@ private fun SELinuxPanel(profile: Natives.Profile, onSELinuxChange: (domain: Str
}, },
validationListener = { value -> validationListener = { value ->
if (isSepolicyValid(value)) ValidationResult.Valid if (isSepolicyValid(value)) ValidationResult.Valid
else ValidationResult.Invalid("Rules must be valid sepolicy") else ValidationResult.Invalid("SELinux rules is invalid!")
}, }
) )
) )
@@ -412,7 +425,7 @@ private fun SELinuxPanel(profile: Natives.Profile, onSELinuxChange: (domain: Str
onSELinuxChange(domain, rules) onSELinuxChange(domain, rules)
}, },
onCloseRequest = { onCloseRequest = {
showDialog = false dismiss()
}), }),
header = Header.Default( header = Header.Default(
title = stringResource(R.string.profile_selinux_context), title = stringResource(R.string.profile_selinux_context),
@@ -431,7 +444,7 @@ private fun SELinuxPanel(profile: Natives.Profile, onSELinuxChange: (domain: Str
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.clickable { .clickable {
showDialog = true editSELinuxDialog.show()
}, },
enabled = false, enabled = false,
colors = TextFieldDefaults.outlinedTextFieldColors( colors = TextFieldDefaults.outlinedTextFieldColors(

View File

@@ -0,0 +1,116 @@
package me.weishu.kernelsu.ui.component.profile
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowDropDown
import androidx.compose.material.icons.filled.ArrowDropUp
import androidx.compose.material.icons.filled.Create
import androidx.compose.material.icons.filled.ReadMore
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExposedDropdownMenuBox
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.ListItem
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import me.weishu.kernelsu.Natives
import me.weishu.kernelsu.R
import me.weishu.kernelsu.ui.util.listAppProfileTemplates
import me.weishu.kernelsu.ui.util.setSepolicy
import me.weishu.kernelsu.ui.viewmodel.getTemplateInfoById
/**
* @author weishu
* @date 2023/10/21.
*/
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TemplateConfig(
profile: Natives.Profile,
onViewTemplate: (id: String) -> Unit = {},
onManageTemplate: () -> Unit = {},
onProfileChange: (Natives.Profile) -> Unit
) {
var expanded by remember { mutableStateOf(false) }
var template by rememberSaveable {
mutableStateOf(profile.rootTemplate ?: "")
}
val profileTemplates = listAppProfileTemplates()
val noTemplates = profileTemplates.isEmpty()
ListItem(headlineContent = {
ExposedDropdownMenuBox(
expanded = expanded,
onExpandedChange = { expanded = it },
) {
OutlinedTextField(
modifier = Modifier
.menuAnchor()
.fillMaxWidth(),
readOnly = true,
label = { Text(stringResource(R.string.profile_template)) },
value = template.ifEmpty { "None" },
onValueChange = {},
trailingIcon = {
if (noTemplates) {
IconButton(
onClick = onManageTemplate
) {
Icon(Icons.Filled.Create, null)
}
} else if (expanded) Icon(Icons.Filled.ArrowDropUp, null)
else Icon(Icons.Filled.ArrowDropDown, null)
},
)
if (profileTemplates.isEmpty()) {
return@ExposedDropdownMenuBox
}
ExposedDropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false }
) {
profileTemplates.forEach { tid ->
val templateInfo =
getTemplateInfoById(tid) ?: return@forEach
DropdownMenuItem(
text = { Text(tid) },
onClick = {
template = tid
if (setSepolicy(tid, templateInfo.rules.joinToString("\n"))) {
onProfileChange(
profile.copy(
rootTemplate = tid,
rootUseDefault = false,
uid = templateInfo.uid,
gid = templateInfo.gid,
groups = templateInfo.groups,
capabilities = templateInfo.capabilities,
context = templateInfo.context,
namespace = templateInfo.namespace,
)
)
}
expanded = false
},
trailingIcon = {
IconButton(onClick = {
onViewTemplate(tid)
}) {
Icon(Icons.Filled.ReadMore, null)
}
}
)
}
}
}
})
}

View File

@@ -1,11 +1,13 @@
package me.weishu.kernelsu.ui.screen package me.weishu.kernelsu.ui.screen
import android.util.Log
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.compose.animation.Crossfade import androidx.compose.animation.Crossfade
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
@@ -16,17 +18,15 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.AccountCircle import androidx.compose.material.icons.filled.AccountCircle
import androidx.compose.material.icons.filled.Android import androidx.compose.material.icons.filled.Android
import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.ArrowDropDown
import androidx.compose.material.icons.filled.ArrowDropUp
import androidx.compose.material.icons.filled.Security import androidx.compose.material.icons.filled.Security
import androidx.compose.material3.Divider import androidx.compose.material3.Divider
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExposedDropdownMenuBox
import androidx.compose.material3.FilterChip import androidx.compose.material3.FilterChip
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
import androidx.compose.material3.ListItem import androidx.compose.material3.ListItem
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBar
@@ -38,10 +38,14 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import coil.compose.AsyncImage import coil.compose.AsyncImage
import coil.request.ImageRequest import coil.request.ImageRequest
@@ -53,8 +57,17 @@ import me.weishu.kernelsu.R
import me.weishu.kernelsu.ui.component.SwitchItem import me.weishu.kernelsu.ui.component.SwitchItem
import me.weishu.kernelsu.ui.component.profile.AppProfileConfig import me.weishu.kernelsu.ui.component.profile.AppProfileConfig
import me.weishu.kernelsu.ui.component.profile.RootProfileConfig import me.weishu.kernelsu.ui.component.profile.RootProfileConfig
import me.weishu.kernelsu.ui.component.profile.TemplateConfig
import me.weishu.kernelsu.ui.screen.destinations.AppProfileTemplateScreenDestination
import me.weishu.kernelsu.ui.screen.destinations.TemplateEditorScreenDestination
import me.weishu.kernelsu.ui.util.LocalSnackbarHost import me.weishu.kernelsu.ui.util.LocalSnackbarHost
import me.weishu.kernelsu.ui.util.forceStopApp
import me.weishu.kernelsu.ui.util.getSepolicy
import me.weishu.kernelsu.ui.util.launchApp
import me.weishu.kernelsu.ui.util.restartApp
import me.weishu.kernelsu.ui.util.setSepolicy
import me.weishu.kernelsu.ui.viewmodel.SuperUserViewModel import me.weishu.kernelsu.ui.viewmodel.SuperUserViewModel
import me.weishu.kernelsu.ui.viewmodel.getTemplateInfoById
/** /**
* @author weishu * @author weishu
@@ -71,16 +84,20 @@ fun AppProfileScreen(
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val failToUpdateAppProfile = val failToUpdateAppProfile =
stringResource(R.string.failed_to_update_app_profile).format(appInfo.label) stringResource(R.string.failed_to_update_app_profile).format(appInfo.label)
val failToUpdateSepolicy =
stringResource(R.string.failed_to_update_sepolicy).format(appInfo.label)
val packageName = appInfo.packageName val packageName = appInfo.packageName
val initialProfile = Natives.getAppProfile(packageName, appInfo.uid)
if (initialProfile.allowSu) {
initialProfile.rules = getSepolicy(packageName)
}
var profile by rememberSaveable { var profile by rememberSaveable {
mutableStateOf(Natives.getAppProfile(packageName, appInfo.uid)) mutableStateOf(initialProfile)
} }
Log.i("mylog", "profile: $profile")
Scaffold( Scaffold(
topBar = { TopBar { navigator.popBackStack() } } topBar = { TopBar { navigator.popBackStack() } },
) { paddingValues -> ) { paddingValues ->
AppProfileInner( AppProfileInner(
modifier = Modifier modifier = Modifier
@@ -90,9 +107,7 @@ fun AppProfileScreen(
appLabel = appInfo.label, appLabel = appInfo.label,
appIcon = { appIcon = {
AsyncImage( AsyncImage(
model = ImageRequest.Builder(context) model = ImageRequest.Builder(context).data(appInfo.packageInfo).crossfade(true)
.data(appInfo.packageInfo)
.crossfade(true)
.build(), .build(),
contentDescription = appInfo.label, contentDescription = appInfo.label,
modifier = Modifier modifier = Modifier
@@ -102,8 +117,22 @@ fun AppProfileScreen(
) )
}, },
profile = profile, profile = profile,
onViewTemplate = {
getTemplateInfoById(it)?.let { info ->
navigator.navigate(TemplateEditorScreenDestination(info))
}
},
onManageTemplate = {
navigator.navigate(AppProfileTemplateScreenDestination())
},
onProfileChange = { onProfileChange = {
scope.launch { scope.launch {
if (it.allowSu && !it.rootUseDefault && it.rules.isNotEmpty()) {
if (!setSepolicy(profile.name, it.rules)) {
snackbarHost.showSnackbar(failToUpdateSepolicy)
return@launch
}
}
if (!Natives.setAppProfile(it)) { if (!Natives.setAppProfile(it)) {
snackbarHost.showSnackbar(failToUpdateAppProfile.format(appInfo.uid)) snackbarHost.showSnackbar(failToUpdateAppProfile.format(appInfo.uid))
} else { } else {
@@ -115,7 +144,6 @@ fun AppProfileScreen(
} }
} }
@OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
private fun AppProfileInner( private fun AppProfileInner(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
@@ -123,16 +151,20 @@ private fun AppProfileInner(
appLabel: String, appLabel: String,
appIcon: @Composable () -> Unit, appIcon: @Composable () -> Unit,
profile: Natives.Profile, profile: Natives.Profile,
onViewTemplate: (id: String) -> Unit = {},
onManageTemplate: () -> Unit = {},
onProfileChange: (Natives.Profile) -> Unit, onProfileChange: (Natives.Profile) -> Unit,
) { ) {
val isRootGranted = profile.allowSu val isRootGranted = profile.allowSu
Column(modifier = modifier) { Column(modifier = modifier) {
ListItem( AppMenuBox(packageName) {
headlineContent = { Text(appLabel) }, ListItem(
supportingContent = { Text(packageName) }, headlineContent = { Text(appLabel) },
leadingContent = appIcon, supportingContent = { Text(packageName) },
) leadingContent = appIcon,
)
}
SwitchItem( SwitchItem(
icon = Icons.Filled.Security, icon = Icons.Filled.Security,
@@ -151,10 +183,10 @@ private fun AppProfileInner(
} else { } else {
Mode.Custom Mode.Custom
} }
var mode by remember { var mode by rememberSaveable {
mutableStateOf(initialMode) mutableStateOf(initialMode)
} }
ProfileBox(mode, false) { ProfileBox(mode, true) {
// template mode shouldn't change profile here! // template mode shouldn't change profile here!
if (it == Mode.Default || it == Mode.Custom) { if (it == Mode.Default || it == Mode.Custom) {
onProfileChange(profile.copy(rootUseDefault = it == Mode.Default)) onProfileChange(profile.copy(rootUseDefault = it == Mode.Default))
@@ -163,43 +195,12 @@ private fun AppProfileInner(
} }
Crossfade(targetState = mode, label = "") { currentMode -> Crossfade(targetState = mode, label = "") { currentMode ->
if (currentMode == Mode.Template) { if (currentMode == Mode.Template) {
var expanded by remember { mutableStateOf(false) } TemplateConfig(
val templateNone = "None" profile = profile,
var template by rememberSaveable { onViewTemplate = onViewTemplate,
mutableStateOf( onManageTemplate = onManageTemplate,
profile.rootTemplate onProfileChange = onProfileChange
?: templateNone )
)
}
ListItem(headlineContent = {
ExposedDropdownMenuBox(
expanded = expanded,
onExpandedChange = { expanded = it },
) {
OutlinedTextField(
modifier = Modifier.menuAnchor(),
readOnly = true,
label = { Text(stringResource(R.string.profile_template)) },
value = template,
onValueChange = {
if (template != templateNone) {
onProfileChange(
profile.copy(
rootTemplate = it,
rootUseDefault = false
)
)
template = it
}
},
trailingIcon = {
if (expanded) Icon(Icons.Filled.ArrowDropUp, null)
else Icon(Icons.Filled.ArrowDropDown, null)
},
)
// TODO: Template
}
})
} else if (mode == Mode.Custom) { } else if (mode == Mode.Custom) {
RootProfileConfig( RootProfileConfig(
fixedName = true, fixedName = true,
@@ -229,9 +230,7 @@ private fun AppProfileInner(
} }
private enum class Mode(@StringRes private val res: Int) { private enum class Mode(@StringRes private val res: Int) {
Default(R.string.profile_default), Default(R.string.profile_default), Template(R.string.profile_template), Custom(R.string.profile_custom);
Template(R.string.profile_template),
Custom(R.string.profile_custom);
val text: String val text: String
@Composable get() = stringResource(res) @Composable get() = stringResource(res)
@@ -267,8 +266,7 @@ private fun ProfileBox(
Divider(thickness = Dp.Hairline) Divider(thickness = Dp.Hairline)
ListItem(headlineContent = { ListItem(headlineContent = {
Row( Row(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceEvenly
horizontalArrangement = Arrangement.SpaceEvenly
) { ) {
FilterChip( FilterChip(
selected = mode == Mode.Default, selected = mode == Mode.Default,
@@ -291,6 +289,63 @@ private fun ProfileBox(
}) })
} }
@Composable
private fun AppMenuBox(packageName: String, content: @Composable () -> Unit) {
var expanded by remember { mutableStateOf(false) }
var touchPoint: Offset by remember { mutableStateOf(Offset.Zero) }
val density = LocalDensity.current
BoxWithConstraints(
Modifier
.fillMaxSize()
.pointerInput(Unit) {
detectTapGestures {
touchPoint = it
expanded = true
}
}) {
content()
val (offsetX, offsetY) = with(density) {
(touchPoint.x.toDp()) to (touchPoint.y.toDp())
}
DropdownMenu(
expanded = expanded,
offset = DpOffset(offsetX, -offsetY),
onDismissRequest = {
expanded = false
},
) {
DropdownMenuItem(
text = { Text(stringResource(id = R.string.launch_app)) },
onClick = {
expanded = false
launchApp(packageName)
},
)
DropdownMenuItem(
text = { Text(stringResource(id = R.string.force_stop_app)) },
onClick = {
expanded = false
forceStopApp(packageName)
},
)
DropdownMenuItem(
text = { Text(stringResource(id = R.string.restart_app)) },
onClick = {
expanded = false
restartApp(packageName)
},
)
}
}
}
@Preview @Preview
@Composable @Composable
private fun AppProfilePreview() { private fun AppProfilePreview() {

View File

@@ -0,0 +1,189 @@
package me.weishu.kernelsu.ui.screen
import android.net.Uri
import android.os.Environment
import android.os.Parcelable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.Refresh
import androidx.compose.material.icons.filled.Save
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.key.Key
import androidx.compose.ui.input.key.key
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.parcelize.Parcelize
import me.weishu.kernelsu.R
import me.weishu.kernelsu.ui.component.KeyEventBlocker
import me.weishu.kernelsu.ui.util.LocalSnackbarHost
import me.weishu.kernelsu.ui.util.installBoot
import me.weishu.kernelsu.ui.util.installModule
import me.weishu.kernelsu.ui.util.reboot
import java.io.File
import java.text.SimpleDateFormat
import java.util.*
/**
* @author weishu
* @date 2023/1/1.
*/
@OptIn(ExperimentalComposeUiApi::class)
@Composable
@Destination
fun FlashScreen(navigator: DestinationsNavigator, flashIt: FlashIt) {
var text by rememberSaveable { mutableStateOf("") }
val logContent = rememberSaveable { StringBuilder() }
var showFloatAction by rememberSaveable { mutableStateOf(false) }
val snackBarHost = LocalSnackbarHost.current
val scope = rememberCoroutineScope()
val scrollState = rememberScrollState()
LaunchedEffect(Unit) {
if (text.isNotEmpty()) {
return@LaunchedEffect
}
withContext(Dispatchers.IO) {
flashIt(flashIt, onFinish = { showReboot ->
if (showReboot) {
showFloatAction = true
}
}, onStdout = {
text += "$it\n"
logContent.append(it).append("\n")
}, onStderr = {
logContent.append(it).append("\n")
});
}
}
Scaffold(
topBar = {
TopBar(
onBack = {
navigator.popBackStack()
},
onSave = {
scope.launch {
val format = SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.getDefault())
val date = format.format(Date())
val file = File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
"KernelSU_install_log_${date}.log"
)
file.writeText(logContent.toString())
snackBarHost.showSnackbar("Log saved to ${file.absolutePath}")
}
}
)
},
floatingActionButton = {
if (showFloatAction) {
val reboot = stringResource(id = R.string.reboot)
ExtendedFloatingActionButton(
onClick = {
scope.launch {
withContext(Dispatchers.IO) {
reboot()
}
}
},
icon = { Icon(Icons.Filled.Refresh, reboot) },
text = { Text(text = reboot) },
)
}
}
) { innerPadding ->
KeyEventBlocker {
it.key == Key.VolumeDown || it.key == Key.VolumeUp
}
Column(
modifier = Modifier
.fillMaxSize(1f)
.padding(innerPadding)
.verticalScroll(scrollState),
) {
LaunchedEffect(text) {
scrollState.animateScrollTo(scrollState.maxValue)
}
Text(
modifier = Modifier.padding(8.dp),
text = text,
fontSize = MaterialTheme.typography.bodySmall.fontSize,
fontFamily = FontFamily.Monospace,
lineHeight = MaterialTheme.typography.bodySmall.lineHeight,
)
}
}
}
@Parcelize
sealed class FlashIt : Parcelable {
data class FlashBoot(val bootUri: Uri? = null, val koUri: Uri, val ota: Boolean) : FlashIt()
data class FlashModule(val uri: Uri) : FlashIt()
}
fun flashIt(
flashIt: FlashIt, onFinish: (Boolean) -> Unit,
onStdout: (String) -> Unit,
onStderr: (String) -> Unit
) {
when (flashIt) {
is FlashIt.FlashBoot -> installBoot(
flashIt.bootUri,
flashIt.koUri,
flashIt.ota,
onFinish,
onStdout,
onStderr
)
is FlashIt.FlashModule -> installModule(flashIt.uri, onFinish, onStdout, onStderr)
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun TopBar(onBack: () -> Unit = {}, onSave: () -> Unit = {}) {
TopAppBar(
title = { Text(stringResource(R.string.install)) },
navigationIcon = {
IconButton(
onClick = onBack
) { Icon(Icons.Filled.ArrowBack, contentDescription = null) }
},
actions = {
IconButton(onClick = onSave) {
Icon(
imageVector = Icons.Filled.Save,
contentDescription = "Localized description"
)
}
}
)
}
@Preview
@Composable
fun InstallPreview() {
// InstallScreen(DestinationsNavigator(), uri = Uri.EMPTY)
}

View File

@@ -5,11 +5,13 @@ import android.os.Build
import android.os.PowerManager import android.os.PowerManager
import android.system.Os import android.system.Os
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.compose.animation.*
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Archive
import androidx.compose.material.icons.filled.Refresh import androidx.compose.material.icons.filled.Refresh
import androidx.compose.material.icons.filled.Settings import androidx.compose.material.icons.filled.Settings
import androidx.compose.material.icons.outlined.Block import androidx.compose.material.icons.outlined.Block
@@ -23,7 +25,6 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.annotation.Destination
@@ -33,6 +34,8 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import me.weishu.kernelsu.* import me.weishu.kernelsu.*
import me.weishu.kernelsu.R import me.weishu.kernelsu.R
import me.weishu.kernelsu.ui.component.rememberConfirmDialog
import me.weishu.kernelsu.ui.screen.destinations.InstallScreenDestination
import me.weishu.kernelsu.ui.screen.destinations.SettingScreenDestination import me.weishu.kernelsu.ui.screen.destinations.SettingScreenDestination
import me.weishu.kernelsu.ui.util.* import me.weishu.kernelsu.ui.util.*
@@ -40,9 +43,13 @@ import me.weishu.kernelsu.ui.util.*
@Destination @Destination
@Composable @Composable
fun HomeScreen(navigator: DestinationsNavigator) { fun HomeScreen(navigator: DestinationsNavigator) {
val kernelVersion = getKernelVersion()
Scaffold(topBar = { Scaffold(topBar = {
TopBar(onSettingsClick = { TopBar(kernelVersion, onSettingsClick = {
navigator.navigate(SettingScreenDestination) navigator.navigate(SettingScreenDestination)
}, onInstallClick = {
navigator.navigate(InstallScreenDestination)
}) })
}) { innerPadding -> }) { innerPadding ->
Column( Column(
@@ -52,14 +59,15 @@ fun HomeScreen(navigator: DestinationsNavigator) {
.verticalScroll(rememberScrollState()), .verticalScroll(rememberScrollState()),
verticalArrangement = Arrangement.spacedBy(16.dp) verticalArrangement = Arrangement.spacedBy(16.dp)
) { ) {
val kernelVersion = getKernelVersion()
val isManager = Natives.becomeManager(ksuApp.packageName) val isManager = Natives.becomeManager(ksuApp.packageName)
SideEffect { SideEffect {
if (isManager) install() if (isManager) install()
} }
val ksuVersion = if (isManager) Natives.version else null val ksuVersion = if (isManager) Natives.version else null
StatusCard(kernelVersion, ksuVersion) StatusCard(kernelVersion, ksuVersion) {
navigator.navigate(InstallScreenDestination)
}
if (isManager && Natives.requireNewKernel()) { if (isManager && Natives.requireNewKernel()) {
WarningCard( WarningCard(
stringResource(id = R.string.require_kernel_version).format( stringResource(id = R.string.require_kernel_version).format(
@@ -67,7 +75,17 @@ fun HomeScreen(navigator: DestinationsNavigator) {
) )
) )
} }
UpdateCard() if (ksuVersion != null && !rootAvailable()) {
WarningCard(
stringResource(id = R.string.grant_root_failed)
)
}
val checkUpdate =
LocalContext.current.getSharedPreferences("settings", Context.MODE_PRIVATE)
.getBoolean("check_update", true)
if (checkUpdate) {
UpdateCard()
}
InfoCard() InfoCard()
DonateCard() DonateCard()
LearnMoreCard() LearnMoreCard()
@@ -79,22 +97,37 @@ fun HomeScreen(navigator: DestinationsNavigator) {
@Composable @Composable
fun UpdateCard() { fun UpdateCard() {
val context = LocalContext.current val context = LocalContext.current
val newVersion by produceState(initialValue = 0 to "") { val newVersion by produceState(initialValue = Triple(0, "", "")) {
value = withContext(Dispatchers.IO) { checkNewVersion() } value = withContext(Dispatchers.IO) { checkNewVersion() }
} }
val currentVersionCode = getManagerVersion(context).second val currentVersionCode = getManagerVersion(context).second
val newVersionCode = newVersion.first val newVersionCode = newVersion.first
val newVersionUrl = newVersion.second val newVersionUrl = newVersion.second
if (newVersionCode <= currentVersionCode) { val changelog = newVersion.third
return
}
val uriHandler = LocalUriHandler.current val uriHandler = LocalUriHandler.current
WarningCard( val title = stringResource(id = R.string.module_changelog)
message = stringResource(id = R.string.new_version_available).format(newVersionCode), val updateText = stringResource(id = R.string.module_update)
MaterialTheme.colorScheme.outlineVariant
AnimatedVisibility(
visible = newVersionCode >= currentVersionCode,
enter = fadeIn() + expandVertically(),
exit = shrinkVertically() + fadeOut()
) { ) {
uriHandler.openUri(newVersionUrl) val updateDialog = rememberConfirmDialog(onConfirm = { uriHandler.openUri(newVersionUrl) })
WarningCard(
message = stringResource(id = R.string.new_version_available).format(newVersionCode),
MaterialTheme.colorScheme.outlineVariant
) {
if (changelog.isNotEmpty()) {
updateDialog.showConfirm(
title = title,
content = changelog,
markdown = true,
confirm = updateText
)
}
}
} }
} }
@@ -109,8 +142,17 @@ fun RebootDropdownItem(@StringRes id: Int, reason: String = "") {
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
private fun TopBar(onSettingsClick: () -> Unit) { private fun TopBar(kernelVersion: KernelVersion, onInstallClick: () -> Unit, onSettingsClick: () -> Unit) {
TopAppBar(title = { Text(stringResource(R.string.app_name)) }, actions = { TopAppBar(title = { Text(stringResource(R.string.app_name)) }, actions = {
if (kernelVersion.isGKI()) {
IconButton(onClick = onInstallClick) {
Icon(
imageVector = Icons.Filled.Archive,
contentDescription = stringResource(id = R.string.install)
)
}
}
var showDropdown by remember { mutableStateOf(false) } var showDropdown by remember { mutableStateOf(false) }
IconButton(onClick = { IconButton(onClick = {
showDropdown = true showDropdown = true
@@ -148,7 +190,7 @@ private fun TopBar(onSettingsClick: () -> Unit) {
} }
@Composable @Composable
private fun StatusCard(kernelVersion: KernelVersion, ksuVersion: Int?) { private fun StatusCard(kernelVersion: KernelVersion, ksuVersion: Int?, onClickInstall: () -> Unit = {}) {
ElevatedCard( ElevatedCard(
colors = CardDefaults.elevatedCardColors(containerColor = run { colors = CardDefaults.elevatedCardColors(containerColor = run {
if (ksuVersion != null) MaterialTheme.colorScheme.secondaryContainer if (ksuVersion != null) MaterialTheme.colorScheme.secondaryContainer
@@ -159,8 +201,8 @@ private fun StatusCard(kernelVersion: KernelVersion, ksuVersion: Int?) {
Row(modifier = Modifier Row(modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.clickable { .clickable {
if (kernelVersion.isGKI() && ksuVersion == null) { if (kernelVersion.isGKI()) {
uriHandler.openUri("https://kernelsu.org/guide/installation.html") onClickInstall()
} }
} }
.padding(24.dp), verticalAlignment = Alignment.CenterVertically) { .padding(24.dp), verticalAlignment = Alignment.CenterVertically) {
@@ -216,7 +258,6 @@ private fun StatusCard(kernelVersion: KernelVersion, ksuVersion: Int?) {
Column(Modifier.padding(start = 20.dp)) { Column(Modifier.padding(start = 20.dp)) {
Text( Text(
text = stringResource(R.string.home_unsupported), text = stringResource(R.string.home_unsupported),
fontFamily = FontFamily.Serif,
style = MaterialTheme.typography.titleMedium style = MaterialTheme.typography.titleMedium
) )
Spacer(Modifier.height(4.dp)) Spacer(Modifier.height(4.dp))
@@ -233,7 +274,7 @@ private fun StatusCard(kernelVersion: KernelVersion, ksuVersion: Int?) {
@Composable @Composable
fun WarningCard( fun WarningCard(
message: String, color: Color = MaterialTheme.colorScheme.error, onClick: () -> Unit = {} message: String, color: Color = MaterialTheme.colorScheme.error, onClick: (() -> Unit)? = null
) { ) {
ElevatedCard( ElevatedCard(
colors = CardDefaults.elevatedCardColors( colors = CardDefaults.elevatedCardColors(
@@ -243,16 +284,12 @@ fun WarningCard(
Row( Row(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.then(onClick?.let { Modifier.clickable { it() } } ?: Modifier)
.padding(24.dp) .padding(24.dp)
.clickable {
onClick()
}, verticalAlignment = Alignment.CenterVertically
) { ) {
Column() { Text(
Text( text = message, style = MaterialTheme.typography.bodyMedium
text = message, style = MaterialTheme.typography.bodyMedium )
)
}
} }
} }
} }
@@ -364,3 +401,15 @@ private fun StatusCardPreview() {
StatusCard(KernelVersion(4, 10, 101), null) StatusCard(KernelVersion(4, 10, 101), null)
} }
} }
@Preview
@Composable
private fun WarningCardPreview() {
Column {
WarningCard(message = "Warning message")
WarningCard(
message = "Warning message ",
MaterialTheme.colorScheme.outlineVariant,
onClick = {})
}
}

View File

@@ -1,19 +1,36 @@
package me.weishu.kernelsu.ui.screen package me.weishu.kernelsu.ui.screen
import android.app.Activity
import android.content.Intent
import android.net.Uri import android.net.Uri
import android.os.Environment import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.Refresh import androidx.compose.material3.Button
import androidx.compose.material.icons.filled.Save import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.* import androidx.compose.material3.Icon
import androidx.compose.runtime.* import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.RadioButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@@ -21,102 +38,232 @@ import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.navigation.DestinationsNavigator import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import me.weishu.kernelsu.R import me.weishu.kernelsu.R
import me.weishu.kernelsu.ui.util.LocalSnackbarHost import me.weishu.kernelsu.ui.component.rememberConfirmDialog
import me.weishu.kernelsu.ui.util.installModule import me.weishu.kernelsu.ui.component.rememberLoadingDialog
import me.weishu.kernelsu.ui.util.reboot import me.weishu.kernelsu.ui.screen.destinations.FlashScreenDestination
import java.io.File import me.weishu.kernelsu.ui.util.DownloadListener
import java.text.SimpleDateFormat import me.weishu.kernelsu.ui.util.download
import java.util.* import me.weishu.kernelsu.ui.util.getLKMUrl
import me.weishu.kernelsu.ui.util.isAbDevice
import me.weishu.kernelsu.ui.util.rootAvailable
/** /**
* @author weishu * @author weishu
* @date 2023/1/1. * @date 2024/3/12.
*/ */
@Composable
@Destination @Destination
fun InstallScreen(navigator: DestinationsNavigator, uri: Uri) { @Composable
fun InstallScreen(navigator: DestinationsNavigator) {
var text by remember { mutableStateOf("") }
var showFloatAction by remember { mutableStateOf(false) }
val snackBarHost = LocalSnackbarHost.current
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val loadingDialog = rememberLoadingDialog()
val context = LocalContext.current
var installMethod by remember {
mutableStateOf<InstallMethod?>(null)
}
LaunchedEffect(Unit) { val onFileDownloaded = { uri: Uri ->
if (text.isNotEmpty()) {
return@LaunchedEffect installMethod?.let {
} scope.launch(Dispatchers.Main) {
withContext(Dispatchers.IO) { when (it) {
installModule(uri, onFinish = { success -> InstallMethod.DirectInstall -> {
if (success) { navigator.navigate(
showFloatAction = true FlashScreenDestination(
FlashIt.FlashBoot(
null,
uri,
false
)
)
)
}
InstallMethod.DirectInstallToInactiveSlot -> {
navigator.navigate(
FlashScreenDestination(
FlashIt.FlashBoot(
null,
uri,
true
)
)
)
}
is InstallMethod.SelectFile -> {
navigator.navigate(
FlashScreenDestination(
FlashIt.FlashBoot(
it.uri,
uri,
false
)
)
)
}
} }
}) {
text += "$it\n"
} }
} }
} }
Scaffold( Scaffold(topBar = {
topBar = { TopBar {
TopBar( navigator.popBackStack()
onBack = { }
navigator.popBackStack() }) {
}, Column(modifier = Modifier.padding(it)) {
onSave = { SelectInstallMethod { method ->
scope.launch { installMethod = method
val format = SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.getDefault()) }
val date = format.format(Date())
val file = File( Row(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), modifier = Modifier
"KernelSU_install_log_${date}.log" .fillMaxWidth()
) .padding(16.dp)
file.writeText(text) ) {
snackBarHost.showSnackbar("Log saved to ${file.absolutePath}")
} DownloadListener(context = context) { uri ->
onFileDownloaded(uri)
loadingDialog.hide()
} }
)
}, val failedMessage = stringResource(id = R.string.failed_to_fetch_lkm_url)
floatingActionButton = { val downloadingMessage = stringResource(id = R.string.downloading)
if (showFloatAction) { Button(
val reboot = stringResource(id = R.string.reboot) modifier = Modifier.fillMaxWidth(),
ExtendedFloatingActionButton( enabled = installMethod != null,
onClick = { onClick = {
scope.launch { loadingDialog.showLoading()
withContext(Dispatchers.IO) { scope.launch(Dispatchers.IO) {
reboot() getLKMUrl().onFailure { throwable ->
loadingDialog.hide()
scope.launch(Dispatchers.Main) {
Toast.makeText(
context,
failedMessage.format(throwable.message),
Toast.LENGTH_SHORT
).show()
}
}.onSuccess { result ->
download(
context = context,
url = result.second,
fileName = result.first,
description = downloadingMessage.format(
result.first
),
onDownloaded = { uri ->
onFileDownloaded(uri)
loadingDialog.hide()
},
onDownloading = {}
)
} }
} }
}, }) {
icon = { Icon(Icons.Filled.Refresh, reboot) }, Text(
text = { Text(text = reboot) }, stringResource(id = R.string.install_next),
fontSize = MaterialTheme.typography.bodyMedium.fontSize
)
}
}
}
}
}
sealed class InstallMethod {
data class SelectFile(val uri: Uri? = null, override val label: Int = R.string.select_file) :
InstallMethod()
object DirectInstall : InstallMethod() {
override val label: Int
get() = R.string.direct_install
}
object DirectInstallToInactiveSlot : InstallMethod() {
override val label: Int
get() = R.string.install_inactive_slot
}
abstract val label: Int
}
@Composable
private fun SelectInstallMethod(onSelected: (InstallMethod) -> Unit = {}) {
val rootAvailable = rootAvailable()
val isAbDevice = isAbDevice()
val radioOptions = mutableListOf<InstallMethod>(InstallMethod.SelectFile())
if (rootAvailable) {
radioOptions.add(InstallMethod.DirectInstall)
if (isAbDevice) {
radioOptions.add(InstallMethod.DirectInstallToInactiveSlot)
}
}
var selectedOption by remember { mutableStateOf<InstallMethod?>(null) }
val selectImageLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.StartActivityForResult()
) {
if (it.resultCode == Activity.RESULT_OK) {
it.data?.data?.let { uri ->
val option = InstallMethod.SelectFile(uri)
selectedOption = option
onSelected(option)
}
}
}
val confirmDialog = rememberConfirmDialog(onConfirm = {
selectedOption = InstallMethod.DirectInstallToInactiveSlot
onSelected(InstallMethod.DirectInstallToInactiveSlot)
}, onDismiss = null)
val dialogTitle = stringResource(id = android.R.string.dialog_alert_title)
val dialogContent = stringResource(id = R.string.install_inactive_slot_warning)
val onClick = { option: InstallMethod ->
when (option) {
is InstallMethod.SelectFile -> {
selectImageLauncher.launch(
Intent(Intent.ACTION_GET_CONTENT).apply {
type = "application/octet-stream"
}
) )
} }
is InstallMethod.DirectInstall -> {
selectedOption = option
onSelected(option)
}
is InstallMethod.DirectInstallToInactiveSlot -> {
confirmDialog.showConfirm(dialogTitle, dialogContent)
}
} }
) { innerPadding -> }
Column(
modifier = Modifier Column {
.fillMaxSize(1f) radioOptions.forEach { option ->
.padding(innerPadding) Row(verticalAlignment = Alignment.CenterVertically,
.verticalScroll(rememberScrollState()), modifier = Modifier
) { .fillMaxWidth()
Text( .clickable {
modifier = Modifier.padding(8.dp), onClick(option)
text = text, }) {
fontSize = MaterialTheme.typography.bodySmall.fontSize, RadioButton(selected = option.javaClass == selectedOption?.javaClass, onClick = {
fontFamily = MaterialTheme.typography.bodySmall.fontFamily, onClick(option)
lineHeight = MaterialTheme.typography.bodySmall.lineHeight, })
) Text(text = stringResource(id = option.label))
}
} }
} }
} }
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
private fun TopBar(onBack: () -> Unit = {}, onSave: () -> Unit = {}) { private fun TopBar(onBack: () -> Unit = {}) {
TopAppBar( TopAppBar(
title = { Text(stringResource(R.string.install)) }, title = { Text(stringResource(R.string.install)) },
navigationIcon = { navigationIcon = {
@@ -124,19 +271,11 @@ private fun TopBar(onBack: () -> Unit = {}, onSave: () -> Unit = {}) {
onClick = onBack onClick = onBack
) { Icon(Icons.Filled.ArrowBack, contentDescription = null) } ) { Icon(Icons.Filled.ArrowBack, contentDescription = null) }
}, },
actions = {
IconButton(onClick = onSave) {
Icon(
imageVector = Icons.Filled.Save,
contentDescription = "Localized description"
)
}
}
) )
} }
@Preview
@Composable @Composable
fun InstallPreview() { @Preview
// InstallScreen(DestinationsNavigator(), uri = Uri.EMPTY) fun SelectInstall_Preview() {
// InstallScreen(DestinationsNavigator())
} }

View File

@@ -7,6 +7,7 @@ import android.util.Log
import android.widget.Toast import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
@@ -19,6 +20,7 @@ import androidx.compose.material.pullrefresh.pullRefresh
import androidx.compose.material.pullrefresh.rememberPullRefreshState import androidx.compose.material.pullrefresh.rememberPullRefreshState
import androidx.compose.material3.* import androidx.compose.material3.*
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
@@ -33,14 +35,19 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.navigation.DestinationsNavigator import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import me.weishu.kernelsu.Natives import me.weishu.kernelsu.Natives
import me.weishu.kernelsu.R import me.weishu.kernelsu.R
import me.weishu.kernelsu.ui.component.ConfirmDialog
import me.weishu.kernelsu.ui.component.ConfirmResult import me.weishu.kernelsu.ui.component.ConfirmResult
import me.weishu.kernelsu.ui.screen.destinations.InstallScreenDestination import me.weishu.kernelsu.ui.component.rememberConfirmDialog
import me.weishu.kernelsu.ui.component.rememberLoadingDialog
import me.weishu.kernelsu.ui.screen.destinations.FlashScreenDestination
import me.weishu.kernelsu.ui.screen.destinations.WebScreenDestination
import me.weishu.kernelsu.ui.util.* import me.weishu.kernelsu.ui.util.*
import me.weishu.kernelsu.ui.viewmodel.ModuleViewModel import me.weishu.kernelsu.ui.viewmodel.ModuleViewModel
import okhttp3.OkHttpClient
@Destination @Destination
@Composable @Composable
@@ -48,7 +55,7 @@ fun ModuleScreen(navigator: DestinationsNavigator) {
val viewModel = viewModel<ModuleViewModel>() val viewModel = viewModel<ModuleViewModel>()
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
if (viewModel.moduleList.isEmpty()) { if (viewModel.moduleList.isEmpty() || viewModel.isNeedRefresh) {
viewModel.fetchModuleList() viewModel.fetchModuleList()
} }
} }
@@ -74,7 +81,9 @@ fun ModuleScreen(navigator: DestinationsNavigator) {
val data = it.data ?: return@rememberLauncherForActivityResult val data = it.data ?: return@rememberLauncherForActivityResult
val uri = data.data ?: return@rememberLauncherForActivityResult val uri = data.data ?: return@rememberLauncherForActivityResult
navigator.navigate(InstallScreenDestination(uri)) navigator.navigate(FlashScreenDestination(FlashIt.FlashModule(uri)))
viewModel.markNeedRefresh()
Log.i("ModuleScreen", "select zip result: ${it.data}") Log.i("ModuleScreen", "select zip result: ${it.data}")
} }
@@ -92,8 +101,6 @@ fun ModuleScreen(navigator: DestinationsNavigator) {
} }
}) { innerPadding -> }) { innerPadding ->
ConfirmDialog()
when { when {
hasMagisk -> { hasMagisk -> {
Box( Box(
@@ -113,10 +120,15 @@ fun ModuleScreen(navigator: DestinationsNavigator) {
ModuleList( ModuleList(
viewModel = viewModel, modifier = Modifier viewModel = viewModel, modifier = Modifier
.padding(innerPadding) .padding(innerPadding)
.fillMaxSize() .fillMaxSize(),
) { onInstallModule =
navigator.navigate(InstallScreenDestination(it)) {
} navigator.navigate(FlashScreenDestination(FlashIt.FlashModule(it)))
}, onClickModule = { id, name, hasWebUi ->
if (hasWebUi) {
navigator.navigate(WebScreenDestination(id, name))
}
})
} }
} }
} }
@@ -125,7 +137,10 @@ fun ModuleScreen(navigator: DestinationsNavigator) {
@OptIn(ExperimentalMaterialApi::class) @OptIn(ExperimentalMaterialApi::class)
@Composable @Composable
private fun ModuleList( private fun ModuleList(
viewModel: ModuleViewModel, modifier: Modifier = Modifier, onInstallModule: (Uri) -> Unit viewModel: ModuleViewModel,
modifier: Modifier = Modifier,
onInstallModule: (Uri) -> Unit,
onClickModule: (id: String, name: String, hasWebUi: Boolean) -> Unit
) { ) {
val failedEnable = stringResource(R.string.module_failed_to_enable) val failedEnable = stringResource(R.string.module_failed_to_enable)
val failedDisable = stringResource(R.string.module_failed_to_disable) val failedDisable = stringResource(R.string.module_failed_to_disable)
@@ -137,12 +152,85 @@ private fun ModuleList(
val uninstall = stringResource(id = R.string.uninstall) val uninstall = stringResource(id = R.string.uninstall)
val cancel = stringResource(id = android.R.string.cancel) val cancel = stringResource(id = android.R.string.cancel)
val moduleUninstallConfirm = stringResource(id = R.string.module_uninstall_confirm) val moduleUninstallConfirm = stringResource(id = R.string.module_uninstall_confirm)
val updateText = stringResource(R.string.module_update)
val changelogText = stringResource(R.string.module_changelog)
val downloadingText = stringResource(R.string.module_downloading)
val startDownloadingText = stringResource(R.string.module_start_downloading)
val fetchChangeLogFailed = stringResource(R.string.module_changelog_failed)
val dialogHost = LocalDialogHost.current
val snackBarHost = LocalSnackbarHost.current val snackBarHost = LocalSnackbarHost.current
val context = LocalContext.current
val loadingDialog = rememberLoadingDialog()
val confirmDialog = rememberConfirmDialog()
suspend fun onModuleUpdate(
module: ModuleViewModel.ModuleInfo,
changelogUrl: String,
downloadUrl: String,
fileName: String
) {
val changelogResult = loadingDialog.withLoading {
withContext(Dispatchers.IO) {
runCatching {
OkHttpClient().newCall(
okhttp3.Request.Builder().url(changelogUrl).build()
).execute().body!!.string()
}
}
}
val showToast: suspend (String) -> Unit = { msg ->
withContext(Dispatchers.Main) {
Toast.makeText(
context,
msg,
Toast.LENGTH_SHORT
).show()
}
}
val changelog = changelogResult.getOrElse {
showToast(fetchChangeLogFailed.format(it.message))
return
}.ifBlank {
showToast(fetchChangeLogFailed.format(module.name))
return
}
// changelog is not empty, show it and wait for confirm
val confirmResult = confirmDialog.awaitConfirm(
changelogText,
content = changelog,
markdown = true,
confirm = updateText,
)
if (confirmResult != ConfirmResult.Confirmed) {
return
}
showToast(startDownloadingText.format(module.name))
val downloading = downloadingText.format(module.name)
withContext(Dispatchers.IO) {
download(
context,
downloadUrl,
fileName,
downloading,
onDownloaded = onInstallModule,
onDownloading = {
launch(Dispatchers.Main) {
Toast.makeText(context, downloading, Toast.LENGTH_SHORT).show()
}
}
)
}
}
suspend fun onModuleUninstall(module: ModuleViewModel.ModuleInfo) { suspend fun onModuleUninstall(module: ModuleViewModel.ModuleInfo) {
val confirmResult = dialogHost.showConfirm( val confirmResult = confirmDialog.awaitConfirm(
moduleStr, moduleStr,
content = moduleUninstallConfirm.format(module.name), content = moduleUninstallConfirm.format(module.name),
confirm = uninstall, confirm = uninstall,
@@ -152,7 +240,12 @@ private fun ModuleList(
return return
} }
val success = uninstallModule(module.id) val success = loadingDialog.withLoading {
withContext(Dispatchers.IO) {
uninstallModule(module.id)
}
}
if (success) { if (success) {
viewModel.fetchModuleList() viewModel.fetchModuleList()
} }
@@ -175,48 +268,70 @@ private fun ModuleList(
val refreshState = rememberPullRefreshState(refreshing = viewModel.isRefreshing, val refreshState = rememberPullRefreshState(refreshing = viewModel.isRefreshing,
onRefresh = { viewModel.fetchModuleList() }) onRefresh = { viewModel.fetchModuleList() })
Box(modifier.pullRefresh(refreshState)) { Box(modifier.pullRefresh(refreshState)) {
if (viewModel.isOverlayAvailable) { val context = LocalContext.current
val context = LocalContext.current
LazyColumn( LazyColumn(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.spacedBy(16.dp), verticalArrangement = Arrangement.spacedBy(16.dp),
contentPadding = remember { contentPadding = remember {
PaddingValues( PaddingValues(
start = 16.dp, start = 16.dp,
top = 16.dp, top = 16.dp,
end = 16.dp, end = 16.dp,
bottom = 16.dp + 16.dp + 56.dp /* Scaffold Fab Spacing + Fab container height */ bottom = 16.dp + 16.dp + 56.dp /* Scaffold Fab Spacing + Fab container height */
) )
}, },
) { ) {
val isEmpty = viewModel.moduleList.isEmpty() when {
if (isEmpty) { !viewModel.isOverlayAvailable -> {
item { item {
Box( Box(
modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center modifier = Modifier.fillParentMaxSize(),
contentAlignment = Alignment.Center
) { ) {
Text(stringResource(R.string.module_empty)) Text(
stringResource(R.string.module_overlay_fs_not_available),
textAlign = TextAlign.Center
)
} }
} }
} else { }
viewModel.moduleList.isEmpty() -> {
item {
Box(
modifier = Modifier.fillParentMaxSize(),
contentAlignment = Alignment.Center
) {
Text(
stringResource(R.string.module_empty),
textAlign = TextAlign.Center
)
}
}
}
else -> {
items(viewModel.moduleList) { module -> items(viewModel.moduleList) { module ->
var isChecked by remember(module) { mutableStateOf(module.enabled) } var isChecked by rememberSaveable(module) { mutableStateOf(module.enabled) }
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val updateUrl by produceState(initialValue = "") { val updatedModule by produceState(initialValue = Triple("", "", "")) {
viewModel.checkUpdate(module) { value = it.orEmpty() } scope.launch(Dispatchers.IO) {
value = viewModel.checkUpdate(module)
}
} }
val downloadingText = stringResource(R.string.module_downloading) ModuleItem(module, isChecked, updatedModule.first, onUninstall = {
val startDownloadingText = stringResource(R.string.module_start_downloading)
ModuleItem(module, isChecked, updateUrl, onUninstall = {
scope.launch { onModuleUninstall(module) } scope.launch { onModuleUninstall(module) }
}, onCheckChanged = { }, onCheckChanged = {
val success = toggleModule(module.id, !isChecked) scope.launch {
if (success) { val success = loadingDialog.withLoading {
isChecked = it withContext(Dispatchers.IO) {
scope.launch { toggleModule(module.id, !isChecked)
}
}
if (success) {
isChecked = it
viewModel.fetchModuleList() viewModel.fetchModuleList()
val result = snackBarHost.showSnackbar( val result = snackBarHost.showSnackbar(
@@ -225,32 +340,22 @@ private fun ModuleList(
if (result == SnackbarResult.ActionPerformed) { if (result == SnackbarResult.ActionPerformed) {
reboot() reboot()
} }
} else {
val message = if (isChecked) failedDisable else failedEnable
snackBarHost.showSnackbar(message.format(module.name))
} }
} else scope.launch {
val message = if (isChecked) failedDisable else failedEnable
snackBarHost.showSnackbar(message.format(module.name))
} }
}, onUpdate = { }, onUpdate = {
scope.launch { scope.launch {
Toast.makeText( onModuleUpdate(
context, module,
startDownloadingText.format(module.name), updatedModule.third,
Toast.LENGTH_SHORT updatedModule.first,
).show() "${module.name}-${updatedModule.second}.zip"
)
} }
}, onClick = {
val downloading = downloadingText.format(module.name) onClickModule(it.id, it.name, it.hasWebUi)
download(
context,
updateUrl,
"${module.name}-${module.version}.zip",
downloading,
onDownloaded = onInstallModule,
onDownloading = {
Toast.makeText(context, downloading, Toast.LENGTH_SHORT).show()
}
)
}) })
// fix last item shadow incomplete in LazyColumn // fix last item shadow incomplete in LazyColumn
@@ -258,15 +363,10 @@ private fun ModuleList(
} }
} }
} }
DownloadListener(context, onInstallModule)
} else {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Text(stringResource(R.string.module_overlay_fs_not_available))
}
} }
DownloadListener(context, onInstallModule)
PullRefreshIndicator( PullRefreshIndicator(
refreshing = viewModel.isRefreshing, state = refreshState, modifier = Modifier.align( refreshing = viewModel.isRefreshing, state = refreshState, modifier = Modifier.align(
Alignment.TopCenter Alignment.TopCenter
@@ -289,9 +389,12 @@ private fun ModuleItem(
onUninstall: (ModuleViewModel.ModuleInfo) -> Unit, onUninstall: (ModuleViewModel.ModuleInfo) -> Unit,
onCheckChanged: (Boolean) -> Unit, onCheckChanged: (Boolean) -> Unit,
onUpdate: (ModuleViewModel.ModuleInfo) -> Unit, onUpdate: (ModuleViewModel.ModuleInfo) -> Unit,
onClick: (ModuleViewModel.ModuleInfo) -> Unit
) { ) {
ElevatedCard( ElevatedCard(
modifier = Modifier.fillMaxWidth(), modifier = Modifier
.fillMaxWidth()
.clickable { onClick(module) },
colors = CardDefaults.elevatedCardColors(containerColor = MaterialTheme.colorScheme.surface) colors = CardDefaults.elevatedCardColors(containerColor = MaterialTheme.colorScheme.surface)
) { ) {
@@ -397,6 +500,18 @@ private fun ModuleItem(
text = stringResource(R.string.uninstall), text = stringResource(R.string.uninstall),
) )
} }
if (module.hasWebUi) {
TextButton(
onClick = { onClick(module) },
) {
Text(
fontFamily = MaterialTheme.typography.labelMedium.fontFamily,
fontSize = MaterialTheme.typography.labelMedium.fontSize,
text = stringResource(R.string.open),
)
}
}
} }
} }
} }
@@ -415,7 +530,8 @@ fun ModuleItemPreview() {
enabled = true, enabled = true,
update = true, update = true,
remove = true, remove = true,
updateJson = "" updateJson = "",
hasWebUi = false,
) )
ModuleItem(module, true, "", {}, {}, {}) ModuleItem(module, true, "", {}, {}, {}, {})
} }

View File

@@ -1,14 +1,13 @@
package me.weishu.kernelsu.ui.screen package me.weishu.kernelsu.ui.screen
import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material.icons.filled.*
import androidx.compose.material.icons.filled.BugReport
import androidx.compose.material.icons.filled.ContactPage
import androidx.compose.material.icons.filled.RemoveModerator
import androidx.compose.material3.* import androidx.compose.material3.*
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.saveable.rememberSaveable
@@ -25,9 +24,10 @@ import me.weishu.kernelsu.BuildConfig
import me.weishu.kernelsu.Natives import me.weishu.kernelsu.Natives
import me.weishu.kernelsu.R import me.weishu.kernelsu.R
import me.weishu.kernelsu.ui.component.AboutDialog import me.weishu.kernelsu.ui.component.AboutDialog
import me.weishu.kernelsu.ui.component.LoadingDialog
import me.weishu.kernelsu.ui.component.SwitchItem import me.weishu.kernelsu.ui.component.SwitchItem
import me.weishu.kernelsu.ui.util.LocalDialogHost import me.weishu.kernelsu.ui.component.rememberCustomDialog
import me.weishu.kernelsu.ui.component.rememberLoadingDialog
import me.weishu.kernelsu.ui.screen.destinations.AppProfileTemplateScreenDestination
import me.weishu.kernelsu.ui.util.getBugreportFile import me.weishu.kernelsu.ui.util.getBugreportFile
/** /**
@@ -37,7 +37,6 @@ import me.weishu.kernelsu.ui.util.getBugreportFile
@Destination @Destination
@Composable @Composable
fun SettingScreen(navigator: DestinationsNavigator) { fun SettingScreen(navigator: DestinationsNavigator) {
Scaffold( Scaffold(
topBar = { topBar = {
TopBar(onBack = { TopBar(onBack = {
@@ -45,16 +44,25 @@ fun SettingScreen(navigator: DestinationsNavigator) {
}) })
} }
) { paddingValues -> ) { paddingValues ->
LoadingDialog() val aboutDialog = rememberCustomDialog {
AboutDialog(it)
val showAboutDialog = remember { mutableStateOf(false) } }
AboutDialog(showAboutDialog) val loadingDialog = rememberLoadingDialog()
Column(modifier = Modifier.padding(paddingValues)) { Column(modifier = Modifier.padding(paddingValues)) {
val context = LocalContext.current val context = LocalContext.current
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val dialogHost = LocalDialogHost.current
val profileTemplate = stringResource(id = R.string.settings_profile_template)
ListItem(
leadingContent = { Icon(Icons.Filled.Fence, profileTemplate) },
headlineContent = { Text(profileTemplate) },
supportingContent = { Text(stringResource(id = R.string.settings_profile_template_summary)) },
modifier = Modifier.clickable {
navigator.navigate(AppProfileTemplateScreenDestination)
}
)
var umountChecked by rememberSaveable { var umountChecked by rememberSaveable {
mutableStateOf(Natives.isDefaultUmountModules()) mutableStateOf(Natives.isDefaultUmountModules())
@@ -70,12 +78,49 @@ fun SettingScreen(navigator: DestinationsNavigator) {
} }
} }
val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
var checkUpdate by rememberSaveable {
mutableStateOf(
prefs.getBoolean("check_update", true)
)
}
SwitchItem(
icon = Icons.Filled.Update,
title = stringResource(id = R.string.settings_check_update),
summary = stringResource(id = R.string.settings_check_update_summary),
checked = checkUpdate
) {
prefs.edit().putBoolean("check_update", it).apply()
checkUpdate = it
}
var enableWebDebugging by rememberSaveable {
mutableStateOf(
prefs.getBoolean("enable_web_debugging", false)
)
}
SwitchItem(
icon = Icons.Filled.DeveloperMode,
title = stringResource(id = R.string.enable_web_debugging),
summary = stringResource(id = R.string.enable_web_debugging_summary),
checked = enableWebDebugging
) {
prefs.edit().putBoolean("enable_web_debugging", it).apply()
enableWebDebugging = it
}
ListItem( ListItem(
leadingContent = { Icon(Icons.Filled.BugReport, stringResource(id = R.string.send_log)) }, leadingContent = {
Icon(
Icons.Filled.BugReport,
stringResource(id = R.string.send_log)
)
},
headlineContent = { Text(stringResource(id = R.string.send_log)) }, headlineContent = { Text(stringResource(id = R.string.send_log)) },
modifier = Modifier.clickable { modifier = Modifier.clickable {
scope.launch { scope.launch {
val bugreport = dialogHost.withLoading { val bugreport = loadingDialog.withLoading {
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
getBugreportFile(context) getBugreportFile(context)
} }
@@ -105,10 +150,15 @@ fun SettingScreen(navigator: DestinationsNavigator) {
val about = stringResource(id = R.string.about) val about = stringResource(id = R.string.about)
ListItem( ListItem(
leadingContent = { Icon(Icons.Filled.ContactPage, stringResource(id = R.string.about)) }, leadingContent = {
Icon(
Icons.Filled.ContactPage,
stringResource(id = R.string.about)
)
},
headlineContent = { Text(about) }, headlineContent = { Text(about) },
modifier = Modifier.clickable { modifier = Modifier.clickable {
showAboutDialog.value = true aboutDialog.show()
} }
) )
} }

View File

@@ -30,7 +30,6 @@ import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import me.weishu.kernelsu.Natives import me.weishu.kernelsu.Natives
import me.weishu.kernelsu.R import me.weishu.kernelsu.R
import me.weishu.kernelsu.ui.component.ConfirmDialog
import me.weishu.kernelsu.ui.component.SearchAppBar import me.weishu.kernelsu.ui.component.SearchAppBar
import me.weishu.kernelsu.ui.screen.destinations.AppProfileScreenDestination import me.weishu.kernelsu.ui.screen.destinations.AppProfileScreenDestination
import me.weishu.kernelsu.ui.viewmodel.SuperUserViewModel import me.weishu.kernelsu.ui.viewmodel.SuperUserViewModel
@@ -95,9 +94,6 @@ fun SuperUserScreen(navigator: DestinationsNavigator) {
) )
} }
) { innerPadding -> ) { innerPadding ->
ConfirmDialog()
val refreshState = rememberPullRefreshState( val refreshState = rememberPullRefreshState(
refreshing = viewModel.isRefreshing, refreshing = viewModel.isRefreshing,
onRefresh = { scope.launch { viewModel.fetchAppList() } }, onRefresh = { scope.launch { viewModel.fetchAppList() } },

Some files were not shown because too many files have changed in this diff Show More