为Android应用程序读取/dev下设备而提权(二)
在 为Android应用程序读取/dev下设备而提权(一)
中,简单总结了提权的两种方法:
device_init
和
init.rc
。在此篇文章中,我将详细总结的是稍一不留神,就容易把人弄晕乎的
init.c
、device_init和init.rc 三者之间的关系,TA们到底是如何工作的。
目录结构
ls一下system/core/init/
devices.c、devices.h、init.c、init.h、keywords.h、parser.c、property_service.c....
另外system/core/rootdir/init.rc ,当然init.rc的位置可以另行指定。
init流程
init过程的起点是init.c :
*注释中的序号表示执行顺序
- int main(int argc, char **argv)
- {
- … …
- mkdir("/dev", 0755);
- mkdir("/proc", 0755);
- mkdir("/sys", 0755);
- mount("tmpfs", "/dev", "tmpfs", 0, "mode=0755");
- mkdir("/dev/pts", 0755);
- mkdir("/dev/socket", 0755);
- mount("devpts", "/dev/pts", "devpts", 0, NULL);
- mount("proc", "/proc", "proc", 0, NULL);
- mount("sysfs", "/sys", "sysfs", 0, NULL);
- … …
- INFO("reading config file\n");
- parse_config_file("/init.rc");
-
- action_for_each_trigger("early-init", action_add_queue_tail);
- drain_action_queue();
- … …
- INFO("device init\n");
- device_fd = device_init();
- property_init();
-
- action_for_each_trigger("init", action_add_queue_tail);
- drain_action_queue();
- … …
- }
system/core/init/parser.c:
- static void parse_config(const char *fn, char *s)
- {
- struct parse_state state;
- char *args[MAXARGS];
- int nargs;
-
- nargs = 0;
- state.filename = fn;
- state.line = 1;
- state.ptr = s;
- state.nexttoken = 0;
- state.parse_line = parse_line_no_op;
- for (;;) {
- switch (next_token(&state)) {
- case T_EOF:
- state.parse_line(&state, 0, 0);
- return;
- case T_NEWLINE:
- if (nargs) {
- int kw = lookup_keyword(args[0]);
- if (kw_is(kw, SECTION)) {
- state.parse_line(&state, 0, 0);
- parse_new_section(&state, kw, nargs, args);
- } else {
- state.parse_line(&state, nargs, args);
- }
- nargs = 0;
- }
- break;
- case T_TEXT:
- if (nargs < MAXARGS) {
- args[nargs++] = state.text;
- }
- break;
- }
- }
- }
-
-
- void parse_new_section(struct parse_state *state, int kw,
- int nargs, char **args)
- {
- printf("[ %s %s ]\n", args[0],
- nargs > 1 ? args[1] : "");
- switch(kw) {
- case K_service:
- state->context = parse_service(state, nargs, args);
- if (state->context) {
- state->parse_line = parse_line_service;
- return;
- }
- break;
- case K_on:
- state->context = parse_action(state, nargs, args);
- if (state->context) {
- state->parse_line = parse_line_action;
- return;
- }
- break;
- }
- state->parse_line = parse_line_no_op;
- }
本章小结
经过上面的分析,对/dev/设备权限的修改放在不同的位置会有覆盖的效果,device.c内的修改会覆盖early-init段内的命令,init 段内的命令会覆盖device.c中的修改,如果3个位置都有对用一个设备权限的修改,那init段的修改会最终生效。