You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android应用中如何限制JNI调用的C代码仅访问指定文件夹?

Android JNI调用C代码的存储访问范围限制

先说结论:可以实现,但单纯重写POSIX符号的路子行不通(因为共享库能用dlsym绕过去),得结合Android的底层机制来搞。

靠谱的实现方案

1. 用SELinux定制访问规则(Android 8.0及以上)

Android的SELinux是强制访问控制的核心,能给你的native组件锁死访问范围:

  • 给应用的native进程/共享库定义专属的SELinux域,只允许这个域访问/data/data/[你的包名]/files/c_storage/路径下的文件
  • 简化版规则示例:
    allow my_app_native app_data_file:file { read write open }
    allow my_app_native app_data_file:dir { search read write }
    # 单独放开c_storage目录的权限
    allow my_app_native my_app_c_storage_dir:dir { all }
    allow my_app_native my_app_c_storage_file:file { all }
    
  • 操作要点:要把c_storage目录标记上对应的SELinux上下文,可以在应用初始化时用chcon命令设置,或者在编译脚本(Android.mk/CMakeLists.txt)里配置安装时的上下文。

2. 只传文件描述符,不让native碰路径

  • 彻底不让native代码直接用路径访问文件,由Java层提前打开c_storage下的文件,把文件描述符(FD)传给JNI层
  • native代码只通过FD做读写操作,根本碰不到其他路径,自然没法越界
  • 示例代码:
    Java层:
    File cFile = new File(getFilesDir(), "c_storage/test.txt");
    try (FileInputStream fis = new FileInputStream(cFile)) {
        int fd = fis.getFD();
        nativeWriteToFd(fd, "test content");
    } catch (IOException e) {
        e.printStackTrace();
    }
    
    JNI层:
    JNIEXPORT void JNICALL Java_com_example_MainActivity_nativeWriteToFd(JNIEnv *env, jobject thiz, jint fd, jstring content) {
        const char *str = (*env)->GetStringUTFChars(env, content, NULL);
        if (str != NULL) {
            write(fd, str, strlen(str));
            (*env)->ReleaseStringUTFChars(env, content, str);
        }
    }
    
  • 这种方式从根源上切断了native代码访问其他目录的可能,就算共享库用dlsym拿到原始系统调用,也只能操作你给的FD。

3. 替换系统调用表(仅限root/定制ROM场景)

  • 如果有root权限或者能定制ROM,可以直接修改native进程的系统调用表,拦截open/openat这类文件访问的系统调用
  • 在系统调用层面检查路径是否属于c_storage,不符合就返回权限错误
  • 但这个方案兼容性极差,普通应用没法用,只适合定制化场景。

为什么重写POSIX符号会被绕过

共享库可以通过dlsym(RTLD_NEXT, "open")拿到libc里的原始open函数,直接绕开你重写的符号。这种方式只能防防没刻意规避的代码,对付主动绕的完全没用。

内容的提问来源于stack exchange,提问作者Papers.ch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 18:12:23