Skip to content

Instantly share code, notes, and snippets.

@jouyouyun
Created September 17, 2020 02:32
Show Gist options
  • Save jouyouyun/85ca39c8cba03a5709fded05e7815a01 to your computer and use it in GitHub Desktop.
Save jouyouyun/85ca39c8cba03a5709fded05e7815a01 to your computer and use it in GitHub Desktop.
hookmanager 接口说明

UOS LSM Hook Manager

Kernel LSM 中提供了大量常用操作的 hook ,可以让开发者在这些操作执行前进行检查,便于对程序进行管控。 但由于 LSM Module 必须编译进内核,因此需要公开源码,这通常不符合很多开发者的要求。 基于这种情况, uos 基于 LSM 开发了一个 hook manager 的模块,可提供接口给开发者使用,达到了动态注册/移除 LSM Hook 的目的。

接口描述

由于 LSM 提供的接口太多,有些接口基本上很少使用,因此 uos 经过调研, hook manager 计划部分接口的动态注册/移除的功能,接口说明和 hook 列表如下:

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);

上面定义了 hook manager 提供的接口,开发者使用 uos_hook_register 进行 hook 的注册,使用 uos_hook_cancel 取消注册。

与之对应的 LSM Hook 函数如下:

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);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment