[RFC 1/3] security: Add safe, dynamic (runtime-loadable) hook support

2017-11-26 Thread Sargun Dhillon
This patch adds dynamic security hooks. These hooks are designed to allow
for safe runtime loading, and unloading. Each dynamic_security_hook is
protected by an SRCU, allowing for arbitrary computation inside of the
callback. Concurrency-control, loading, and unloading is done on a
per-dynamic_security_hook (per-callback) basis.

The primary purpose of this patchset is to facilitate the development of
out-of-tree minor LSMs. The recent developments around stacking LSMs
have results in a great many number of people being interested in
use-case specific minor LSMs, and this opens the door to automatically
generated custom LSMs.

These hooks are only run after all built-in, and major LSMs are run.
The LSMs enabled by this feature must be minor LSMs, but they can poke
at the security blobs, as they should be initialized by the time their
callback happens.

There should be little runtime performance overhead for this feature,
as it's protected behind static_keys, which are disabled by default,
and are only enabled per-hook at runtime, when a module is loaded.

It also uses an enum, as opposed to a set of list_heads for loading,
and unloading hooks. These are a new set of hooks that aren't protected
(currently) by the read-only memory allocator, but the patch is written
in the direction where the memory around the hooks could eventual be
written in a sealable manner.

Signed-off-by: Sargun Dhillon 
---
 include/linux/lsm_hooks.h | 254 +
 security/Kconfig  |   9 ++
 security/Makefile |   1 +
 security/dynamic.c| 316 ++
 security/dynamic.h|  24 
 security/security.c   |  66 +-
 6 files changed, 669 insertions(+), 1 deletion(-)
 create mode 100644 security/dynamic.c
 create mode 100644 security/dynamic.h

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 7161d8e..25f8749 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -28,6 +28,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 /**
  * union security_list_options - Linux Security Module hook function list
@@ -1983,6 +1985,258 @@ extern char *lsm_names;
 extern void security_add_hooks(struct security_hook_list *hooks, int count,
char *lsm);
 
+#ifdef CONFIG_SECURITY_DYNAMIC_HOOKS
+enum dynamic_security_hook_type {
+   DYNAMIC_SECURITY_HOOK_binder_set_context_mgr,
+   DYNAMIC_SECURITY_HOOK_binder_transaction,
+   DYNAMIC_SECURITY_HOOK_binder_transfer_binder,
+   DYNAMIC_SECURITY_HOOK_binder_transfer_file,
+   DYNAMIC_SECURITY_HOOK_ptrace_access_check,
+   DYNAMIC_SECURITY_HOOK_ptrace_traceme,
+   DYNAMIC_SECURITY_HOOK_capget,
+   DYNAMIC_SECURITY_HOOK_capset,
+   DYNAMIC_SECURITY_HOOK_capable,
+   DYNAMIC_SECURITY_HOOK_quotactl,
+   DYNAMIC_SECURITY_HOOK_quota_on,
+   DYNAMIC_SECURITY_HOOK_syslog,
+   DYNAMIC_SECURITY_HOOK_settime,
+   DYNAMIC_SECURITY_HOOK_vm_enough_memory,
+   DYNAMIC_SECURITY_HOOK_bprm_set_creds,
+   DYNAMIC_SECURITY_HOOK_bprm_check_security,
+   DYNAMIC_SECURITY_HOOK_bprm_committing_creds,
+   DYNAMIC_SECURITY_HOOK_bprm_committed_creds,
+   DYNAMIC_SECURITY_HOOK_sb_alloc_security,
+   DYNAMIC_SECURITY_HOOK_sb_free_security,
+   DYNAMIC_SECURITY_HOOK_sb_copy_data,
+   DYNAMIC_SECURITY_HOOK_sb_remount,
+   DYNAMIC_SECURITY_HOOK_sb_kern_mount,
+   DYNAMIC_SECURITY_HOOK_sb_show_options,
+   DYNAMIC_SECURITY_HOOK_sb_statfs,
+   DYNAMIC_SECURITY_HOOK_sb_mount,
+   DYNAMIC_SECURITY_HOOK_sb_umount,
+   DYNAMIC_SECURITY_HOOK_sb_pivotroot,
+   DYNAMIC_SECURITY_HOOK_sb_set_mnt_opts,
+   DYNAMIC_SECURITY_HOOK_sb_clone_mnt_opts,
+   DYNAMIC_SECURITY_HOOK_sb_parse_opts_str,
+   DYNAMIC_SECURITY_HOOK_dentry_init_security,
+   DYNAMIC_SECURITY_HOOK_dentry_create_files_as,
+#ifdef CONFIG_SECURITY_PATH
+   DYNAMIC_SECURITY_HOOK_path_unlink,
+   DYNAMIC_SECURITY_HOOK_path_mkdir,
+   DYNAMIC_SECURITY_HOOK_path_rmdir,
+   DYNAMIC_SECURITY_HOOK_path_mknod,
+   DYNAMIC_SECURITY_HOOK_path_truncate,
+   DYNAMIC_SECURITY_HOOK_path_symlink,
+   DYNAMIC_SECURITY_HOOK_path_link,
+   DYNAMIC_SECURITY_HOOK_path_rename,
+   DYNAMIC_SECURITY_HOOK_path_chmod,
+   DYNAMIC_SECURITY_HOOK_path_chown,
+   DYNAMIC_SECURITY_HOOK_path_chroot,
+#endif
+   DYNAMIC_SECURITY_HOOK_inode_alloc_security,
+   DYNAMIC_SECURITY_HOOK_inode_free_security,
+   DYNAMIC_SECURITY_HOOK_inode_init_security,
+   DYNAMIC_SECURITY_HOOK_inode_create,
+   DYNAMIC_SECURITY_HOOK_inode_link,
+   DYNAMIC_SECURITY_HOOK_inode_unlink,
+   DYNAMIC_SECURITY_HOOK_inode_symlink,
+   DYNAMIC_SECURITY_HOOK_inode_mkdir,
+   DYNAMIC_SECURITY_HOOK_inode_rmdir,
+   DYNAMIC_SECURITY_HOOK_inode_mknod,
+   DYNAMIC_SECURITY_HOOK_inode_rename,
+   

[RFC 1/3] security: Add safe, dynamic (runtime-loadable) hook support

2017-11-26 Thread Sargun Dhillon
This patch adds dynamic security hooks. These hooks are designed to allow
for safe runtime loading, and unloading. Each dynamic_security_hook is
protected by an SRCU, allowing for arbitrary computation inside of the
callback. Concurrency-control, loading, and unloading is done on a
per-dynamic_security_hook (per-callback) basis.

The primary purpose of this patchset is to facilitate the development of
out-of-tree minor LSMs. The recent developments around stacking LSMs
have results in a great many number of people being interested in
use-case specific minor LSMs, and this opens the door to automatically
generated custom LSMs.

These hooks are only run after all built-in, and major LSMs are run.
The LSMs enabled by this feature must be minor LSMs, but they can poke
at the security blobs, as they should be initialized by the time their
callback happens.

There should be little runtime performance overhead for this feature,
as it's protected behind static_keys, which are disabled by default,
and are only enabled per-hook at runtime, when a module is loaded.

It also uses an enum, as opposed to a set of list_heads for loading,
and unloading hooks. These are a new set of hooks that aren't protected
(currently) by the read-only memory allocator, but the patch is written
in the direction where the memory around the hooks could eventual be
written in a sealable manner.

Signed-off-by: Sargun Dhillon 
---
 include/linux/lsm_hooks.h | 254 +
 security/Kconfig  |   9 ++
 security/Makefile |   1 +
 security/dynamic.c| 316 ++
 security/dynamic.h|  24 
 security/security.c   |  66 +-
 6 files changed, 669 insertions(+), 1 deletion(-)
 create mode 100644 security/dynamic.c
 create mode 100644 security/dynamic.h

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 7161d8e..25f8749 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -28,6 +28,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 /**
  * union security_list_options - Linux Security Module hook function list
@@ -1983,6 +1985,258 @@ extern char *lsm_names;
 extern void security_add_hooks(struct security_hook_list *hooks, int count,
char *lsm);
 
+#ifdef CONFIG_SECURITY_DYNAMIC_HOOKS
+enum dynamic_security_hook_type {
+   DYNAMIC_SECURITY_HOOK_binder_set_context_mgr,
+   DYNAMIC_SECURITY_HOOK_binder_transaction,
+   DYNAMIC_SECURITY_HOOK_binder_transfer_binder,
+   DYNAMIC_SECURITY_HOOK_binder_transfer_file,
+   DYNAMIC_SECURITY_HOOK_ptrace_access_check,
+   DYNAMIC_SECURITY_HOOK_ptrace_traceme,
+   DYNAMIC_SECURITY_HOOK_capget,
+   DYNAMIC_SECURITY_HOOK_capset,
+   DYNAMIC_SECURITY_HOOK_capable,
+   DYNAMIC_SECURITY_HOOK_quotactl,
+   DYNAMIC_SECURITY_HOOK_quota_on,
+   DYNAMIC_SECURITY_HOOK_syslog,
+   DYNAMIC_SECURITY_HOOK_settime,
+   DYNAMIC_SECURITY_HOOK_vm_enough_memory,
+   DYNAMIC_SECURITY_HOOK_bprm_set_creds,
+   DYNAMIC_SECURITY_HOOK_bprm_check_security,
+   DYNAMIC_SECURITY_HOOK_bprm_committing_creds,
+   DYNAMIC_SECURITY_HOOK_bprm_committed_creds,
+   DYNAMIC_SECURITY_HOOK_sb_alloc_security,
+   DYNAMIC_SECURITY_HOOK_sb_free_security,
+   DYNAMIC_SECURITY_HOOK_sb_copy_data,
+   DYNAMIC_SECURITY_HOOK_sb_remount,
+   DYNAMIC_SECURITY_HOOK_sb_kern_mount,
+   DYNAMIC_SECURITY_HOOK_sb_show_options,
+   DYNAMIC_SECURITY_HOOK_sb_statfs,
+   DYNAMIC_SECURITY_HOOK_sb_mount,
+   DYNAMIC_SECURITY_HOOK_sb_umount,
+   DYNAMIC_SECURITY_HOOK_sb_pivotroot,
+   DYNAMIC_SECURITY_HOOK_sb_set_mnt_opts,
+   DYNAMIC_SECURITY_HOOK_sb_clone_mnt_opts,
+   DYNAMIC_SECURITY_HOOK_sb_parse_opts_str,
+   DYNAMIC_SECURITY_HOOK_dentry_init_security,
+   DYNAMIC_SECURITY_HOOK_dentry_create_files_as,
+#ifdef CONFIG_SECURITY_PATH
+   DYNAMIC_SECURITY_HOOK_path_unlink,
+   DYNAMIC_SECURITY_HOOK_path_mkdir,
+   DYNAMIC_SECURITY_HOOK_path_rmdir,
+   DYNAMIC_SECURITY_HOOK_path_mknod,
+   DYNAMIC_SECURITY_HOOK_path_truncate,
+   DYNAMIC_SECURITY_HOOK_path_symlink,
+   DYNAMIC_SECURITY_HOOK_path_link,
+   DYNAMIC_SECURITY_HOOK_path_rename,
+   DYNAMIC_SECURITY_HOOK_path_chmod,
+   DYNAMIC_SECURITY_HOOK_path_chown,
+   DYNAMIC_SECURITY_HOOK_path_chroot,
+#endif
+   DYNAMIC_SECURITY_HOOK_inode_alloc_security,
+   DYNAMIC_SECURITY_HOOK_inode_free_security,
+   DYNAMIC_SECURITY_HOOK_inode_init_security,
+   DYNAMIC_SECURITY_HOOK_inode_create,
+   DYNAMIC_SECURITY_HOOK_inode_link,
+   DYNAMIC_SECURITY_HOOK_inode_unlink,
+   DYNAMIC_SECURITY_HOOK_inode_symlink,
+   DYNAMIC_SECURITY_HOOK_inode_mkdir,
+   DYNAMIC_SECURITY_HOOK_inode_rmdir,
+   DYNAMIC_SECURITY_HOOK_inode_mknod,
+   DYNAMIC_SECURITY_HOOK_inode_rename,
+   DYNAMIC_SECURITY_HOOK_inode_readlink,
+