|
|
@@ -0,0 +1,303 @@ |
|
|
#+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 |