/* 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 / is_read_level, * 验证鉴别/分级策略的决策表。 * 覆盖「真机需特权路径 /proc/pid/exe 判定」之外的所有纯逻辑分支;真实 pid→exe 解析留真机验证。 * * 用途:dev docs 复现级宿主自测;不进入固件/不部署。用法: * cc -Wall -Wextra -I../meow_launcherd svc_power_authtest.c -o svc_power_authtest && ./svc_power_authtest */ #define main meow_svc_power_prod_main_unused #define MEOW_PS_DIR "/tmp/meow_ps_authtest" /* 充电态判定宿主自测:重定向 sysfs 根 */ #include "meow_svc_power.c" #undef main #undef MEOW_PS_DIR #include #include #include #include static int g_fail = 0; #define CHECK(cond) do { if (!(cond)) { printf(" FAIL: %s (line %d)\n", #cond, __LINE__); g_fail++; } \ else { printf(" ok : %s\n", #cond); } } while (0) int main(void) { caller_t c; printf("== classify_exe ==\n"); memset(&c, 0, sizeof c); classify_exe("/usr/data/mnt/sd_0/MeowAPPs/os.meow.tst/meow", &c); CHECK(c.kind == CALL_PKG && strcmp(c.pkg, "os.meow.tst") == 0); memset(&c, 0, sizeof c); classify_exe("/usr/data/mnt/sd_0/MeowAPPs/com.example.tool/meow", &c); CHECK(c.kind == CALL_PKG && strcmp(c.pkg, "com.example.tool") == 0); memset(&c, 0, sizeof c); classify_exe("/usr/data/mnt/sd_0/MeowAPPs/os.meow.tst/sub/meow", &c); CHECK(c.kind == CALL_PKG && strcmp(c.pkg, "os.meow.tst") == 0); /* 取首段目录 */ memset(&c, 0, sizeof c); classify_exe("/usr/bin/meow_launcherd", &c); CHECK(c.kind == CALL_SYS && strcmp(c.pkg, "os.meow.launcher") == 0); memset(&c, 0, sizeof c); classify_exe("/usr/bin/meow_svc_power", &c); CHECK(c.kind == CALL_SYS); /* /usr/bin/meow_* 前缀批准 */ /* 2B 精确绑定:仅精确命中登记路径(meowpanel.conf 的 exec)才予 os.meow.panel。 * 旧启发式(路径含 /MeowPanel/ 或 meowpanel 子串)会被过宽放行,今已收紧为精确路径登记。 */ memset(&c, 0, sizeof c); classify_exe("/usr/data/mnt/sd_0/MeowOS/opt/MeowPanel/meowpanel", &c); CHECK(c.kind == CALL_SYS && strcmp(c.pkg, "os.meow.panel") == 0); /* 反例:路径含 /MeowPanel/ 或 meowpanel 子串但并非精确登记路径 → 不再放行(CALL_OTHER) */ memset(&c, 0, sizeof c); classify_exe("/usr/data/mnt/sd_0/MeowOS/opt/MeowPanel/backend/meowpanel", &c); CHECK(c.kind == CALL_OTHER); memset(&c, 0, sizeof c); classify_exe("/usr/data/mnt/sd_0/MeowOS/opt/MeowPanel/evil", &c); CHECK(c.kind == CALL_OTHER); memset(&c, 0, sizeof c); classify_exe("/usr/bin/meowpanel_fake", &c); CHECK(c.kind == CALL_OTHER); /* 含 "meowpanel" 但非 /usr/bin/meow_* 精确前缀、非登记路径 */ memset(&c, 0, sizeof c); classify_exe("/usr/data/meow/settings_tool", &c); CHECK(c.kind == CALL_SYS); /* /usr/data/meow/ 批准 */ memset(&c, 0, sizeof c); classify_exe("/usr/bin/bash", &c); CHECK(c.kind == CALL_OTHER); memset(&c, 0, sizeof c); classify_exe("/bin/sh", &c); CHECK(c.kind == CALL_OTHER); memset(&c, 0, sizeof c); classify_exe("/usr/data/mnt/sd_0/MeowAPPs/justadirty/k", &c); CHECK(c.kind == CALL_PKG && strcmp(c.pkg, "justadirty") == 0); /* 第三方包(非 os.meow.*) */ CHECK(is_sys_identity(&c) == 0); /* 非系统身份 → 系统动作被拒 */ printf("== is_sys_identity ==\n"); c.kind = CALL_PKG; snprintf(c.pkg, sizeof c.pkg, "%s", "os.meow.tst"); CHECK(is_sys_identity(&c) == 1); c.kind = CALL_PKG; snprintf(c.pkg, sizeof c.pkg, "%s", "com.example.tool"); CHECK(is_sys_identity(&c) == 0); c.kind = CALL_SYS; snprintf(c.pkg, sizeof c.pkg, "%s", "os.meow.launcher"); CHECK(is_sys_identity(&c) == 1); c.kind = CALL_OTHER; c.pkg[0] = 0; CHECK(is_sys_identity(&c) == 0); printf("== is_system_action ==\n"); CHECK(is_system_action(POWER_SHUTDOWN) == 1); CHECK(is_system_action(POWER_REBOOT) == 1); CHECK(is_system_action(POWER_UPGRADE) == 1); CHECK(is_system_action(POWER_BACK_HIBY) == 1); CHECK(is_system_action(POWER_SET_DEFAULT_MEOW) == 1); CHECK(is_system_action(POWER_SET_DEFAULT_HIBY) == 1); CHECK(is_system_action(POWER_STATUS) == 0); CHECK(is_system_action(POWER_BATTERY) == 0); CHECK(is_system_action(POWER_REBOOT_REASON) == 0); CHECK(is_system_action(POWER_UPGRADE_STATUS) == 0); 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); /* == 充电态权威源(真机实测 2026-09-01:battery/status 恒 Discharging 撒谎)== * 在 /tmp 造 power_supply 假节点(MEOW_PS_DIR 已重定向),覆盖判定优先级: * mp2731-charger/status(权威)→ fusb302-typec-source/online → battery/status|ac/online。 */ printf("== charging_status_str (authoritative mp2731) ==\n"); mkdir("/tmp/meow_ps_authtest", 0755); mkdir("/tmp/meow_ps_authtest/battery", 0755); mkdir("/tmp/meow_ps_authtest/mp2731-charger", 0755); mkdir("/tmp/meow_ps_authtest/fusb302-typec-source", 0755); mkdir("/tmp/meow_ps_authtest/ac", 0755); write_file_str("/tmp/meow_ps_authtest/battery/capacity", "72", 0644); write_file_str("/tmp/meow_ps_authtest/battery/voltage_now", "4150000", 0644); write_file_str("/tmp/meow_ps_authtest/battery/status", "Discharging", 0644); /* 撒谎节点 */ write_file_str("/tmp/meow_ps_authtest/ac/online", "0", 0644); char out[64]; /* T1: mp2731=Charging(battery 撒谎 Discharging)→ 充电中 */ write_file_str("/tmp/meow_ps_authtest/mp2731-charger/status", "Charging", 0644); battery_fill(out, sizeof out); CHECK(strstr(out, "(Charging)") != NULL); /* T2: mp2731=Full → 满电 */ write_file_str("/tmp/meow_ps_authtest/mp2731-charger/status", "Full", 0644); battery_fill(out, sizeof out); CHECK(strstr(out, "(Full)") != NULL); /* T3: mp2731=Discharging 且拔线 → 非充电(权威源的放电可信) */ write_file_str("/tmp/meow_ps_authtest/mp2731-charger/status", "Discharging", 0644); write_file_str("/tmp/meow_ps_authtest/fusb302-typec-source/online", "0", 0644); battery_fill(out, sizeof out); CHECK(strstr(out, "(Discharging)") != NULL); /* T4: mp2731 节点不可读 → 回退 fusb302 online==1 → 充电 */ unlink("/tmp/meow_ps_authtest/mp2731-charger/status"); write_file_str("/tmp/meow_ps_authtest/fusb302-typec-source/online", "1", 0644); battery_fill(out, sizeof out); CHECK(strstr(out, "(Charging)") != NULL); /* T5: 全不可读 → 回退旧逻辑 ac/online==1 → Charging */ unlink("/tmp/meow_ps_authtest/fusb302-typec-source/online"); write_file_str("/tmp/meow_ps_authtest/ac/online", "1", 0644); battery_fill(out, sizeof out); CHECK(strstr(out, "(Charging)") != NULL); /* T6: 全不可读且 ac/online=0、battery=Discharging → Discharging */ write_file_str("/tmp/meow_ps_authtest/ac/online", "0", 0644); battery_fill(out, sizeof out); CHECK(strstr(out, "(Discharging)") != NULL); if (g_fail) { printf("\nAUTH TEST: %d FAIL\n", g_fail); return 1; } printf("\nAUTH TEST: ALL PASS\n"); return 0; }