diff --git a/patch_v2/meow_svc_power/meow_svc_power b/patch_v2/meow_svc_power/meow_svc_power index 27457ca..01f3fbc 100755 Binary files a/patch_v2/meow_svc_power/meow_svc_power and b/patch_v2/meow_svc_power/meow_svc_power differ diff --git a/patch_v2/meow_svc_power/meow_svc_power.c b/patch_v2/meow_svc_power/meow_svc_power.c index 0a4a586..a76a0d4 100644 --- a/patch_v2/meow_svc_power/meow_svc_power.c +++ b/patch_v2/meow_svc_power/meow_svc_power.c @@ -13,8 +13,10 @@ * 鉴权(II 期,MPK_SIGNATURE_DESIGN §6):IPC 服务端按【连接级身份】分级——`SO_PEERCRED` 取 pid → * `readlink /proc/pid/exe` → 命中 `MeowAPPs//` 判定包名,或命中系统二进制 allowlist * (/usr/bin/meow_*、/usr/data/meow/meow*、MeowPanel 后端)判定为系统身份;其余为 OTHER。 - * 动作级策略:系统动作(shutdown/reboot/upgrade/back_hiby/set-default-*)仅放行 `os.meow.*` 包或系统身份; - * 读/状态类(status/battery/reboot_reason/upgrade_status/screen/dac)放行所有 root 调用方;非 root 一律拒。 + * 命令分「读级/动作级」(用户定案 2026-08-31):读级(status/battery/reboot_reason/upgrade_status/ + * dac status,只读无副作用)放宽到**任意调用者**(不查 uid/身份);动作级维持现状——系统动作 + * (shutdown/reboot/upgrade/back_hiby/set-default-*)仅放行 `os.meow.*` 包或系统身份,非系统动作 + * (screen/dac on|off)仍须 root;非 root 一律拒。 * `MSG_HELLO` 自报 app_id 不在此作权威(仅交叉校验,见 §6.1)。CLI=root 免鉴权。 * * 通知转储归属(§3.2/§3.3 已定案):通知存储为 launcher 进程内存(meow_notif.c g_slots[]),服务跨进程 @@ -617,6 +619,21 @@ static int is_system_action(uint32_t cmd) } } +/* 读级命令(用户定案 2026-08-31):只读查询、无副作用——status/battery/reboot_reason/upgrade_status, + * 及 DAC 的 status(flag=2)。读级放宽到任意调用者(不查 uid/身份);screen/dac on|off 等有副作用 → 动作级。 */ +static int is_read_level(const m_power_action_t *a) +{ + switch (a->cmd) { + case POWER_STATUS: case POWER_BATTERY: + case POWER_REBOOT_REASON: case POWER_UPGRADE_STATUS: + return 1; + case POWER_DAC: + return a->flag == 2; /* 仅 dac status 为读;on/off(flag=0/1) 是动作 */ + default: + return 0; + } +} + /* 是否可信系统身份:CALL_SYS(受信系统二进制)或 CALL_PKG 且包前缀 os.meow.*。 */ static int is_sys_identity(const caller_t *c) { @@ -717,12 +734,15 @@ static void handle_conn(int c) memset(&a, 0, sizeof a); if (rlen > sizeof a) rlen = sizeof a; memcpy(&a, payload, rlen); - /* 动作级策略(设计 §6.3):非 root 一律拒;系统动作须 os.meow.* 包或受信系统身份; - * 读/状态类(STATUS/BATTERY/REBOOT_REASON/UPGRADE_STATUS/SCREEN/DAC)放行所有 root 调用方。 */ + /* 动作级策略(设计 §6.3 + 用户定案 2026-08-31):读级(只读无副作用)放宽到任意调用者, + * 不查 uid/身份;动作级维持现状——系统动作(shutdown/reboot/upgrade/back_hiby/set-default-*) + * 须 os.meow.* 包或受信系统身份,非系统动作(screen/dac on|off)仍须 root。 */ int allow = 0; - if (caller.uid == 0) { + if (is_read_level(&a)) { + allow = 1; /* 读级:任意调用者直接放行 */ + } else if (caller.uid == 0) { if (is_system_action(a.cmd)) allow = is_sys_identity(&caller); - else allow = 1; + else allow = 1; /* 动作级非系统动作(screen/dac on|off):root */ } if (!allow) { m_power_status_t st; diff --git a/patch_v2/meow_svc_power/meow_svc_power_host b/patch_v2/meow_svc_power/meow_svc_power_host index e47498f..da1542e 100755 Binary files a/patch_v2/meow_svc_power/meow_svc_power_host and b/patch_v2/meow_svc_power/meow_svc_power_host differ diff --git a/patch_v2/meow_svc_power/svc_power_authtest b/patch_v2/meow_svc_power/svc_power_authtest new file mode 100755 index 0000000..d518155 Binary files /dev/null and b/patch_v2/meow_svc_power/svc_power_authtest differ diff --git a/patch_v2/meow_svc_power/svc_power_authtest.c b/patch_v2/meow_svc_power/svc_power_authtest.c index ed4b96d..823d2da 100644 --- a/patch_v2/meow_svc_power/svc_power_authtest.c +++ b/patch_v2/meow_svc_power/svc_power_authtest.c @@ -1,7 +1,8 @@ /* svc_power_authtest.c — meow_svc_power II 期 IPC 鉴权逻辑 宿主自测(本程序非生产代码)。 * * 通过 #include 生产源文件(meow_svc_power.c,用 #define main 改名避免入口冲突),在同一 TU 内直接 - * 访问其 FILE-STATIC 函数 classify_exe / is_system_action / is_sys_identity,验证鉴别/分级策略的决策表。 + * 访问其 FILE-STATIC 函数 classify_exe / is_system_action / is_sys_identity / is_read_level, + * 验证鉴别/分级策略的决策表。 * 覆盖「真机需特权路径 /proc/pid/exe 判定」之外的所有纯逻辑分支;真实 pid→exe 解析留真机验证。 * * 用途:dev docs 复现级宿主自测;不进入固件/不部署。用法: @@ -87,6 +88,31 @@ int main(void) CHECK(is_system_action(POWER_SCREEN) == 0); CHECK(is_system_action(POWER_DAC) == 0); + printf("== is_read_level ==\n"); + m_power_action_t a; + memset(&a, 0, sizeof a); + + /* 读级(只读无副作用)→ 1:放宽到任意调用者 */ + a.cmd = POWER_STATUS; CHECK(is_read_level(&a) == 1); + a.cmd = POWER_BATTERY; CHECK(is_read_level(&a) == 1); + a.cmd = POWER_REBOOT_REASON; CHECK(is_read_level(&a) == 1); + a.cmd = POWER_UPGRADE_STATUS; CHECK(is_read_level(&a) == 1); + + /* DAC status(flag=2) 为读级;on/off(flag=0/1) 为动作级 */ + a.cmd = POWER_DAC; a.flag = 2; CHECK(is_read_level(&a) == 1); /* dac status */ + a.cmd = POWER_DAC; a.flag = 0; CHECK(is_read_level(&a) == 0); /* dac off */ + a.cmd = POWER_DAC; a.flag = 1; CHECK(is_read_level(&a) == 0); /* dac on */ + + /* 动作级(有副作用/系统级)→ 0:走现有鉴权 */ + a.cmd = POWER_SCREEN; a.flag = 0; CHECK(is_read_level(&a) == 0); /* screen off/on */ + a.cmd = POWER_SCREEN; a.flag = 2; CHECK(is_read_level(&a) == 0); /* screen timeout 写 settings */ + a.cmd = POWER_SHUTDOWN; CHECK(is_read_level(&a) == 0); + a.cmd = POWER_REBOOT; CHECK(is_read_level(&a) == 0); + a.cmd = POWER_UPGRADE; CHECK(is_read_level(&a) == 0); + a.cmd = POWER_BACK_HIBY; CHECK(is_read_level(&a) == 0); + a.cmd = POWER_SET_DEFAULT_MEOW; CHECK(is_read_level(&a) == 0); + a.cmd = POWER_SET_DEFAULT_HIBY; CHECK(is_read_level(&a) == 0); + if (g_fail) { printf("\nAUTH TEST: %d FAIL\n", g_fail); return 1; } printf("\nAUTH TEST: ALL PASS\n"); return 0;