Commit c76ff350 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'lsm-pr-20221212' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm

Pull lsm updates from Paul Moore:

 - Improve the error handling in the device cgroup such that memory
   allocation failures when updating the access policy do not
   potentially alter the policy.

 - Some minor fixes to reiserfs to ensure that it properly releases
   LSM-related xattr values.

 - Update the security_socket_getpeersec_stream() LSM hook to take
   sockptr_t values.

   Previously the net/BPF folks updated the getsockopt code in the
   network stack to leverage the sockptr_t type to make it easier to
   pass both kernel and __user pointers, but unfortunately when they did
   so they didn't convert the LSM hook.

   While there was/is no immediate risk by not converting the LSM hook,
   it seems like this is a mistake waiting to happen so this patch
   proactively does the LSM hook conversion.

 - Convert vfs_getxattr_alloc() to return an int instead of a ssize_t
   and cleanup the callers. Internally the function was never going to
   return anything larger than an int and the callers were doing some
   very odd things casting the return value; this patch fixes all that
   and helps bring a bit of sanity to vfs_getxattr_alloc() and its
   callers.

 - More verbose, and helpful, LSM debug output when the system is booted
   with "lsm.debug" on the command line. There are examples in the
   commit description, but the quick summary is that this patch provides
   better information about which LSMs are enabled and the ordering in
   which they are processed.

 - General comment and kernel-doc fixes and cleanups.

* tag 'lsm-pr-20221212' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm:
  lsm: Fix description of fs_context_parse_param
  lsm: Add/fix return values in lsm_hooks.h and fix formatting
  lsm: Clarify documentation of vm_enough_memory hook
  reiserfs: Add missing calls to reiserfs_security_free()
  lsm,fs: fix vfs_getxattr_alloc() return type and caller error paths
  device_cgroup: Roll back to original exceptions after copy failure
  LSM: Better reporting of actual LSMs at boot
  lsm: make security_socket_getpeersec_stream() sockptr_t safe
  audit: Fix some kernel-doc warnings
  lsm: remove obsoleted comments for security hooks
  fs: edit a comment made in bad taste
parents 57888f7b 577cc143
...@@ -696,6 +696,7 @@ static int reiserfs_create(struct user_namespace *mnt_userns, struct inode *dir, ...@@ -696,6 +696,7 @@ static int reiserfs_create(struct user_namespace *mnt_userns, struct inode *dir,
out_failed: out_failed:
reiserfs_write_unlock(dir->i_sb); reiserfs_write_unlock(dir->i_sb);
reiserfs_security_free(&security);
return retval; return retval;
} }
...@@ -779,6 +780,7 @@ static int reiserfs_mknod(struct user_namespace *mnt_userns, struct inode *dir, ...@@ -779,6 +780,7 @@ static int reiserfs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
out_failed: out_failed:
reiserfs_write_unlock(dir->i_sb); reiserfs_write_unlock(dir->i_sb);
reiserfs_security_free(&security);
return retval; return retval;
} }
...@@ -878,6 +880,7 @@ static int reiserfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, ...@@ -878,6 +880,7 @@ static int reiserfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
retval = journal_end(&th); retval = journal_end(&th);
out_failed: out_failed:
reiserfs_write_unlock(dir->i_sb); reiserfs_write_unlock(dir->i_sb);
reiserfs_security_free(&security);
return retval; return retval;
} }
...@@ -1194,6 +1197,7 @@ static int reiserfs_symlink(struct user_namespace *mnt_userns, ...@@ -1194,6 +1197,7 @@ static int reiserfs_symlink(struct user_namespace *mnt_userns,
retval = journal_end(&th); retval = journal_end(&th);
out_failed: out_failed:
reiserfs_write_unlock(parent_dir->i_sb); reiserfs_write_unlock(parent_dir->i_sb);
reiserfs_security_free(&security);
return retval; return retval;
} }
......
...@@ -50,6 +50,7 @@ int reiserfs_security_init(struct inode *dir, struct inode *inode, ...@@ -50,6 +50,7 @@ int reiserfs_security_init(struct inode *dir, struct inode *inode,
int error; int error;
sec->name = NULL; sec->name = NULL;
sec->value = NULL;
/* Don't add selinux attributes on xattrs - they'll never get used */ /* Don't add selinux attributes on xattrs - they'll never get used */
if (IS_PRIVATE(dir)) if (IS_PRIVATE(dir))
...@@ -95,7 +96,6 @@ int reiserfs_security_write(struct reiserfs_transaction_handle *th, ...@@ -95,7 +96,6 @@ int reiserfs_security_write(struct reiserfs_transaction_handle *th,
void reiserfs_security_free(struct reiserfs_security_handle *sec) void reiserfs_security_free(struct reiserfs_security_handle *sec)
{ {
kfree(sec->name);
kfree(sec->value); kfree(sec->value);
sec->name = NULL; sec->name = NULL;
sec->value = NULL; sec->value = NULL;
......
...@@ -368,11 +368,12 @@ xattr_getsecurity(struct user_namespace *mnt_userns, struct inode *inode, ...@@ -368,11 +368,12 @@ xattr_getsecurity(struct user_namespace *mnt_userns, struct inode *inode,
* vfs_getxattr_alloc - allocate memory, if necessary, before calling getxattr * vfs_getxattr_alloc - allocate memory, if necessary, before calling getxattr
* *
* Allocate memory, if not already allocated, or re-allocate correct size, * Allocate memory, if not already allocated, or re-allocate correct size,
* before retrieving the extended attribute. * before retrieving the extended attribute. The xattr value buffer should
* always be freed by the caller, even on error.
* *
* Returns the result of alloc, if failed, or the getxattr operation. * Returns the result of alloc, if failed, or the getxattr operation.
*/ */
ssize_t int
vfs_getxattr_alloc(struct user_namespace *mnt_userns, struct dentry *dentry, vfs_getxattr_alloc(struct user_namespace *mnt_userns, struct dentry *dentry,
const char *name, char **xattr_value, size_t xattr_size, const char *name, char **xattr_value, size_t xattr_size,
gfp_t flags) gfp_t flags)
......
...@@ -99,7 +99,7 @@ struct fs_context { ...@@ -99,7 +99,7 @@ struct fs_context {
const struct cred *cred; /* The mounter's credentials */ const struct cred *cred; /* The mounter's credentials */
struct p_log log; /* Logging buffer */ struct p_log log; /* Logging buffer */
const char *source; /* The source name (eg. dev path) */ const char *source; /* The source name (eg. dev path) */
void *security; /* Linux S&M options */ void *security; /* LSM options */
void *s_fs_info; /* Proposed s_fs_info */ void *s_fs_info; /* Proposed s_fs_info */
unsigned int sb_flags; /* Proposed superblock flags (SB_*) */ unsigned int sb_flags; /* Proposed superblock flags (SB_*) */
unsigned int sb_flags_mask; /* Superblock flags that were changed */ unsigned int sb_flags_mask; /* Superblock flags that were changed */
......
...@@ -309,7 +309,7 @@ LSM_HOOK(int, 0, socket_setsockopt, struct socket *sock, int level, int optname) ...@@ -309,7 +309,7 @@ LSM_HOOK(int, 0, socket_setsockopt, struct socket *sock, int level, int optname)
LSM_HOOK(int, 0, socket_shutdown, struct socket *sock, int how) LSM_HOOK(int, 0, socket_shutdown, struct socket *sock, int how)
LSM_HOOK(int, 0, socket_sock_rcv_skb, struct sock *sk, struct sk_buff *skb) LSM_HOOK(int, 0, socket_sock_rcv_skb, struct sock *sk, struct sk_buff *skb)
LSM_HOOK(int, 0, socket_getpeersec_stream, struct socket *sock, LSM_HOOK(int, 0, socket_getpeersec_stream, struct socket *sock,
char __user *optval, int __user *optlen, unsigned len) sockptr_t optval, sockptr_t optlen, unsigned int len)
LSM_HOOK(int, 0, socket_getpeersec_dgram, struct socket *sock, LSM_HOOK(int, 0, socket_getpeersec_dgram, struct socket *sock,
struct sk_buff *skb, u32 *secid) struct sk_buff *skb, u32 *secid)
LSM_HOOK(int, 0, sk_alloc_security, struct sock *sk, int family, gfp_t priority) LSM_HOOK(int, 0, sk_alloc_security, struct sock *sk, int family, gfp_t priority)
......
...@@ -92,13 +92,14 @@ ...@@ -92,13 +92,14 @@
* is initialised to NULL by the caller. * is initialised to NULL by the caller.
* @fc indicates the new filesystem context. * @fc indicates the new filesystem context.
* @src_fc indicates the original filesystem context. * @src_fc indicates the original filesystem context.
* Return 0 on success or a negative error code on failure.
* @fs_context_parse_param: * @fs_context_parse_param:
* Userspace provided a parameter to configure a superblock. The LSM may * Userspace provided a parameter to configure a superblock. The LSM may
* reject it with an error and may use it for itself, in which case it * reject it with an error and may use it for itself, in which case it
* should return 0; otherwise it should return -ENOPARAM to pass it on to * should return 0; otherwise it should return -ENOPARAM to pass it on to
* the filesystem. * the filesystem.
* @fc indicates the filesystem context. * @fc indicates the filesystem context.
* @param The parameter * @param The parameter.
* *
* Security hooks for filesystem operations. * Security hooks for filesystem operations.
* *
...@@ -118,6 +119,7 @@ ...@@ -118,6 +119,7 @@
* Free memory associated with @mnt_ops. * Free memory associated with @mnt_ops.
* @sb_eat_lsm_opts: * @sb_eat_lsm_opts:
* Eat (scan @orig options) and save them in @mnt_opts. * Eat (scan @orig options) and save them in @mnt_opts.
* Return 0 on success, negative values on failure.
* @sb_statfs: * @sb_statfs:
* Check permission before obtaining filesystem statistics for the @mnt * Check permission before obtaining filesystem statistics for the @mnt
* mountpoint. * mountpoint.
...@@ -136,31 +138,24 @@ ...@@ -136,31 +138,24 @@
* @flags contains the mount flags. * @flags contains the mount flags.
* @data contains the filesystem-specific data. * @data contains the filesystem-specific data.
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @sb_copy_data:
* Allow mount option data to be copied prior to parsing by the filesystem,
* so that the security module can extract security-specific mount
* options cleanly (a filesystem may modify the data e.g. with strsep()).
* This also allows the original mount data to be stripped of security-
* specific options to avoid having to make filesystems aware of them.
* @orig the original mount data copied from userspace.
* @copy copied data which will be passed to the security module.
* Returns 0 if the copy was successful.
* @sb_mnt_opts_compat: * @sb_mnt_opts_compat:
* Determine if the new mount options in @mnt_opts are allowed given * Determine if the new mount options in @mnt_opts are allowed given
* the existing mounted filesystem at @sb. * the existing mounted filesystem at @sb.
* @sb superblock being compared * @sb superblock being compared.
* @mnt_opts new mount options * @mnt_opts new mount options.
* Return 0 if options are compatible. * Return 0 if options are compatible.
* @sb_remount: * @sb_remount:
* Extracts security system specific mount options and verifies no changes * Extracts security system specific mount options and verifies no changes
* are being made to those options. * are being made to those options.
* @sb superblock being remounted * @sb superblock being remounted.
* @data contains the filesystem-specific data. * @data contains the filesystem-specific data.
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @sb_kern_mount: * @sb_kern_mount:
* Mount this @sb if allowed by permissions. * Mount this @sb if allowed by permissions.
* Return 0 if permission is granted.
* @sb_show_options: * @sb_show_options:
* Show (print on @m) mount options for this @sb. * Show (print on @m) mount options for this @sb.
* Return 0 on success, negative values on failure.
* @sb_umount: * @sb_umount:
* Check permission before the @mnt file system is unmounted. * Check permission before the @mnt file system is unmounted.
* @mnt contains the mounted file system. * @mnt contains the mounted file system.
...@@ -174,31 +169,31 @@ ...@@ -174,31 +169,31 @@
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @sb_set_mnt_opts: * @sb_set_mnt_opts:
* Set the security relevant mount options used for a superblock * Set the security relevant mount options used for a superblock
* @sb the superblock to set security mount options for * @sb the superblock to set security mount options for.
* @opts binary data structure containing all lsm mount data * @opts binary data structure containing all lsm mount data.
* Return 0 on success, error on failure.
* @sb_clone_mnt_opts: * @sb_clone_mnt_opts:
* Copy all security options from a given superblock to another * Copy all security options from a given superblock to another
* @oldsb old superblock which contain information to clone * @oldsb old superblock which contain information to clone.
* @newsb new superblock which needs filled in * @newsb new superblock which needs filled in.
* @sb_parse_opts_str: * Return 0 on success, error on failure.
* Parse a string of security data filling in the opts structure
* @options string containing all mount options known by the LSM
* @opts binary data structure usable by the LSM
* @move_mount: * @move_mount:
* Check permission before a mount is moved. * Check permission before a mount is moved.
* @from_path indicates the mount that is going to be moved. * @from_path indicates the mount that is going to be moved.
* @to_path indicates the mountpoint that will be mounted upon. * @to_path indicates the mountpoint that will be mounted upon.
* Return 0 if permission is granted.
* @dentry_init_security: * @dentry_init_security:
* Compute a context for a dentry as the inode is not yet available * Compute a context for a dentry as the inode is not yet available
* since NFSv4 has no label backed by an EA anyway. * since NFSv4 has no label backed by an EA anyway.
* @dentry dentry to use in calculating the context. * @dentry dentry to use in calculating the context.
* @mode mode used to determine resource type. * @mode mode used to determine resource type.
* @name name of the last path component used to create file * @name name of the last path component used to create file.
* @xattr_name pointer to place the pointer to security xattr name. * @xattr_name pointer to place the pointer to security xattr name.
* Caller does not have to free the resulting pointer. Its * Caller does not have to free the resulting pointer. Its
* a pointer to static string. * a pointer to static string.
* @ctx pointer to place the pointer to the resulting context in. * @ctx pointer to place the pointer to the resulting context in.
* @ctxlen point to place the length of the resulting context. * @ctxlen point to place the length of the resulting context.
* Return 0 on success, negative values on failure.
* @dentry_create_files_as: * @dentry_create_files_as:
* Compute a context for a dentry as the inode is not yet available * Compute a context for a dentry as the inode is not yet available
* and set that context in passed in creds so that new files are * and set that context in passed in creds so that new files are
...@@ -206,9 +201,10 @@ ...@@ -206,9 +201,10 @@
* passed in creds and not the creds of the caller. * passed in creds and not the creds of the caller.
* @dentry dentry to use in calculating the context. * @dentry dentry to use in calculating the context.
* @mode mode used to determine resource type. * @mode mode used to determine resource type.
* @name name of the last path component used to create file * @name name of the last path component used to create file.
* @old creds which should be used for context calculation * @old creds which should be used for context calculation.
* @new creds to modify * @new creds to modify.
* Return 0 on success, error on failure.
* *
* *
* Security hooks for inode operations. * Security hooks for inode operations.
...@@ -236,7 +232,7 @@ ...@@ -236,7 +232,7 @@
* then it should return -EOPNOTSUPP to skip this processing. * then it should return -EOPNOTSUPP to skip this processing.
* @inode contains the inode structure of the newly created inode. * @inode contains the inode structure of the newly created inode.
* @dir contains the inode structure of the parent directory. * @dir contains the inode structure of the parent directory.
* @qstr contains the last path component of the new object * @qstr contains the last path component of the new object.
* @name will be set to the allocated name suffix (e.g. selinux). * @name will be set to the allocated name suffix (e.g. selinux).
* @value will be set to the allocated attribute value. * @value will be set to the allocated attribute value.
* @len will be set to the length of the value. * @len will be set to the length of the value.
...@@ -247,9 +243,9 @@ ...@@ -247,9 +243,9 @@
* Set up the incore security field for the new anonymous inode * Set up the incore security field for the new anonymous inode
* and return whether the inode creation is permitted by the security * and return whether the inode creation is permitted by the security
* module or not. * module or not.
* @inode contains the inode structure * @inode contains the inode structure.
* @name name of the anonymous inode class * @name name of the anonymous inode class.
* @context_inode optional related inode * @context_inode optional related inode.
* Returns 0 on success, -EACCES if the security module denies the * Returns 0 on success, -EACCES if the security module denies the
* creation of this inode, or another -errno upon other errors. * creation of this inode, or another -errno upon other errors.
* @inode_create: * @inode_create:
...@@ -365,7 +361,7 @@ ...@@ -365,7 +361,7 @@
* mode is specified in @mode. * mode is specified in @mode.
* @path contains the path structure of the file to change the mode. * @path contains the path structure of the file to change the mode.
* @mode contains the new DAC's permission, which is a bitmask of * @mode contains the new DAC's permission, which is a bitmask of
* constants from <include/uapi/linux/stat.h> * constants from <include/uapi/linux/stat.h>.
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @path_chown: * @path_chown:
* Check for permission to change owner/group of a file or directory. * Check for permission to change owner/group of a file or directory.
...@@ -380,6 +376,7 @@ ...@@ -380,6 +376,7 @@
* @path_notify: * @path_notify:
* Check permissions before setting a watch on events as defined by @mask, * Check permissions before setting a watch on events as defined by @mask,
* on an object at @path, whose type is defined by @obj_type. * on an object at @path, whose type is defined by @obj_type.
* Return 0 if permission is granted.
* @inode_readlink: * @inode_readlink:
* Check the permission to read the symbolic link. * Check the permission to read the symbolic link.
* @dentry contains the dentry structure for the file link. * @dentry contains the dentry structure for the file link.
...@@ -387,7 +384,7 @@ ...@@ -387,7 +384,7 @@
* @inode_follow_link: * @inode_follow_link:
* Check permission to follow a symbolic link when looking up a pathname. * Check permission to follow a symbolic link when looking up a pathname.
* @dentry contains the dentry structure for the link. * @dentry contains the dentry structure for the link.
* @inode contains the inode, which itself is not stable in RCU-walk * @inode contains the inode, which itself is not stable in RCU-walk.
* @rcu indicates whether we are in RCU-walk mode. * @rcu indicates whether we are in RCU-walk mode.
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @inode_permission: * @inode_permission:
...@@ -453,9 +450,9 @@ ...@@ -453,9 +450,9 @@
* Retrieve a copy of the extended attribute representation of the * Retrieve a copy of the extended attribute representation of the
* security label associated with @name for @inode via @buffer. Note that * security label associated with @name for @inode via @buffer. Note that
* @name is the remainder of the attribute name after the security prefix * @name is the remainder of the attribute name after the security prefix
* has been removed. @alloc is used to specify of the call should return a * has been removed. @alloc is used to specify if the call should return a
* value via the buffer or just the value length Return size of buffer on * value via the buffer or just the value length.
* success. * Return size of buffer on success.
* @inode_setsecurity: * @inode_setsecurity:
* Set the security label associated with @name for @inode from the * Set the security label associated with @name for @inode from the
* extended attribute value @value. @size indicates the size of the * extended attribute value @value. @size indicates the size of the
...@@ -478,7 +475,7 @@ ...@@ -478,7 +475,7 @@
* @inode_killpriv: * @inode_killpriv:
* The setuid bit is being removed. Remove similar security labels. * The setuid bit is being removed. Remove similar security labels.
* Called with the dentry->d_inode->i_mutex held. * Called with the dentry->d_inode->i_mutex held.
* @mnt_userns: user namespace of the mount * @mnt_userns: user namespace of the mount.
* @dentry is the dentry being changed. * @dentry is the dentry being changed.
* Return 0 on success. If error is returned, then the operation * Return 0 on success. If error is returned, then the operation
* causing setuid bit removal is failed. * causing setuid bit removal is failed.
...@@ -505,20 +502,22 @@ ...@@ -505,20 +502,22 @@
* to abort the copy up. Note that the caller is responsible for reading * to abort the copy up. Note that the caller is responsible for reading
* and writing the xattrs as this hook is merely a filter. * and writing the xattrs as this hook is merely a filter.
* @d_instantiate: * @d_instantiate:
* Fill in @inode security information for a @dentry if allowed. * Fill in @inode security information for a @dentry if allowed.
* @getprocattr: * @getprocattr:
* Read attribute @name for process @p and store it into @value if allowed. * Read attribute @name for process @p and store it into @value if allowed.
* Return the length of @value on success, a negative value otherwise.
* @setprocattr: * @setprocattr:
* Write (set) attribute @name to @value, size @size if allowed. * Write (set) attribute @name to @value, size @size if allowed.
* Return written bytes on success, a negative value otherwise.
* *
* Security hooks for kernfs node operations * Security hooks for kernfs node operations
* *
* @kernfs_init_security: * @kernfs_init_security:
* Initialize the security context of a newly created kernfs node based * Initialize the security context of a newly created kernfs node based
* on its own and its parent's attributes. * on its own and its parent's attributes.
* * @kn_dir the parent kernfs node.
* @kn_dir the parent kernfs node * @kn the new child kernfs node.
* @kn the new child kernfs node * Return 0 if permission is granted.
* *
* Security hooks for file operations * Security hooks for file operations
* *
...@@ -557,11 +556,11 @@ ...@@ -557,11 +556,11 @@
* simple integer value. When @arg represents a user space pointer, it * simple integer value. When @arg represents a user space pointer, it
* should never be used by the security module. * should never be used by the security module.
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @mmap_addr : * @mmap_addr:
* Check permissions for a mmap operation at @addr. * Check permissions for a mmap operation at @addr.
* @addr contains virtual address that will be used for the operation. * @addr contains virtual address that will be used for the operation.
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @mmap_file : * @mmap_file:
* Check permissions for a mmap operation. The @file may be NULL, e.g. * Check permissions for a mmap operation. The @file may be NULL, e.g.
* if mapping anonymous memory. * if mapping anonymous memory.
* @file contains the file structure for file to map (may be NULL). * @file contains the file structure for file to map (may be NULL).
...@@ -622,6 +621,7 @@ ...@@ -622,6 +621,7 @@
* Save open-time permission checking state for later use upon * Save open-time permission checking state for later use upon
* file_permission, and recheck access if anything has changed * file_permission, and recheck access if anything has changed
* since inode_permission. * since inode_permission.
* Return 0 if permission is granted.
* *
* Security hooks for task operations. * Security hooks for task operations.
* *
...@@ -639,6 +639,7 @@ ...@@ -639,6 +639,7 @@
* @gfp indicates the atomicity of any memory allocations. * @gfp indicates the atomicity of any memory allocations.
* Only allocate sufficient memory and attach to @cred such that * Only allocate sufficient memory and attach to @cred such that
* cred_transfer() will not get ENOMEM. * cred_transfer() will not get ENOMEM.
* Return 0 on success, negative values on failure.
* @cred_free: * @cred_free:
* @cred points to the credentials. * @cred points to the credentials.
* Deallocate and clear the cred->security field in a set of credentials. * Deallocate and clear the cred->security field in a set of credentials.
...@@ -647,6 +648,7 @@ ...@@ -647,6 +648,7 @@
* @old points to the original credentials. * @old points to the original credentials.
* @gfp indicates the atomicity of any memory allocations. * @gfp indicates the atomicity of any memory allocations.
* Prepare a new set of credentials by copying the data from the old set. * Prepare a new set of credentials by copying the data from the old set.
* Return 0 on success, negative values on failure.
* @cred_transfer: * @cred_transfer:
* @new points to the new credentials. * @new points to the new credentials.
* @old points to the original credentials. * @old points to the original credentials.
...@@ -658,7 +660,7 @@ ...@@ -658,7 +660,7 @@
* @kernel_act_as: * @kernel_act_as:
* Set the credentials for a kernel service to act as (subjective context). * Set the credentials for a kernel service to act as (subjective context).
* @new points to the credentials to be modified. * @new points to the credentials to be modified.
* @secid specifies the security ID to be set * @secid specifies the security ID to be set.
* The current task must be the one that nominated @secid. * The current task must be the one that nominated @secid.
* Return 0 if successful. * Return 0 if successful.
* @kernel_create_files_as: * @kernel_create_files_as:
...@@ -671,19 +673,19 @@ ...@@ -671,19 +673,19 @@
* @kernel_module_request: * @kernel_module_request:
* Ability to trigger the kernel to automatically upcall to userspace for * Ability to trigger the kernel to automatically upcall to userspace for
* userspace to load a kernel module with the given name. * userspace to load a kernel module with the given name.
* @kmod_name name of the module requested by the kernel * @kmod_name name of the module requested by the kernel.
* Return 0 if successful. * Return 0 if successful.
* @kernel_load_data: * @kernel_load_data:
* Load data provided by userspace. * Load data provided by userspace.
* @id kernel load data identifier * @id kernel load data identifier.
* @contents if a subsequent @kernel_post_load_data will be called. * @contents if a subsequent @kernel_post_load_data will be called.
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @kernel_post_load_data: * @kernel_post_load_data:
* Load data provided by a non-file source (usually userspace buffer). * Load data provided by a non-file source (usually userspace buffer).
* @buf pointer to buffer containing the data contents. * @buf pointer to buffer containing the data contents.
* @size length of the data contents. * @size length of the data contents.
* @id kernel load data identifier * @id kernel load data identifier.
* @description a text description of what was loaded, @id-specific * @description a text description of what was loaded, @id-specific.
* Return 0 if permission is granted. * Return 0 if permission is granted.
* This must be paired with a prior @kernel_load_data call that had * This must be paired with a prior @kernel_load_data call that had
* @contents set to true. * @contents set to true.
...@@ -691,7 +693,7 @@ ...@@ -691,7 +693,7 @@
* Read a file specified by userspace. * Read a file specified by userspace.
* @file contains the file structure pointing to the file being read * @file contains the file structure pointing to the file being read
* by the kernel. * by the kernel.
* @id kernel read file identifier * @id kernel read file identifier.
* @contents if a subsequent @kernel_post_read_file will be called. * @contents if a subsequent @kernel_post_read_file will be called.
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @kernel_post_read_file: * @kernel_post_read_file:
...@@ -700,7 +702,7 @@ ...@@ -700,7 +702,7 @@
* by the kernel. * by the kernel.
* @buf pointer to buffer containing the file contents. * @buf pointer to buffer containing the file contents.
* @size length of the file contents. * @size length of the file contents.
* @id kernel read file identifier * @id kernel read file identifier.
* This must be paired with a prior @kernel_read_file call that had * This must be paired with a prior @kernel_read_file call that had
* @contents set to true. * @contents set to true.
* Return 0 if permission is granted. * Return 0 if permission is granted.
...@@ -710,7 +712,7 @@ ...@@ -710,7 +712,7 @@
* indicates which of the set*uid system calls invoked this hook. If * indicates which of the set*uid system calls invoked this hook. If
* @new is the set of credentials that will be installed. Modifications * @new is the set of credentials that will be installed. Modifications
* should be made to this rather than to @current->cred. * should be made to this rather than to @current->cred.
* @old is the set of credentials that are being replaces * @old is the set of credentials that are being replaced.
* @flags contains one of the LSM_SETID_* values. * @flags contains one of the LSM_SETID_* values.
* Return 0 on success. * Return 0 on success.
* @task_fix_setgid: * @task_fix_setgid:
...@@ -762,7 +764,7 @@ ...@@ -762,7 +764,7 @@
* @task_setioprio: * @task_setioprio:
* Check permission before setting the ioprio value of @p to @ioprio. * Check permission before setting the ioprio value of @p to @ioprio.
* @p contains the task_struct of process. * @p contains the task_struct of process.
* @ioprio contains the new ioprio value * @ioprio contains the new ioprio value.
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @task_getioprio: * @task_getioprio:
* Check permission before getting the ioprio value of @p. * Check permission before getting the ioprio value of @p.
...@@ -893,6 +895,7 @@ ...@@ -893,6 +895,7 @@
* @type contains the requested communications type. * @type contains the requested communications type.
* @protocol contains the requested protocol. * @protocol contains the requested protocol.
* @kern set to 1 if a kernel socket. * @kern set to 1 if a kernel socket.
* Return 0 if permission is granted.
* @socket_socketpair: * @socket_socketpair:
* Check permissions before creating a fresh pair of sockets. * Check permissions before creating a fresh pair of sockets.
* @socka contains the first socket structure. * @socka contains the first socket structure.
...@@ -976,14 +979,15 @@ ...@@ -976,14 +979,15 @@
* Must not sleep inside this hook because some callers hold spinlocks. * Must not sleep inside this hook because some callers hold spinlocks.
* @sk contains the sock (not socket) associated with the incoming sk_buff. * @sk contains the sock (not socket) associated with the incoming sk_buff.
* @skb contains the incoming network data. * @skb contains the incoming network data.
* Return 0 if permission is granted.
* @socket_getpeersec_stream: * @socket_getpeersec_stream:
* This hook allows the security module to provide peer socket security * This hook allows the security module to provide peer socket security
* state for unix or connected tcp sockets to userspace via getsockopt * state for unix or connected tcp sockets to userspace via getsockopt
* SO_GETPEERSEC. For tcp sockets this can be meaningful if the * SO_GETPEERSEC. For tcp sockets this can be meaningful if the
* socket is associated with an ipsec SA. * socket is associated with an ipsec SA.
* @sock is the local socket. * @sock is the local socket.
* @optval userspace memory where the security state is to be copied. * @optval memory where the security state is to be copied.
* @optlen userspace int where the module should copy the actual length * @optlen memory where the module should copy the actual length
* of the security state. * of the security state.
* @len as input is the maximum length to copy to userspace provided * @len as input is the maximum length to copy to userspace provided
* by the caller. * by the caller.
...@@ -1003,6 +1007,7 @@ ...@@ -1003,6 +1007,7 @@
* @sk_alloc_security: * @sk_alloc_security:
* Allocate and attach a security structure to the sk->sk_security field, * Allocate and attach a security structure to the sk->sk_security field,
* which is used to copy security attributes between local stream sockets. * which is used to copy security attributes between local stream sockets.
* Return 0 on success, error on failure.
* @sk_free_security: * @sk_free_security:
* Deallocate security structure. * Deallocate security structure.
* @sk_clone_security: * @sk_clone_security:
...@@ -1015,17 +1020,19 @@ ...@@ -1015,17 +1020,19 @@
* @inet_conn_request: * @inet_conn_request:
* Sets the openreq's sid to socket's sid with MLS portion taken * Sets the openreq's sid to socket's sid with MLS portion taken
* from peer sid. * from peer sid.
* Return 0 if permission is granted.
* @inet_csk_clone: * @inet_csk_clone:
* Sets the new child socket's sid to the openreq sid. * Sets the new child socket's sid to the openreq sid.
* @inet_conn_established: * @inet_conn_established:
* Sets the connection's peersid to the secmark on skb. * Sets the connection's peersid to the secmark on skb.
* @secmark_relabel_packet: * @secmark_relabel_packet:
* check if the process should be allowed to relabel packets to * Check if the process should be allowed to relabel packets to
* the given secid * the given secid.
* Return 0 if permission is granted.
* @secmark_refcount_inc: * @secmark_refcount_inc:
* tells the LSM to increment the number of secmark labeling rules loaded * Tells the LSM to increment the number of secmark labeling rules loaded.
* @secmark_refcount_dec: * @secmark_refcount_dec:
* tells the LSM to decrement the number of secmark labeling rules loaded * Tells the LSM to decrement the number of secmark labeling rules loaded.
* @req_classify_flow: * @req_classify_flow:
* Sets the flow's sid to the openreq sid. * Sets the flow's sid to the openreq sid.
* @tun_dev_alloc_security: * @tun_dev_alloc_security:
...@@ -1036,21 +1043,25 @@ ...@@ -1036,21 +1043,25 @@
* @tun_dev_free_security: * @tun_dev_free_security:
* This hook allows a module to free the security structure for a TUN * This hook allows a module to free the security structure for a TUN
* device. * device.
* @security pointer to the TUN device's security structure * @security pointer to the TUN device's security structure.
* @tun_dev_create: * @tun_dev_create:
* Check permissions prior to creating a new TUN device. * Check permissions prior to creating a new TUN device.
* Return 0 if permission is granted.
* @tun_dev_attach_queue: * @tun_dev_attach_queue:
* Check permissions prior to attaching to a TUN device queue. * Check permissions prior to attaching to a TUN device queue.
* @security pointer to the TUN device's security structure. * @security pointer to the TUN device's security structure.
* Return 0 if permission is granted.
* @tun_dev_attach: * @tun_dev_attach:
* This hook can be used by the module to update any security state * This hook can be used by the module to update any security state
* associated with the TUN device's sock structure. * associated with the TUN device's sock structure.
* @sk contains the existing sock structure. * @sk contains the existing sock structure.
* @security pointer to the TUN device's security structure. * @security pointer to the TUN device's security structure.
* Return 0 if permission is granted.
* @tun_dev_open: * @tun_dev_open:
* This hook can be used by the module to update any security state * This hook can be used by the module to update any security state
* associated with the TUN device's security structure. * associated with the TUN device's security structure.
* @security pointer to the TUN devices's security structure. * @security pointer to the TUN devices's security structure.
* Return 0 if permission is granted.
* *
* Security hooks for SCTP * Security hooks for SCTP
* *
...@@ -1083,6 +1094,7 @@ ...@@ -1083,6 +1094,7 @@
* to the security module. * to the security module.
* @asoc pointer to sctp association structure. * @asoc pointer to sctp association structure.
* @skb pointer to skbuff of association packet. * @skb pointer to skbuff of association packet.
* Return 0 if permission is granted.
* *
* Security hooks for Infiniband * Security hooks for Infiniband
* *
...@@ -1091,15 +1103,17 @@ ...@@ -1091,15 +1103,17 @@
* @subnet_prefix the subnet prefix of the port being used. * @subnet_prefix the subnet prefix of the port being used.
* @pkey the pkey to be accessed. * @pkey the pkey to be accessed.
* @sec pointer to a security structure. * @sec pointer to a security structure.
* Return 0 if permission is granted.
* @ib_endport_manage_subnet: * @ib_endport_manage_subnet:
* Check permissions to send and receive SMPs on a end port. * Check permissions to send and receive SMPs on a end port.
* @dev_name the IB device name (i.e. mlx4_0). * @dev_name the IB device name (i.e. mlx4_0).
* @port_num the port number. * @port_num the port number.
* @sec pointer to a security structure. * @sec pointer to a security structure.
* Return 0 if permission is granted.
* @ib_alloc_security: * @ib_alloc_security:
* Allocate a security structure for Infiniband objects. * Allocate a security structure for Infiniband objects.
* @sec pointer to a security structure pointer. * @sec pointer to a security structure pointer.
* Returns 0 on success, non-zero on failure * Returns 0 on success, non-zero on failure.
* @ib_free_security: * @ib_free_security:
* Deallocate an Infiniband security structure. * Deallocate an Infiniband security structure.
* @sec contains the security structure to be freed. * @sec contains the security structure to be freed.
...@@ -1111,10 +1125,11 @@ ...@@ -1111,10 +1125,11 @@
* Database used by the XFRM system. * Database used by the XFRM system.
* @sec_ctx contains the security context information being provided by * @sec_ctx contains the security context information being provided by
* the user-level policy update program (e.g., setkey). * the user-level policy update program (e.g., setkey).
* @gfp is to specify the context for the allocation.
* Allocate a security structure to the xp->security field; the security * Allocate a security structure to the xp->security field; the security
* field is initialized to NULL when the xfrm_policy is allocated. * field is initialized to NULL when the xfrm_policy is allocated.
* Return 0 if operation was successful (memory to allocate, legal context) * Return 0 if operation was successful (memory to allocate, legal
* @gfp is to specify the context for the allocation * context).
* @xfrm_policy_clone_security: * @xfrm_policy_clone_security:
* @old_ctx contains an existing xfrm_sec_ctx. * @old_ctx contains an existing xfrm_sec_ctx.
* @new_ctxp contains a new xfrm_sec_ctx being cloned from old. * @new_ctxp contains a new xfrm_sec_ctx being cloned from old.
...@@ -1122,11 +1137,12 @@ ...@@ -1122,11 +1137,12 @@
* information from the old_ctx structure. * information from the old_ctx structure.
* Return 0 if operation was successful (memory to allocate). * Return 0 if operation was successful (memory to allocate).
* @xfrm_policy_free_security: * @xfrm_policy_free_security:
* @ctx contains the xfrm_sec_ctx * @ctx contains the xfrm_sec_ctx.
* Deallocate xp->security. * Deallocate xp->security.
* @xfrm_policy_delete_security: * @xfrm_policy_delete_security:
* @ctx contains the xfrm_sec_ctx. * @ctx contains the xfrm_sec_ctx.
* Authorize deletion of xp->security. * Authorize deletion of xp->security.
* Return 0 if permission is granted.
* @xfrm_state_alloc: * @xfrm_state_alloc:
* @x contains the xfrm_state being added to the Security Association * @x contains the xfrm_state being added to the Security Association
* Database by the XFRM system. * Database by the XFRM system.
...@@ -1152,6 +1168,7 @@ ...@@ -1152,6 +1168,7 @@
* @xfrm_state_delete_security: * @xfrm_state_delete_security:
* @x contains the xfrm_state. * @x contains the xfrm_state.
* Authorize deletion of x->security. * Authorize deletion of x->security.
* Return 0 if permission is granted.
* @xfrm_policy_lookup: * @xfrm_policy_lookup:
* @ctx contains the xfrm_sec_ctx for which the access control is being * @ctx contains the xfrm_sec_ctx for which the access control is being
* checked. * checked.
...@@ -1180,7 +1197,7 @@ ...@@ -1180,7 +1197,7 @@
* Permit allocation of a key and assign security data. Note that key does * Permit allocation of a key and assign security data. Note that key does
* not have a serial number assigned at this point. * not have a serial number assigned at this point.
* @key points to the key. * @key points to the key.
* @flags is the allocation flags * @flags is the allocation flags.
* Return 0 if permission is granted, -ve error otherwise. * Return 0 if permission is granted, -ve error otherwise.
* @key_free: * @key_free:
* Notification of destruction; free security data. * Notification of destruction; free security data.
...@@ -1210,8 +1227,8 @@ ...@@ -1210,8 +1227,8 @@
* *
* @ipc_permission: * @ipc_permission:
* Check permissions for access to IPC * Check permissions for access to IPC
* @ipcp contains the kernel IPC permission structure * @ipcp contains the kernel IPC permission structure.
* @flag contains the desired (requested) permission set * @flag contains the desired (requested) permission set.
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @ipc_getsecid: * @ipc_getsecid:
* Get the secid associated with the ipc object. * Get the secid associated with the ipc object.
...@@ -1356,15 +1373,18 @@ ...@@ -1356,15 +1373,18 @@
* to @to. * to @to.
* @from contains the struct cred for the sending process. * @from contains the struct cred for the sending process.
* @to contains the struct cred for the receiving process. * @to contains the struct cred for the receiving process.
* Return 0 if permission is granted.
* @binder_transfer_binder: * @binder_transfer_binder:
* Check whether @from is allowed to transfer a binder reference to @to. * Check whether @from is allowed to transfer a binder reference to @to.
* @from contains the struct cred for the sending process. * @from contains the struct cred for the sending process.
* @to contains the struct cred for the receiving process. * @to contains the struct cred for the receiving process.
* Return 0 if permission is granted.
* @binder_transfer_file: * @binder_transfer_file:
* Check whether @from is allowed to transfer @file to @to. * Check whether @from is allowed to transfer @file to @to.
* @from contains the struct cred for the sending process. * @from contains the struct cred for the sending process.
* @file contains the struct file being transferred. * @file contains the struct file being transferred.
* @to contains the struct cred for the receiving process. * @to contains the struct cred for the receiving process.
* Return 0 if permission is granted.
* *
* @ptrace_access_check: * @ptrace_access_check:
* Check permission before allowing the current process to trace the * Check permission before allowing the current process to trace the
...@@ -1406,32 +1426,39 @@ ...@@ -1406,32 +1426,39 @@
* Check whether the @tsk process has the @cap capability in the indicated * Check whether the @tsk process has the @cap capability in the indicated
* credentials. * credentials.
* @cred contains the credentials to use. * @cred contains the credentials to use.
* @ns contains the user namespace we want the capability in * @ns contains the user namespace we want the capability in.
* @cap contains the capability <include/linux/capability.h>. * @cap contains the capability <include/linux/capability.h>.
* @opts contains options for the capable check <include/linux/security.h> * @opts contains options for the capable check <include/linux/security.h>.
* Return 0 if the capability is granted for @tsk. * Return 0 if the capability is granted for @tsk.
* @quotactl: * @quotactl:
* Check whether the quotactl syscall is allowed for this @sb. * Check whether the quotactl syscall is allowed for this @sb.
* Return 0 if permission is granted.
* @quota_on: * @quota_on:
* Check whether QUOTAON is allowed for this @dentry. * Check whether QUOTAON is allowed for this @dentry.
* Return 0 if permission is granted.
* @syslog: * @syslog:
* Check permission before accessing the kernel message ring or changing * Check permission before accessing the kernel message ring or changing
* logging to the console. * logging to the console.
* See the syslog(2) manual page for an explanation of the @type values. * See the syslog(2) manual page for an explanation of the @type values.
* @type contains the SYSLOG_ACTION_* constant from <include/linux/syslog.h> * @type contains the SYSLOG_ACTION_* constant from
* <include/linux/syslog.h>.
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @settime: * @settime:
* Check permission to change the system time. * Check permission to change the system time.
* struct timespec64 is defined in <include/linux/time64.h> and timezone * struct timespec64 is defined in <include/linux/time64.h> and timezone
* is defined in <include/linux/time.h> * is defined in <include/linux/time.h>
* @ts contains new time * @ts contains new time.
* @tz contains new timezone * @tz contains new timezone.
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @vm_enough_memory: * @vm_enough_memory:
* Check permissions for allocating a new virtual mapping. * Check permissions for allocating a new virtual mapping.
* @mm contains the mm struct it is being added to. * @mm contains the mm struct it is being added to.
* @pages contains the number of pages. * @pages contains the number of pages.
* Return 0 if permission is granted. * Return 0 if permission is granted by the LSM infrastructure to the
* caller. If all LSMs return a positive value, __vm_enough_memory() will
* be called with cap_sys_admin set. If at least one LSM returns 0 or
* negative, __vm_enough_memory() will be called with cap_sys_admin
* cleared.
* *
* @ismaclabel: * @ismaclabel:
* Check if the extended attribute specified by @name * Check if the extended attribute specified by @name
...@@ -1449,11 +1476,13 @@ ...@@ -1449,11 +1476,13 @@
* @secid contains the security ID. * @secid contains the security ID.
* @secdata contains the pointer that stores the converted security * @secdata contains the pointer that stores the converted security
* context. * context.
* @seclen pointer which contains the length of the data * @seclen pointer which contains the length of the data.
* Return 0 on success, error on failure.
* @secctx_to_secid: * @secctx_to_secid:
* Convert security context to secid. * Convert security context to secid.
* @secid contains the pointer to the generated security ID. * @secid contains the pointer to the generated security ID.
* @secdata contains the security context. * @secdata contains the security context.
* Return 0 on success, error on failure.
* *
* @release_secctx: * @release_secctx:
* Release the security context. * Release the security context.
...@@ -1490,7 +1519,7 @@ ...@@ -1490,7 +1519,7 @@
* @audit_rule_free: * @audit_rule_free:
* Deallocate the LSM audit rule structure previously allocated by * Deallocate the LSM audit rule structure previously allocated by
* audit_rule_init. * audit_rule_init.
* @lsmrule contains the allocated rule * @lsmrule contains the allocated rule.
* *
* @inode_invalidate_secctx: * @inode_invalidate_secctx:
* Notify the security module that it must revalidate the security context * Notify the security module that it must revalidate the security context
...@@ -1507,6 +1536,7 @@ ...@@ -1507,6 +1536,7 @@
* @inode we wish to set the security context of. * @inode we wish to set the security context of.
* @ctx contains the string which we wish to set in the inode. * @ctx contains the string which we wish to set in the inode.
* @ctxlen contains the length of @ctx. * @ctxlen contains the length of @ctx.
* Return 0 on success, error on failure.
* *
* @inode_setsecctx: * @inode_setsecctx:
* Change the security context of an inode. Updates the * Change the security context of an inode. Updates the
...@@ -1520,6 +1550,7 @@ ...@@ -1520,6 +1550,7 @@
* @dentry contains the inode we wish to set the security context of. * @dentry contains the inode we wish to set the security context of.
* @ctx contains the string which we wish to set in the inode. * @ctx contains the string which we wish to set in the inode.
* @ctxlen contains the length of @ctx. * @ctxlen contains the length of @ctx.
* Return 0 on success, error on failure.
* *
* @inode_getsecctx: * @inode_getsecctx:
* On success, returns 0 and fills out @ctx and @ctxlen with the security * On success, returns 0 and fills out @ctx and @ctxlen with the security
...@@ -1527,6 +1558,7 @@ ...@@ -1527,6 +1558,7 @@
* @inode we wish to get the security context of. * @inode we wish to get the security context of.
* @ctx is a pointer in which to place the allocated security context. * @ctx is a pointer in which to place the allocated security context.
* @ctxlen points to the place to put the length of @ctx. * @ctxlen points to the place to put the length of @ctx.
* Return 0 on success, error on failure.
* *
* Security hooks for the general notification queue: * Security hooks for the general notification queue:
* *
...@@ -1534,13 +1566,15 @@ ...@@ -1534,13 +1566,15 @@
* Check to see if a watch notification can be posted to a particular * Check to see if a watch notification can be posted to a particular
* queue. * queue.
* @w_cred: The credentials of the whoever set the watch. * @w_cred: The credentials of the whoever set the watch.
* @cred: The event-triggerer's credentials * @cred: The event-triggerer's credentials.
* @n: The notification being posted * @n: The notification being posted.
* Return 0 if permission is granted.
* *
* @watch_key: * @watch_key:
* Check to see if a process is allowed to watch for event notifications * Check to see if a process is allowed to watch for event notifications
* from a key or keyring. * from a key or keyring.
* @key: The key to watch. * @key: The key to watch.
* Return 0 if permission is granted.
* *
* Security hooks for using the eBPF maps and programs functionalities through * Security hooks for using the eBPF maps and programs functionalities through
* eBPF syscalls. * eBPF syscalls.
...@@ -1549,65 +1583,74 @@ ...@@ -1549,65 +1583,74 @@
* Do a initial check for all bpf syscalls after the attribute is copied * Do a initial check for all bpf syscalls after the attribute is copied
* into the kernel. The actual security module can implement their own * into the kernel. The actual security module can implement their own
* rules to check the specific cmd they need. * rules to check the specific cmd they need.
* Return 0 if permission is granted.
* *
* @bpf_map: * @bpf_map:
* Do a check when the kernel generate and return a file descriptor for * Do a check when the kernel generate and return a file descriptor for
* eBPF maps. * eBPF maps.
* * @map: bpf map that we want to access.
* @map: bpf map that we want to access * @mask: the access flags.
* @mask: the access flags * Return 0 if permission is granted.
* *
* @bpf_prog: * @bpf_prog:
* Do a check when the kernel generate and return a file descriptor for * Do a check when the kernel generate and return a file descriptor for
* eBPF programs. * eBPF programs.
*
* @prog: bpf prog that userspace want to use. * @prog: bpf prog that userspace want to use.
* Return 0 if permission is granted.
* *
* @bpf_map_alloc_security: * @bpf_map_alloc_security:
* Initialize the security field inside bpf map. * Initialize the security field inside bpf map.
* Return 0 on success, error on failure.
* *
* @bpf_map_free_security: * @bpf_map_free_security:
* Clean up the security information stored inside bpf map. * Clean up the security information stored inside bpf map.
* *
* @bpf_prog_alloc_security: * @bpf_prog_alloc_security:
* Initialize the security field inside bpf program. * Initialize the security field inside bpf program.
* Return 0 on success, error on failure.
* *
* @bpf_prog_free_security: * @bpf_prog_free_security:
* Clean up the security information stored inside bpf prog. * Clean up the security information stored inside bpf prog.
* *
* @locked_down: * @locked_down:
* Determine whether a kernel feature that potentially enables arbitrary * Determine whether a kernel feature that potentially enables arbitrary
* code execution in kernel space should be permitted. * code execution in kernel space should be permitted.
* * @what: kernel feature being accessed.
* @what: kernel feature being accessed * Return 0 if permission is granted.
* *
* Security hooks for perf events * Security hooks for perf events
* *
* @perf_event_open: * @perf_event_open:
* Check whether the @type of perf_event_open syscall is allowed. * Check whether the @type of perf_event_open syscall is allowed.
* Return 0 if permission is granted.
* @perf_event_alloc: * @perf_event_alloc:
* Allocate and save perf_event security info. * Allocate and save perf_event security info.
* Return 0 on success, error on failure.
* @perf_event_free: * @perf_event_free:
* Release (free) perf_event security info. * Release (free) perf_event security info.
* @perf_event_read: * @perf_event_read:
* Read perf_event security info if allowed. * Read perf_event security info if allowed.
* Return 0 if permission is granted.
* @perf_event_write: * @perf_event_write:
* Write perf_event security info if allowed. * Write perf_event security info if allowed.
* Return 0 if permission is granted.
* *
* Security hooks for io_uring * Security hooks for io_uring
* *
* @uring_override_creds: * @uring_override_creds:
* Check if the current task, executing an io_uring operation, is allowed * Check if the current task, executing an io_uring operation, is allowed
* to override it's credentials with @new. * to override it's credentials with @new.
* * @new: the new creds to use.
* @new: the new creds to use * Return 0 if permission is granted.
* *
* @uring_sqpoll: * @uring_sqpoll:
* Check whether the current task is allowed to spawn a io_uring polling * Check whether the current task is allowed to spawn a io_uring polling
* thread (IORING_SETUP_SQPOLL). * thread (IORING_SETUP_SQPOLL).
* Return 0 if permission is granted.
* *
* @uring_cmd: * @uring_cmd:
* Check whether the file_operations uring_cmd is allowed to run. * Check whether the file_operations uring_cmd is allowed to run.
* Return 0 if permission is granted.
* *
*/ */
union security_list_options { union security_list_options {
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/sockptr.h>
struct linux_binprm; struct linux_binprm;
struct cred; struct cred;
...@@ -1446,8 +1447,8 @@ int security_socket_getsockopt(struct socket *sock, int level, int optname); ...@@ -1446,8 +1447,8 @@ int security_socket_getsockopt(struct socket *sock, int level, int optname);
int security_socket_setsockopt(struct socket *sock, int level, int optname); int security_socket_setsockopt(struct socket *sock, int level, int optname);
int security_socket_shutdown(struct socket *sock, int how); int security_socket_shutdown(struct socket *sock, int how);
int security_sock_rcv_skb(struct sock *sk, struct sk_buff *skb); int security_sock_rcv_skb(struct sock *sk, struct sk_buff *skb);
int security_socket_getpeersec_stream(struct socket *sock, char __user *optval, int security_socket_getpeersec_stream(struct socket *sock, sockptr_t optval,
int __user *optlen, unsigned len); sockptr_t optlen, unsigned int len);
int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid); int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid);
int security_sk_alloc(struct sock *sk, int family, gfp_t priority); int security_sk_alloc(struct sock *sk, int family, gfp_t priority);
void security_sk_free(struct sock *sk); void security_sk_free(struct sock *sk);
...@@ -1583,8 +1584,10 @@ static inline int security_sock_rcv_skb(struct sock *sk, ...@@ -1583,8 +1584,10 @@ static inline int security_sock_rcv_skb(struct sock *sk,
return 0; return 0;
} }
static inline int security_socket_getpeersec_stream(struct socket *sock, char __user *optval, static inline int security_socket_getpeersec_stream(struct socket *sock,
int __user *optlen, unsigned len) sockptr_t optval,
sockptr_t optlen,
unsigned int len)
{ {
return -ENOPROTOOPT; return -ENOPROTOOPT;
} }
......
...@@ -74,9 +74,9 @@ int __vfs_removexattr_locked(struct user_namespace *, struct dentry *, ...@@ -74,9 +74,9 @@ int __vfs_removexattr_locked(struct user_namespace *, struct dentry *,
int vfs_removexattr(struct user_namespace *, struct dentry *, const char *); int vfs_removexattr(struct user_namespace *, struct dentry *, const char *);
ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size); ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size);
ssize_t vfs_getxattr_alloc(struct user_namespace *mnt_userns, int vfs_getxattr_alloc(struct user_namespace *mnt_userns,
struct dentry *dentry, const char *name, struct dentry *dentry, const char *name,
char **xattr_value, size_t size, gfp_t flags); char **xattr_value, size_t size, gfp_t flags);
int xattr_supported_namespace(struct inode *inode, const char *prefix); int xattr_supported_namespace(struct inode *inode, const char *prefix);
......
...@@ -1793,7 +1793,8 @@ int sk_getsockopt(struct sock *sk, int level, int optname, ...@@ -1793,7 +1793,8 @@ int sk_getsockopt(struct sock *sk, int level, int optname,
break; break;
case SO_PEERSEC: case SO_PEERSEC:
return security_socket_getpeersec_stream(sock, optval.user, optlen.user, len); return security_socket_getpeersec_stream(sock,
optval, optlen, len);
case SO_MARK: case SO_MARK:
v.val = sk->sk_mark; v.val = sk->sk_mark;
......
...@@ -311,10 +311,9 @@ static int aa_xattrs_match(const struct linux_binprm *bprm, ...@@ -311,10 +311,9 @@ static int aa_xattrs_match(const struct linux_binprm *bprm,
struct aa_profile *profile, unsigned int state) struct aa_profile *profile, unsigned int state)
{ {
int i; int i;
ssize_t size;
struct dentry *d; struct dentry *d;
char *value = NULL; char *value = NULL;
int value_size = 0, ret = profile->xattr_count; int size, value_size = 0, ret = profile->xattr_count;
if (!bprm || !profile->xattr_count) if (!bprm || !profile->xattr_count)
return 0; return 0;
......
...@@ -1117,11 +1117,10 @@ static struct aa_label *sk_peer_label(struct sock *sk) ...@@ -1117,11 +1117,10 @@ static struct aa_label *sk_peer_label(struct sock *sk)
* Note: for tcp only valid if using ipsec or cipso on lan * Note: for tcp only valid if using ipsec or cipso on lan
*/ */
static int apparmor_socket_getpeersec_stream(struct socket *sock, static int apparmor_socket_getpeersec_stream(struct socket *sock,
char __user *optval, sockptr_t optval, sockptr_t optlen,
int __user *optlen,
unsigned int len) unsigned int len)
{ {
char *name; char *name = NULL;
int slen, error = 0; int slen, error = 0;
struct aa_label *label; struct aa_label *label;
struct aa_label *peer; struct aa_label *peer;
...@@ -1138,23 +1137,21 @@ static int apparmor_socket_getpeersec_stream(struct socket *sock, ...@@ -1138,23 +1137,21 @@ static int apparmor_socket_getpeersec_stream(struct socket *sock,
/* don't include terminating \0 in slen, it breaks some apps */ /* don't include terminating \0 in slen, it breaks some apps */
if (slen < 0) { if (slen < 0) {
error = -ENOMEM; error = -ENOMEM;
} else { goto done;
if (slen > len) { }
error = -ERANGE; if (slen > len) {
} else if (copy_to_user(optval, name, slen)) { error = -ERANGE;
error = -EFAULT; goto done_len;
goto out;
}
if (put_user(slen, optlen))
error = -EFAULT;
out:
kfree(name);
} }
if (copy_to_sockptr(optval, name, slen))
error = -EFAULT;
done_len:
if (copy_to_sockptr(optlen, &slen, sizeof(slen)))
error = -EFAULT;
done: done:
end_current_label_crit_section(label); end_current_label_crit_section(label);
kfree(name);
return error; return error;
} }
......
...@@ -352,14 +352,14 @@ static __u32 sansflags(__u32 m) ...@@ -352,14 +352,14 @@ static __u32 sansflags(__u32 m)
return m & ~VFS_CAP_FLAGS_EFFECTIVE; return m & ~VFS_CAP_FLAGS_EFFECTIVE;
} }
static bool is_v2header(size_t size, const struct vfs_cap_data *cap) static bool is_v2header(int size, const struct vfs_cap_data *cap)
{ {
if (size != XATTR_CAPS_SZ_2) if (size != XATTR_CAPS_SZ_2)
return false; return false;
return sansflags(le32_to_cpu(cap->magic_etc)) == VFS_CAP_REVISION_2; return sansflags(le32_to_cpu(cap->magic_etc)) == VFS_CAP_REVISION_2;
} }
static bool is_v3header(size_t size, const struct vfs_cap_data *cap) static bool is_v3header(int size, const struct vfs_cap_data *cap)
{ {
if (size != XATTR_CAPS_SZ_3) if (size != XATTR_CAPS_SZ_3)
return false; return false;
...@@ -381,7 +381,7 @@ int cap_inode_getsecurity(struct user_namespace *mnt_userns, ...@@ -381,7 +381,7 @@ int cap_inode_getsecurity(struct user_namespace *mnt_userns,
struct inode *inode, const char *name, void **buffer, struct inode *inode, const char *name, void **buffer,
bool alloc) bool alloc)
{ {
int size, ret; int size;
kuid_t kroot; kuid_t kroot;
vfsuid_t vfsroot; vfsuid_t vfsroot;
u32 nsmagic, magic; u32 nsmagic, magic;
...@@ -398,22 +398,18 @@ int cap_inode_getsecurity(struct user_namespace *mnt_userns, ...@@ -398,22 +398,18 @@ int cap_inode_getsecurity(struct user_namespace *mnt_userns,
dentry = d_find_any_alias(inode); dentry = d_find_any_alias(inode);
if (!dentry) if (!dentry)
return -EINVAL; return -EINVAL;
size = vfs_getxattr_alloc(mnt_userns, dentry, XATTR_NAME_CAPS, &tmpbuf,
size = sizeof(struct vfs_ns_cap_data); sizeof(struct vfs_ns_cap_data), GFP_NOFS);
ret = (int)vfs_getxattr_alloc(mnt_userns, dentry, XATTR_NAME_CAPS,
&tmpbuf, size, GFP_NOFS);
dput(dentry); dput(dentry);
/* gcc11 complains if we don't check for !tmpbuf */
if (ret < 0 || !tmpbuf) { if (size < 0 || !tmpbuf)
size = ret;
goto out_free; goto out_free;
}
fs_ns = inode->i_sb->s_user_ns; fs_ns = inode->i_sb->s_user_ns;
cap = (struct vfs_cap_data *) tmpbuf; cap = (struct vfs_cap_data *) tmpbuf;
if (is_v2header((size_t) ret, cap)) { if (is_v2header(size, cap)) {
root = 0; root = 0;
} else if (is_v3header((size_t) ret, cap)) { } else if (is_v3header(size, cap)) {
nscap = (struct vfs_ns_cap_data *) tmpbuf; nscap = (struct vfs_ns_cap_data *) tmpbuf;
root = le32_to_cpu(nscap->rootid); root = le32_to_cpu(nscap->rootid);
} else { } else {
......
...@@ -82,6 +82,17 @@ static int dev_exceptions_copy(struct list_head *dest, struct list_head *orig) ...@@ -82,6 +82,17 @@ static int dev_exceptions_copy(struct list_head *dest, struct list_head *orig)
return -ENOMEM; return -ENOMEM;
} }
static void dev_exceptions_move(struct list_head *dest, struct list_head *orig)
{
struct dev_exception_item *ex, *tmp;
lockdep_assert_held(&devcgroup_mutex);
list_for_each_entry_safe(ex, tmp, orig, list) {
list_move_tail(&ex->list, dest);
}
}
/* /*
* called under devcgroup_mutex * called under devcgroup_mutex
*/ */
...@@ -604,11 +615,13 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup, ...@@ -604,11 +615,13 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup,
int count, rc = 0; int count, rc = 0;
struct dev_exception_item ex; struct dev_exception_item ex;
struct dev_cgroup *parent = css_to_devcgroup(devcgroup->css.parent); struct dev_cgroup *parent = css_to_devcgroup(devcgroup->css.parent);
struct dev_cgroup tmp_devcgrp;
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
memset(&ex, 0, sizeof(ex)); memset(&ex, 0, sizeof(ex));
memset(&tmp_devcgrp, 0, sizeof(tmp_devcgrp));
b = buffer; b = buffer;
switch (*b) { switch (*b) {
...@@ -620,15 +633,27 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup, ...@@ -620,15 +633,27 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup,
if (!may_allow_all(parent)) if (!may_allow_all(parent))
return -EPERM; return -EPERM;
dev_exception_clean(devcgroup); if (!parent) {
devcgroup->behavior = DEVCG_DEFAULT_ALLOW; devcgroup->behavior = DEVCG_DEFAULT_ALLOW;
if (!parent) dev_exception_clean(devcgroup);
break; break;
}
INIT_LIST_HEAD(&tmp_devcgrp.exceptions);
rc = dev_exceptions_copy(&tmp_devcgrp.exceptions,
&devcgroup->exceptions);
if (rc)
return rc;
dev_exception_clean(devcgroup);
rc = dev_exceptions_copy(&devcgroup->exceptions, rc = dev_exceptions_copy(&devcgroup->exceptions,
&parent->exceptions); &parent->exceptions);
if (rc) if (rc) {
dev_exceptions_move(&devcgroup->exceptions,
&tmp_devcgrp.exceptions);
return rc; return rc;
}
devcgroup->behavior = DEVCG_DEFAULT_ALLOW;
dev_exception_clean(&tmp_devcgrp);
break; break;
case DEVCG_DENY: case DEVCG_DENY:
if (css_has_online_children(&devcgroup->css)) if (css_has_online_children(&devcgroup->css))
......
...@@ -335,14 +335,15 @@ static int evm_is_immutable(struct dentry *dentry, struct inode *inode) ...@@ -335,14 +335,15 @@ static int evm_is_immutable(struct dentry *dentry, struct inode *inode)
(char **)&xattr_data, 0, GFP_NOFS); (char **)&xattr_data, 0, GFP_NOFS);
if (rc <= 0) { if (rc <= 0) {
if (rc == -ENODATA) if (rc == -ENODATA)
return 0; rc = 0;
return rc; goto out;
} }
if (xattr_data->type == EVM_XATTR_PORTABLE_DIGSIG) if (xattr_data->type == EVM_XATTR_PORTABLE_DIGSIG)
rc = 1; rc = 1;
else else
rc = 0; rc = 0;
out:
kfree(xattr_data); kfree(xattr_data);
return rc; return rc;
} }
......
...@@ -455,14 +455,17 @@ static int evm_xattr_change(struct user_namespace *mnt_userns, ...@@ -455,14 +455,17 @@ static int evm_xattr_change(struct user_namespace *mnt_userns,
rc = vfs_getxattr_alloc(&init_user_ns, dentry, xattr_name, &xattr_data, rc = vfs_getxattr_alloc(&init_user_ns, dentry, xattr_name, &xattr_data,
0, GFP_NOFS); 0, GFP_NOFS);
if (rc < 0) if (rc < 0) {
return 1; rc = 1;
goto out;
}
if (rc == xattr_value_len) if (rc == xattr_value_len)
rc = !!memcmp(xattr_value, xattr_data, rc); rc = !!memcmp(xattr_value, xattr_data, rc);
else else
rc = 1; rc = 1;
out:
kfree(xattr_data); kfree(xattr_data);
return rc; return rc;
} }
......
...@@ -326,7 +326,7 @@ enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint, ...@@ -326,7 +326,7 @@ enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
enum hash_algo ima_get_hash_algo(const struct evm_ima_xattr_data *xattr_value, enum hash_algo ima_get_hash_algo(const struct evm_ima_xattr_data *xattr_value,
int xattr_len); int xattr_len);
int ima_read_xattr(struct dentry *dentry, int ima_read_xattr(struct dentry *dentry,
struct evm_ima_xattr_data **xattr_value); struct evm_ima_xattr_data **xattr_value, int xattr_len);
#else #else
static inline int ima_check_blacklist(struct integrity_iint_cache *iint, static inline int ima_check_blacklist(struct integrity_iint_cache *iint,
...@@ -372,7 +372,8 @@ ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, int xattr_len) ...@@ -372,7 +372,8 @@ ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, int xattr_len)
} }
static inline int ima_read_xattr(struct dentry *dentry, static inline int ima_read_xattr(struct dentry *dentry,
struct evm_ima_xattr_data **xattr_value) struct evm_ima_xattr_data **xattr_value,
int xattr_len)
{ {
return 0; return 0;
} }
......
...@@ -221,12 +221,12 @@ enum hash_algo ima_get_hash_algo(const struct evm_ima_xattr_data *xattr_value, ...@@ -221,12 +221,12 @@ enum hash_algo ima_get_hash_algo(const struct evm_ima_xattr_data *xattr_value,
} }
int ima_read_xattr(struct dentry *dentry, int ima_read_xattr(struct dentry *dentry,
struct evm_ima_xattr_data **xattr_value) struct evm_ima_xattr_data **xattr_value, int xattr_len)
{ {
ssize_t ret; int ret;
ret = vfs_getxattr_alloc(&init_user_ns, dentry, XATTR_NAME_IMA, ret = vfs_getxattr_alloc(&init_user_ns, dentry, XATTR_NAME_IMA,
(char **)xattr_value, 0, GFP_NOFS); (char **)xattr_value, xattr_len, GFP_NOFS);
if (ret == -EOPNOTSUPP) if (ret == -EOPNOTSUPP)
ret = 0; ret = 0;
return ret; return ret;
......
...@@ -293,7 +293,8 @@ static int process_measurement(struct file *file, const struct cred *cred, ...@@ -293,7 +293,8 @@ static int process_measurement(struct file *file, const struct cred *cred,
/* HASH sets the digital signature and update flags, nothing else */ /* HASH sets the digital signature and update flags, nothing else */
if ((action & IMA_HASH) && if ((action & IMA_HASH) &&
!(test_bit(IMA_DIGSIG, &iint->atomic_flags))) { !(test_bit(IMA_DIGSIG, &iint->atomic_flags))) {
xattr_len = ima_read_xattr(file_dentry(file), &xattr_value); xattr_len = ima_read_xattr(file_dentry(file),
&xattr_value, xattr_len);
if ((xattr_value && xattr_len > 2) && if ((xattr_value && xattr_len > 2) &&
(xattr_value->type == EVM_IMA_XATTR_DIGSIG)) (xattr_value->type == EVM_IMA_XATTR_DIGSIG))
set_bit(IMA_DIGSIG, &iint->atomic_flags); set_bit(IMA_DIGSIG, &iint->atomic_flags);
...@@ -316,7 +317,8 @@ static int process_measurement(struct file *file, const struct cred *cred, ...@@ -316,7 +317,8 @@ static int process_measurement(struct file *file, const struct cred *cred,
if ((action & IMA_APPRAISE_SUBMASK) || if ((action & IMA_APPRAISE_SUBMASK) ||
strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) != 0) { strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) != 0) {
/* read 'security.ima' */ /* read 'security.ima' */
xattr_len = ima_read_xattr(file_dentry(file), &xattr_value); xattr_len = ima_read_xattr(file_dentry(file),
&xattr_value, xattr_len);
/* /*
* Read the appended modsig if allowed by the policy, and allow * Read the appended modsig if allowed by the policy, and allow
......
...@@ -601,16 +601,15 @@ int ima_eventevmsig_init(struct ima_event_data *event_data, ...@@ -601,16 +601,15 @@ int ima_eventevmsig_init(struct ima_event_data *event_data,
rc = vfs_getxattr_alloc(&init_user_ns, file_dentry(event_data->file), rc = vfs_getxattr_alloc(&init_user_ns, file_dentry(event_data->file),
XATTR_NAME_EVM, (char **)&xattr_data, 0, XATTR_NAME_EVM, (char **)&xattr_data, 0,
GFP_NOFS); GFP_NOFS);
if (rc <= 0) if (rc <= 0 || xattr_data->type != EVM_XATTR_PORTABLE_DIGSIG) {
return 0; rc = 0;
goto out;
if (xattr_data->type != EVM_XATTR_PORTABLE_DIGSIG) {
kfree(xattr_data);
return 0;
} }
rc = ima_write_template_field_data((char *)xattr_data, rc, DATA_FMT_HEX, rc = ima_write_template_field_data((char *)xattr_data, rc, DATA_FMT_HEX,
field_data); field_data);
out:
kfree(xattr_data); kfree(xattr_data);
return rc; return rc;
} }
......
...@@ -190,6 +190,7 @@ static inline void print_ipv4_addr(struct audit_buffer *ab, __be32 addr, ...@@ -190,6 +190,7 @@ static inline void print_ipv4_addr(struct audit_buffer *ab, __be32 addr,
/** /**
* dump_common_audit_data - helper to dump common audit data * dump_common_audit_data - helper to dump common audit data
* @ab : the audit buffer
* @a : common audit data * @a : common audit data
* *
*/ */
......
...@@ -161,8 +161,8 @@ static void __init append_ordered_lsm(struct lsm_info *lsm, const char *from) ...@@ -161,8 +161,8 @@ static void __init append_ordered_lsm(struct lsm_info *lsm, const char *from)
lsm->enabled = &lsm_enabled_true; lsm->enabled = &lsm_enabled_true;
ordered_lsms[last_lsm++] = lsm; ordered_lsms[last_lsm++] = lsm;
init_debug("%s ordering: %s (%sabled)\n", from, lsm->name, init_debug("%s ordered: %s (%s)\n", from, lsm->name,
is_enabled(lsm) ? "en" : "dis"); is_enabled(lsm) ? "enabled" : "disabled");
} }
/* Is an LSM allowed to be initialized? */ /* Is an LSM allowed to be initialized? */
...@@ -225,7 +225,7 @@ static void __init prepare_lsm(struct lsm_info *lsm) ...@@ -225,7 +225,7 @@ static void __init prepare_lsm(struct lsm_info *lsm)
if (enabled) { if (enabled) {
if ((lsm->flags & LSM_FLAG_EXCLUSIVE) && !exclusive) { if ((lsm->flags & LSM_FLAG_EXCLUSIVE) && !exclusive) {
exclusive = lsm; exclusive = lsm;
init_debug("exclusive chosen: %s\n", lsm->name); init_debug("exclusive chosen: %s\n", lsm->name);
} }
lsm_set_blob_sizes(lsm->blobs); lsm_set_blob_sizes(lsm->blobs);
...@@ -253,7 +253,7 @@ static void __init ordered_lsm_parse(const char *order, const char *origin) ...@@ -253,7 +253,7 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
/* LSM_ORDER_FIRST is always first. */ /* LSM_ORDER_FIRST is always first. */
for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) { for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
if (lsm->order == LSM_ORDER_FIRST) if (lsm->order == LSM_ORDER_FIRST)
append_ordered_lsm(lsm, "first"); append_ordered_lsm(lsm, " first");
} }
/* Process "security=", if given. */ /* Process "security=", if given. */
...@@ -271,7 +271,7 @@ static void __init ordered_lsm_parse(const char *order, const char *origin) ...@@ -271,7 +271,7 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
if ((major->flags & LSM_FLAG_LEGACY_MAJOR) && if ((major->flags & LSM_FLAG_LEGACY_MAJOR) &&
strcmp(major->name, chosen_major_lsm) != 0) { strcmp(major->name, chosen_major_lsm) != 0) {
set_enabled(major, false); set_enabled(major, false);
init_debug("security=%s disabled: %s\n", init_debug("security=%s disabled: %s (only one legacy major LSM)\n",
chosen_major_lsm, major->name); chosen_major_lsm, major->name);
} }
} }
...@@ -292,7 +292,8 @@ static void __init ordered_lsm_parse(const char *order, const char *origin) ...@@ -292,7 +292,8 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
} }
if (!found) if (!found)
init_debug("%s ignored: %s\n", origin, name); init_debug("%s ignored: %s (not built into kernel)\n",
origin, name);
} }
/* Process "security=", if given. */ /* Process "security=", if given. */
...@@ -310,7 +311,8 @@ static void __init ordered_lsm_parse(const char *order, const char *origin) ...@@ -310,7 +311,8 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
if (exists_ordered_lsm(lsm)) if (exists_ordered_lsm(lsm))
continue; continue;
set_enabled(lsm, false); set_enabled(lsm, false);
init_debug("%s disabled: %s\n", origin, lsm->name); init_debug("%s skipped: %s (not in requested order)\n",
origin, lsm->name);
} }
kfree(sep); kfree(sep);
...@@ -321,6 +323,24 @@ static void __init lsm_early_task(struct task_struct *task); ...@@ -321,6 +323,24 @@ static void __init lsm_early_task(struct task_struct *task);
static int lsm_append(const char *new, char **result); static int lsm_append(const char *new, char **result);
static void __init report_lsm_order(void)
{
struct lsm_info **lsm, *early;
int first = 0;
pr_info("initializing lsm=");
/* Report each enabled LSM name, comma separated. */
for (early = __start_early_lsm_info; early < __end_early_lsm_info; early++)
if (is_enabled(early))
pr_cont("%s%s", first++ == 0 ? "" : ",", early->name);
for (lsm = ordered_lsms; *lsm; lsm++)
if (is_enabled(*lsm))
pr_cont("%s%s", first++ == 0 ? "" : ",", (*lsm)->name);
pr_cont("\n");
}
static void __init ordered_lsm_init(void) static void __init ordered_lsm_init(void)
{ {
struct lsm_info **lsm; struct lsm_info **lsm;
...@@ -330,7 +350,8 @@ static void __init ordered_lsm_init(void) ...@@ -330,7 +350,8 @@ static void __init ordered_lsm_init(void)
if (chosen_lsm_order) { if (chosen_lsm_order) {
if (chosen_major_lsm) { if (chosen_major_lsm) {
pr_info("security= is ignored because it is superseded by lsm=\n"); pr_warn("security=%s is ignored because it is superseded by lsm=%s\n",
chosen_major_lsm, chosen_lsm_order);
chosen_major_lsm = NULL; chosen_major_lsm = NULL;
} }
ordered_lsm_parse(chosen_lsm_order, "cmdline"); ordered_lsm_parse(chosen_lsm_order, "cmdline");
...@@ -340,6 +361,8 @@ static void __init ordered_lsm_init(void) ...@@ -340,6 +361,8 @@ static void __init ordered_lsm_init(void)
for (lsm = ordered_lsms; *lsm; lsm++) for (lsm = ordered_lsms; *lsm; lsm++)
prepare_lsm(*lsm); prepare_lsm(*lsm);
report_lsm_order();
init_debug("cred blob size = %d\n", blob_sizes.lbs_cred); init_debug("cred blob size = %d\n", blob_sizes.lbs_cred);
init_debug("file blob size = %d\n", blob_sizes.lbs_file); init_debug("file blob size = %d\n", blob_sizes.lbs_file);
init_debug("inode blob size = %d\n", blob_sizes.lbs_inode); init_debug("inode blob size = %d\n", blob_sizes.lbs_inode);
...@@ -396,13 +419,17 @@ int __init security_init(void) ...@@ -396,13 +419,17 @@ int __init security_init(void)
{ {
struct lsm_info *lsm; struct lsm_info *lsm;
pr_info("Security Framework initializing\n"); init_debug("legacy security=%s\n", chosen_major_lsm ?: " *unspecified*");
init_debug(" CONFIG_LSM=%s\n", builtin_lsm_order);
init_debug("boot arg lsm=%s\n", chosen_lsm_order ?: " *unspecified*");
/* /*
* Append the names of the early LSM modules now that kmalloc() is * Append the names of the early LSM modules now that kmalloc() is
* available * available
*/ */
for (lsm = __start_early_lsm_info; lsm < __end_early_lsm_info; lsm++) { for (lsm = __start_early_lsm_info; lsm < __end_early_lsm_info; lsm++) {
init_debug(" early started: %s (%s)\n", lsm->name,
is_enabled(lsm) ? "enabled" : "disabled");
if (lsm->enabled) if (lsm->enabled)
lsm_append(lsm->name, &lsm_names); lsm_append(lsm->name, &lsm_names);
} }
...@@ -2315,11 +2342,11 @@ int security_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) ...@@ -2315,11 +2342,11 @@ int security_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
} }
EXPORT_SYMBOL(security_sock_rcv_skb); EXPORT_SYMBOL(security_sock_rcv_skb);
int security_socket_getpeersec_stream(struct socket *sock, char __user *optval, int security_socket_getpeersec_stream(struct socket *sock, sockptr_t optval,
int __user *optlen, unsigned len) sockptr_t optlen, unsigned int len)
{ {
return call_int_hook(socket_getpeersec_stream, -ENOPROTOOPT, sock, return call_int_hook(socket_getpeersec_stream, -ENOPROTOOPT, sock,
optval, optlen, len); optval, optlen, len);
} }
int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid) int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid)
......
...@@ -5138,11 +5138,12 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) ...@@ -5138,11 +5138,12 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
return err; return err;
} }
static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *optval, static int selinux_socket_getpeersec_stream(struct socket *sock,
int __user *optlen, unsigned len) sockptr_t optval, sockptr_t optlen,
unsigned int len)
{ {
int err = 0; int err = 0;
char *scontext; char *scontext = NULL;
u32 scontext_len; u32 scontext_len;
struct sk_security_struct *sksec = sock->sk->sk_security; struct sk_security_struct *sksec = sock->sk->sk_security;
u32 peer_sid = SECSID_NULL; u32 peer_sid = SECSID_NULL;
...@@ -5158,17 +5159,15 @@ static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *op ...@@ -5158,17 +5159,15 @@ static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *op
&scontext_len); &scontext_len);
if (err) if (err)
return err; return err;
if (scontext_len > len) { if (scontext_len > len) {
err = -ERANGE; err = -ERANGE;
goto out_len; goto out_len;
} }
if (copy_to_user(optval, scontext, scontext_len)) if (copy_to_sockptr(optval, scontext, scontext_len))
err = -EFAULT; err = -EFAULT;
out_len: out_len:
if (put_user(scontext_len, optlen)) if (copy_to_sockptr(optlen, &scontext_len, sizeof(scontext_len)))
err = -EFAULT; err = -EFAULT;
kfree(scontext); kfree(scontext);
return err; return err;
......
...@@ -4074,12 +4074,12 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) ...@@ -4074,12 +4074,12 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
* returns zero on success, an error code otherwise * returns zero on success, an error code otherwise
*/ */
static int smack_socket_getpeersec_stream(struct socket *sock, static int smack_socket_getpeersec_stream(struct socket *sock,
char __user *optval, sockptr_t optval, sockptr_t optlen,
int __user *optlen, unsigned len) unsigned int len)
{ {
struct socket_smack *ssp; struct socket_smack *ssp;
char *rcp = ""; char *rcp = "";
int slen = 1; u32 slen = 1;
int rc = 0; int rc = 0;
ssp = sock->sk->sk_security; ssp = sock->sk->sk_security;
...@@ -4087,15 +4087,16 @@ static int smack_socket_getpeersec_stream(struct socket *sock, ...@@ -4087,15 +4087,16 @@ static int smack_socket_getpeersec_stream(struct socket *sock,
rcp = ssp->smk_packet->smk_known; rcp = ssp->smk_packet->smk_known;
slen = strlen(rcp) + 1; slen = strlen(rcp) + 1;
} }
if (slen > len) {
if (slen > len)
rc = -ERANGE; rc = -ERANGE;
else if (copy_to_user(optval, rcp, slen) != 0) goto out_len;
rc = -EFAULT; }
if (put_user(slen, optlen) != 0) if (copy_to_sockptr(optval, rcp, slen))
rc = -EFAULT;
out_len:
if (copy_to_sockptr(optlen, &slen, sizeof(slen)))
rc = -EFAULT; rc = -EFAULT;
return rc; return rc;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment