SEAndroid kernel层源码解析1——从hook点到策略点

xiaoxiao2021-02-28  110

从hook点到策略点

SEAndroid 利用LSM模块实施MAC访问控制,LSM模块在内核中设置很多的hook点,对资源的访问会重定向到SElinux的函数策略执行函数,接下来以create_socket为例,分析从hook点到策略点的流程: /goldfish/net/socket.c

static int _sock_create(struct net *net,int family, int type, int protocol,struct socket **res,int kern) { ... //此处为hook点,进行MAC访问控制检查 err=security_socket_create(family, type,protocol,kerm); //err为1,则权限检查的结果为denied if(err) return err; ... }

security_socket_create函数的声明如下: /goldfish/include/linux/security.h int security_socket_create(int family, int type, int protocol, int kern);

security_socket_create函数的实现如下: /goldfish/security/security.c

... struct security_operations *security_ops; ... int security_socket_create(int family, int type, int protocol, int kern) { return security_ops->socket_create(family, type, protocol, kern); }

security_operation 是一个结构体,里面都是函数指针,指向执行hook点对应的权限检查函数,定义如下: /goldfish/include/linux/security.h

struct security_operation{ char name[SECURITY_NAME_MAX+1]; ... int(*socket_create)(int family,int type,int protocol,int kern); ... };

结构体security_operations 初始化 /goldfish/security/security.c 定义了 default_security_ops 并进行初始化

int __init security_init(void) { ... security_fixup_ops(&default_security_ops); ... }

/goldfish/security/capability.c

void security_fixup_ops(struct security_operations *ops) { ... set_to_cap_if_null(ops,socket_create); ... }

set_to_cap_if_null 是一个宏(定义在capability.c中),将 default_security_operations->socket_create 指向函数cap_socket_create /goldfish/security/capability.c

static int cap_socket_create(struct socket *sock,int family,int type,int protocol,int kern) { return 0; }

此时,初始化完成之后并未启动selinux,hook处的函数

err=security_socket_create(family, type,protocol,kerm);

的返回值为0( 没有错误,即权限检查通过 ),并未执行任何策略检查


接下来继续分析selinux启动,从之上的分析可以得出,要想启动selinux,执行对应的MAC策略,只需要对security_operations结构体的内容进行重新赋值,使之指向对应的selinux策略检查函数即可 /goldfish/security/selinux/hooks.c

extern struct security_operations *security_ops; static __init int selinux_init(void) { ... secondary_ops = security_ops; if (!secondary_ops) panic("SELinux: No initial security operations\n"); if (register_security(&selinux_ops)) panic("SELinux: Unable to register with kernel.\n"); ... } static struct security_operations selinux_ops = { .name = "selinux", ... .socket_create = selinux_socket_create, ... };

selinux_init 中有对是否启动selinux的检查,有机会之后再讨论,然后检查security_ops (extern) 是否初始化,然后执行register_security 将selinux_ops 注册 /goldfish/security/security.c

int register_security(struct security_operations *ops) { ... security_ops=ops; ... }

执行注册之后,再次从hook点重定向之后会执行selinux_socket_create /goldfish/security/selinux/hooks.c

static int selinux_socket_create(int family, int type, int protocol, int kern) { const struct cred *cred = current_cred(); const struct task_security_struct *tsec = cred->security; u32 sid, newsid; u16 secclass; int err = 0; if (kern) goto out; sid = tsec->sid; newsid = tsec->sockcreate_sid ?: sid; secclass = socket_type_to_security_class(family, type, protocol); err = avc_has_perm(sid, newsid, secclass, SOCKET__CREATE, NULL); out: return err; }

这里将会执行到avc_has_perm,进行真正的MAC策略检查,具体流程后续会再分析。


源码版本为android-goldfish-2.6.29


如有错误,环境指正

转载请注明原文地址: https://www.6miu.com/read-31786.html

最新回复(0)