浅谈android add_service PERMISSION DENIED问题

背景:

在Android开发中,经常会用到ServiceManager.addService(name, service);添加系统服务
也许你会很迷惑,在程序运行时,部分service name能成功添加,而部分service name会抛出如下异常:


Tag: ServiceManager
Message: add_service('xxx',xx) uid=xxxx - PERMISSION DENIED

这是Android SELinux 的policy配置引起的,在读了部分SELinux的源码之后就很容易理解这个异常了
接下来我会先给出解决办法,然后再进行分析。

解决办法:

针对不同得设备,可以在device或vendor目录下的BoardConfig.mk中使用BOARD_SEPOLICY_DIRS变量指定配置文件的目录;
新的service_type定义在service.te中,对应该service_type的service name定义在service_contexts中。

注: service_manager 不能add default_android_service类型的service

例如:
针对samsung tuna设备:device/samsung/tuna/BoardConfig.mk

BOARD_SEPOLICY_DIRS += device/samsung/tuna/sepolicy

device/samsung/tuna/sepolicy/service.te

type yyy,           service_manager_type

device/samsung/tuna/sepolicy/service_contexts

xxx             u:object_r:yyy:s0

这样再使用ServiceManager.addService(“xxx”, this);添加系统服务就不会抛异常了。

分析:

service_manager初始化以及ServiceManager.addService(“xxx”, this);方法调用流程:
service_manager.c

static bool check_mac_perms_from_lookup(pid_t spid, uid_t uid, const char *perm, const char *name)
{
    ...
    if (selabel_lookup(sehandle, &tctx, name, 0) != 0) {    //libselinux/src/label.c : selabel_lookup()
                                                            //service name 会在该函数中进行匹配
        ALOGE("SELinux: No match for %s in service_contexts.\n", name);
        return false;
    }
    ...
}

static int svc_can_register(const uint16_t *name, size_t name_len, pid_t spid, uid_t uid)
{
    const char *perm = "add";
    return check_mac_perms_from_lookup(spid, uid, perm, str8(name, name_len)) ? 1 : 0;
}

int do_add_service(struct binder_state *bs,
                   const uint16_t *s, size_t len,
                   uint32_t handle, uid_t uid, int allow_isolated,
                   pid_t spid)
{
    ...
    i
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值