Android SELinux——工作模式(二)

news2024/10/10 10:28:02

        通过上一篇文章我们对 SELinux 有一初步的了解,这里我们主要来看一下 SELinux 中的工作模式。

一、模式介绍

        SELinux 提供了三种不同的工作模式,每种模式都有其特定的目的和使用场景。这里我们就来介绍这三种模式的使用场景。

1、Disabled(禁用模式)

        在 Disabled 模式下,SELinux 完全不工作,系统退回到传统的自主访问控制(DAC)机制。此模式下,SELinux 不会对系统中的任何操作进行干预或记录。当系统管理员决定完全禁用 SELinux 时使用此模式,通常是为了简化系统管理或解决特定的兼容性问题。

2、Permissive(宽容模式)

        在 Permissive 模式下,SELinux 被激活,但不会强制执行安全策略。相反,它会记录所有违反安全策略的尝试,并将其记录在日志中。此模式主要用于测试和调试目的,帮助系统管理员了解 SELinux 如何影响系统行为,以及在完全启用 SELinux 之前识别和解决潜在问题。当系统管理员希望监控 SELinux 的行为但又不想立即启用严格的访问控制时,可以使用此模式。

3、Enforcing(强制模式)

        在 Enforcing 模式下,SELinux 完全启用,并且会强制执行所有的安全策略。此模式下,任何违反安全策略的操作都会被阻止,并且系统会记录相应的 AVC 日志。这是 SELinux 的默认模式,适用于生产环境,以确保系统的安全性。在此模式下,系统会严格执行 SELinux 安全策略,防止未经授权的访问。 

        通过这些不同的工作模式,系统管理员可以根据实际需要选择最适合当前环境的 SELinux 设置,既可以保证系统的安全性,又能灵活应对不同的需求。所以我们通常在开发中使用的都是Permissive(宽容模式),记录问题但有未启用访问控制。而正是上线的时候为Enforcing(强制模式)。

二、模式切换

1、ADB命令设置

查看工作模式

进入到 shell:adb shell

查看工作模式:getenforce

        首先进入到 shell 下,使用 getenforce 命令来查看当前 SELinux 的工作模式(或者直接使用 adb shell getenforce 命令查看 SELinux 的工作模式),输出内容:Enforcing 或 Permissive。

切换工作模式

获取 root 权限:adb root

进入到 shell:adb shell

切换到 Permissive 模式:setenforce 0

切换到 Enforcing 模式:setenforce 1

        使用 setenforce [0|1] 来切换 SELinux 的工作模式(0 表示 Permissive,1 表示 Enforcing)。注意这里一定要获取 root 权限,否则会出现如下错误:

setenforce: Couldn't set enforcing status to '0': Permission denied

2、fastboot模式设置      

        除此通过 ADB 命令设置模式之外还可以进入 fastboot 模式对工作模式的 bootargs 参数进行设置。

fastboot setenv

# 设置 androidboot.selinux 参数

$ fastboot setenv bootargs  androidboot.selinux = permissive/enforcing
# 保存参数
$ fastboot flash bootconfig bootconfig 
# 重启系统
$ fastboot reboot

fastboot oem

# 设置 androidboot.selinux 参数

$ fastboot oem setenv "androidboot.selinux = permissive/enforcing
# 保存参数
$ fastboot oem saveenv
# 重启系统
$ fastboot reboot

        对于使用 fastboot 命令更改工作模式需要设备支持,不同的设备和厂商可能有不同的命令格式。这里实际操作均设置失败,fastboot setenv 命令提示 fastboot: usage: unknown command setenv。fastboot oem 命令提示 FAILED (remote: unknown command)。

3、配置文件设置

        其实上面的命令都是在 Permissive 和 Enforcing 模式之间进行切换,无法设置成 Disabled 模式。所以 SELinux 的默认模式也可以通过配置文件进行设置。

config.xml

        修改 /etc/selinux/config.xml 文件中的 SELINUX 选项来设定,可以选择 Disabled、Permissive 或 Enforcing。编辑配置文件 /etc/selinux/config.xml,把SELINUX=disabled,然后重启系统,SELinux 就被禁用了。

        某些 Android 设备可能会有特定的 SELinux 配置文件,这些文件可能位于不同的路径,例如 /vendor/etc/selinux、/system/etc/selinux、/vendor/etc/security 或 /system/etc/security 。当然也有不使用 config.xml 配置文件的情况,这些都需要根据项目实际情况设定。

系统属性

        如果项目中并没有找到上面的 config.xml 配置文件,可以通过如下命令确认是否使用了系统属性设置了 SELinux 的工作模式。

进入 shell 模式:adb shell

查找相关属性:getprop | grep "selinux"

        这里在 shell 模式下,通过 getprop 查找 "selinux" 关键字的属性内容,可以看到如下输出内容:

[androidboot.selinux]: [enforcing]

        可以看到这个属性其实就是上面通过 fastboot 修改的对应属性值,androidboot.selinux 属性是一个特殊的内核启动参数,它在设备启动时被内核读取,并不是普通的系统属性,所以也不能通过 /system/build.prop 文件进行修改。

  • androidboot.selinux 名称由厂商自定义设置,可能与这里的名称并不相同。
  • /system/build.prop 文件主要用于定义构建信息和其他非启动时的系统属性。它可以用来设置诸如设备型号、制造商、构建版本等信息。

4、代码修改

源码位置:/system/core/init/selinux.cpp

SelinuxInitialize

void SelinuxInitialize() {
    LOG(INFO) << "Loading SELinux policy";
    // 加载 SELinux 策略
    if (!LoadPolicy()) {
        LOG(FATAL) << "Unable to load SELinux policy";
    }
  
    // 获取内核当前的 SELinux 模式
    bool kernel_enforcing = (security_getenforce() == 1);
    // 获取期望的 SELinux 模式
    bool is_enforcing = IsEnforcing();
    // 如果两者不一致,则尝试设置 SELinux 模式
    if (kernel_enforcing != is_enforcing) {
        if (security_setenforce(is_enforcing)) {
            PLOG(FATAL) << "security_setenforce(" << (is_enforcing ? "true" : "false") << ") failed";
        }
    }
  
    // 将 checkreqprot 设置为 0,关闭 SELinux 请求保护功能
    if (auto result = WriteFile("/sys/fs/selinux/checkreqprot", "0"); !result.ok()) {
        LOG(FATAL) << "Unable to write to /sys/fs/selinux/checkreqprot: " << result.error();
    }
}

        函数用于初始化 SELinux 并确保其工作模式符合预期。这里我们是不是直接修改期望的 SELinux 模式就可以实现工作模式的修改。在修改之前,我们先来看一下这里为什么要关闭 SELinux 请求保护功能(checkreqprot)。

checkreqprot

        SELinux 请求保护功能(checkreqprot)主要用于记录 SELinux 策略违规(avc denials)。当 SELinux 处于 enforcing 模式时,如果某个进程请求了不允许的操作,SELinux 会拒绝该操作并记录一条违规日志。

默认情况下:checkreqprot 的值为 1,表示启用请求保护功能。
启用时:SELinux 会记录所有违规行为,并将这些违规行为记录到日志中。
禁用时:SELinux 不会记录违规行为,只会在 enforcing 模式下直接拒绝违规操作。

        关闭 checkreqprot 的原因:

  • 性能考虑:当 checkreqprot 为 1 时,SELinux 会记录大量的违规日志,这可能会导致较高的系统开销。关闭 checkreqprot 可以减少系统日志记录的开销,提高系统性能。
  • 安全性考虑:在生产环境中,通常希望 SELinux 严格控制违规行为,而不记录过多的日志。
  • 在开发和调试阶段,可能会开启 checkreqprot 以便更好地了解违规情况,但在生产环境中通常不需要这些详细的日志记录。
  • 系统稳定性:大量的日志记录可能会导致日志文件迅速增长,占用大量磁盘空间。关闭 checkreqprot 可以避免这种情况,保持系统的稳定性和高效性。

        关闭 checkreqprot 功能的原因主要是为了提高系统性能和稳定性。在生产环境中,通常不需要记录大量的 SELinux 违规日志,因此关闭 checkreqprot 是一个常见的做法。 

IsEnforcing

bool IsEnforcing() {
    // 是否允许 SELinux 处于 permissive 模式
    if (ALLOW_PERMISSIVE_SELINUX) {
        return StatusFromCmdline() == SELINUX_ENFORCING;
    }
    return true;
}

        该函数的主要作用是根据配置和命令行参数来决定 SELinux 是否应该处于 enforcing 模式。这种设计使得 SELinux 的模式可以根据不同的配置和命令行参数灵活调整,适用于不同的场景。 

enum EnforcingStatus { SELINUX_PERMISSIVE, SELINUX_ENFORCING };

EnforcingStatus StatusFromCmdline() {
    EnforcingStatus status = SELINUX_ENFORCING;

    ImportKernelCmdline([&](const std::string& key, const std::string& value) {
        if (key == "androidboot.selinux" && value == "permissive") {
            status = SELINUX_PERMISSIVE;
        }
    });

    return status;
}

        该函数通常用于解析内核命令行参数,并执行相应的处理。可以看到这里还是根据上面的 androidboot.selinux 属性进行 SELinux 的工作模式初始化,如果我们在这里修改,可以直接修改 IsEnforcing() 函数的返回值即可。

bool IsEnforcing() {
    // 关闭SELinux
    return false;
}

        这里通过直接修改 IsEnforcing() 函数的返回值来修改 SELinux 的工作模式。接下来我们回过头来看一下 ALLOW_PERMISSIVE_SELINUX 参数的设置。

ALLOW_PERMISSIVE_SELINUX

源码位置:/system/core/init/Android.bp

cc_defaults {
	cflags: [
		"-DALLOW_PERMISSIVE_SELINUX=0",
        ……
	],
	product_variables: {
		debuggable: {
			cppflags: [
				"-UALLOW_PERMISSIVE_SELINUX",
				"-DALLOW_PERMISSIVE_SELINUX=1",
                ……
			],
            ……
		},
        ……
	},
    ……
}

        首先在 C 和 C++ 中,预处理器宏定义通常使用 -D 开头。这里的 -D 是一个编译器选项,用于定义预处理器宏。

        在 Android.bp 文件中,cc_defaults 用于设置默认的编译选项,这里 cc_defaults 通过 cflags 和 product_variables 来定义不同的编译配置。具体来说,-DALLOW_PERMISSIVE_SELINUX=0 和 product_variables 中的条件定义使得编译行为可以根据不同的产品变量进行调整。

  • 默认编译选项 (cflags):"-DALLOW_PERMISSIVE_SELINUX=0":默认情况下,定义 ALLOW_PERMISSIVE_SELINUX 为 0。
  • 产品变量 (product_variables):debuggable 变量。

         1) "-UALLOW_PERMISSIVE_SELINUX":取消定义 ALLOW_PERMISSIVE_SELINUX。
         2)"-DALLOW_PERMISSIVE_SELINUX=1":重新定义 ALLOW_PERMISSIVE_SELINUX 为 1。

        这样非调试版本 (debuggable=false) 时,只有默认的编译选项生效,因此,编译时 ALLOW_PERMISSIVE_SELINUX 的值为 0。调试版本 (debuggable=true),在这种情况下,product_variables 中的配置生效,首先,-UALLOW_PERMISSIVE_SELINUX 取消定义 ALLOW_PERMISSIVE_SELINUX,然后 "-DALLOW_PERMISSIVE_SELINUX=1" 重新定义 ALLOW_PERMISSIVE_SELINUX 为 1。

        这种方式使得编译行为可以根据不同的产品变量进行灵活调整,从而适应不同的开发和部署环境。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2201744.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【含开题报告+文档+PPT+源码】基于过滤协同算法的旅游推荐管理系统设计与实现

开题报告 旅游业作为一种重要的经济活动&#xff0c;对于一个地区的经济发展和文化传承具有重要意义。泉州作为中国华东地区的重要城市&#xff0c;拥有丰富的自然资源和独特的文化底蕴&#xff0c;吸引了大量的游客。然而&#xff0c;随着旅游业的快速发展&#xff0c;游客数…

将长图按宽度切割保存成小图,‌长图图片切图快速操作

长图图片切图技术如同一把锋利的剑&#xff0c;为编辑高手们披荆斩棘&#xff0c;开辟出一条高效操作与创意实现的道路。面对冗长而信息丰富的长图&#xff0c;如何精准地进行切分&#xff0c;以便更好地编辑、管理与利用&#xff0c;成为了每位追求卓越的编辑高手必须掌握的绝…

计算机毕业设计 基于Hadoop的租房数据分析系统的设计与实现 Python毕业设计 Python毕业设计选题 数据分析【附源码+安装调试】

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

SpringBoot 整合 阿里云 OSS图片上传

一、OOS 简介 ‌阿里云OSS&#xff08;Object Storage Service&#xff09;是一种基于云存储的产品&#xff0c;适用于存储和管理各种类型的文件&#xff0c;包括图片、视频、文档等。‌ 阿里云OSS具有高可靠性、高可用性和低成本等优点&#xff0c;因此被广泛应用于各种场景&…

能源监控大数据界面,洞察一切生产态势

能源监控大数据界面犹如一扇洞察一切生产态势的神奇之窗。在这个界面上&#xff0c;丰富的数据以直观的图表、动态的图形和醒目的数字呈现出来。 通过色彩鲜明的仪表盘&#xff0c;能清晰地了解能源的实时消耗情况&#xff0c;红色区域的警示提醒着可能存在的能源浪费或异常情…

【exp报错注入】

整数范围 最大整数 exp 函数介绍 报错盲注注入 payload分析 709C-ASCII 值就等于我们下面的 7091-1 &#xff0c;C就是我们要猜的值&#xff0c;当我们猜测的值和ASCII码相等时&#xff0c;那么exp就不会出现报错&#xff0c;因为1-1还是等于709&#xff1a; 练习 id1 an…

wordpress使用popup弹窗插件的对比

您在寻找最好的 WordPress 弹出插件吗&#xff1f;大多数网站利用某种形状或形式的弹出窗口来将访问者指向他们希望他们去的地方。例如&#xff0c;这可能用于结帐、电子邮件订阅或用于生成潜在客户。 表现 弹出插件会减慢您的网站速度。当插件使用 WordPress 跟踪弹出窗口的…

《网络安全自学教程》- Nmap使用及扫描原理分析

《网络安全自学教程》 Nmap&#xff08;Network Mapper&#xff09;是一款免费的开源网络扫描器&#xff0c;向目标主机发送特定的数据包&#xff0c;根据返回的流量特征&#xff0c;分析主机信息。主要功能有&#xff1a;「端口扫描」、「主机探测」、「服务识别」和「系统识别…

数学建模算法与应用 第3章 非线性规划及其求解方法

目录 3.1 非线性规划概述 3.2 约束优化问题 3.3 无约束优化问题的Matlab求解 3.4 牛顿法与梯度下降法 Matlab代码示例&#xff1a;梯度下降法求解简单非线性问题 3.5 非线性规划在机器学习中的应用 习题 3 总结 非线性规划&#xff08;Nonlinear Programming, NLP&…

Vue3入门学习

Vue3入门学习 1. Vue3简介1.1. 【性能的提升】1.2.【 源码的升级】1.3. 【拥抱TypeScript】1.4. 【新的特性】 2. 创建Vue3工程2.1. 【基于 vue-cli 创建】2.2. 【基于 vite 创建】(推荐)2.3. 【一个简单的效果】 3. Vue3核心语法3.1. 【OptionsAPI 与 CompositionAPI】Options…

【源码+文档+调试讲解】二手物品调剂系统NODEJS

摘 要 二手物品调剂系统是一种在线平台&#xff0c;旨在促进用户之间的二手物品交易。该系统提供了一个方便的界面&#xff0c;让用户能够发布、浏览和搜索二手物品信息。用户可以根据自己的需求和兴趣&#xff0c;筛选出合适的物品&#xff0c;并通过系统与卖家进行联系。系统…

MES 系统在制造业数字化转型中的关键角色_SunMES

【大家好&#xff0c;我是唐Sun&#xff0c;唐Sun的唐&#xff0c;唐Sun的Sun。一站式数智工厂解决方案服务商】 在制造业数字化转型的宏大进程中&#xff0c;MES&#xff08;制造执行系统&#xff09;系统扮演着举足轻重的角色。 首先&#xff0c;MES 系统是数据采集与整合的…

QDateTime 使用详解

QDateTime 是 Qt 框架中用于处理日期和时间的类。本篇文章详细介绍、通过示例 快速了解QDateTime的各种操作&#xff0c;包括: 当前时间、获取日期和时间、获取日期、获取时间、获取时间戳、格式化输出、年、月、日、QTime时间、获取微妙、操作日期和时间、添加时间、减去时间、…

搭建 golang 项目的目录介绍及其用途对比表

文章目录 1.目录细则表2.目录使用说明及典型内容2.例 K8S 源码目录编排 1.目录细则表 常见 Go 项目目录的作用、典型内容、文件类型和使用场景~ 目录名作用/用途常见文件类型使用场景及详细说明典型内容举例cmd/存放可执行文件的入口点&#xff0c;通常为项目主程序入口或工具…

SAP_FI模块-公司间资产转移ABT1N操作

业务背景&#xff1a; 1、用户在OA走公司间资产的转移流程时&#xff0c;提示错误以下错误&#xff1b; 通过与OA开发的同事沟通发现&#xff0c;调用的接口是自开发的这个&#xff1a;ZFIF_AA_TRANSFER_POST&#xff0c;使用的是BDC录屏的方式&#xff0c;真正执行的事务码是A…

重学SpringBoot3-集成Redis(一)之基础功能

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 重学SpringBoot3-集成Redis&#xff08;一&#xff09;之基础功能 1. 项目初始化2. 配置 Redis3. 配置 Redis 序列化4. 操作 Redis 工具类5. 编写 REST 控制器6. 测试 AP…

DAMA数据管理知识体系(第12章 元数据管理)

课本内容 12.1 引言 图12-1 语境关系图&#xff1a;元数据概念理解 元数据的信息范围很广&#xff0c;不仅包括技术和业务流程、数据规则和约束&#xff0c;还包括逻辑数据结构与物理数据结构等。它描述了数据本身&#xff08;如数据库、数据元素、数据模型&#xff09;&#x…

MokeJs使用实例

文章目录 MokeJs使用实例介绍使用安装配置文件导入配置到main.js使用 axios 发送网络请求测试&#xff08;如果不会axios&#xff0c;具体可以见上篇文章axios&#xff09;启动示例 MokeJs使用实例 介绍 使用 安装 npm install mockjs --save-dev # 或者 yarn add mockj…

python画图|两个Y轴共享X轴

【1】引言 在前述学习中&#xff0c;对使用matplotlib模块输出图形已经非常熟练&#xff0c;但常见的画图方式并未穷尽&#xff0c;如两个Y轴共享X轴就没有探索过。 对此&#xff0c;我进行了一些学习&#xff0c;获得一些心得&#xff0c;在此和大家共享。 【2】官网教程 …

点评项目-4-隐藏敏感信息、使用 redis 优化登录业务

一、隐藏敏感信息 之前我们对 /user/me 路径&#xff0c;直接返回了登录的所有用户信息&#xff0c;其中的 passward 等敏感信息也会被返回到前端&#xff0c;这是很危险的&#xff0c;故我们需要选择性的返回用户信息&#xff0c;隐藏敏感用户信息 我们可以创建一个 UserDTO…