linux/security/smack/smack_lsm.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 *  Simplified MAC Kernel (smack) security module
 *
 *  This file contains the smack hook function implementations.
 *
 *  Authors:
 *	Casey Schaufler <[email protected]>
 *	Jarkko Sakkinen <[email protected]>
 *
 *  Copyright (C) 2007 Casey Schaufler <[email protected]>
 *  Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
 *                Paul Moore <[email protected]>
 *  Copyright (C) 2010 Nokia Corporation
 *  Copyright (C) 2011 Intel Corporation.
 */

#include <linux/xattr.h>
#include <linux/pagemap.h>
#include <linux/mount.h>
#include <linux/stat.h>
#include <linux/kd.h>
#include <asm/ioctls.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/dccp.h>
#include <linux/icmpv6.h>
#include <linux/slab.h>
#include <linux/mutex.h>
#include <net/cipso_ipv4.h>
#include <net/ip.h>
#include <net/ipv6.h>
#include <linux/audit.h>
#include <linux/magic.h>
#include <linux/dcache.h>
#include <linux/personality.h>
#include <linux/msg.h>
#include <linux/shm.h>
#include <uapi/linux/shm.h>
#include <linux/binfmts.h>
#include <linux/parser.h>
#include <linux/fs_context.h>
#include <linux/fs_parser.h>
#include <linux/watch_queue.h>
#include <linux/io_uring/cmd.h>
#include <uapi/linux/lsm.h>
#include "smack.h"

#define TRANS_TRUE
#define TRANS_TRUE_SIZE

#define SMK_CONNECTING
#define SMK_RECEIVING
#define SMK_SENDING

/*
 * Smack uses multiple xattrs.
 * SMACK64 - for access control,
 * SMACK64TRANSMUTE - label initialization,
 * Not saved on files - SMACK64IPIN and SMACK64IPOUT,
 * Must be set explicitly - SMACK64EXEC and SMACK64MMAP
 */
#define SMACK_INODE_INIT_XATTRS

#ifdef SMACK_IPV6_PORT_LABELING
static DEFINE_MUTEX(smack_ipv6_lock);
static LIST_HEAD(smk_ipv6_port_list);
#endif
struct kmem_cache *smack_rule_cache;
int smack_enabled __initdata;

#define A
static struct {} smk_mount_opts[] =;
#undef A

static int match_opt_prefix(char *s, int l, char **arg)
{}

#ifdef CONFIG_SECURITY_SMACK_BRINGUP
static char *smk_bu_mess[] =;

static void smk_bu_mode(int mode, char *s)
{}
#endif

#ifdef CONFIG_SECURITY_SMACK_BRINGUP
static int smk_bu_note(char *note, struct smack_known *sskp,
		       struct smack_known *oskp, int mode, int rc)
{}
#else
#define smk_bu_note
#endif

#ifdef CONFIG_SECURITY_SMACK_BRINGUP
static int smk_bu_current(char *note, struct smack_known *oskp,
			  int mode, int rc)
{}
#else
#define smk_bu_current
#endif

#ifdef CONFIG_SECURITY_SMACK_BRINGUP
static int smk_bu_task(struct task_struct *otp, int mode, int rc)
{}
#else
#define smk_bu_task
#endif

#ifdef CONFIG_SECURITY_SMACK_BRINGUP
static int smk_bu_inode(struct inode *inode, int mode, int rc)
{}
#else
#define smk_bu_inode
#endif

#ifdef CONFIG_SECURITY_SMACK_BRINGUP
static int smk_bu_file(struct file *file, int mode, int rc)
{}
#else
#define smk_bu_file
#endif

#ifdef CONFIG_SECURITY_SMACK_BRINGUP
static int smk_bu_credfile(const struct cred *cred, struct file *file,
				int mode, int rc)
{}
#else
#define smk_bu_credfile
#endif

/**
 * smk_fetch - Fetch the smack label from a file.
 * @name: type of the label (attribute)
 * @ip: a pointer to the inode
 * @dp: a pointer to the dentry
 *
 * Returns a pointer to the master list entry for the Smack label,
 * NULL if there was no label to fetch, or an error code.
 */
static struct smack_known *smk_fetch(const char *name, struct inode *ip,
					struct dentry *dp)
{}

/**
 * init_inode_smack - initialize an inode security blob
 * @inode: inode to extract the info from
 * @skp: a pointer to the Smack label entry to use in the blob
 *
 */
static void init_inode_smack(struct inode *inode, struct smack_known *skp)
{}

/**
 * init_task_smack - initialize a task security blob
 * @tsp: blob to initialize
 * @task: a pointer to the Smack label for the running task
 * @forked: a pointer to the Smack label for the forked task
 *
 */
static void init_task_smack(struct task_smack *tsp, struct smack_known *task,
					struct smack_known *forked)
{}

/**
 * smk_copy_rules - copy a rule set
 * @nhead: new rules header pointer
 * @ohead: old rules header pointer
 * @gfp: type of the memory for the allocation
 *
 * Returns 0 on success, -ENOMEM on error
 */
static int smk_copy_rules(struct list_head *nhead, struct list_head *ohead,
				gfp_t gfp)
{}

/**
 * smk_copy_relabel - copy smk_relabel labels list
 * @nhead: new rules header pointer
 * @ohead: old rules header pointer
 * @gfp: type of the memory for the allocation
 *
 * Returns 0 on success, -ENOMEM on error
 */
static int smk_copy_relabel(struct list_head *nhead, struct list_head *ohead,
				gfp_t gfp)
{}

/**
 * smk_ptrace_mode - helper function for converting PTRACE_MODE_* into MAY_*
 * @mode: input mode in form of PTRACE_MODE_*
 *
 * Returns a converted MAY_* mode usable by smack rules
 */
static inline unsigned int smk_ptrace_mode(unsigned int mode)
{}

/**
 * smk_ptrace_rule_check - helper for ptrace access
 * @tracer: tracer process
 * @tracee_known: label entry of the process that's about to be traced
 * @mode: ptrace attachment mode (PTRACE_MODE_*)
 * @func: name of the function that called us, used for audit
 *
 * Returns 0 on access granted, -error on error
 */
static int smk_ptrace_rule_check(struct task_struct *tracer,
				 struct smack_known *tracee_known,
				 unsigned int mode, const char *func)
{}

/*
 * LSM hooks.
 * We he, that is fun!
 */

/**
 * smack_ptrace_access_check - Smack approval on PTRACE_ATTACH
 * @ctp: child task pointer
 * @mode: ptrace attachment mode (PTRACE_MODE_*)
 *
 * Returns 0 if access is OK, an error code otherwise
 *
 * Do the capability checks.
 */
static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode)
{}

/**
 * smack_ptrace_traceme - Smack approval on PTRACE_TRACEME
 * @ptp: parent task pointer
 *
 * Returns 0 if access is OK, an error code otherwise
 *
 * Do the capability checks, and require PTRACE_MODE_ATTACH.
 */
static int smack_ptrace_traceme(struct task_struct *ptp)
{}

/**
 * smack_syslog - Smack approval on syslog
 * @typefrom_file: unused
 *
 * Returns 0 on success, error code otherwise.
 */
static int smack_syslog(int typefrom_file)
{}

/*
 * Superblock Hooks.
 */

/**
 * smack_sb_alloc_security - allocate a superblock blob
 * @sb: the superblock getting the blob
 *
 * Returns 0 on success or -ENOMEM on error.
 */
static int smack_sb_alloc_security(struct super_block *sb)
{}

struct smack_mnt_opts {};

static void smack_free_mnt_opts(void *mnt_opts)
{}

static int smack_add_opt(int token, const char *s, void **mnt_opts)
{}

/**
 * smack_fs_context_submount - Initialise security data for a filesystem context
 * @fc: The filesystem context.
 * @reference: reference superblock
 *
 * Returns 0 on success or -ENOMEM on error.
 */
static int smack_fs_context_submount(struct fs_context *fc,
				 struct super_block *reference)
{}

/**
 * smack_fs_context_dup - Duplicate the security data on fs_context duplication
 * @fc: The new filesystem context.
 * @src_fc: The source filesystem context being duplicated.
 *
 * Returns 0 on success or -ENOMEM on error.
 */
static int smack_fs_context_dup(struct fs_context *fc,
				struct fs_context *src_fc)
{}

static const struct fs_parameter_spec smack_fs_parameters[] =;

/**
 * smack_fs_context_parse_param - Parse a single mount parameter
 * @fc: The new filesystem context being constructed.
 * @param: The parameter.
 *
 * Returns 0 on success, -ENOPARAM to pass the parameter on or anything else on
 * error.
 */
static int smack_fs_context_parse_param(struct fs_context *fc,
					struct fs_parameter *param)
{}

static int smack_sb_eat_lsm_opts(char *options, void **mnt_opts)
{}

/**
 * smack_set_mnt_opts - set Smack specific mount options
 * @sb: the file system superblock
 * @mnt_opts: Smack mount options
 * @kern_flags: mount option from kernel space or user space
 * @set_kern_flags: where to store converted mount opts
 *
 * Returns 0 on success, an error code on failure
 *
 * Allow filesystems with binary mount data to explicitly set Smack mount
 * labels.
 */
static int smack_set_mnt_opts(struct super_block *sb,
		void *mnt_opts,
		unsigned long kern_flags,
		unsigned long *set_kern_flags)
{}

/**
 * smack_sb_statfs - Smack check on statfs
 * @dentry: identifies the file system in question
 *
 * Returns 0 if current can read the floor of the filesystem,
 * and error code otherwise
 */
static int smack_sb_statfs(struct dentry *dentry)
{}

/*
 * BPRM hooks
 */

/**
 * smack_bprm_creds_for_exec - Update bprm->cred if needed for exec
 * @bprm: the exec information
 *
 * Returns 0 if it gets a blob, -EPERM if exec forbidden and -ENOMEM otherwise
 */
static int smack_bprm_creds_for_exec(struct linux_binprm *bprm)
{}

/*
 * Inode hooks
 */

/**
 * smack_inode_alloc_security - allocate an inode blob
 * @inode: the inode in need of a blob
 *
 * Returns 0
 */
static int smack_inode_alloc_security(struct inode *inode)
{}

/**
 * smack_inode_init_security - copy out the smack from an inode
 * @inode: the newly created inode
 * @dir: containing directory object
 * @qstr: unused
 * @xattrs: where to put the attributes
 * @xattr_count: current number of LSM-provided xattrs (updated)
 *
 * Returns 0 if it all works out, -ENOMEM if there's no memory
 */
static int smack_inode_init_security(struct inode *inode, struct inode *dir,
				     const struct qstr *qstr,
				     struct xattr *xattrs, int *xattr_count)
{}

/**
 * smack_inode_link - Smack check on link
 * @old_dentry: the existing object
 * @dir: unused
 * @new_dentry: the new object
 *
 * Returns 0 if access is permitted, an error code otherwise
 */
static int smack_inode_link(struct dentry *old_dentry, struct inode *dir,
			    struct dentry *new_dentry)
{}

/**
 * smack_inode_unlink - Smack check on inode deletion
 * @dir: containing directory object
 * @dentry: file to unlink
 *
 * Returns 0 if current can write the containing directory
 * and the object, error code otherwise
 */
static int smack_inode_unlink(struct inode *dir, struct dentry *dentry)
{}

/**
 * smack_inode_rmdir - Smack check on directory deletion
 * @dir: containing directory object
 * @dentry: directory to unlink
 *
 * Returns 0 if current can write the containing directory
 * and the directory, error code otherwise
 */
static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry)
{}

/**
 * smack_inode_rename - Smack check on rename
 * @old_inode: unused
 * @old_dentry: the old object
 * @new_inode: unused
 * @new_dentry: the new object
 *
 * Read and write access is required on both the old and
 * new directories.
 *
 * Returns 0 if access is permitted, an error code otherwise
 */
static int smack_inode_rename(struct inode *old_inode,
			      struct dentry *old_dentry,
			      struct inode *new_inode,
			      struct dentry *new_dentry)
{}

/**
 * smack_inode_permission - Smack version of permission()
 * @inode: the inode in question
 * @mask: the access requested
 *
 * This is the important Smack hook.
 *
 * Returns 0 if access is permitted, an error code otherwise
 */
static int smack_inode_permission(struct inode *inode, int mask)
{}

/**
 * smack_inode_setattr - Smack check for setting attributes
 * @idmap: idmap of the mount
 * @dentry: the object
 * @iattr: for the force flag
 *
 * Returns 0 if access is permitted, an error code otherwise
 */
static int smack_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
			       struct iattr *iattr)
{}

/**
 * smack_inode_getattr - Smack check for getting attributes
 * @path: path to extract the info from
 *
 * Returns 0 if access is permitted, an error code otherwise
 */
static int smack_inode_getattr(const struct path *path)
{}

/**
 * smack_inode_xattr_skipcap - Skip the xattr capability checks?
 * @name: name of the xattr
 *
 * Returns 1 to indicate that Smack "owns" the access control rights to xattrs
 * named @name; the LSM layer should avoid enforcing any traditional
 * capability based access controls on this xattr.  Returns 0 to indicate that
 * Smack does not "own" the access control rights to xattrs named @name and is
 * deferring to the LSM layer for further access controls, including capability
 * based controls.
 */
static int smack_inode_xattr_skipcap(const char *name)
{}

/**
 * smack_inode_setxattr - Smack check for setting xattrs
 * @idmap: idmap of the mount
 * @dentry: the object
 * @name: name of the attribute
 * @value: value of the attribute
 * @size: size of the value
 * @flags: unused
 *
 * This protects the Smack attribute explicitly.
 *
 * Returns 0 if access is permitted, an error code otherwise
 */
static int smack_inode_setxattr(struct mnt_idmap *idmap,
				struct dentry *dentry, const char *name,
				const void *value, size_t size, int flags)
{}

/**
 * smack_inode_post_setxattr - Apply the Smack update approved above
 * @dentry: object
 * @name: attribute name
 * @value: attribute value
 * @size: attribute size
 * @flags: unused
 *
 * Set the pointer in the inode blob to the entry found
 * in the master label list.
 */
static void smack_inode_post_setxattr(struct dentry *dentry, const char *name,
				      const void *value, size_t size, int flags)
{}

/**
 * smack_inode_getxattr - Smack check on getxattr
 * @dentry: the object
 * @name: unused
 *
 * Returns 0 if access is permitted, an error code otherwise
 */
static int smack_inode_getxattr(struct dentry *dentry, const char *name)
{}

/**
 * smack_inode_removexattr - Smack check on removexattr
 * @idmap: idmap of the mount
 * @dentry: the object
 * @name: name of the attribute
 *
 * Removing the Smack attribute requires CAP_MAC_ADMIN
 *
 * Returns 0 if access is permitted, an error code otherwise
 */
static int smack_inode_removexattr(struct mnt_idmap *idmap,
				   struct dentry *dentry, const char *name)
{}

/**
 * smack_inode_set_acl - Smack check for setting posix acls
 * @idmap: idmap of the mnt this request came from
 * @dentry: the object
 * @acl_name: name of the posix acl
 * @kacl: the posix acls
 *
 * Returns 0 if access is permitted, an error code otherwise
 */
static int smack_inode_set_acl(struct mnt_idmap *idmap,
			       struct dentry *dentry, const char *acl_name,
			       struct posix_acl *kacl)
{}

/**
 * smack_inode_get_acl - Smack check for getting posix acls
 * @idmap: idmap of the mnt this request came from
 * @dentry: the object
 * @acl_name: name of the posix acl
 *
 * Returns 0 if access is permitted, an error code otherwise
 */
static int smack_inode_get_acl(struct mnt_idmap *idmap,
			       struct dentry *dentry, const char *acl_name)
{}

/**
 * smack_inode_remove_acl - Smack check for getting posix acls
 * @idmap: idmap of the mnt this request came from
 * @dentry: the object
 * @acl_name: name of the posix acl
 *
 * Returns 0 if access is permitted, an error code otherwise
 */
static int smack_inode_remove_acl(struct mnt_idmap *idmap,
				  struct dentry *dentry, const char *acl_name)
{}

/**
 * smack_inode_getsecurity - get smack xattrs
 * @idmap: idmap of the mount
 * @inode: the object
 * @name: attribute name
 * @buffer: where to put the result
 * @alloc: duplicate memory
 *
 * Returns the size of the attribute or an error code
 */
static int smack_inode_getsecurity(struct mnt_idmap *idmap,
				   struct inode *inode, const char *name,
				   void **buffer, bool alloc)
{}


/**
 * smack_inode_listsecurity - list the Smack attributes
 * @inode: the object
 * @buffer: where they go
 * @buffer_size: size of buffer
 */
static int smack_inode_listsecurity(struct inode *inode, char *buffer,
				    size_t buffer_size)
{}

/**
 * smack_inode_getsecid - Extract inode's security id
 * @inode: inode to extract the info from
 * @secid: where result will be saved
 */
static void smack_inode_getsecid(struct inode *inode, u32 *secid)
{}

/*
 * File Hooks
 */

/*
 * There is no smack_file_permission hook
 *
 * Should access checks be done on each read or write?
 * UNICOS and SELinux say yes.
 * Trusted Solaris, Trusted Irix, and just about everyone else says no.
 *
 * I'll say no for now. Smack does not do the frequent
 * label changing that SELinux does.
 */

/**
 * smack_file_alloc_security - assign a file security blob
 * @file: the object
 *
 * The security blob for a file is a pointer to the master
 * label list, so no allocation is done.
 *
 * f_security is the owner security information. It
 * isn't used on file access checks, it's for send_sigio.
 *
 * Returns 0
 */
static int smack_file_alloc_security(struct file *file)
{}

/**
 * smack_file_ioctl - Smack check on ioctls
 * @file: the object
 * @cmd: what to do
 * @arg: unused
 *
 * Relies heavily on the correct use of the ioctl command conventions.
 *
 * Returns 0 if allowed, error code otherwise
 */
static int smack_file_ioctl(struct file *file, unsigned int cmd,
			    unsigned long arg)
{}

/**
 * smack_file_lock - Smack check on file locking
 * @file: the object
 * @cmd: unused
 *
 * Returns 0 if current has lock access, error code otherwise
 */
static int smack_file_lock(struct file *file, unsigned int cmd)
{}

/**
 * smack_file_fcntl - Smack check on fcntl
 * @file: the object
 * @cmd: what action to check
 * @arg: unused
 *
 * Generally these operations are harmless.
 * File locking operations present an obvious mechanism
 * for passing information, so they require write access.
 *
 * Returns 0 if current has access, error code otherwise
 */
static int smack_file_fcntl(struct file *file, unsigned int cmd,
			    unsigned long arg)
{}

/**
 * smack_mmap_file - Check permissions for a mmap operation.
 * @file: contains the file structure for file to map (may be NULL).
 * @reqprot: contains the protection requested by the application.
 * @prot: contains the protection that will be applied by the kernel.
 * @flags: contains the operational flags.
 *
 * The @file may be NULL, e.g. if mapping anonymous memory.
 *
 * Return 0 if permission is granted.
 */
static int smack_mmap_file(struct file *file,
			   unsigned long reqprot, unsigned long prot,
			   unsigned long flags)
{}

/**
 * smack_file_set_fowner - set the file security blob value
 * @file: object in question
 *
 */
static void smack_file_set_fowner(struct file *file)
{}

/**
 * smack_file_send_sigiotask - Smack on sigio
 * @tsk: The target task
 * @fown: the object the signal come from
 * @signum: unused
 *
 * Allow a privileged task to get signals even if it shouldn't
 *
 * Returns 0 if a subject with the object's smack could
 * write to the task, an error code otherwise.
 */
static int smack_file_send_sigiotask(struct task_struct *tsk,
				     struct fown_struct *fown, int signum)
{}

/**
 * smack_file_receive - Smack file receive check
 * @file: the object
 *
 * Returns 0 if current has access, error code otherwise
 */
static int smack_file_receive(struct file *file)
{}

/**
 * smack_file_open - Smack dentry open processing
 * @file: the object
 *
 * Set the security blob in the file structure.
 * Allow the open only if the task has read access. There are
 * many read operations (e.g. fstat) that you can do with an
 * fd even if you have the file open write-only.
 *
 * Returns 0 if current has access, error code otherwise
 */
static int smack_file_open(struct file *file)
{}

/*
 * Task hooks
 */

/**
 * smack_cred_alloc_blank - "allocate" blank task-level security credentials
 * @cred: the new credentials
 * @gfp: the atomicity of any memory allocations
 *
 * Prepare a blank set of credentials for modification.  This must allocate all
 * the memory the LSM module might require such that cred_transfer() can
 * complete without error.
 */
static int smack_cred_alloc_blank(struct cred *cred, gfp_t gfp)
{}


/**
 * smack_cred_free - "free" task-level security credentials
 * @cred: the credentials in question
 *
 */
static void smack_cred_free(struct cred *cred)
{}

/**
 * smack_cred_prepare - prepare new set of credentials for modification
 * @new: the new credentials
 * @old: the original credentials
 * @gfp: the atomicity of any memory allocations
 *
 * Prepare a new set of credentials for modification.
 */
static int smack_cred_prepare(struct cred *new, const struct cred *old,
			      gfp_t gfp)
{}

/**
 * smack_cred_transfer - Transfer the old credentials to the new credentials
 * @new: the new credentials
 * @old: the original credentials
 *
 * Fill in a set of blank credentials from another set of credentials.
 */
static void smack_cred_transfer(struct cred *new, const struct cred *old)
{}

/**
 * smack_cred_getsecid - get the secid corresponding to a creds structure
 * @cred: the object creds
 * @secid: where to put the result
 *
 * Sets the secid to contain a u32 version of the smack label.
 */
static void smack_cred_getsecid(const struct cred *cred, u32 *secid)
{}

/**
 * smack_kernel_act_as - Set the subjective context in a set of credentials
 * @new: points to the set of credentials to be modified.
 * @secid: specifies the security ID to be set
 *
 * Set the security data for a kernel service.
 */
static int smack_kernel_act_as(struct cred *new, u32 secid)
{}

/**
 * smack_kernel_create_files_as - Set the file creation label in a set of creds
 * @new: points to the set of credentials to be modified
 * @inode: points to the inode to use as a reference
 *
 * Set the file creation context in a set of credentials to the same
 * as the objective context of the specified inode
 */
static int smack_kernel_create_files_as(struct cred *new,
					struct inode *inode)
{}

/**
 * smk_curacc_on_task - helper to log task related access
 * @p: the task object
 * @access: the access requested
 * @caller: name of the calling function for audit
 *
 * Return 0 if access is permitted
 */
static int smk_curacc_on_task(struct task_struct *p, int access,
				const char *caller)
{}

/**
 * smack_task_setpgid - Smack check on setting pgid
 * @p: the task object
 * @pgid: unused
 *
 * Return 0 if write access is permitted
 */
static int smack_task_setpgid(struct task_struct *p, pid_t pgid)
{}

/**
 * smack_task_getpgid - Smack access check for getpgid
 * @p: the object task
 *
 * Returns 0 if current can read the object task, error code otherwise
 */
static int smack_task_getpgid(struct task_struct *p)
{}

/**
 * smack_task_getsid - Smack access check for getsid
 * @p: the object task
 *
 * Returns 0 if current can read the object task, error code otherwise
 */
static int smack_task_getsid(struct task_struct *p)
{}

/**
 * smack_current_getsecid_subj - get the subjective secid of the current task
 * @secid: where to put the result
 *
 * Sets the secid to contain a u32 version of the task's subjective smack label.
 */
static void smack_current_getsecid_subj(u32 *secid)
{}

/**
 * smack_task_getsecid_obj - get the objective secid of the task
 * @p: the task
 * @secid: where to put the result
 *
 * Sets the secid to contain a u32 version of the task's objective smack label.
 */
static void smack_task_getsecid_obj(struct task_struct *p, u32 *secid)
{}

/**
 * smack_task_setnice - Smack check on setting nice
 * @p: the task object
 * @nice: unused
 *
 * Return 0 if write access is permitted
 */
static int smack_task_setnice(struct task_struct *p, int nice)
{}

/**
 * smack_task_setioprio - Smack check on setting ioprio
 * @p: the task object
 * @ioprio: unused
 *
 * Return 0 if write access is permitted
 */
static int smack_task_setioprio(struct task_struct *p, int ioprio)
{}

/**
 * smack_task_getioprio - Smack check on reading ioprio
 * @p: the task object
 *
 * Return 0 if read access is permitted
 */
static int smack_task_getioprio(struct task_struct *p)
{}

/**
 * smack_task_setscheduler - Smack check on setting scheduler
 * @p: the task object
 *
 * Return 0 if read access is permitted
 */
static int smack_task_setscheduler(struct task_struct *p)
{}

/**
 * smack_task_getscheduler - Smack check on reading scheduler
 * @p: the task object
 *
 * Return 0 if read access is permitted
 */
static int smack_task_getscheduler(struct task_struct *p)
{}

/**
 * smack_task_movememory - Smack check on moving memory
 * @p: the task object
 *
 * Return 0 if write access is permitted
 */
static int smack_task_movememory(struct task_struct *p)
{}

/**
 * smack_task_kill - Smack check on signal delivery
 * @p: the task object
 * @info: unused
 * @sig: unused
 * @cred: identifies the cred to use in lieu of current's
 *
 * Return 0 if write access is permitted
 *
 */
static int smack_task_kill(struct task_struct *p, struct kernel_siginfo *info,
			   int sig, const struct cred *cred)
{}

/**
 * smack_task_to_inode - copy task smack into the inode blob
 * @p: task to copy from
 * @inode: inode to copy to
 *
 * Sets the smack pointer in the inode security blob
 */
static void smack_task_to_inode(struct task_struct *p, struct inode *inode)
{}

/*
 * Socket hooks.
 */

/**
 * smack_sk_alloc_security - Allocate a socket blob
 * @sk: the socket
 * @family: unused
 * @gfp_flags: memory allocation flags
 *
 * Assign Smack pointers to current
 *
 * Returns 0 on success, -ENOMEM is there's no memory
 */
static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags)
{}

/**
 * smack_sk_free_security - Free a socket blob
 * @sk: the socket
 *
 * Clears the blob pointer
 */
static void smack_sk_free_security(struct sock *sk)
{}

/**
 * smack_sk_clone_security - Copy security context
 * @sk: the old socket
 * @newsk: the new socket
 *
 * Copy the security context of the old socket pointer to the cloned
 */
static void smack_sk_clone_security(const struct sock *sk, struct sock *newsk)
{}

/**
* smack_ipv4host_label - check host based restrictions
* @sip: the object end
*
* looks for host based access restrictions
*
* This version will only be appropriate for really small sets of single label
* hosts.  The caller is responsible for ensuring that the RCU read lock is
* taken before calling this function.
*
* Returns the label of the far end or NULL if it's not special.
*/
static struct smack_known *smack_ipv4host_label(struct sockaddr_in *sip)
{}

/*
 * smk_ipv6_localhost - Check for local ipv6 host address
 * @sip: the address
 *
 * Returns boolean true if this is the localhost address
 */
static bool smk_ipv6_localhost(struct sockaddr_in6 *sip)
{}

/**
* smack_ipv6host_label - check host based restrictions
* @sip: the object end
*
* looks for host based access restrictions
*
* This version will only be appropriate for really small sets of single label
* hosts.  The caller is responsible for ensuring that the RCU read lock is
* taken before calling this function.
*
* Returns the label of the far end or NULL if it's not special.
*/
static struct smack_known *smack_ipv6host_label(struct sockaddr_in6 *sip)
{}

/**
 * smack_netlbl_add - Set the secattr on a socket
 * @sk: the socket
 *
 * Attach the outbound smack value (smk_out) to the socket.
 *
 * Returns 0 on success or an error code
 */
static int smack_netlbl_add(struct sock *sk)
{}

/**
 * smack_netlbl_delete - Remove the secattr from a socket
 * @sk: the socket
 *
 * Remove the outbound smack value from a socket
 */
static void smack_netlbl_delete(struct sock *sk)
{}

/**
 * smk_ipv4_check - Perform IPv4 host access checks
 * @sk: the socket
 * @sap: the destination address
 *
 * Set the correct secattr for the given socket based on the destination
 * address and perform any outbound access checks needed.
 *
 * Returns 0 on success or an error code.
 *
 */
static int smk_ipv4_check(struct sock *sk, struct sockaddr_in *sap)
{}

/**
 * smk_ipv6_check - check Smack access
 * @subject: subject Smack label
 * @object: object Smack label
 * @address: address
 * @act: the action being taken
 *
 * Check an IPv6 access
 */
static int smk_ipv6_check(struct smack_known *subject,
				struct smack_known *object,
				struct sockaddr_in6 *address, int act)
{}

#ifdef SMACK_IPV6_PORT_LABELING
/**
 * smk_ipv6_port_label - Smack port access table management
 * @sock: socket
 * @address: address
 *
 * Create or update the port list entry
 */
static void smk_ipv6_port_label(struct socket *sock, struct sockaddr *address)
{
	struct sock *sk = sock->sk;
	struct sockaddr_in6 *addr6;
	struct socket_smack *ssp = sock->sk->sk_security;
	struct smk_port_label *spp;
	unsigned short port = 0;

	if (address == NULL) {
		/*
		 * This operation is changing the Smack information
		 * on the bound socket. Take the changes to the port
		 * as well.
		 */
		rcu_read_lock();
		list_for_each_entry_rcu(spp, &smk_ipv6_port_list, list) {
			if (sk != spp->smk_sock)
				continue;
			spp->smk_in = ssp->smk_in;
			spp->smk_out = ssp->smk_out;
			rcu_read_unlock();
			return;
		}
		/*
		 * A NULL address is only used for updating existing
		 * bound entries. If there isn't one, it's OK.
		 */
		rcu_read_unlock();
		return;
	}

	addr6 = (struct sockaddr_in6 *)address;
	port = ntohs(addr6->sin6_port);
	/*
	 * This is a special case that is safely ignored.
	 */
	if (port == 0)
		return;

	/*
	 * Look for an existing port list entry.
	 * This is an indication that a port is getting reused.
	 */
	rcu_read_lock();
	list_for_each_entry_rcu(spp, &smk_ipv6_port_list, list) {
		if (spp->smk_port != port || spp->smk_sock_type != sock->type)
			continue;
		if (spp->smk_can_reuse != 1) {
			rcu_read_unlock();
			return;
		}
		spp->smk_port = port;
		spp->smk_sock = sk;
		spp->smk_in = ssp->smk_in;
		spp->smk_out = ssp->smk_out;
		spp->smk_can_reuse = 0;
		rcu_read_unlock();
		return;
	}
	rcu_read_unlock();
	/*
	 * A new port entry is required.
	 */
	spp = kzalloc(sizeof(*spp), GFP_KERNEL);
	if (spp == NULL)
		return;

	spp->smk_port = port;
	spp->smk_sock = sk;
	spp->smk_in = ssp->smk_in;
	spp->smk_out = ssp->smk_out;
	spp->smk_sock_type = sock->type;
	spp->smk_can_reuse = 0;

	mutex_lock(&smack_ipv6_lock);
	list_add_rcu(&spp->list, &smk_ipv6_port_list);
	mutex_unlock(&smack_ipv6_lock);
	return;
}

/**
 * smk_ipv6_port_check - check Smack port access
 * @sk: socket
 * @address: address
 * @act: the action being taken
 *
 * Create or update the port list entry
 */
static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address,
				int act)
{
	struct smk_port_label *spp;
	struct socket_smack *ssp = sk->sk_security;
	struct smack_known *skp = NULL;
	unsigned short port;
	struct smack_known *object;

	if (act == SMK_RECEIVING) {
		skp = smack_ipv6host_label(address);
		object = ssp->smk_in;
	} else {
		skp = ssp->smk_out;
		object = smack_ipv6host_label(address);
	}

	/*
	 * The other end is a single label host.
	 */
	if (skp != NULL && object != NULL)
		return smk_ipv6_check(skp, object, address, act);
	if (skp == NULL)
		skp = smack_net_ambient;
	if (object == NULL)
		object = smack_net_ambient;

	/*
	 * It's remote, so port lookup does no good.
	 */
	if (!smk_ipv6_localhost(address))
		return smk_ipv6_check(skp, object, address, act);

	/*
	 * It's local so the send check has to have passed.
	 */
	if (act == SMK_RECEIVING)
		return 0;

	port = ntohs(address->sin6_port);
	rcu_read_lock();
	list_for_each_entry_rcu(spp, &smk_ipv6_port_list, list) {
		if (spp->smk_port != port || spp->smk_sock_type != sk->sk_type)
			continue;
		object = spp->smk_in;
		if (act == SMK_CONNECTING)
			ssp->smk_packet = spp->smk_out;
		break;
	}
	rcu_read_unlock();

	return smk_ipv6_check(skp, object, address, act);
}
#endif

/**
 * smack_inode_setsecurity - set smack xattrs
 * @inode: the object
 * @name: attribute name
 * @value: attribute value
 * @size: size of the attribute
 * @flags: unused
 *
 * Sets the named attribute in the appropriate blob
 *
 * Returns 0 on success, or an error code
 */
static int smack_inode_setsecurity(struct inode *inode, const char *name,
				   const void *value, size_t size, int flags)
{}

/**
 * smack_socket_post_create - finish socket setup
 * @sock: the socket
 * @family: protocol family
 * @type: unused
 * @protocol: unused
 * @kern: unused
 *
 * Sets the netlabel information on the socket
 *
 * Returns 0 on success, and error code otherwise
 */
static int smack_socket_post_create(struct socket *sock, int family,
				    int type, int protocol, int kern)
{}

/**
 * smack_socket_socketpair - create socket pair
 * @socka: one socket
 * @sockb: another socket
 *
 * Cross reference the peer labels for SO_PEERSEC
 *
 * Returns 0
 */
static int smack_socket_socketpair(struct socket *socka,
		                   struct socket *sockb)
{}

#ifdef SMACK_IPV6_PORT_LABELING
/**
 * smack_socket_bind - record port binding information.
 * @sock: the socket
 * @address: the port address
 * @addrlen: size of the address
 *
 * Records the label bound to a port.
 *
 * Returns 0 on success, and error code otherwise
 */
static int smack_socket_bind(struct socket *sock, struct sockaddr *address,
				int addrlen)
{
	if (sock->sk != NULL && sock->sk->sk_family == PF_INET6) {
		if (addrlen < SIN6_LEN_RFC2133 ||
		    address->sa_family != AF_INET6)
			return -EINVAL;
		smk_ipv6_port_label(sock, address);
	}
	return 0;
}
#endif /* SMACK_IPV6_PORT_LABELING */

/**
 * smack_socket_connect - connect access check
 * @sock: the socket
 * @sap: the other end
 * @addrlen: size of sap
 *
 * Verifies that a connection may be possible
 *
 * Returns 0 on success, and error code otherwise
 */
static int smack_socket_connect(struct socket *sock, struct sockaddr *sap,
				int addrlen)
{}

/**
 * smack_flags_to_may - convert S_ to MAY_ values
 * @flags: the S_ value
 *
 * Returns the equivalent MAY_ value
 */
static int smack_flags_to_may(int flags)
{}

/**
 * smack_msg_msg_alloc_security - Set the security blob for msg_msg
 * @msg: the object
 *
 * Returns 0
 */
static int smack_msg_msg_alloc_security(struct msg_msg *msg)
{}

/**
 * smack_of_ipc - the smack pointer for the ipc
 * @isp: the object
 *
 * Returns a pointer to the smack value
 */
static struct smack_known *smack_of_ipc(struct kern_ipc_perm *isp)
{}

/**
 * smack_ipc_alloc_security - Set the security blob for ipc
 * @isp: the object
 *
 * Returns 0
 */
static int smack_ipc_alloc_security(struct kern_ipc_perm *isp)
{}

/**
 * smk_curacc_shm : check if current has access on shm
 * @isp : the object
 * @access : access requested
 *
 * Returns 0 if current has the requested access, error code otherwise
 */
static int smk_curacc_shm(struct kern_ipc_perm *isp, int access)
{}

/**
 * smack_shm_associate - Smack access check for shm
 * @isp: the object
 * @shmflg: access requested
 *
 * Returns 0 if current has the requested access, error code otherwise
 */
static int smack_shm_associate(struct kern_ipc_perm *isp, int shmflg)
{}

/**
 * smack_shm_shmctl - Smack access check for shm
 * @isp: the object
 * @cmd: what it wants to do
 *
 * Returns 0 if current has the requested access, error code otherwise
 */
static int smack_shm_shmctl(struct kern_ipc_perm *isp, int cmd)
{}

/**
 * smack_shm_shmat - Smack access for shmat
 * @isp: the object
 * @shmaddr: unused
 * @shmflg: access requested
 *
 * Returns 0 if current has the requested access, error code otherwise
 */
static int smack_shm_shmat(struct kern_ipc_perm *isp, char __user *shmaddr,
			   int shmflg)
{}

/**
 * smk_curacc_sem : check if current has access on sem
 * @isp : the object
 * @access : access requested
 *
 * Returns 0 if current has the requested access, error code otherwise
 */
static int smk_curacc_sem(struct kern_ipc_perm *isp, int access)
{}

/**
 * smack_sem_associate - Smack access check for sem
 * @isp: the object
 * @semflg: access requested
 *
 * Returns 0 if current has the requested access, error code otherwise
 */
static int smack_sem_associate(struct kern_ipc_perm *isp, int semflg)
{}

/**
 * smack_sem_semctl - Smack access check for sem
 * @isp: the object
 * @cmd: what it wants to do
 *
 * Returns 0 if current has the requested access, error code otherwise
 */
static int smack_sem_semctl(struct kern_ipc_perm *isp, int cmd)
{}

/**
 * smack_sem_semop - Smack checks of semaphore operations
 * @isp: the object
 * @sops: unused
 * @nsops: unused
 * @alter: unused
 *
 * Treated as read and write in all cases.
 *
 * Returns 0 if access is allowed, error code otherwise
 */
static int smack_sem_semop(struct kern_ipc_perm *isp, struct sembuf *sops,
			   unsigned nsops, int alter)
{}

/**
 * smk_curacc_msq : helper to check if current has access on msq
 * @isp : the msq
 * @access : access requested
 *
 * return 0 if current has access, error otherwise
 */
static int smk_curacc_msq(struct kern_ipc_perm *isp, int access)
{}

/**
 * smack_msg_queue_associate - Smack access check for msg_queue
 * @isp: the object
 * @msqflg: access requested
 *
 * Returns 0 if current has the requested access, error code otherwise
 */
static int smack_msg_queue_associate(struct kern_ipc_perm *isp, int msqflg)
{}

/**
 * smack_msg_queue_msgctl - Smack access check for msg_queue
 * @isp: the object
 * @cmd: what it wants to do
 *
 * Returns 0 if current has the requested access, error code otherwise
 */
static int smack_msg_queue_msgctl(struct kern_ipc_perm *isp, int cmd)
{}

/**
 * smack_msg_queue_msgsnd - Smack access check for msg_queue
 * @isp: the object
 * @msg: unused
 * @msqflg: access requested
 *
 * Returns 0 if current has the requested access, error code otherwise
 */
static int smack_msg_queue_msgsnd(struct kern_ipc_perm *isp, struct msg_msg *msg,
				  int msqflg)
{}

/**
 * smack_msg_queue_msgrcv - Smack access check for msg_queue
 * @isp: the object
 * @msg: unused
 * @target: unused
 * @type: unused
 * @mode: unused
 *
 * Returns 0 if current has read and write access, error code otherwise
 */
static int smack_msg_queue_msgrcv(struct kern_ipc_perm *isp,
				  struct msg_msg *msg,
				  struct task_struct *target, long type,
				  int mode)
{}

/**
 * smack_ipc_permission - Smack access for ipc_permission()
 * @ipp: the object permissions
 * @flag: access requested
 *
 * Returns 0 if current has read and write access, error code otherwise
 */
static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag)
{}

/**
 * smack_ipc_getsecid - Extract smack security id
 * @ipp: the object permissions
 * @secid: where result will be saved
 */
static void smack_ipc_getsecid(struct kern_ipc_perm *ipp, u32 *secid)
{}

/**
 * smack_d_instantiate - Make sure the blob is correct on an inode
 * @opt_dentry: dentry where inode will be attached
 * @inode: the object
 *
 * Set the inode's security blob if it hasn't been done already.
 */
static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
{}

/**
 * smack_getselfattr - Smack current process attribute
 * @attr: which attribute to fetch
 * @ctx: buffer to receive the result
 * @size: available size in, actual size out
 * @flags: unused
 *
 * Fill the passed user space @ctx with the details of the requested
 * attribute.
 *
 * Returns the number of attributes on success, an error code otherwise.
 * There will only ever be one attribute.
 */
static int smack_getselfattr(unsigned int attr, struct lsm_ctx __user *ctx,
			     u32 *size, u32 flags)
{}

/**
 * smack_getprocattr - Smack process attribute access
 * @p: the object task
 * @name: the name of the attribute in /proc/.../attr
 * @value: where to put the result
 *
 * Places a copy of the task Smack into value
 *
 * Returns the length of the smack label or an error code
 */
static int smack_getprocattr(struct task_struct *p, const char *name, char **value)
{}

/**
 * do_setattr - Smack process attribute setting
 * @attr: the ID of the attribute
 * @value: the value to set
 * @size: the size of the value
 *
 * Sets the Smack value of the task. Only setting self
 * is permitted and only with privilege
 *
 * Returns the length of the smack label or an error code
 */
static int do_setattr(u64 attr, void *value, size_t size)
{}

/**
 * smack_setselfattr - Set a Smack process attribute
 * @attr: which attribute to set
 * @ctx: buffer containing the data
 * @size: size of @ctx
 * @flags: unused
 *
 * Fill the passed user space @ctx with the details of the requested
 * attribute.
 *
 * Returns 0 on success, an error code otherwise.
 */
static int smack_setselfattr(unsigned int attr, struct lsm_ctx *ctx,
			     u32 size, u32 flags)
{}

/**
 * smack_setprocattr - Smack process attribute setting
 * @name: the name of the attribute in /proc/.../attr
 * @value: the value to set
 * @size: the size of the value
 *
 * Sets the Smack value of the task. Only setting self
 * is permitted and only with privilege
 *
 * Returns the length of the smack label or an error code
 */
static int smack_setprocattr(const char *name, void *value, size_t size)
{}

/**
 * smack_unix_stream_connect - Smack access on UDS
 * @sock: one sock
 * @other: the other sock
 * @newsk: unused
 *
 * Return 0 if a subject with the smack of sock could access
 * an object with the smack of other, otherwise an error code
 */
static int smack_unix_stream_connect(struct sock *sock,
				     struct sock *other, struct sock *newsk)
{}

/**
 * smack_unix_may_send - Smack access on UDS
 * @sock: one socket
 * @other: the other socket
 *
 * Return 0 if a subject with the smack of sock could access
 * an object with the smack of other, otherwise an error code
 */
static int smack_unix_may_send(struct socket *sock, struct socket *other)
{}

/**
 * smack_socket_sendmsg - Smack check based on destination host
 * @sock: the socket
 * @msg: the message
 * @size: the size of the message
 *
 * Return 0 if the current subject can write to the destination host.
 * For IPv4 this is only a question if the destination is a single label host.
 * For IPv6 this is a check against the label of the port.
 */
static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
				int size)
{}

/**
 * smack_from_secattr - Convert a netlabel attr.mls.lvl/attr.mls.cat pair to smack
 * @sap: netlabel secattr
 * @ssp: socket security information
 *
 * Returns a pointer to a Smack label entry found on the label list.
 */
static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
						struct socket_smack *ssp)
{}

#if IS_ENABLED(CONFIG_IPV6)
static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip)
{}
#endif /* CONFIG_IPV6 */

/**
 * smack_from_skb - Smack data from the secmark in an skb
 * @skb: packet
 *
 * Returns smack_known of the secmark or NULL if that won't work.
 */
#ifdef CONFIG_NETWORK_SECMARK
static struct smack_known *smack_from_skb(struct sk_buff *skb)
{}
#else
static inline struct smack_known *smack_from_skb(struct sk_buff *skb)
{
	return NULL;
}
#endif

/**
 * smack_from_netlbl - Smack data from the IP options in an skb
 * @sk: socket data came in on
 * @family: address family
 * @skb: packet
 *
 * Find the Smack label in the IP options. If it hasn't been
 * added to the netlabel cache, add it here.
 *
 * Returns smack_known of the IP options or NULL if that won't work.
 */
static struct smack_known *smack_from_netlbl(const struct sock *sk, u16 family,
					     struct sk_buff *skb)
{}

/**
 * smack_socket_sock_rcv_skb - Smack packet delivery access check
 * @sk: socket
 * @skb: packet
 *
 * Returns 0 if the packet should be delivered, an error code otherwise
 */
static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
{}

/**
 * smack_socket_getpeersec_stream - pull in packet label
 * @sock: the socket
 * @optval: user's destination
 * @optlen: size thereof
 * @len: max thereof
 *
 * returns zero on success, an error code otherwise
 */
static int smack_socket_getpeersec_stream(struct socket *sock,
					  sockptr_t optval, sockptr_t optlen,
					  unsigned int len)
{}


/**
 * smack_socket_getpeersec_dgram - pull in packet label
 * @sock: the peer socket
 * @skb: packet data
 * @secid: pointer to where to put the secid of the packet
 *
 * Sets the netlabel socket state on sk from parent
 */
static int smack_socket_getpeersec_dgram(struct socket *sock,
					 struct sk_buff *skb, u32 *secid)

{}

/**
 * smack_sock_graft - Initialize a newly created socket with an existing sock
 * @sk: child sock
 * @parent: parent socket
 *
 * Set the smk_{in,out} state of an existing sock based on the process that
 * is creating the new socket.
 */
static void smack_sock_graft(struct sock *sk, struct socket *parent)
{}

/**
 * smack_inet_conn_request - Smack access check on connect
 * @sk: socket involved
 * @skb: packet
 * @req: unused
 *
 * Returns 0 if a task with the packet label could write to
 * the socket, otherwise an error code
 */
static int smack_inet_conn_request(const struct sock *sk, struct sk_buff *skb,
				   struct request_sock *req)
{}

/**
 * smack_inet_csk_clone - Copy the connection information to the new socket
 * @sk: the new socket
 * @req: the connection's request_sock
 *
 * Transfer the connection's peer label to the newly created socket.
 */
static void smack_inet_csk_clone(struct sock *sk,
				 const struct request_sock *req)
{}

/*
 * Key management security hooks
 *
 * Casey has not tested key support very heavily.
 * The permission check is most likely too restrictive.
 * If you care about keys please have a look.
 */
#ifdef CONFIG_KEYS

/**
 * smack_key_alloc - Set the key security blob
 * @key: object
 * @cred: the credentials to use
 * @flags: unused
 *
 * No allocation required
 *
 * Returns 0
 */
static int smack_key_alloc(struct key *key, const struct cred *cred,
			   unsigned long flags)
{}

/**
 * smack_key_free - Clear the key security blob
 * @key: the object
 *
 * Clear the blob pointer
 */
static void smack_key_free(struct key *key)
{}

/**
 * smack_key_permission - Smack access on a key
 * @key_ref: gets to the object
 * @cred: the credentials to use
 * @need_perm: requested key permission
 *
 * Return 0 if the task has read and write to the object,
 * an error code otherwise
 */
static int smack_key_permission(key_ref_t key_ref,
				const struct cred *cred,
				enum key_need_perm need_perm)
{}

/*
 * smack_key_getsecurity - Smack label tagging the key
 * @key points to the key to be queried
 * @_buffer points to a pointer that should be set to point to the
 * resulting string (if no label or an error occurs).
 * Return the length of the string (including terminating NUL) or -ve if
 * an error.
 * May also return 0 (and a NULL buffer pointer) if there is no label.
 */
static int smack_key_getsecurity(struct key *key, char **_buffer)
{}


#ifdef CONFIG_KEY_NOTIFICATIONS
/**
 * smack_watch_key - Smack access to watch a key for notifications.
 * @key: The key to be watched
 *
 * Return 0 if the @watch->cred has permission to read from the key object and
 * an error otherwise.
 */
static int smack_watch_key(struct key *key)
{}
#endif /* CONFIG_KEY_NOTIFICATIONS */
#endif /* CONFIG_KEYS */

#ifdef CONFIG_WATCH_QUEUE
/**
 * smack_post_notification - Smack access to post a notification to a queue
 * @w_cred: The credentials of the watcher.
 * @cred: The credentials of the event source (may be NULL).
 * @n: The notification message to be posted.
 */
static int smack_post_notification(const struct cred *w_cred,
				   const struct cred *cred,
				   struct watch_notification *n)
{}
#endif /* CONFIG_WATCH_QUEUE */

/*
 * Smack Audit hooks
 *
 * Audit requires a unique representation of each Smack specific
 * rule. This unique representation is used to distinguish the
 * object to be audited from remaining kernel objects and also
 * works as a glue between the audit hooks.
 *
 * Since repository entries are added but never deleted, we'll use
 * the smack_known label address related to the given audit rule as
 * the needed unique representation. This also better fits the smack
 * model where nearly everything is a label.
 */
#ifdef CONFIG_AUDIT

/**
 * smack_audit_rule_init - Initialize a smack audit rule
 * @field: audit rule fields given from user-space (audit.h)
 * @op: required testing operator (=, !=, >, <, ...)
 * @rulestr: smack label to be audited
 * @vrule: pointer to save our own audit rule representation
 * @gfp: type of the memory for the allocation
 *
 * Prepare to audit cases where (@field @op @rulestr) is true.
 * The label to be audited is created if necessay.
 */
static int smack_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule,
				 gfp_t gfp)
{}

/**
 * smack_audit_rule_known - Distinguish Smack audit rules
 * @krule: rule of interest, in Audit kernel representation format
 *
 * This is used to filter Smack rules from remaining Audit ones.
 * If it's proved that this rule belongs to us, the
 * audit_rule_match hook will be called to do the final judgement.
 */
static int smack_audit_rule_known(struct audit_krule *krule)
{}

/**
 * smack_audit_rule_match - Audit given object ?
 * @secid: security id for identifying the object to test
 * @field: audit rule flags given from user-space
 * @op: required testing operator
 * @vrule: smack internal rule presentation
 *
 * The core Audit hook. It's used to take the decision of
 * whether to audit or not to audit a given object.
 */
static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule)
{}

/*
 * There is no need for a smack_audit_rule_free hook.
 * No memory was allocated.
 */

#endif /* CONFIG_AUDIT */

/**
 * smack_ismaclabel - check if xattr @name references a smack MAC label
 * @name: Full xattr name to check.
 */
static int smack_ismaclabel(const char *name)
{}


/**
 * smack_secid_to_secctx - return the smack label for a secid
 * @secid: incoming integer
 * @secdata: destination
 * @seclen: how long it is
 *
 * Exists for networking code.
 */
static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
{}

/**
 * smack_secctx_to_secid - return the secid for a smack label
 * @secdata: smack label
 * @seclen: how long result is
 * @secid: outgoing integer
 *
 * Exists for audit and networking code.
 */
static int smack_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
{}

/*
 * There used to be a smack_release_secctx hook
 * that did nothing back when hooks were in a vector.
 * Now that there's a list such a hook adds cost.
 */

static int smack_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
{}

static int smack_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
{}

static int smack_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
{}

static int smack_inode_copy_up(struct dentry *dentry, struct cred **new)
{}

static int smack_inode_copy_up_xattr(struct dentry *src, const char *name)
{}

static int smack_dentry_create_files_as(struct dentry *dentry, int mode,
					struct qstr *name,
					const struct cred *old,
					struct cred *new)
{}

#ifdef CONFIG_IO_URING
/**
 * smack_uring_override_creds - Is io_uring cred override allowed?
 * @new: the target creds
 *
 * Check to see if the current task is allowed to override it's credentials
 * to service an io_uring operation.
 */
static int smack_uring_override_creds(const struct cred *new)
{}

/**
 * smack_uring_sqpoll - check if a io_uring polling thread can be created
 *
 * Check to see if the current task is allowed to create a new io_uring
 * kernel polling thread.
 */
static int smack_uring_sqpoll(void)
{}

/**
 * smack_uring_cmd - check on file operations for io_uring
 * @ioucmd: the command in question
 *
 * Make a best guess about whether a io_uring "command" should
 * be allowed. Use the same logic used for determining if the
 * file could be opened for read in the absence of better criteria.
 */
static int smack_uring_cmd(struct io_uring_cmd *ioucmd)
{}

#endif /* CONFIG_IO_URING */

struct lsm_blob_sizes smack_blob_sizes __ro_after_init =;

static const struct lsm_id smack_lsmid =;

static struct security_hook_list smack_hooks[] __ro_after_init =;


static __init void init_smack_known_list(void)
{}

/**
 * smack_init - initialize the smack system
 *
 * Returns 0 on success, -ENOMEM is there's no memory
 */
static __init int smack_init(void)
{}

/*
 * Smack requires early initialization in order to label
 * all processes and objects when they are created.
 */
DEFINE_LSM(smack) =;