fix(nyai): 导出 exec 绝对路径相对化 + gzip stderr 重定向 (agent-签名产签链路)
- cmd_export 原先对 app.json 的 exec(绝对路径,如 /usr/data/mnt/sd_0/MeowAPPs/<pkg>/<bin>) 误用 sanitize_member 剥前导 '/' 拼到包目录下,导致 access(<src>/usr/data/...) 必然失败, 所有真实 app 导出被拒(exec 文件不存在或不可执行),卡死「导出→产签」链路。 新增 exec_rel_to_pkg(): 按 ①src/ 前缀 ②/MeowAPPs/<pkg>/ 段(根路径不一致的沙箱/CI) ③相对路径 ④绝对但定位不到包目录→拒, 正确相对化 exec。 - install/upgrade 解包命令把 2>/dev/null 只绑到 tar,gzip stderr(footer trailing garbage / 损坏 crc error)会漏到用户输出;改 gzip 也重定向。 - 同链验证: 宿主 meow_sign/meow_verify_host/qemu-mipsel 验签矩阵通过; 真机(10.78.193.50) 无签 os.meow.*拒装/已签安装OK+.mpk.src/篡改拒装/降级拒装 全过; 装后已卸并恢复原状。 (devdocs 本地不入库; 产签实走记录+README 见 patch_v2/meow_sign/README.md §8)
This commit is contained in:
1 parent
92086129c5
commit
5fac5e380d
4 files changed
+47
-4
No files matched your search
+34
-4
@@ -840,7 +840,7 @@ static int install_mpk_file(const char *mpk_path)
|
||||
rm_rf(stg);
|
||||
if (mkdir_p(stg)!=0) { fprintf(stderr,"nyai: install: 无法建临时目录 %s\n", stg); return 1; }
|
||||
char cmd[1024];
|
||||
snprintf(cmd,sizeof cmd,"gzip -dc '%s' | tar -x -C '%s' 2>/dev/null && [ -f '%s/app.json' ]", mpk_path, stg, stg);
|
||||
snprintf(cmd,sizeof cmd,"gzip -dc '%s' 2>/dev/null | tar -x -C '%s' 2>/dev/null && [ -f '%s/app.json' ]", mpk_path, stg, stg);
|
||||
printf("Preparing to unpack %s ...\n", pkg);
|
||||
if (system(cmd)!=0) {
|
||||
fprintf(stderr,"nyai: install: 解压/校验 app.json 失败(%s 可能损坏或非 .mpk)\n", mpk_path);
|
||||
@@ -1065,6 +1065,36 @@ static int sanitize_member(const char *in, char *out, int n)
|
||||
snprintf(out,n,"%s", p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 把 app.json 的 exec 路径相对化到包目录下(导出前存在性检查 + 白名单打包用)。
|
||||
* 约定(MEOW_APP_SDK 现有惯例,launcher 以绝对路径直接 execve):
|
||||
* - exec 以本包目录 src/ 为前缀 → 取其后相对部分(同一 meow_root,如真机 src=.../MeowAPPs/os.meow.hello → hello);
|
||||
* - exec 含 "/MeowAPPs/<pkg>/" 段 → 取该段后的相对路径(根路径与 src 不一致时仍可定位,如沙箱/CI 测试);
|
||||
* - exec 为相对路径(无前导 /)→ 沿用 sanitize_member 语义(剥 ./、禁 ../、禁 shell 元字符);
|
||||
* - 绝对路径但定位不到包目录段 → 非本包程序,返回 -1(拒绝导出)。
|
||||
* 返回 0 成功,-1 非法。 */
|
||||
static int exec_rel_to_pkg(const char *src, const char *exec, const char *pkg, char *out, int n)
|
||||
{
|
||||
if (!exec || !*exec) return -1;
|
||||
const char *rel = NULL;
|
||||
size_t sl = strlen(src);
|
||||
if (strncmp(exec, src, sl) == 0 && exec[sl] == '/') {
|
||||
rel = exec + sl + 1;
|
||||
} else if (pkg && *pkg) {
|
||||
char marker[272]; snprintf(marker, sizeof marker, "/MeowAPPs/%s/", pkg);
|
||||
const char *m = strstr(exec, marker);
|
||||
if (m) rel = m + strlen(marker);
|
||||
}
|
||||
if (rel) {
|
||||
size_t rl = strlen(rel);
|
||||
if (rl == 0 || rl >= (size_t)n) return -1;
|
||||
if (has_dotdot_comp(rel) || unsafe_path(rel)) return -1;
|
||||
memcpy(out, rel, rl); out[rl] = 0;
|
||||
return 0;
|
||||
}
|
||||
if (exec[0] != '/') return sanitize_member(exec, out, n);
|
||||
return -1;
|
||||
}
|
||||
/* 从 JSON 数组串(含 '[' ']')提取字符串成员;返回项数,负=格式错 */
|
||||
static int json_array_strings(const char *arr, char items[][256], int max)
|
||||
{
|
||||
@@ -1147,9 +1177,9 @@ static int cmd_export(const char *pkg, const char *out)
|
||||
char appj[BUF]; snprintf(appj,sizeof appj,"%s/app.json", src);
|
||||
appmeta m;
|
||||
if (load_app_meta(appj,&m)!=0) { fprintf(stderr,"nyai: export: %s/app.json 不合法(缺 name 或 exec)\n", pkg); return 1; }
|
||||
/* 导出前体检:exec 文件存在且可执行 */
|
||||
/* 导出前体检:exec 文件存在且可执行。exec 可为绝对(包目录下,相对化)或相对路径。 */
|
||||
char exec_rel[BUF];
|
||||
if (sanitize_member(m.exec, exec_rel, sizeof exec_rel)!=0) {
|
||||
if (exec_rel_to_pkg(src, m.exec, pkg, exec_rel, sizeof exec_rel)!=0) {
|
||||
fprintf(stderr,"nyai: export: exec 字段非法: %s\n", m.exec); return 1;
|
||||
}
|
||||
char exepath[BUF]; snprintf(exepath,sizeof exepath,"%s/%s", src, exec_rel);
|
||||
@@ -1246,7 +1276,7 @@ static int cmd_upgrade(const char *pkg, const char *file)
|
||||
if (rename(dst,bak)!=0) { fprintf(stderr,"nyai: upgrade: 备份失败: %s\n", strerror(errno)); return 1; }
|
||||
if (mkdir_p(dst)!=0) { rename(bak,dst); return 1; }
|
||||
char cmd[1024];
|
||||
snprintf(cmd,sizeof cmd,"gzip -dc '%s' | tar -x -C '%s' 2>/dev/null && [ -f '%s/app.json' ]", mpk,dst,dst);
|
||||
snprintf(cmd,sizeof cmd,"gzip -dc '%s' 2>/dev/null | tar -x -C '%s' 2>/dev/null && [ -f '%s/app.json' ]", mpk,dst,dst);
|
||||
printf("Upgrading %s ...\n", pkg);
|
||||
if (system(cmd)!=0) { fprintf(stderr,"nyai: upgrade: 解压失败,回滚\n"); rm_rf(dst); rename(bak,dst); return 1; }
|
||||
char appj[BUF]; snprintf(appj,sizeof appj,"%s/app.json", dst);
|
||||
|
||||
Reference in new issue
Block a user