当前位置:   article > 正文

SElinux init.rc 赋予 脚本执行权限_怎么在rc中设置文件的权限

怎么在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
  • 1
  • 2
  • 3

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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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

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

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

其实这里赋予了权限并没有什么用,这里也是转载网上的
为什么?接着查,在查看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, },
    ......
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

/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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

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();
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

这个函数的实现也在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都改好了,现在就可以编译源码了,编译好了装到机子开发板上就可以了。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/318959
推荐阅读
相关标签
  

闽ICP备14008679号