SElinux init.rc 赋予 脚本执行权限

我们前面看到了,可以编写自己的 .te 文件, 定义自己的类型。
目标案例可以参考, 高通或者 mtk 平台下自带的 system\core\init\readme.txt

一、 init.rc

1.1 如何写服务

在android源码根目录下有android/system/core/rootdir/init.rc文件, 有很多地方都有
.rc 文件, 类似 init.target.rc init.usb.rc init.environ.rc.in

注:每个设备下都会有自己对应的init.rc,init.设备名.rc脚本文件

init.rc 该脚本文件中有很多 服务权限的赋予,定义等等,

假设我现在写了一个脚本 my.sh 那么,我需要赋予它权限的,所以就可以在 init.rc 中去定义和赋予

service  usblp_test  /data/setip/my.sh
oneshot
disabled

oneshot disabled向我们说明了在系统启动的时候这个服务是不会自动启动的,并且该服务的目的是执行/data/setip/init.usblpmod.sh脚本。脚本的内容你可以随便写,只要符合shell语法就可以了

这里。我后面会好好 总结一下 一些 sh脚本的用法等等

书写完 sh 脚本后,需要编译进 android 系统中 比如 system/bin vender/

(1)有几种在模块中的 mk文件中, 要看这个sh是为哪个模块工作的
编译进 system

include $(CLEAR_VARS)
LOCAL_MODULE := my.sh
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := EXECUTABLES
LOCAL_SRC_FILES := assets/my.sh
LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_EXECUTABLES)
include $(BUILD_PREBUILT)

(2)再就是编译的时候 copy file 了

前面是文件源路径,后面的是目的路径
PRODUCT_COPY_FILES += \
        device/xx/xx/etc/my.sh:system/etc/my.sh

1.2 添加 服务

添加启动动作,使Android在启动时候执行。

init.rc文件末尾处加入以下内容

service mount-usbfs /system/etc/usbfs.sh
    class main
    user root
    group root
    oneshot

chown root shell /system/etc/usbfs.sh
chmod 0550 /system/etc/usbfs.sh

其实这里赋予了权限并没有什么用,这里也是转载网上的
为什么?接着查,在查看init.rc的过程中,发现了以下内容:

mount ext4 ext4@system /system ro 原来system分区是以只读的形式进行挂载的,忽略这点了。以只读形式挂载,再怎么赋权限,也是徒劳啊
那为什么相同目录下的 其他sh可以

6.0 /android/system/core/include/private/android_filesystem_config.h
这里定义的,谁对应的谁 比如: AID_SYSTEM - “system”

    #define AID_ROOT             0  /* traditional unix root user */
    #define AID_SYSTEM        1000  /* system server */

    #define AID_RADIO         1001  /* telephony subsystem, RIL */
    #define AID_BLUETOOTH     1002  /* bluetooth subsystem */
    #define AID_GRAPHICS      1003  /* graphics devices */
    #define AID_INPUT         1004  /* input devices */
    #define AID_AUDIO         1005  /* audio devices */
    #define AID_CAMERA        1006  /* camera devices */
    #define AID_LOG           1007  /* log devices */
    #define AID_COMPASS       1008  /* compass device */
    #define AID_MOUNT         1009  /* mountd socket */
    #define AID_WIFI          1010  /* wifi subsystem */


  static const struct android_id_info android_ids[] = {

    { "root",          AID_ROOT, },
    { "system",        AID_SYSTEM, },
    { "radio",         AID_RADIO, },
    { "bluetooth",     AID_BLUETOOTH, },
    { "graphics",      AID_GRAPHICS, },
    { "input",         AID_INPUT, },
    { "audio",         AID_AUDIO, },
    { "camera",        AID_CAMERA, },
    { "log",           AID_LOG, },
    { "compass",       AID_COMPASS, },
    { "mount",         AID_MOUNT, },
    ......

/android/system/core/libcutils/fs_config.c 有对他的定义, 这里就定义了哪些sh 属于哪个权限组了

....
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
#include <private/android_filesystem_config.h>
....


static const struct fs_path_config android_dirs[] = {
    { 00770, AID_SYSTEM, AID_CACHE,  0, "cache" },
    { 00771, AID_SYSTEM, AID_SYSTEM, 0, "data/app" },
    { 00771, AID_SYSTEM, AID_SYSTEM, 0, "data/app-private" },
    { 00771, AID_ROOT,   AID_ROOT,   0, "data/dalvik-cache" },
    { 00771, AID_SYSTEM, AID_SYSTEM, 0, "data/data" },
    { 00771, AID_SHELL,  AID_SHELL,  0, "data/local/tmp" },
    { 00771, AID_SHELL,  AID_SHELL,  0, "data/local" },
    { 01771, AID_SYSTEM, AID_MISC,   0, "data/misc" },
    { 00770, AID_DHCP,   AID_DHCP,   0, "data/misc/dhcp" },
    { 00771, AID_SHARED_RELRO, AID_SHARED_RELRO, 0, "data/misc/shared_relro" },
    { 00775, AID_MEDIA_RW, AID_MEDIA_RW, 0, "data/media" },
    { 00775, AID_MEDIA_RW, AID_MEDIA_RW, 0, "data/media/Music" },
    { 00771, AID_SYSTEM, AID_SYSTEM, 0, "data" },
    { 00750, AID_ROOT,   AID_SHELL,  0, "sbin" },
    { 00755, AID_ROOT,   AID_SHELL,  0, "system/bin" },
    { 00755, AID_ROOT,   AID_SHELL,  0, "system/vendor" },
    { 00755, AID_ROOT,   AID_SHELL,  0, "system/xbin" },
    { 00755, AID_ROOT,   AID_ROOT,   0, "system/etc/ppp" },
    { 00755, AID_ROOT,   AID_SHELL,  0, "vendor" },
    { 00777, AID_ROOT,   AID_ROOT,   0, "sdcard" },
    { 00755, AID_ROOT,   AID_ROOT,   0, 0 },



static const struct fs_path_config android_files[] = {
    { 00440, AID_ROOT,      AID_SHELL,     0, "system/etc/init.goldfish.rc" },
    { 00550, AID_ROOT,      AID_SHELL,     0, "system/etc/init.goldfish.sh" },
    { 00771, AID_ROOT,      AID_SHELL,    0,   "system/bin/atmel_ts.sh" },
    { 00550, AID_ROOT,      AID_SHELL,     0, "system/etc/init.ril" },
    { 00550, AID_DHCP,      AID_SHELL,     0, "system/etc/dhcpcd/dhcpcd-run-hooks" },
    { 00555, AID_ROOT,      AID_ROOT,      0, "system/etc/ppp/*" },
    { 00555, AID_ROOT,      AID_ROOT,      0, "system/etc/rc.*" },
    { 00444, AID_ROOT,      AID_ROOT,      0, conf_dir + 1 },
    { 00444, AID_ROOT,      AID_ROOT,      0, conf_file + 1 },
    { 00644, AID_SYSTEM,    AID_SYSTEM,    0, "data/app/*" },
    { 00644, AID_MEDIA_RW,  AID_MEDIA_RW,  0, "data/media/*" },
    { 00644, AID_SYSTEM,    AID_SYSTEM,    0, "data/app-private/*" },
    { 00644, AID_APP,       AID_APP,       0, "data/data/*" },

1)首先了解下在服务启动的流程

  1. 在你的应用中让init.rc中添加的服务启动起来。
    首先了解下在服务启动的流程:
    在设备目录下的init.c(切记并不是system/core/init/init.rc)

Main函数的for(;;)循环中有一个handle_property_set_fd(),函数:

  for (i = 0; i < fd_count; i++) {
        if (ufds[i].revents == POLLIN) {
            if (ufds[i].fd == get_property_set_fd())
                handle_property_set_fd();
            else if (ufds[i].fd == get_keychord_fd())
                handle_keychord();
            else if (ufds[i].fd == get_signal_fd())
                handle_signal();
        }
    }

这个函数的实现也在system/core/init目录下,该函数中的check_control_perms(msg.value, cr.uid, cr.gid)函数就是检查该uid是否有权限启动服务(msg.value就是你服务的名字),如果应用为root或system用户则直接返回1.之后就是调用handle_control_message((char*) msg.name + 4, (char*) msg.value),该函数的参数就是去掉1.ctl.后的start和2.你服务的名字。这个函数的详细内容:

void handle_control_message(const char *msg, const char *arg)
{
if (!strcmp(msg,”start”)) {
msg_start(arg);
} else if (!strcmp(msg,”stop”)) {
msg_stop(arg);
} else if (!strcmp(msg,”restart”)) {
msg_stop(arg);
msg_start(arg);
} else {
ERROR(“unknown control msg ‘%s’\n”, msg);
}
}

匹配start后调用msg_start.服务就这样起来了,我们的解决方案就是在检查权限的地方“下点功夫”,因为我们不确定uid,所以就让check_control_perms这个函数不要检查我们的uid,直接检查我们服务的名字,看看这个函数:

static int check_control_perms(const char *name, unsigned int uid, unsigned int gid) {
int i;
if (uid == AID_SYSTEM || uid == AID_ROOT)
return 1;
/* Search the ACL */
for (i = 0; control_perms[i].service; i++) {
if (strcmp(control_perms[i].service, name) == 0) {
if ((uid && control_perms[i].uid == uid) ||
(gid && control_perms[i].gid == gid)) {
return 1;
}
}
}
return 0;
}

这个函数里面是必须要检查uid的,我们只要在for循环上写上。
if(strcmp(“usblp_test”,name)==0) //usblp_test就是我们服务的名字。
return 1;

这样做不会破坏android原本的结构,不会有什么副作用。

init.c和init.rc都改好了,现在就可以编译源码了,编译好了装到机子开发板上就可以了。

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
课程简述  Android是目前最为流行的移动操作系统之一,它的开发涉及到多个知识领域。本课程将深入介绍Android系统启动过程的重要组成部分——init进程,并探讨与之相关的多项关键技术。我们还将提供实际的开发案例,以RK3399开发板为例,通过演示Android产品配置、init启动流程、selinux权限管理、init.rc启动脚本定制等实际案例,让学员深入理解这些技术在实际产品开发的应用场景和实现方法,提高学员的实际开发能力和经验,从而更好地应对实际产品开发遇到的问题和挑战。知识运用方向学习Android启动方面的知识,可以参与如下实际开发工作项:启动流程定制: 根据产品需求调整Android启动流程,包括修改init.rc脚本、修改启动顺序和等待时间、加入自定义服务等。属性系统定制: 通过Android属性系统定制化启动流程,例如增加产品版本信息、定制开机音量等。日志系统分析: 掌握日志的捕捉、分析和排错技术,在启动过程,需要加入调试信息来方便开发人员进行调试,同时需要进行日志的优化,避免日志输出过多占用过多的系统资源。selinux安全策略定制:在Android系统selinux是一种安全机制,用于保护系统的敏感资源和数据。在实际开发,可能需要对selinux策略进行定制,以确保系统的安全性和稳定性。课程内容主要内容简述1, RK3399 开发板操作这部分内容重点介绍如何在FIreFly开发板上将Android 10系统运行起来, 包含编译FireFly的Android源码下载和编译, 镜像烧录运行,内核和模块编译,以及RK3399内核启动init进程的过程。2, 产品定制这部分讲解获取到方案商或者原厂提供的源码后, 如何定制一个新的产品,产品配置文件和模型, 原始代码的配置文件和定制化东西3, Android日志代码编写之前讲过Android的日志系统, 并没涉及到代码编写, 这个部分重点讲解C/C++, java代码编写日志的API和代码4, 属性系统在Android,属性使用的非常频繁的,可以用来作为进程间通信,也可以用于一些行为控制, 这个部分会重点介绍属性系统框架, API接口, 属性文件等知识点5,selinux进程对文件进行访问时,Android 4.3就开始集成了selinux权限管控, 如果需要启动某个脚本或者服务, selinux的配置就避免不了,并且Android8之后, Android系统对进程访问的权限管控的非常严格。6, init.rc脚本Android定义的一种脚本, 改脚本是有init进程启动, 是非常重要的一个脚本, 会包含系统的其他很多脚本, 在我们系统开发时, 我们经常通过这个脚本进行一些定制化动作。7, init进程代码分析想要了解一个系统,就必须对源码进行分析和理解, 这个章节,带大家去跟读init进程代码, 这样,换了另外一个Android版本,完全就可以去读代码, 知道有什么变化。 

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

空白的泡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值