设置进程安全上下文的代码实现 ---- SEAndroid in android 5.x

本文详细介绍了Android 5.x系统中如何设置进程的安全上下文,涉及ActivityManagerService、Zygote进程以及selinux_android_setcontext函数的作用。通过分析源码,揭示了从启动应用进程到设置安全上下文的具体步骤,包括setcon函数的工作原理,它通过写入/proc/self/task/pid/attr/current文件来更新进程的安全上下文。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 
     应用程序进程是由ActivityManagerService请求Zygote进程创建的。ActivityManagerService在请求Zygote进程创建应用程序进程的时候,会传递很多参数,其中就包括seinfo。当ActivityMangerService需要创建应用程序进程的时候,就会调用ActivityMangerService类的成员函数startProcessLocked,查看这个函数(/home/chris/anrom-5.0/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java):
private final void startProcessLocked(ProcessRecord app, StringhostingType,
           String hostingNameStr, String abiOverride, String entryPoint,String[] entryPointArgs) {
      ........
           Process.ProcessStartResult startResult =Process.start(entryPoint,
                   app.processName, uid, uid, gids, debugFlags, mountExternal,
                   app.info.targetSdkVersion, app.info.seinfo, requiredAbi,instructionSet,
                   app.info.dataDir, refreshTheme, entryPointArgs);
      .........
}
       startProcessLocked通过调用Process类的静态成员函数start来创建应用程序进程,包含了要创建的应用程序进程的各种参数。其中app.info.seinfo从mac_permission.xml中获得。这些参数会通过SocketIPC传递给Zygote进程。最后,Zygote进程会通过调用ZygoteConnection类的成员函数runOnce来执行创建应用程序进程的工作。查看ZygoteConnection类的成员函数runOnce中,与selinux有关的代码(frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java):
boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {
     ......
       pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,parsedArgs.gids,
                   parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal,parsedArgs.seInfo,
                   parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet,
                   parsedArgs.appDataDir);
   .........
}
查看同一文件夹下的Zygote.java中的forkAndSpecialize函数,其中调用到:
       int pid = nativeForkAndSpecialize(
                 uid, gid, gids, debugFlags, rlimits, mountExternal, seInfo,niceName, fdsToClose,
                 instructionSet, appDataDir);

int selinux_android_setcontext(uid_t uid,
               int isSystemServer,
               const char *seinfo,
               const char *pkgname)
{
    char*orig_ctx_str = NULL, *ctx_str;
    context_tctx = NULL;
    int rc =-1;

    if(is_selinux_enabled() <= 0)
       return0;

    rc =getcon(&ctx_str);
    if(rc)
       gotoerr;

    ctx =context_new(ctx_str);
    orig_ctx_str= ctx_str;
    if(!ctx)
       gotooom;

    rc =seapp_context_lookup(SEAPP_DOMAIN,uid, isSystemServer, seinfo, pkgname, NULL, ctx);
    if (rc ==-1)
       gotoerr;
    else if (rc== -2)
       gotooom;

    ctx_str =context_str(ctx);
    if(!ctx_str)
       gotooom;

    rc =security_check_context(ctx_str);
    if (rc <0)
       gotoerr;

    if(strcmp(ctx_str, orig_ctx_str)) {
       rc =setcon(ctx_str);
       if (rc <0)
          gotoerr;
    }

    rc =0;
  ..........
}
      这个函数的实现过程,和设置文件的安全上下文非常相似,也要通过seapp_context_lookup查看并设置进程的domain,再通过security_check_context检查安全上下文的正确性,最后通过setcon来设置安全上下文。
     函数setcon通过external/libselinux/src/procattr.c中的三个宏来定义:
#define setselfattr_def(fn, attr) \
    intset##fn(const char * c) \
    { \
       returnsetprocattrcon(c, 0, #attr); \
    }

#define all_selfattr_def(fn, attr) \
   getselfattr_def(fn,attr)    \
   setselfattr_def(fn, attr)
       从这三个宏的定义就可以看出,函数setcon最终通过调用另外一个函数setprocattrcon来设置当前进程的安全上下文,其中,第一个参数c描述的是要设置的安全上下文,第三个参数的值等于"current"。
       static int setprocattrcon(const char * context,
           pid_t pid, const char *attr)
{
    char*path;
    int fd,rc;
    pid_ttid;
    ssize_tret;
    interrno_hold;

    if (pid >0)
       rc =asprintf(&path, "/proc/%d/attr/%s", pid, attr);
    else {
       tid =gettid();
       rc =asprintf(&path, "/proc/self/task/%d/attr/%s", tid, attr);
    }
    if (rc <0)
       return-1;

    fd =open(path, O_RDWR);
   free(path);
    if (fd <0)
       return-1;
    if(context)
       do {
          ret =write(fd, context, strlen(context) + 1);
       } while (ret< 0 && errno == EINTR);
    else
       do {
          ret =write(fd, NULL,0);   
       } while (ret< 0 && errno == EINTR);
    errno_hold =errno;
   close(fd);
    errno =errno_hold;
    if (ret <0)
       return-1;
    else
       return0;
}
     函数setcon实际上就是打开proc文件系统中的/proc/self/task/pid/attr/current文件,并且向其写入参数context所描述的安全上下文。其中,描述的是当前线程的id。向/proc/self/task//attr/current文件写入安全上下文实际上就是将进程的安全上下文保存在内核中用来描述进程的结构体task_struct中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值