#+OPTIONS: toc:nil num:nil timestamp:nil ^:nil <:nil #+TITLE: UOS LSM Hook Manager =Kernel LSM= 中提供了大量常用操作的 =hook= ,可以让开发者在这些操作执行前进行检查,便于对程序进行管控。 但由于 =LSM Module= 必须编译进内核,因此需要公开源码,这通常不符合很多开发者的要求。 基于这种情况, =uos= 基于 =LSM= 开发了一个 =hook manager= 的模块,可提供接口给开发者使用,达到了动态注册/移除 =LSM Hook= 的目的。 ** 接口描述 由于 =LSM= 提供的接口太多,有些接口基本上很少使用,因此 =uos= 经过调研, =hook manager= 计划部分接口的动态注册/移除的功能,接口说明和 =hook= 列表如下: #+BEGIN_SRC c enum UOS_HOOK_LIST { UOS_PATH_UNLINK, UOS_PATH_MKDIR, UOS_PATH_RMDIR, UOS_PATH_MKNOD, UOS_PATH_TRUNCATE, UOS_PATH_SYMLINK, UOS_PATH_LINK, UOS_PATH_RENAME, UOS_PATH_CHMOD, UOS_PATH_CHOWN, UOS_PATH_CHROOT, UOS_INODE_CREATE, UOS_INODE_FREE_SECURITY, UOS_INODE_FREE, UOS_INODE_UNLINK, UOS_INODE_SYMLINK, UOS_INODE_MKDIR, UOS_INODE_RMDIR, UOS_INODE_MKNOD, UOS_INODE_RENAME, UOS_INODE_READLINK, UOS_INODE_FOLLOW_LINK, UOS_INODE_PERMISSION, UOS_INODE_SETATTR, UOS_INODE_SETXATTR, UOS_INODE_REMOVEEXATTR, UOS_FILE_PERMISSION, UOS_FILE_IOCTL, UOS_MMAP_ADDR, UOS_MMAP_FILE, UOS_FILE_LOCK, UOS_FILE_FCNTL, UOS_FILE_RECEIVE, UOS_FILE_OPEN, UOS_FILE_FREE_SECURITY, UOS_BPRM_SET_CREDS, UOS_BPRM_CHECK_SECURITY, UOS_BPRM_COMMITTING_CREDS, UOS_BPRM_COMMITTED_CREDS, UOS_TASK_ALLOC, UOS_TASK_FREE, UOS_TASK_FIX_SETUID, UOS_TASK_SETPGID, UOS_TASK_GETPGID, UOS_TASK_GETSID, UOS_TASK_SETNICE, UOS_TASK_SETIOPRIO, UOS_TASK_GETIOPRIO, UOS_TASK_PRLIMIT, UOS_TASK_SETRLIMIT, UOS_TASK_SETSCHEDULER, UOS_TASK_GETSCHEDULER, UOS_TASK_MOVEMEMORY, UOS_TASK_KILL, UOS_TASK_PRCTL, UOS_SOCKET_CREATE, UOS_SOCKET_POST_CREATE, UOS_SOCKET_SOCKETPAIR, UOS_SOCKET_BIND, UOS_SOCKET_CONNECT, UOS_SOCKET_LISTEN, UOS_SOCKET_ACCEPT, UOS_SOCKET_SENDMSG, UOS_SOCKET_RECVMSG, UOS_SOCKET_GETSOCKNAME, UOS_SOCKET_GETPEERNAME, UOS_SOCKET_GETSOCKOPT, UOS_SOCKET_SETSOCKOPT, UOS_SOCKET_SHUTDOWN, UOS_TUN_DEV_CREATE, UOS_TUN_DEV_ATTACH_QUEUE, UOS_TUN_DEV_ATTACH, UOS_TUN_DEV_OPEN, UOS_SCTP_ASSOC_REQUEST, UOS_SCTP_BIND_CONNECT, UOS_NETLINK_SEND, UOS_SB_REMOUNT, UOS_SB_SHOW_OPTIONS, UOS_SB_STATFS, UOS_SB_MOUNT, UOS_SB_UMOUNT, UOS_SB_SET_MNT_OPTS, UOS_SB_CLONE_MNT_OPTS, UOS_SHM_ASSOCIATE, UOS_SHM_SHMCTL, UOS_SHM_SHMAT, UOS_SEM_ASSOCIATE, UOS_SEM_SEMCTL, UOS_SEM_SEMOP, UOS_AUDIT_RULE_INIT, UOS_AUDIT_RULE_KNOWN, UOS_AUDIT_RULE_MATCH, UOS_PTRACE_ACCESS_CHECK, UOS_PTRACE_TRACEME, UOS_CAPGET, UOS_CAPSET, UOS_CAPABLE, UOS_SYSLOG, UOS_SETTIME, UOS_HOOK_NONE, }; enum UOS_HOOK_RETURN_TYPE { UOS_HOOK_RET_TY_NONE, UOS_HOOK_RET_TY_INT, }; struct uos_hook_cb_entry { char *owner; // the module name of the hook unsigned long cb_addr; // the callback address of the hook enum UOS_HOOK_RETURN_TYPE ret_type; // the return type of the hook unsigned int arg_len; // the argument length of the hook }; int uos_hook_register(enum UOS_HOOK_LIST hook_id, struct uos_hook_cb_entry *entry); int uos_hook_cancel(enum UOS_HOOK_LIST hook_id, char *owner); #+END_SRC -------- 上面定义了 =hook manager= 提供的接口,开发者使用 =uos_hook_register= 进行 =hook= 的注册,使用 =uos_hook_cancel= 取消注册。 与之对应的 =LSM Hook= 函数如下: #+BEGIN_SRC c int (*path_unlink)(const struct path *dir, struct dentry *dentry); int (*path_mkdir)(const struct path *dir, struct dentry *dentry, umode_t mode); int (*path_rmdir)(const struct path *dir, struct dentry *dentry); int (*path_mknod)(const struct path *dir, struct dentry *dentry, umode_t mode, unsigned int dev); int (*path_truncate)(const struct path *path); int (*path_symlink)(const struct path *dir, struct dentry *dentry, const char *old_name); int (*path_link)(struct dentry *old_dentry, const struct path *new_dir, struct dentry *new_dentry); int (*path_rename)(const struct path *old_dir, struct dentry *old_dentry, const struct path *new_dir, struct dentry *new_dentry); int (*path_chmod)(const struct path *path, umode_t mode); int (*path_chown)(const struct path *path, kuid_t uid, kgid_t gid); int (*path_chroot)(const struct path *path); int (*inode_create)(struct inode *dir, struct dentry *dentry, umode_t mode); void (*inode_free_security)(struct inode *inode); int (*inode_link)(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry); int (*inode_unlink)(struct inode *dir, struct dentry *dentry); int (*inode_symlink)(struct inode *dir, struct dentry *dentry, const char *old_name); int (*inode_mkdir)(struct inode *dir, struct dentry *dentry, umode_t mode); int (*inode_rmdir)(struct inode *dir, struct dentry *dentry); int (*inode_mknod)(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev); int (*inode_rename)(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry); int (*inode_readlink)(struct dentry *dentry); int (*inode_follow_link)(struct dentry *dentry, struct inode *inode, bool rcu); int (*inode_permission)(struct inode *inode, int mask); int (*inode_setattr)(struct dentry *dentry, struct iattr *attr); int (*inode_setxattr)(struct dentry *dentry, const char *name, const void *value, size_t size, int flags); int (*inode_removexattr)(struct dentry *dentry, const char *name); int (*file_permission)(struct file *file, int mask); int (*file_ioctl)(struct file *file, unsigned int cmd, unsigned long arg); int (*mmap_addr)(unsigned long addr); int (*mmap_file)(struct file *file, unsigned long reqprot, unsigned long prot, unsigned long flags); int (*file_lock)(struct file *file, unsigned int cmd); int (*file_fcntl)(struct file *file, unsigned int cmd, unsigned long arg); int (*file_receive)(struct file *file); int (*file_open)(struct file *file); void (*file_free_security)(struct file *file); int (*bprm_set_creds)(struct linux_binprm *bprm); int (*bprm_check_security)(struct linux_binprm *bprm); void (*bprm_committing_creds)(struct linux_binprm *bprm); void (*bprm_committed_creds)(struct linux_binprm *bprm); int (*task_alloc)(struct task_struct *task, unsigned long clone_flags); void (*task_free)(struct task_struct *task); int (*task_fix_setuid)(struct cred *new, const struct cred *old, int flags); int (*task_setpgid)(struct task_struct *p, pid_t pgid); int (*task_getpgid)(struct task_struct *p); int (*task_getsid)(struct task_struct *p); int (*task_setnice)(struct task_struct *p, int nice); int (*task_setioprio)(struct task_struct *p, int ioprio); int (*task_getioprio)(struct task_struct *p); int (*task_prlimit)(const struct cred *cred, const struct cred *tcred, unsigned int flags); int (*task_setrlimit)(struct task_struct *p, unsigned int resource, struct rlimit *new_rlim); int (*task_setscheduler)(struct task_struct *p); int (*task_getscheduler)(struct task_struct *p); int (*task_movememory)(struct task_struct *p); int (*task_kill)(struct task_struct *p, struct siginfo *info, int sig, const struct cred *cred); int (*task_prctl)(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5); int (*socket_create)(int family, int type, int protocol, int kern); int (*socket_post_create)(struct socket *sock, int family, int type, int protocol, int kern); int (*socket_socketpair)(struct socket *socka, struct socket *sockb); int (*socket_bind)(struct socket *sock, struct sockaddr *address, int addrlen); int (*socket_connect)(struct socket *sock, struct sockaddr *address, int addrlen); int (*socket_listen)(struct socket *sock, int backlog); int (*socket_accept)(struct socket *sock, struct socket *newsock); int (*socket_sendmsg)(struct socket *sock, struct msghdr *msg, int size); int (*socket_recvmsg)(struct socket *sock, struct msghdr *msg, int size, int flags); int (*socket_getsockname)(struct socket *sock); int (*socket_getpeername)(struct socket *sock); int (*socket_getsockopt)(struct socket *sock, int level, int optname); int (*socket_setsockopt)(struct socket *sock, int level, int optname); int (*socket_shutdown)(struct socket *sock, int how); int (*tun_dev_create)(void); int (*tun_dev_attach_queue)(void *security); int (*tun_dev_attach)(struct sock *sk, void *security); int (*tun_dev_open)(void *security); int (*sctp_assoc_request)(struct sctp_endpoint *ep, struct sk_buff *skb); int (*sctp_bind_connect)(struct sock *sk, int optname, struct sockaddr *address, int addrlen); int (*netlink_send)(struct sock *sk, struct sk_buff *skb); int (*sb_remount)(struct super_block *sb, void *data); int (*sb_show_options)(struct seq_file *m, struct super_block *sb); int (*sb_statfs)(struct dentry *dentry); int (*sb_mount)(const char *dev_name, const struct path *path, const char *type, unsigned long flags, void *data); int (*sb_umount)(struct vfsmount *mnt, int flags); int (*sb_set_mnt_opts)(struct super_block *sb, struct security_mnt_opts *opts, unsigned long kern_flags, unsigned long *set_kern_flags); int (*sb_clone_mnt_opts)(const struct super_block *oldsb, struct super_block *newsb, unsigned long kern_flags, unsigned long *set_kern_flags); int (*shm_associate)(struct kern_ipc_perm *shp, int shmflg); int (*shm_shmctl)(struct kern_ipc_perm *shp, int cmd); int (*shm_shmat)(struct kern_ipc_perm *shp, char __user *shmaddr, int shmflg); int (*sem_associate)(struct kern_ipc_perm *sma, int semflg); int (*sem_semctl)(struct kern_ipc_perm *sma, int cmd); int (*sem_semop)(struct kern_ipc_perm *sma, struct sembuf *sops, unsigned nsops, int alter); int (*audit_rule_init)(u32 field, u32 op, char *rulestr, void **lsmrule); int (*audit_rule_known)(struct audit_krule *krule); int (*audit_rule_match)(u32 secid, u32 field, u32 op, void *lsmrule, struct audit_context *actx); int (*ptrace_access_check)(struct task_struct *child, unsigned int mode); int (*ptrace_traceme)(struct task_struct *parent); int (*capget)(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted); int (*capset)(struct cred *new, const struct cred *old, const kernel_cap_t *effective, const kernel_cap_t *inheritable, const kernel_cap_t *permitted); int (*capable)(const struct cred *cred, struct user_namespace *ns, int cap, int audit); int (*syslog)(int type); int (*settime)(const struct timespec64 *ts, const struct timezone *tz); #+END_SRC