zoukankan      html  css  js  c++  java
  • Android下添加自启动应用

    1. 介绍

    这里介绍的是基于开启selinux的Android 4.4及以上版本添加自启用应用的方法

    2. 关于selinux

    Android下的selinux被称为SEAndroid, 其原理可以参考Linux下的selinux, 这里不详细介绍

    3. 为sshd添加自启动

    在前面文章<Android上sshd的使用>中, 笔者为sshd添加自启动由于selinux的存在一直失败
    这里作为一个补充为sshd添加seplicy以保证能成功启动

    3.1 修改init.rc

    对于CM, 其init.rc位于/system/core/rootdir/目录下
    笔者这里不使用启动start-sshd脚本的方法, 而直接启动应用程序,
    在init.rc将sshd启动配置修改如下

    service sshd /system/bin/sshd -f /system/etc/ssh/sshd_config -D
        class main
        user  root
        oneshot

    3.2 添加sshd.te文件

    为sshd定义sepolicy

    Android默认的sepolicy位于external/sepolicy/
    而厂商自定义sepolicy通常位于devices/platform/platform-sub/sepolicy/
    对于i9100, 位于device/samsung/galaxys2-common/selinux

    对于CM, 我们添加到external/sepolicy/目录下即可
    sshd.te内容如下, 这里只是申明, 并没有规则

    # sshd daemon
    type sshd, domain;
    type sshd_exec, exec_type, file_type;
    init_daemon_domain(sshd)

    同时要保证sshd.te文件要编译到sepolicy中, 部分系统可能需要修改external/sepolicy/Android.mk
    将sshd.te加入BOARD_SEPOLICY_UNION中
    笔者使用的CM会自动添加external/sepolicy/*.te, 故只要添加文件即编译到sepolicy中

    3.3 修改file_contexts

    file_contexts位于external/sepolicy/目录下, 厂商同样也有自定义该
    该文件通过正则表达式来描述系统文件的安全上下文

    为sshd加入如下内容

    /system/bin/sshd     u:object_r:sshd_exec:s0
    ...
    /data/ssh(/.*)?	u:object_r:sshd_data_file:s0
    

    上面的内容将sshd定义为sshd_exec文件类型, 将sshd配置文件设置为sshd_data_file类型

    同时修改external/sepolicy/file.te, 定义sshd_data_file类型

    # /data/ssh - sshd conf files
    type sshd_data_file, file_type, data_file_type;

    3.4 修改selinux模式

    在CentOS中selinux有如下三种模式

    # SELINUX= can take one of these three values:
    #     enforcing  - SELinux security policy is enforced.
    #     permissive - SELinux prints warnings instead of enforcing.
    #     disabled   - No SELinux policy is loaded.

    而在Android中则精简为enforcing (1)和permissive (0)两种模式
    enforcing模式会严格执行权限操作, 一旦越权则禁止运行; permissive则只是记录行为, 并不终止运行
    我们的目的是为了让sshd工作在enforcing模式下, 这里先设置为permissive模式
    selinux相关命令如下

     # getenforce
    Enforcing
    # setenforce 0
    # getenforce
    Permissive

    但是上面的命令只能临时生效, 重启后就恢复为默认的模式(enforcing)
    所以我们需要编译出默认就是permissive模式的Android版本, 方法有下面两种

    3.4.1 通过脚本设置selinux模式

    参考<Set Selinux to permissive on boot>的做法
    写一个脚本, 在脚本中设置selinux模式, 放在init.d或者su.d目录下, 让init或者su在启动时执行
    笔者没有使用该方法, 因为感觉对sshd不一定起作用, 而且这也不是标准做法

    3.4.2 配置默认selinux模式

    在参考<Disabling SELinux in Android 5.0.1>了解到
    selinux由init进程(system/core/init/init.cpp)来初始化, 调用时序为

    main() -> selinux_initialize() -> selinux_is_disabled()/selinux_is_enforcing()
    -> ALLOW_DISABLE_SELINUX -> selinux_status_from_cmdline()

    其中ALLOW_DISABLE_SELINUX宏来判断selinux是否允许被禁用(包括disable和permissive), 否则后面不用再进行判断
    ALLOW_DISABLE_SELINUX是在编译时就制定, 位于system/core/init/Android.mk(userdebug和eng为1)

    selinux_status_from_cmdline()通过读取内核传递的命令行中androidboot.selinux的值来判断selinux模式
    判读依据为disabled和permissive或其他

    在笔者的Android上, 命令行参数如下

    # cat /proc/cmdline
    console=ttySAC2,115200 consoleblank=0 androidboot.hardware=smdk4210 loglevel=4 console=ram sec_debug.enable=0 sec_debug.enable_user=0 c1_watchdog.sec_pet=5 sec_log=0x100000@0x4d900000 s3cfb.bootloaderfb=0x5ec00000 ld9040.get_lcdtype=0x2 consoleblank=0 lpj=3981312 vmalloc=144m
    

    那么我们可以配置内核命令行参数来控制selinux的默认模式
    内核命令行参数是在编译时通过BOARD_KERNEL_CMDLINE来指定
    笔者使用的i9100中该值位于 device/samsung/galaxys2-common/BoardCommonConfig.mk
    找到对应位置在后面加上androidboot.selinux=permissive

    3.5 编译Android

    在上面的修改之后, 重新编译Android

    笔者使用lunch xxx命令重新编译升级后发现selinux仍然是enforcing模式
    通过/proc/cmdline获取内核命令发现并没有生效
    查看编译中间件$PACKG/BOOT/cmdline, $PACKG/BOOT/cmdline也是如此
    $PACKG = out/target/product/i9100/obj/PACKAGING/target_files_intermediates/
    于是笔者删除$PACKG目录下的所有内容, 再次编译升级

    这次仍然没有成功, 也不清楚是什么原因, 这卧槽谁受得了
    懒得去折腾了, 修改selinux_is_enforcing()函数直接返回SELINUX_PERMISSIVE

    3.6 sshd权限

    3.6.1 截取avc log

    此时sshd应该已经成功启动, 为了查看所有sshd需要的权限, 使用ssh client进行一次连接
    同时连接sftp及scp,  传递文件等动作

    然后通过logcat截取log, 然后找到所有sshd相关的log

    12-13 19:28:25.050  2009  2009 I sshd    : type=1400 audit(0.0:15): avc: denied { 
    open
     } for name="ssh_host_rsa_key" dev=mmcblk0p10 ino=49165 scontext=u:r:
    sshd
    :s0 tcontext=u:object_r:
    system_data_file
    :s0 tclass=
    file
     permissive=1

    3.6.2 生成规则

    对照被deny的项目可以按照如下方法来生产规则

             scontext   tcontext        tclass   avc denied
     allow   
    sshd system_data_file: file  open

    网上称使用audit2allow工具可以批量生成规则
    由于在我的CentOS 7上一直提示指定policy文件, 不深究

    3.6.3 添加规则

    将所有生成的规则加入到sshd.te中, 然后重新编译升级

    sshd.te文件内容如下

    # sshd daemon
    type sshd, domain; type sshd_exec, exec_type, file_type; #init_daemon_domain(sshd) net_domain(sshd) allow sshd self:capability { setuid setgid net_admin net_raw net_bind_service }; allow sshd sshd_exec:file execute_no_trans; allow sshd sshd_data_file:file { open read create getattr setattr append write link unlink rename }; allow sshd sshd_data_file:dir { create setattr add_name remove_name rmdir rename }; allow sshd ptmx_device:chr_file { open read write ioctl getattr setattr }; allow sshd devpts:chr_file { open read write ioctl getattr setattr }; allow sshd shell_exec:file rx_file_perms; allow sshd system_file:file rx_file_perms;

    上面的方法在一定程度上适用, 但部分功能仍然受限制
    不折腾了, init.cpp中的修改已经完全够用了

    4. 应用层的自启动

    上面的自启动是基于C或者说底层的自启动,下面介绍一种在应用层面或者Java层面的自启动方法

    具体<How to Start an Application at Device Bootup in Android>

    参考:
    <android init.rc文件语法详解>
    <深入理解SELinux SEAndroid>
    <Android 5.x 权限问题解决方法>
    <android中SELINUX规则分析和语法简介>
    <Android 4.0及以上版本接收开机广播BOOT_COMPLETED、开机自启动服务>

     
  • 相关阅读:
    狗狗急性肠胃炎
    shell change password
    男职工为什么要交生育保险
    预扣预缴个税
    转《最优状态机》
    状态机编程-队列缓冲事件,事件可异步触发
    max713镍氢电池充电管理IC
    NUP2201MR
    LSP5513
    74HC14D(6反向施密特触发器)
  • 原文地址:https://www.cnblogs.com/wangzhe1635/p/8675989.html
Copyright © 2011-2022 走看看