//include/linux/types.h
struct hlist_head {
struct hlist_node *first;
};
//lsm_hooks.h
struct security_hook_heads {
struct hlist_head binder_set_context_mgr;
struct hlist_head binder_transaction;
struct hlist_head binder_transfer_binder;
...
struct hlist_head secid_to_secctx; // Entry point for the secid_to_secctx linked list
struct hlist_head file_permission; // Entry point for checking file permissions
struct hlist_head inode_permission; // Entry point for checking inode permissions
struct hlist_head task_alloc; // Entry point for checking process creation
...
};
//security.c
//declare global variable
struct security_hook_heads security_hook_heads;
//lsm_hooks.h
struct security_hook_list {
struct hlist_node list;
struct hlist_head *head;
union security_list_options hook;
const char *lsm;
};
//selinux/hooks.c
static struct security_hook_list selinux_hooks[] = {
LSM_HOOK_INIT(binder_set_context_mgr, selinux_binder_set_context_mgr),
LSM_HOOK_INIT(binder_transaction, selinux_binder_transaction),
LSM_HOOK_INIT(binder_transfer_binder, selinux_binder_transfer_binder),
LSM_HOOK_INIT(binder_transfer_file, selinux_binder_transfer_file),
...
LSM_HOOK_INIT(secid_to_secctx, selinux_secid_to_secctx),
...
}
******** selinux_init ********
//include/linux/lsm_hooks.h
#define LSM_HOOK_INIT(HEAD, HOOK) \
{ .head = &security_hook_heads.HEAD, .hook = { .HEAD = HOOK } }
//selinux/hooks.c
//run LSM_HOOK_INIT(secid_to_secctx, selinux_secid_to_secctx)
#define LSM_HOOK_INIT(HEAD, HOOK) \
{ \
.head = &security_hook_heads.secid_to_secctx, \
.hook = { .secid_to_secctx = selinux_secid_to_secctx } \
}
selinux_hooks[202] = {
.head = &security_hook_heads.secid_to_secctx,
.hook = { .secid_to_secctx = selinux_secid_to_secctx },
.lsm = NULL, // not yet initialized
.list = { .next = NULL, .pprev = NULL } // not yet load
};
//selinux/hooks.c
static __init int selinux_init(void) {
....
security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks), "selinux");
....
}
//security.c
void __init security_add_hooks(struct security_hook_list *hooks, int count, const char *lsm)
{
int i;
for (i = 0; i < count; i++) {
hooks[i].lsm = lsm;
hlist_add_tail_rcu(&hooks[i].list, hooks[i].head);
}
...
}
//include/linux/rculist.h
static inline void hlist_add_tail_rcu(struct hlist_node *n, struct hlist_head *h)
{
struct hlist_node *i, *last = NULL;
for (i = h->first; i; i = i->next)
last = i;
if (last) {
n->next = last->next;
WRITE_ONCE(n->pprev, &last->next);
rcu_assign_pointer(hlist_next_rcu(last), n);
} else {
//hlist_add_head_rcu(n, h);
struct hlist_node *first = h->first;
n->next = first;
WRITE_ONCE(n->pprev, &h->first);
rcu_assign_pointer(hlist_first_rcu(h), n);
if (first)
WRITE_ONCE(first->pprev, &n->next);
}
}
//after security_add_hooks cause result 1
selinux_hooks[202] = {
.head = &security_hook_heads.secid_to_secctx,
.hook = { .secid_to_secctx = selinux_secid_to_secctx },
.lsm = "selinux",
.list = {
.next = NULL, .pprev = &security_hook_heads.secid_to_secctx.first
}
};
//security.c
//after security_add_hooks cause result 2
security_hook_heads.secid_to_secctx.first = &selinux_hooks[202].list;
******** get secctx ********
//binder.c
static void binder_transaction(...) {
...
security_secid_to_secctx(secid, &secctx, &secctx_sz);
...
}
//security.c
int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
{
struct security_hook_list *hp;
int rc;
/*hlist_for_each_entry(hp, &security_hook_heads.secid_to_secctx, list) {
rc = hp->hook.secid_to_secctx(secid, secdata, seclen);
if (rc != LSM_RET_DEFAULT(secid_to_secctx))
return rc;
}*/
for (hp = hlist_entry_safe((&security_hook_heads.secid_to_secctx)->first, struct security_hook_list, list);
hp != NULL;
hp = hlist_entry_safe((hp)->list.next, struct security_hook_list, list))
{
rc = hp->hook.secid_to_secctx(secid, secdata, seclen);
if (rc != LSM_RET_DEFAULT(secid_to_secctx))
return rc;
}
return LSM_RET_DEFAULT(secid_to_secctx);
}
secctx = "u:r:untrusted_app:s0:c164,c512"
沒有留言:
張貼留言