feat(svc_power): 读级命令鉴权放宽到任意调用者 (agent-189, 用户定案) — STATUS/BATTERY/REBOOT_REASON/UPGRADE_STATUS/dac status 读级不再查 uid;动作级维持 os.meow.*/系统身份;authtest +16 断言 ALL PASS。svc_power e0494eb7→c6ddf3f8

This commit is contained in:
MeowOS committed 2026-08-31 04:55:49 +08:00
1 parent c8ffdfbad9
commit 555c4a458e
5 files changed
+53 -7

No files matched your search

Binary file not shown.
+26 -6
View File
@@ -13,8 +13,10 @@
* 鉴权(II 期,MPK_SIGNATURE_DESIGN §6):IPC 服务端按【连接级身份】分级——`SO_PEERCRED` 取 pid → * 鉴权(II 期,MPK_SIGNATURE_DESIGN §6):IPC 服务端按【连接级身份】分级——`SO_PEERCRED` 取 pid →
* `readlink /proc/pid/exe` → 命中 `MeowAPPs/<pkg>/` 判定包名,或命中系统二进制 allowlist * `readlink /proc/pid/exe` → 命中 `MeowAPPs/<pkg>/` 判定包名,或命中系统二进制 allowlist
* (/usr/bin/meow_*、/usr/data/meow/meow*、MeowPanel 后端)判定为系统身份;其余为 OTHER。 * (/usr/bin/meow_*、/usr/data/meow/meow*、MeowPanel 后端)判定为系统身份;其余为 OTHER。
* 动作级策略:系统动作(shutdown/reboot/upgrade/back_hiby/set-default-*)仅放行 `os.meow.*` 包或系统身份; * 命令分「读级/动作级」(用户定案 2026-08-31):读级(status/battery/reboot_reason/upgrade_status/
* 读/状态类(status/battery/reboot_reason/upgrade_status/screen/dac)放行所有 root 调用方;非 root 一律拒。 * 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 免鉴权。 * `MSG_HELLO` 自报 app_id 不在此作权威(仅交叉校验,见 §6.1)。CLI=root 免鉴权。
* *
* 通知转储归属(§3.2/§3.3 已定案):通知存储为 launcher 进程内存(meow_notif.c g_slots[]),服务跨进程 * 通知转储归属(§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.*。 */ /* 是否可信系统身份:CALL_SYS(受信系统二进制)或 CALL_PKG 且包前缀 os.meow.*。 */
static int is_sys_identity(const caller_t *c) static int is_sys_identity(const caller_t *c)
{ {
@@ -717,12 +734,15 @@ static void handle_conn(int c)
memset(&a, 0, sizeof a); memset(&a, 0, sizeof a);
if (rlen > sizeof a) rlen = sizeof a; if (rlen > sizeof a) rlen = sizeof a;
memcpy(&a, payload, rlen); memcpy(&a, payload, rlen);
/* 动作级策略(设计 §6.3):非 root 一律拒;系统动作须 os.meow.* 包或受信系统身份; /* 动作级策略(设计 §6.3 + 用户定案 2026-08-31):读级(只读无副作用)放宽到任意调用者,
* 读/状态类(STATUS/BATTERY/REBOOT_REASON/UPGRADE_STATUS/SCREEN/DAC)放行所有 root 调用方。 */ * 不查 uid/身份;动作级维持现状——系统动作(shutdown/reboot/upgrade/back_hiby/set-default-*)
* 须 os.meow.* 包或受信系统身份,非系统动作(screen/dac on|off)仍须 root。 */
int allow = 0; 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); if (is_system_action(a.cmd)) allow = is_sys_identity(&caller);
else allow = 1; else allow = 1; /* 动作级非系统动作(screen/dac on|off):root */
} }
if (!allow) { if (!allow) {
m_power_status_t st; m_power_status_t st;
Binary file not shown.
Binary file not shown.
+27 -1
View File
@@ -1,7 +1,8 @@
/* svc_power_authtest.c — meow_svc_power II 期 IPC 鉴权逻辑 宿主自测(本程序非生产代码)。 /* svc_power_authtest.c — meow_svc_power II 期 IPC 鉴权逻辑 宿主自测(本程序非生产代码)。
* *
* 通过 #include 生产源文件(meow_svc_power.c,用 #define main 改名避免入口冲突),在同一 TU 内直接 * 通过 #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 解析留真机验证。 * 覆盖「真机需特权路径 /proc/pid/exe 判定」之外的所有纯逻辑分支;真实 pid→exe 解析留真机验证。
* *
* 用途:dev docs 复现级宿主自测;不进入固件/不部署。用法: * 用途:dev docs 复现级宿主自测;不进入固件/不部署。用法:
@@ -87,6 +88,31 @@ int main(void)
CHECK(is_system_action(POWER_SCREEN) == 0); CHECK(is_system_action(POWER_SCREEN) == 0);
CHECK(is_system_action(POWER_DAC) == 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; } if (g_fail) { printf("\nAUTH TEST: %d FAIL\n", g_fail); return 1; }
printf("\nAUTH TEST: ALL PASS\n"); printf("\nAUTH TEST: ALL PASS\n");
return 0; return 0;