鸿蒙OpenHarmony SELinux学习

2022年2月20日

注:通过代码走读方式了解流程和概述,部分细节有待完善

代码版本:基于OpenHarmony在线代码https://gitee.com/organizations/openharmony/projects

SELinux主库地址:(https://gitee.com/openharmony/security_selinux)

先抛出问题和疑问:

1,OpenHarmony SELinux模块按照了解是由万里红科技有限公司捐赠并合入主线,根据OpenHarmony的系统特点在各个方面是如何考虑和实现?如应用层,框架层和内核层的自研和适配,裁剪,优化逻辑等

FireShot Capture 004 - 如何为OpenHarmony构筑数字安全万里长城?万里红接受专访发布时间:20_财富号_东方财富网 - caifuhao.eastmoney.com.png

2,从OpenHarmony SELinux介绍中看到,在内核层主要是适配了DBinder和文件系统模块?具体逻辑流程是如何的?

3,OpenHarmony SELinux在kernel层的hook选择,与SELinux原生模块有什么区别?是否保留了完全的hook点与路径?

4,应用程序框架在上层的表现形式与Android app/frameworks区别较大?OpenHarmony SELinux的进程域是如何考虑的和设计的?

5,从OpenHarmony SELinux的构建介绍来看,最后编译出来的是集中式策略文件,和Android上面的 有什么区别?

OpenHarmony SELinux整体架构
整体架构.png
OpenHarmony SELinux目标

目标
SELinux (安全增强式 Linux , Security-Enhanced Linux )是 Linux 历史上杰出的安全子系统。 SELinux SIG 的工作目标是将 SELinux 引入 OpenHarmony 。

  1. SELinux 是一组内核修改和用户空间工具,其提供了访问控制安全策略机制,包括了强制访问控制( Mandatory Access Control , MAC )。
  2. SELinux 已经被添加到各种 Linux 发行版中。其软件架构力图将安全决策的执行与安全策略分离,并简化涉及执行安全策略的软件的数量
AppSpawn进程域设置

App进程域的修改从提交记录看到是于2022-1-26号上传的:
https://gitee.com/openharmony/startup_appspawn/commit/e4eb49f1d924df6fdbb6c4af597d11decdfce271

FireShot Capture 705 - Add_ 支持在配置文件中配置服务进程的绑核、优先级、MAC信息以及AccessToken信息 · e4eb49f · OpenHarmo_ - gitee.com.png

设置接口:

FireShot Capture 707 - Add_ 支持在配置文件中配置服务进程的绑核、优先级、MAC信息以及AccessToken信息 · e4eb49f · OpenHarmo_ - gitee.com.png

可以看到SELinux接口是调用共享库libhap_restorecon,是自研实现的,代码库位于:
base/security/selinux

AppProperty关键结构体定义,其中apl值表示App的SELinux属性

https://gitee.com/openharmony/startup_appspawn/blob/master/interfaces/innerkits/include/client_socket.h

   static constexpr int APPSPAWN_MSG_MAX_SIZE = 4096;  // appspawn message max size
    static constexpr int LEN_PROC_NAME = 256;           // process name length
    static constexpr int LEN_BUNDLE_NAME = 256;         // bundle name length
    static constexpr int LEN_SO_PATH = 256;             // load so lib
    static constexpr int MAX_GIDS = 64;
    static constexpr int APL_MAX_LEN = 32;

    struct AppProperty {
        uint32_t uid;                     // the UNIX uid that the child process setuid() to after fork()
        uint32_t gid;                     // the UNIX gid that the child process setgid() to after fork()
        uint32_t gidTable[MAX_GIDS];      // a list of UNIX gids that the child process setgroups() to after fork()
        uint32_t gidCount;                // the size of gidTable
        char processName[LEN_PROC_NAME];  // process name
        char bundleName[LEN_BUNDLE_NAME]; // bundle name
        char soPath[LEN_SO_PATH];         // so lib path
        uint32_t accessTokenId;
        char apl[APL_MAX_LEN];
    };

通过代码中看出,App的selinux属性是应用程序框架服务中通过socket传递过来的,并在Appspawn中进行获取解析:

 while (isRunning_) {
        std::unique_lock<std::mutex> lock(mut_);
        dataCond_.wait(lock, [this] { return !this->appQueue_.empty(); });
        std::unique_ptr<AppSpawnMsgPeer> msg = std::move(appQueue_.front());
        appQueue_.pop();
        int connectFd = msg->GetConnectFd();
        ClientSocket::AppProperty *appProperty = msg->GetMsg();
        if (!CheckAppProperty(appProperty)) {
            msg->Response(-EINVAL);
            continue;
        }

        int32_t fd[FDLEN2] = {FD_INIT_VALUE, FD_INIT_VALUE};
        int32_t buff = 0;
        if (pipe(fd) == -1) {
            HiLog::Error(LABEL, "create pipe fail, errno = %{public}d", errno);
            msg->Response(ERR_PIPE_FAIL);
            continue;
        }

缓冲区数据转换:

https://gitee.com/openharmony/startup_appspawn/blob/master/src/appspawn_server.cpp
 ClientSocket::AppProperty *AppSpawnMsgPeer::GetMsg() const
40  {
41      return reinterpret_cast<ClientSocket::AppProperty *>(buf_.get());
42  }

而在系统框架服务这一侧,App的selinux属性则是通过AppSpawnStartMsg中的apl值来传递的:

https://gitee.com/openharmony/aafwk_standard/blob/weekly_20220215/services/appmgr/include/app_spawn_msg_wrapper.h
namespace OHOS {
namespace AppExecFwk {
struct AppSpawnStartMsg {
    int32_t uid;
    int32_t gid;
    std::vector<int32_t> gids;
    std::string procName;
    std::string soPath;
    uint32_t accessTokenId;
    std::string apl;
    std::string bundleName;
};

aafwk框架服务中通过applicationInfo中的appPrivilegeLevel标签赋值,与Android非常类似,可能也是通过安装时匹配签名与se配置文件规则得出应用进程的所属域:

https://gitee.com/openharmony/aafwk_standard/blob/weekly_20220215/services/appmgr/src/app_mgr_service_inner.cpp

    startMsg.uid = (*bundleInfoIter).uid;
    startMsg.gid = (*bundleInfoIter).gid;
    startMsg.accessTokenId = (*bundleInfoIter).applicationInfo.accessTokenId;
    startMsg.apl = (*bundleInfoIter).applicationInfo.appPrivilegeLevel;
    startMsg.bundleName = bundleName;
    APP_LOGD("StartProcess come, accessTokenId: %{public}d, apl: %{public}s, bundleName: %{public}s",
        startMsg.accessTokenId, startMsg.apl.c_str(), bundleName.c_str());

    bundleMgrResult = bundleMgr_->GetBundleGidsByUid(bundleName, uid, startMsg.gids);
    if (!bundleMgrResult) {
        APP_LOGE("GetBundleGids is fail");
        return;
    }

如OpenHarmony中的sehap_contexts对应Android中的system/sepolicy/private/seapp_contexts类似

https://gitee.com/openharmony/security_selinux/blob/master/sepolicy/sehap_contexts

apl=system_core domain=platform_hap_domain type=platform_hap_data_file
apl=system_basic domain=priv_hap_domain type=priv_hap_data_file
apl=normal domain=normal_hap_domain type=normal_hap_data_file

回到设置进程域的部分:
hap_restorecon.cpp这个类的主要作用是提供设置进程域的接口HapDomainSetcontext,通过解析规则文件,最后通过setcon系统调用走到kernel层设置。

base/security/selinux/interfaces/policycoreutils/src/hap_restorecon.cpp

int HapContext::HapDomainSetcontext(const std::string &apl, const std::string &packageName)
{
    if (apl.empty()) {
        return -SELINUX_ARG_INVALID;
    }

    if (is_selinux_enabled() < 1) {
        SELINUX_LOG_INFO(LABEL, "Selinux not enbaled");
        return SELINUX_SUCC;
    }

    char *typeContext = nullptr;
    if (getcon(&typeContext)) {
        return -SELINUX_GETCON_ERR;
    }

    context_t con = nullptr;
    con = context_new(typeContext);
    if (con == nullptr) {
        return -SELINUX_PTR_NULL;
    }
    char *oldTypeContext = typeContext;

    int res = HapContextsLookup(true, apl, packageName, con);
    if (res < 0) {
        freecon(oldTypeContext);
        context_free(con);
        return res;
    }

    typeContext = context_str(con);
    if (typeContext == nullptr) {
        freecon(oldTypeContext);
        context_free(con);
        return -SELINUX_PTR_NULL;
    }

    SELINUX_LOG_INFO(LABEL, "Hap type for %{public}s is changing from %{public}s to %{public}s", packageName.c_str(),
                     oldTypeContext, typeContext);

    if (security_check_context(typeContext) < 0) {
        freecon(oldTypeContext);
        context_free(con);
        return -SELINUX_TYPE_INVALID;
    }

    if (strcmp(typeContext, oldTypeContext)) {
        if (setcon(typeContext) < 0) {
            freecon(oldTypeContext);
            context_free(con);
            return -SELINUX_SETCON_ERR;
        }
    }
    SELINUX_LOG_INFO(LABEL, "Hap setcon finish for %{public}s", packageName.c_str());

    freecon(oldTypeContext);
    context_free(con);
    return SELINUX_SUCC;
}
OpenHarmony SELinux Kernel层的变化(待续)

DBinder新增加模块
文件系统的适配

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,451评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,172评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,782评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,709评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,733评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,578评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,320评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,241评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,686评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,878评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,992评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,715评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,336评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,912评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,040评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,173评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,947评论 2 355

推荐阅读更多精彩内容