/* * Linux Security plug * * Copyright (C) 2001 WireX Communications, Inc (chris@wirex.com) * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) * Copyright (C) 2001 Networks Associates Technology, Inc (ssmalley@nai.com) * Copyright (c) 2001 James Morris <jmorris@intercode.com.au> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #ifndef __LINUX_SECURITY_H #define __LINUX_SECURITY_H #ifdef __KERNEL__ #include <linux/fs.h> #include <linux/binfmts.h> #include <linux/signal.h> #include <linux/resource.h> #include <linux/sem.h> #include <linux/sysctl.h> #include <linux/shm.h> #include <linux/msg.h> /* change these every time the security_operations structure changes */ #define SECURITY_INTERFACE_VERSION 0x00000101 #define SECURITY_SCAFFOLD_VERSION "1.0.0" /* * Values used in the task_security_ops calls */ /* setuid or setgid, id0 == uid or gid */ #define LSM_SETID_ID 1 /* setreuid or setregid, id0 == real, id1 == eff */ #define LSM_SETID_RE 2 /* setresuid or setresgid, id0 == real, id1 == eff, uid2 == saved */ #define LSM_SETID_RES 4 /* setfsuid or setfsgid, id0 == fsuid or fsgid */ #define LSM_SETID_FS 8 /** * Security hooks for program execution operations. */ struct binprm_security_ops { /** * alloc_security - allocate security structure for linux_binprm * @bprm: linux_binprm structure to be modified * * called: do_execve <fs/exec.c> * * Allocate and attach a security structure to the bprm->security * field. The security field is initialized to NULL when the bprm * structure is allocated. Return 0 if operation was successful. */ int (* alloc_security) (struct linux_binprm *bprm); /** * free_security - deallocate security structure for linux_binprm * @bprm: linux_binprm structure to be modified * * called: do_execve <fs/exec.c> * * Deallocate and clear the bprm->security field. */ void (* free_security) (struct linux_binprm *bprm); /** * compute_creds - compute and set process security attributes * @bprm: linux_binprm structure * * called: compute_creds <fs/exec.c> * * Compute and set the security attributes of a process * being transformed by an execve operation based on the * old attributes (current->security) and the information * saved in bprm->security by the set_security hook. * Since this hook function (and its caller) are void, * this hook can not return an error. However, it can * leave the security attributes of the process unchanged * if an access failure occurs at this point. It can * also perform other state changes on the process (e.g. * closing open file descriptors to which access is no * longer granted if the attributes were changed). */ void (* compute_creds) (struct linux_binprm *bprm); /** * set_security - save security information in linux_binprm * @bprm: linux_binprm structure * * called: prepare_binprm <fs/exec.c> * * Save security information in the bprm->security field, * typically based on information about the bprm->file, * for later use by the compute_creds hook. This hook may * also optionally check permissions (e.g. for transitions between * security domains). Return 0 if the hook is successful * and permission is granted. * * This hook may be called multiple times during a single execve, * e.g. for interpreters. The hook can tell whether it has already * been called by checking to see if bprm->security is non-NULL. * If so, then the hook may decide either to retain the security * information saved earlier or to replace it. */ int (* set_security) (struct linux_binprm *bprm); }; /** * Security hooks for filesystem operations. */ struct super_block_security_ops { /** * alloc_security - allocate security structure for this filesystem * @sb: super_block structure to be modified * * called: read_super <fs/super.c> * * locks: lock_super() has been called, so the per-filesystem * semaphore is taken. The big kernel lock is held * by sys_mount. * * Allocate and attach a security structure to the * sb->s_security field. The s_security field is initialized to * NULL when the structure is allocated. Return 0 if * operation was successful. */ int (* alloc_security) (struct super_block *sb); /** * free_security - deallocate security structure for this filesystem * @sb: super_block structure to be modified * * called: read_super <fs/super.c> * called: kill_super <fs/super.c> * * locks: lock_super() has been called, so the per-filesystem * semaphore is taken. The big kernel lock is held * by sys_mount across the read_super call or by kill_super. * * Deallocate and clear the sb->s_security field. */ void (* free_security) (struct super_block *sb); /** * statfs - check permission when obtaining filesystem statistics * @sb: super_block structure for filesystem * * called: vfs_statfs <fs/open.c> * * Check permission before obtaining filesystem statistics * for the @sb filesystem. Return 0 if permission is granted. */ int (* statfs) (struct super_block *sb); /** * mount - check permission when mounting or remounting * @dev_name: name for object being mounted * @nd: nameidata structure for mount point object * @type: filesystem type * @flags: mount flags * @data: filesystem-specific data * * called: do_mount <fs/super.c> * * lock: The big kernel lock is held by sys_mount. * * Check permission before an object specified by @dev_name * is mounted on the mount point named by @nd. For an ordinary * mount, @dev_name identifies a device if the file system type * requires a device. For a remount (@flags & MS_REMOUNT), @dev_name * is irrelevant. For a loopback/bind mount (@flags & MS_BIND), * @dev_name identifies the pathname of the object being mounted. * Return 0 if permission is granted. */ int (* mount) (char * dev_name, struct nameidata *nd, char * type, unsigned long flags, void * data); /** * umount - check permission when unmounting a file system * @mnt: the mounted file system * @flags: unmount flags, e.g. MNT_FORCE * * called: do_umount <fs/super.c> * * lock: The mount semaphore and the big kernel lock are * held by sys_umount. * * Check permission before the @mnt file system is * unmounted. Return 0 if permission is granted. */ int (* umount) (struct vfsmount *mnt, int flags); /** * umount_close - close any files in a mounted filesystem held open by the security module * @mnt: the mounted filesystem * * called: do_umount <fs/super.c> * * locks: The mount semaphore and the big kernel lock are held * by sys_umount. * * Close any files in the @mnt mounted filesystem that are * held open by the security module. This hook is called during * an umount operation prior to checking whether the filesystem is * still busy. */ void (* umount_close) (struct vfsmount *mnt); /** * umount_busy - handle a failed umount of a filesystem * @mnt: the mounted filesystem * * called: do_umount <fs/super.c> * * locks: The mount semaphore and the big kernel lock are held * by sys_umount. * * Handle a failed umount of the @mnt mounted filesystem, e.g. * re-opening any files that were closed by umount_close. * This hook is called during an umount operation if the umount * fails after a call to the umount_close hook. */ void (* umount_busy) (struct vfsmount *mnt); /** * post_remount - Update module state when a filesystem is remounted * @mnt: the mounted file system * @flags: new filesystem flags * @data: filesystem-specific data * * called: do_remount <fs/super.c> * * lock: The big kernel lock is held by sys_mount. * * Update the security module's state when a filesystem is remounted. * This hook is only called if the remount was successful. */ void (* post_remount) (struct vfsmount *mnt, unsigned long flags, void *data); /** * post_mountroot - Update module state when the root filesystem is mounted * @sb: the super_block structure for the root filesystem * * called: mount_root <fs/super.c> * * Update the security module's state when the root filesystem * is mounted. This hook is only called if the mount was successful. */ void (* post_mountroot) (struct super_block *sb); /** * post_addmount - Update module state when a non-root filesystem is mounted * @mnt: the mounted filesystem * @mountpoint_nd: the nameidata structure for the mount point * * called: do_add_mount <fs/super.c> * * lock: The big kernel lock is held by sys_mount. * * Update the security module's state when a non-root filesystem is * mounted. This hook is not called after a loopback/bind mount. */ void (* post_addmount) (struct vfsmount *mnt, struct nameidata *mountpoint_nd); }; /** * Security hooks for inode operations. */ struct inode_security_ops { /** * alloc_security - allocate security structure for this inode * @inode: the inode structure * * called: alloc_inode <fs/inode.c> * * Allocate and attach a security structure to @inode->i_security. * The i_security field is initialized to NULL when the inode * structure is allocated. Return 0 if operation was successful. */ int (* alloc_security) (struct inode *inode); /** * free_security - deallocate security structure for this inode * @inode: the inode structure * * called: destroy_inode <fs/inode.c> * * Deallocate the inode security structure and set @inode->i_security * to NULL. */ void (* free_security) (struct inode *inode); /** * create - check the permissions when creating a directory or file * @dir: inode structure of the parent of the new file * @dentry: the dentry structure for the file to be created * @mode: the file mode of the file to be created * * called: vfs_create <fs/namei.c> * * lock: The @dir i_sem semaphore is held. * lock: The @dir i_zombie semaphore is held. * * Check permission to create a regular file. * Return 0 if permission is granted. */ int (* create) (struct inode *dir, struct dentry *dentry, int mode); /** * post_create - set the security attributes on a newly created file * @dir: inode structure of the parent directory of the new file * @dentry: the dentry structure for the newly created file * @mode: the file mode * * called: vfs_create <fs/namei.c> * * lock: The @dir i_sem semaphore is held. * * Set the security attributes on a newly created regular file. * This hook is called after a file has been successfully created. */ void (* post_create) (struct inode *dir, struct dentry *dentry, int mode); /** * link - check permissions when creating a hard link to a file * @old_dentry: dentry structure for an existing link to the file * @dir: the inode structure of the parent directory of the new link * @new_dentry: dentry structure for the new link * * called: vfs_link <fs/namei.c> * * lock: The @dir i_sem semaphore is held. * lock: The @dir i_zombie semaphore is held. * * Check permission before creating a new hard link to a file. * Return 0 if permission is granted. */ int (* link) (struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry); /** * post_link - set security attributes for a new file link * @old_dentry: dentry structure for the existing link * @dir: the inode structure of the parent directory of the new file * @new_dentry: dentry structure for the new file link * * called: vfs_link <fs/namei.c> * * lock: The @dir i_sem semaphore is held. * * Set security attributes for a new hard link to a file. */ void (* post_link) (struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry); /** * unlink - check permissions when unlinking a file * @dir: inode structure of parent directory of the file * @dentry: dentry structure for file to be unlinked * * called: vfs_unlink <fs/namei.c> * * lock: The @dir i_sem semaphore is held. * lock: The @dir i_zombie semaphore is held. * * Check the permission to remove a hard link to a file. * Return 0 if permission is granted. */ int (* unlink) (struct inode *dir, struct dentry *dentry); /** * symlink - check permissions when creating a symbolic link to a file * @dir: inode structure of parent directory of the symbolic link * @dentry: dentry structure of the symbolic link * @old_name: pathname of file * * called: vfs_symlink <fs/namei.c> * * lock: The @dir i_sem semaphore is held. * lock: The @dir i_zombie semaphore is held. * * Check the permission to create a symbolic link to a file. * Return 0 if permission is granted. */ int (* symlink) (struct inode *dir, struct dentry *dentry, const char *old_name); /** * post_symlink - set security attributes on a new symbolic link * @dir: inode structure of the parent directory of the new link * @dentry: dentry structure of new symbolic link * @old_name: pathname of file * * called: vfs_symlink <fs/namei.c> * * lock: The @dir i_sem semaphore is held. * * Set security attributes for a newly created symbolic link. * Note that @dentry->d_inode may be NULL, since the filesystem * might not instantiate the dentry (e.g. NFS). */ void (* post_symlink) (struct inode *dir, struct dentry *dentry, const char *old_name); /** * mkdir - check permissions when creating a directory * @dir: inode structure of parent of the directory to be created * @dentry: dentry structure of new directory * @mode: mode of new directory * * called: vfs_mkdir <fs/namei.c> * * lock: The @dir i_sem semaphore is held. * lock: The @dir i_zombie semaphore is held. * * Check permissions to create a new directory in the existing * directory associated with inode strcture @dir. * Return 0 if permission is granted. */ int (* mkdir) (struct inode *dir, struct dentry *dentry, int mode); /** * post_mkdir - set security attributes on new directory * @dir: inode structure of parent of the directory to be created * @dentry: dentry structure of new directory * @mode: mode of new directory * * called: vfs_mkdir <fs/namei.c> * * lock: The @dir i_sem semaphore is held. * * Set security attributes on a newly created directory. */ void (* post_mkdir) (struct inode *dir, struct dentry *dentry, int mode); /** * rmdir - check permissions when removing a directory * @dir: inode structure of parent of the directory to be removed * @dentry: dentry structure of directory to be removed * * called: vfs_rmdir <fs/namei.c> * * lock: The @dir i_sem semaphore is held. * lock: The @dir i_zombie semaphore is held. * lock: The @dentry->d_inode i_zombie semaphore is held. * * Check the permission to remove a directory. * Return 0 if permission is granted. */ int (* rmdir) (struct inode *dir, struct dentry *dentry); /** * mknod - check permissions when creating a special file * @dir: inode structure of parent of the new file * @dentry: dentry structure of the new file * @mode: mode of the new file * @dev: the device number * * called: vfs_mknod <fs/namei.c> * * lock: The @dir i_sem semaphore is held. * lock: The @dir i_zombie semaphore is held. * * Check permissions when creating a special file (or a * socket or a fifo file created via the mknod system call). * Note that if mknod operation is being done for a regular file, * then the create hook will be called and not this hook. * Return 0 if permission is granted. */ int (* mknod) (struct inode *dir, struct dentry *dentry, int mode, dev_t dev); /** * post_mknod - set security attributes on a special file * @dir: inode structure of parent of the new node * @dentry: dentry structure of the new node * @mode: mode of the new node * @dev: the device number * * called: vfs_mknod <fs/namei.c> * * lock: The @dir i_sem semaphore is held. * * Set security attributes on a newly created special file * (or socket or fifo file created via the mknod system call). */ void (* post_mknod) (struct inode *dir, struct dentry *dentry, int mode, dev_t dev); /** * rename - check permissions to rename a file or directory * @old_dir: inode structure for parent of the old link * @old_dentry: dentry structure of the old link * @new_dir: inode structure for parent of the new link * @new_dentry: dentry structure of the new link * * called: vfs_rename_dir <fs/namei.c> * called: vfs_rename_other <fs/namei.c> * * lock: The @old_dir->d_inode i_sem lock is held by do_rename. * lock: The @new_dir_d_inode i_sem lock is held by do_rename. * lock: The big kernel lock is held by do_rename <fs/namei.c> * * Check for permission to rename a file or directory. * Return 0 if permission is granted. */ int (* rename) (struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry); /** * post_rename - set security attributes on newly renamed file or directory * @old_dir: inode structure for parent of the old link * @old_dentry: dentry structure of the old link * @new_dir: inode structure for parent of the new link * @new_dentry: dentry structure of the new link * * called: vfs_rename_dir <fs/namei.c> * called: vfs_rename_other <fs/namei.c> * * lock: The big kernel lock is held by do_rename <fs/namei.c> * lock: The @old_dir->i_sb->s_vfs_rename_sem semaphore is held. * * Set security attributes on a renamed file or directory. */ void (* post_rename) (struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry); /** * readlink - check permissions when reading a symbolic link * @dentry: dentry structure for the file link * * called: sys_readlink <fs/stat.c> * * Check the permission to read the symbolic link. * Return 0 if permission is granted. */ int (* readlink) (struct dentry *dentry); /** * follow_link - check permission to follow symbolic links * @dentry: dentry structure for the link * @nd: nameidata structure for the parent directory * * called: do_follow_link <fs/namei.c> * called: open_namei <fs/namei.c> * * Check permission to follow a symbolic link when looking up * a pathname. Return 0 if permission is granted. */ int (* follow_link) (struct dentry *dentry, struct nameidata *nd); /** * permission - check permission when accessing an inode * @inode: inode structure to check * @mask: permission mask * * called: permission <fs/namei.c> * * Check permission before accessing an inode. This hook * is called by the existing Linux permission function, * so a security module can use it to provide additional * checking for existing Linux permission checks. Notice * that this hook is called when a file is opened (as well * as many other operations), whereas the file_security_ops * permission hook is called when the actual read/write * operations are performed. * Return 0 if permission is granted. */ int (* permission) (struct inode *inode, int mask); /** * revalidate - revalidate the inode attributes * @dentry: dentry structure associated with the inode * * called: do_revalidate <fs/stat.c> * * Revalidate the inode attributes. This hook can be used * by a security module to revalidate the attributes stored in * the i_security field to maintain consistency when the file * is remote. Return 0 if successful. */ int (* revalidate) (struct dentry *dentry); /** * setattr - check permissions to set file attributes * @dentry: dentry structure for the file * @attr: iattr structure containing the new file attributes * * called: notify_change <fs/attr.c> * * lock: The big kernel lock is held by notify_change * * Check permission before setting file attributes. * Note that the kernel call to notify_change is performed from several * locations, whenever file attributes change (such as when a file * is truncated, chown/chmod operations, transferring disk quotas, * etc). Return 0 if permission is granted. */ int (* setattr) (struct dentry *dentry, struct iattr *attr); /** * stat - check permissions to get file attributes * @inode: inode structure for the file * * called: cp_old_stat <fs/stat.c> * called: cp_new_stat <fs/stat.c> * called: cp_new_stat64 <fs/stat.c> * * Check permission before obtaining file attributes. * Return 0 if permission is granted. */ int (* stat) (struct inode *inode); /** * post_lookup - set security attributes for looked up file * @ino: inode structure for parent directory * @d: dentry structure for the file * * called: real_lookup <fs/namei.c> * called: lookup_hash <fs/namei.c> * * lock: The @ino i_sem semaphore MAY be held. * * Set the security attributes for a file after it has * been looked up. */ void (* post_lookup) (struct inode *ino, struct dentry *d); /** * delete - update module's state when an inode is deleted * @ino: inode structure for deleted inode * * called: iput <fs/inode.c> * * This hook is called when a deleted inode is released * (i.e. an inode with no hard links has its use count drop to * zero). A security module can use this hook to release any * persistent label associated with the inode. */ void (* delete) (struct inode *ino); }; struct file_security_ops { /** * permission - check permission when accessing an open file * @file: file structure being accessed * @mask: requested permissions * * called: sys_read <fs/read_write.c> * called: sys_write <fs/read_write.c> * called: sys_readv <fs/read_write.c> * called: sys_writev <fs/read_write.c> * called: sys_pread <fs/read_write.c> * called: sys_pwrite <fs/read_write.c> * called: vfs_readdir <fs/readdir.c> * called: sys_sendfile <mm/filemap.c> * called: sys_sendfile <mm/filemap.c> * * Check file permissions before accessing an open file. * This hook is called by various operations that read * or write files. A security module can use this hook * to perform additional checking on these operations, e.g. * to revalidate permissions on use to support privilege * bracketing or policy changes. Notice that this hook * is used when the actual read/write operations are * performed, whereas the inode_security_ops hook is called * when a file is opened (as well as many other operations). * Return 0 if permission is granted. * * Caveat: Although this hook can be used to revalidate * permissions for various system call operations that * read or write files, it does not address the revalidation * of permissions for memory-mapped files. Security modules * must handle this separately if they need such revalidation. */ int (*permission) (struct file * file, int mask); /** * alloc_security - allocate file security information * @file: file structure to secure * * called: get_empty_filp <fs/file_table.c> * * lock: a spin lock is held on the file list * * Allocate and attach a security structure to the * file->f_security field. The security field is initialized * to NULL when the structure is first created. Return 0 if * the hook is successful and permission is granted. */ int (*alloc_security) (struct file * file); /** * free_security - deallocate file security information * @file: file structure being modified * * called: fput <fs/file_table.c> * called: put_filp <fs/file_table.c> * * Deallocate and free any security structures stored in * file->f_security. */ void (*free_security) (struct file * file); /** * llseek - check permission when changing the file offset * @file: file structure being modified * * called: sys_lseek <fs/read_write.c> * called: sys_llseek <fs/read_write.c> * * Check permission before re-positioning the file offset in * @file. Return 0 if permission is granted. */ int (*llseek) (struct file * file); /** * ioctl - check permission for an ioctl operation * @file: file structure * @cmd: operation to perform * @arg: operational arguments * * called: sys_ioctl <fs/ioctl.c> * * Check permission for an ioctl operation on @file. Note that @arg * can sometimes represents a user space pointer; in other * cases, it may be a simple integer value. When @arg represents * a user space pointer, it should never be used by the security * module. Return 0 if permission is granted. */ int (*ioctl) (struct file * file, unsigned int cmd, unsigned long arg); /** * mmap - check permission for a mmap operation * @file: file structure for file to map (may be NULL) * @prot: requested permissions * @flags: operational flags * * called: do_mmap_pgoff <mm/mmap.c> * * Check permissions for a mmap operation. Return 0 if * permission is granted. The @file may be NULL, e.g. * if mapping anonymous memory. */ int (*mmap) (struct file * file, unsigned long prot, unsigned long flags); /** * mprotect - check permissions when changing memory protections * @vma: memory region to modify * @prot: requested permissions * * called: sys_mprotect <mm/mprotect.c> * * locks: down_write has been called on current->mm->mmap_sem * * Check permissions before changing memory access * permissions. Return 0 if permission is granted. */ int (*mprotect) (struct vm_area_struct * vma, unsigned long prot); /** * lock - check permission to perform file locking operations * @file: file structure * @cmd: operation to perform * * called: sys_flock <fs/locks.c> * * Check permission before performing file locking operations. * Return 0 if permission is granted. */ int (*lock) (struct file * file, unsigned int cmd); /** * fcntl - check permission for file control operations * @file: file structure * @cmd: operation to be performed * @arg: operational arguments * * called: sys_fcntl <fs/fcntl.c> * called: sys_fcntl64 <fs/fcntl.c> * * Check permission before allowing the file operation * specified by @cmd from being performed on the file @file. * Note that @arg can sometimes represents a user space * pointer; in other cases, it may be a simple integer value. * When @arg represents a user space pointer, it should never be * used by the security module. Return 0 if permission is granted. */ int (*fcntl) (struct file * file, unsigned int cmd, unsigned long arg); /** * set_fowner - save owner security information * @file: file structure to update * * called: do_fcntl <fs/fcntl.c> * called: fcntl_dirnotify <fs/dnotify.c> * called: tty_fasync <drivers/char/tty_io.c> * called: fcntl_setlease <fs/locks.c> * * lock: The big kernel lock is held by do_fcntl and fcntl_setlease * * Save owner security information (typically from current->security) * in file->f_security for later use by the send_sigiotask hook. * Return 0 on success. */ int (*set_fowner) (struct file * file); /** * send_sigiotask - check permission to send SIGIO * @tsk: structure of task receiving signal * @fown: file owner information * @fd: file descriptor * @reason: operational flags * * called: send_sigio_to_task <fs/fcntl.c> * * Check permission for the file owner @fown to send * SIGIO to the process @tsk. Note that this hook is always * called from interrupt. Note that the fown_struct, @fown, * is never outside the context of a struct file, so the file * structure (and associated security information) can always * be obtained: * (struct file *)((long)fown - offsetof(struct file,f_owner)); * Return 0 if permission is granted. */ int (*send_sigiotask) (struct task_struct * tsk, struct fown_struct * fown, int fd, int reason); /** * receive - check permission when receiving file descriptors via IPC * @file: file structure being received * * called: scm_detach_fds <net/core/scm.c> * * This hook allows security modules to control the ability of * a process to receive an open file descriptor via socket * IPC. Return 0 if permission is granted. */ int (*receive) (struct file * file); }; struct sched_param; /** * Security hooks for task operations. */ struct task_security_ops { /** * create - check permission when creating a child process * @clone_flags: flags indicating what should be shared * * called: do_fork <kernel/fork.c> * * Check permission before creating a child process. * Return 0 if permission is granted. * See the clone(2) manual page for definitions of the @clone_flags. */ int (* create) (unsigned long clone_flags); /** * alloc_security - allocate security structure for child process * @p: task_struct for child process * * called: do_fork <kernel/fork.c> * * Allocate and attach a security structure to the p->security * field. The security field is initialized to NULL when the * task structure is allocated. Return 0 if operation was successful. */ int (* alloc_security) (struct task_struct *p); /** * free_security - deallocate security structure for this process * @p: task_struct for process * * called: release_task <kernel/exit.c> * * Deallocate and clear the p->security field. */ void (* free_security) (struct task_struct *p); /** * setuid - check permission when setting user identity attributes * @id0: uid * @id1: uid * @id2: uid * @flags: one of the LSM_SETID_* values * * called: sys_setreuid <kernel/sys.c> * called: sys_setuid <kernel/sys.c> * called: sys_setresuid <kernel/sys.c> * called: sys_setfsuid <kernel/sys.c> * * Check permission before setting one or more of the user identity * attributes of the current process. The @flags parameter indicates * which of the set*uid system calls invoked this hook and how * to interpret the @id0, @id1, and @id2 parameters. See the * LSM_SETID definitions at the beginning of this file for the * @flags values and their meanings. Return 0 if permission is * granted. */ int (* setuid) (uid_t id0, uid_t id1, uid_t id2, int flags); /** * post_setuid - update state after setting user identity attributes * @old_ruid: old real uid (or fs uid if LSM_SETID_FS) * @old_euid: old effective uid (or -1 if LSM_SETID_FS) * @old_suid: old saved uid (or -1 if LSM_SETID_FS) * @flags: one of the LSM_SETID_* values * * called: sys_setreuid <kernel/sys.c> * called: sys_setuid <kernel/sys.c> * called: sys_setresuid <kernel/sys.c> * called: sys_setfsuid <kernel/sys.c> * * Update the module's state after setting one or more of the * user identity attributes of the current process. The @flags * parameter indicates which of the set*uid system calls invoked * this hook. If @flags is LSM_SETID_FS, then @old_ruid is * the old fs uid and the other parameters are not used. Return * 0 on success. */ int (* post_setuid) (uid_t old_ruid /* or fsuid */, uid_t old_euid, uid_t old_suid, int flags); /** * setgid - check permission when setting group identity attributes * @id0: gid * @id1: gid * @id2: gid * @flags: one of the LSM_SETID_* values * * called: sys_setregid <kernel/sys.c> * called: sys_setgid <kernel/sys.c> * called: sys_setresgid <kernel/sys.c> * called: sys_setfsgid <kernel/sys.c> * * Check permission before setting one or more of the group identity * attributes of the current process. The @flags parameter indicates * which of the set*gid system calls invoked this hook and how * to interpret the @id0, @id1, and @id2 parameters. See the * LSM_SETID definitions at the beginning of this file for the * @flags values and their meanings. Return 0 if permission is * granted. */ int (* setgid) (gid_t id0, gid_t id1, gid_t id2, int flags); /** * setpgid - check permission when setting process group identifier * @p: task_struct for process being modified * @pgid: new pgid * * called: sys_setpgid <kernel/sys.c> * * lock: tasklist_lock is read-locked. * * Check permission before setting the process group identifier * of the process @p to @pgid. Return 0 if permission is * granted. */ int (* setpgid) (struct task_struct *p, pid_t pgid); /** * getpgid - check permission when getting process group identifier * @p: task_struct for process * * called: sys_getpgid <kernel/sys.c> * * lock: tasklist_lock is read-locked. * * Check permission before getting the process group identifier * of the process @p. Return 0 if permission is granted. */ int (* getpgid) (struct task_struct *p); /** * getsid - check permission when getting session identifier * @p: task_struct for process * * called: sys_getsid <kernel/sys.c> * * lock: tasklist_lock is read-locked. * * Check permission before getting the session identifier * of the process @p. Return 0 if permission is granted. */ int (* getsid) (struct task_struct *p); /** * setgroups - check permission when setting supplementary group set * @gidsetsize: number of elements in @grouplist * @grouplist: array of gids * * called: sys_setgroups <kernel/sys.c> * * Check permission before setting the supplementary group set * of the current process to @grouplist. Return 0 if permission * is granted. */ int (* setgroups) (int gidsetsize, gid_t *grouplist); /** * setnice - check permission when setting process nice value * @p: task_struct of process * @nice: new nice value * * called: sys_setpriority <kernel/sys.c> * called: sys_nice <kernel/sched.c> * * lock: the tasklist_lock is read-locked in sys_setpriority. * * Check permission before setting the nice value of @p * to @nice. Return 0 if permission is granted. */ int (* setnice) (struct task_struct *p, int nice); /** * setrlimit - check permission when setting resource limits * @resource: resource whose limit is being set * @new_rlim: new limits for @resource * * called: sys_setrlimit <kernel/sys.c> * * Check permission before setting the resource limits * of the current process for @resource to @new_rlim. * The old resource limit values can be examined by * dereferencing (current->rlim + resource). * Return 0 if permission is granted. */ int (* setrlimit) (unsigned int resource, struct rlimit *new_rlim); /** * setscheduler - check permission when setting scheduling info * @p: task_struct for process * @policy: scheduling policy * @lp: scheduling parameters * * called: setscheduler <kernel/sched.c> * * lock: tasklist_lock is read-locked, and runqueue_lock is locked. * * Check permission before setting scheduling policy * and/or parameters of process @p based on @policy * and @lp. Return 0 if permission is granted. */ int (* setscheduler) (struct task_struct *p, int policy, struct sched_param *lp); /** * getscheduler - check permission when obtaining scheduling info * @p: task_struct for process * * called: sys_sched_getscheduler <kernel/sched.c> * called: sys_sched_getparam <kernel/sched.c> * called: sys_sched_rr_get_interval <kernel/sched.c> * * lock: tasklist_lock is read-locked. * * Check permission before obtaining scheduling information * for process @p. Return 0 if permission is granted. */ int (* getscheduler) (struct task_struct *p); /** * kill - check permission when sending a signal * @p: task_struct for process * @info: signal information * @sig: signal value * * called: send_sig_info <kernel/signal.c> * * lock: tasklist_lock may be read-locked by the caller. * * Check permission before sending signal @sig to @p. * @info can be NULL, the constant 1, or a pointer to * a siginfo structure. If @info is 1 or SI_FROMKERNEL(info) * is true, then the signal should be viewed as coming from * the kernel and should typically be permitted. * Return 0 if permission is granted. * * SIGIO signals are handled separately by the send_sigiotask * hook in file_security_ops. */ int (* kill) (struct task_struct *p, struct siginfo *info, int sig); /** * wait - check permission when reaping a child process * @p: task_struct for process * * called: sys_wait4 <kernel/exit.c> * * lock: tasklist_lock is read-locked. * * Check permission before allowing a process to reap * a child process @p and collect its status information. * Return 0 if permission is granted. */ int (* wait) (struct task_struct *p); /** * prctl - check permission when performing process control operations * @option: the operation * @arg2: argument * @arg3: argument * @arg4: argument * @arg5: argument * * called: sys_prctl <kernel/sys.c> * * Check permission before performing a process control operation * on the current process. Return 0 if permission is granted. */ int (* prctl) (int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5); /** * kmod_set_label - set security attributes for kernel module loader * * called: exec_usermodehelper <kernel/kmod.c> * * Set the security attributes in current->security * for the kernel module loader thread, so that it * has the permissions needed to perform its function. */ void (* kmod_set_label) (void); }; struct sk_buff; /** * Security hooks for socket operations. */ struct socket_security_ops { /** * create - Check socket create permission * @family: requested protocol family * @type: requested communications type * @protocol: requested protocol * * called: sock_create <net/socket.c> * * Check permissions prior to creating a new socket. Return 0 * if permission is granted. */ int (*create) (int family, int type, int protocol); /** * post_create - Update socket security information after creation * @sock: newly created socket structure * @family: requested protocol family * @type: requested communications type * @protocol: requested protocol * * called: sock_create <net/socket.c> * * This hook allows a module to update or allocate a * per-socket security structure. Note that the security field * was not added directly to the socket structure, but rather, * the socket security information is stored in the associated * inode. Typically, the inode alloc_security hook will allocate and * and attach security information to sock->inode->i_security. * This hook may be used to update the sock->inode->i_security field * with additional information that wasn't available when the inode * was allocated. */ void (*post_create) (struct socket * sock, int family, int type, int protocol); /** * bind - check permission for socket bind operation * @sock: socket structure * @address: address to bind to * @addrlen: length of address * * called: sys_bind <net/socket.c> * * Check permission before socket protocol layer bind operation * is performed and the socket @sock is bound to the address * specified in the @address parameter. Return 0 if permission * is granted. */ int (*bind) (struct socket * sock, struct sockaddr * address, int addrlen); /** * connect - check permission for socket connect operation * @sock: socket structure * @address: address of remote endpoint * @addrlen: length of address * * called: sys_connect <net/socket.c> * * Check permission before socket protocol layer connect * operation attempts to connect socket @sock to a remote * address, @address. Return 0 if permission is granted. */ int (*connect) (struct socket * sock, struct sockaddr * address, int addrlen); /** * listen - check permission for socket listen operation * @sock: socket structure * @backlog: maximum length for the pending connection queue * * called: sys_listen <net/socket.c> * * Check permission before socket protocol layer listen operation. * Return 0 if permission is granted. */ int (*listen) (struct socket * sock, int backlog); /** * accept - check permission for socket accept operation * @sock: listening socket structure * @newsock: newly created server socket for connection * * called: sys_accept <net/socket.c> * * Check permission before accepting a new connection. * Note that the new socket, @newsock, has been created and * some information copied to it, but the accept operation has * not actually been performed. This hook also allows a * security module to copy security information into the newly * created socket's inode. Return 0 if permission is granted. */ int (*accept) (struct socket * sock, struct socket * newsock); /** * sendmsg - check permission when sending message from this socket * @sock: socket structure * @msg: message to be transmitted * @size: size of message * * called: sock_sendmsg <net/socket.c> * * Check permission before transmitting a message to another * socket. Return 0 if permission is granted. */ int (*sendmsg) (struct socket * sock, struct msghdr * msg, int size); /** * recvmsg - check permission when receiving messages from this socket * @sock: socket structure * @msg: message structure * @size: size of message structure * @flags: operational flags * * called: sock_recvmsg <net/socket.c> * * Check permission before receiving a message from a socket. * Return 0 if permission is granted. */ int (*recvmsg) (struct socket * sock, struct msghdr * msg, int size, int flags); /** * getsockname - check permission when retrieving socket name * @sock: socket structure * * called: sys_getsockname <net/socket.c> * * Check permission before the local address (name) of the * socket object @sock is retrieved. Return 0 if permission is * granted. */ int (*getsockname) (struct socket * sock); /** * getpeername - check permission when retrieving socket peer name * @sock: socket structure * * called: sys_getpeername <net/socket.c> * * Check permission before the remote address (name) of a * socket object @sock is retrieved. Return 0 if permission * is granted. */ int (*getpeername) (struct socket * sock); /** * getsockopt - check permission when retrieving socket options * @sock: socket structure * @level: protocol level to retrieve option from * @optname: name of option to retrieve * * called: sys_getsockopt <net/socket.c> * * Check permissions before retrieving the options associated * with socket @sock. Return 0 if permission is granted. */ int (*getsockopt) (struct socket * sock, int level, int optname); /** * setsockopt - check permission when setting socket options * @sock: socket structure * @level: protocol level to set options for * @optname: name of the option to set * * called: sys_setsockopt <net/socket.c> * * Check permissions before setting the options associated * with socket @sock. Return 0 if permission is granted. */ int (*setsockopt) (struct socket * sock, int level, int optname); /** * shutdown - check permission when shutting down a socket * @sock: socket structure * @how: flag indicating how future sends and receives are handled * * called: sys_shutdown <net/socket.c> * * Checks permission before all or part of a connection on the * socket @sock is shut down. Return 0 if permission is * granted. */ int (*shutdown) (struct socket * sock, int how); /** * sock_rcv_skb - check permissions on incoming network packets * @sk: sock (not socket) associated with the incoming sk_buff * @skb: incoming network data * * called: tcp_v4_rcv <net/ipv4/tcp_ipv4.c> * called: sock_queue_rcv_skb <include/net/sock.h> * * Check permissions on incoming network packets. This hook is * distinct from the network input hooks of ip_security_ops since * it is the first time that the incoming sk_buff @skb has been * associated with a particular socket, @sk. Security modules * should not try to dereference @sk->socket if the socket is * in a time wait state (@sk->state == TCP_TIME_WAIT), since * the @sk refers to a tcp_tw_bucket structure in that case. * Also, even if the socket is not in this state, @sk->socket * may be NULL, e.g. a newly created server socket for a connection * that has not yet been accepted by a process. Return 0 if * permission is granted. */ int (*sock_rcv_skb) (struct sock * sk, struct sk_buff * skb); /** Security hooks for Unix domain socket IPC. * * The following two hooks were necessary because Linux provides * an alternative to the conventional file name space for Unix * domain sockets. Whereas binding and connecting to sockets * in the file name space is mediated by the typical file * permissions (and caught by the mknod and permission hooks in * inode_security_ops), binding and connecting to sockets in the * abstract name space is completely unmediated. Sufficient * control of Unix domain sockets in the abstract name space isn't * possible using only the socket layer hooks, since we need * to know the actual target socket, which is not looked up * until we are inside the af_unix code. */ /** * unix_stream_connect - check permissions for Unix domain stream IPC * @sock: socket structure * @other: peer socket structure * * called: unix_stream_connect <net/unix/af_unix.c> * * Check permissions before establishing a Unix domain stream * connection between @sock and @other. Return 0 if * permission is granted. */ int (*unix_stream_connect) (struct socket * sock, struct socket * other); /** * unix_may_send - check permissions for Unix domain datagram IPC * @sock: socket structure * @sock: peer socket structure * * called: unix_dgram_connect <net/unix/af_unix.> * called: unix_dgram_sendmsg <net/unix/af_unix.> * * Check permissions before connecting or sending datagrams * from @sock to @other. Return 0 if permission is granted. */ int (*unix_may_send) (struct socket * sock, struct socket * other); }; /** * Lifecycle hooks for network buffers. * * These hooks are used to help manage the lifecycle of security blobs for * &sk_buff structures, and are not intended to be used for access decisions. */ struct skb_security_ops { /** * alloc_security - new buffer allocation hook * @skb: the buffer being allocated * * called: alloc_skb <net/core/skbuff.c> * * This hook is called by the &sk_buff allocator when a new * buffer is being allocated. An LSM module may allocate and * assign a new security blob for the &sk_buff via this hook. * * Return 0 if successful, or -ENOMEM on out of memory condition. */ int (* alloc_security) (struct sk_buff *skb); /** * clone - sk_buff clone hook * @newskb: the newly cloned buffer * @oldskb: the buffer being cloned * * called: skb_clone <net/core/skbuff.c> * * This hook is called when an &sk_buff is being cloned, and may * be used, for example, to increment a reference count on the * associated security blob. The security blob in the @newskb * will not have been allocated. * * Returns 0 on success -ENOMEM on failure. */ int (* clone) (struct sk_buff *newskb, const struct sk_buff *oldskb); /** * copy - sk_buff copy hook * @newskb: the newly copied buffer * @oldskb: the buffer being copied * * called: copy_skb_header <net/core/skbuff.c> * * This hook is called when an &sk_buff header is being copied, * which occurs during the skb_copy() and pskb_copy() functions in * <net/core/skbuff.c> */ void (* copy) (struct sk_buff *newskb, const struct sk_buff *oldskb); /** * free_security - sk_buff destruction hook * @skb: the buffer being destroyed * * called: __kfree_skb <net/core/skbuff.c> * * This hook is called when an &sk_buff is being destroyed, and * should be used to free any associated security blob. */ void (* free_security) (struct sk_buff *skb); }; struct net_device; typedef unsigned int (*ip_opfn)(unsigned int hooknum, struct sk_buff **skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)); /** * IPv4 networking hooks. */ struct ip_security_ops { /** * Hooks declared with the &ip_opfn function pointer make use * of the Netfilter API for intercepting packets as they traverse * the IP layer. Each Netfilter hook is grabbed twice: before and * after packets are passed through the standard iptables-based * packet filtering and mangling mechanisms. * * Parameters for these hooks are as follows: * * @hooknum - hook the packet arrived on * @skb - &sk_buff containing the packet * @in - incoming netdevice associated with the packet * @out - outgoing netdevice associated with the packet * @okfn - used internally by Netfilter * * These hooks may return NF_ACCEPT to allow the packet through * and NF_DROP to drop the packet. * * Further information on the Netfilter API may be found in the * Netfilter Hacking HOWTO at http://netfilter.samba.org/ */ ip_opfn preroute_first; ip_opfn preroute_last; ip_opfn input_first; ip_opfn input_last; ip_opfn forward_first; ip_opfn forward_last; ip_opfn output_first; ip_opfn output_last; ip_opfn postroute_first; ip_opfn postroute_last; /** * fragment - IP packet fragmentation hook * @newskb: the newly created fragment * @oldskb: the original packet being fragmented * * called: ip_fragment <net/ipv4/ip_output.c> * * This is called for each fragment generated when an outgoing packet * is being fragmented, and may be used to copy security attributes * from the original packet to each fragment. */ void (* fragment) (struct sk_buff *newskb, const struct sk_buff *oldskb); /** * defragment - IP packet defragmentation hook * @skb: the incoming fragment * * called: ip_frag_queue <net/ipv4/ip_fragment.c> * * This hook is called when an incoming fragment is about to be * inserted into a reassembly queue. It's purpose is to enable the * validation of security attributes for each fragment. An LSM * module using this hook will likely need to maintain its own * fragment queue information, handle fragment expiration and * implement DoS countermeasures. * * Returns 0 on success. * */ int (* defragment) (struct sk_buff *skb); /** * encapsulate - IP encapsulation hook * @skb: the encapsulated packet * * called: ipgre_tunnel_xmit <net/ipv4/ip_gre.c> * called: ipip_tunnel_xmit <net/ipv4/ipip.c> * called: ip_encap <net/ipv4/ipmr.c> * * This hook is called when an IP packet is encapsulated, and * may be used to update security attributes prior to reprocessing * via the local_out or forward hooks. */ void (* encapsulate) (struct sk_buff *skb); /** * decapsulate - IP decapsulation hook * @skb: the decapsulated packet * * called: ipgre_rcv <net/ipv4/ip_gre.c> * called: ipip_rcv <net/ipv4/ipip.c> * called: pim_rcv_v1 <net/ipv4/ipmr.c> * called: pim_rcv <net/ipv4/ipmr.c> * * This hook is called when a packet is decapsulated, and may * be used to process security attributes at each level of * encapsulation. An example of this would be keeping track of * nested security associations for an incoming packet. */ void (* decapsulate) (struct sk_buff *skb); /** * decode_options - IP options decoding hook * @skb: &sk_buff containing IP packet (usually NULL for outgoing) * @optptr: &ip_options structure * @pp_ptr: parameter problem pointer * * called: ip_options_compile <net/ipv4/ip_options.c> * * This hook is used for processing IP security options * at the network layer when labeled networking (e.g. CIPSO) * is implemented. * * For outgoing packets, IP options passed down from the * application or transport layers may be verified here * prior the packet being built. * * For incoming packets, IP options may be verified and * their values recorded via the &sk_buff security blob * for later processing. * * Returns 0 on success. * * A non-zero return value will cause an ICMP parameter problem * message to be generated and transmitted to the sender. The * @pp_ptr parameter may be used to point to the offending option * parameter. */ int (* decode_options) (struct sk_buff *skb, const char *optptr, unsigned char **pp_ptr); }; /** * Security hooks for network devices. */ struct netdev_security_ops { /** * unregister - update state when a network device is unregistered * @dev: the network device * * called: unregister_netdevice <net/core/dev.c> * * lock: the rtnl semaphore is held by the caller. * * Update the module's state when a network device is unregistered, * deallocating the dev->security field if it was previously allocated. * Since it would be quite invasive to provide hooks in every * location where a network device might be probed or initialized, * there are no separate hooks for allocation or initialization. * Security modules can allocate and initialize the dev->security * field on the first access to the device, but should be * careful to use nonblocking allocation. */ void (*unregister) (struct net_device *dev); }; /** * Security hooks for kernel module operations. */ struct module_security_ops { /** * create_module - check permission when allocating space for a module * @name: module name * @size: module size * * called: sys_create_module <kernel/module.c> * * lock: The big kernel lock is held. * * Check permission before allocating space for a kernel module. * Return 0 if permission is granted. */ int (* create_module) (const char *name, size_t size); /** * init_module - check permission when initializing a module * @name: module name * @mod: the module * * called: sys_init_module <kernel/module.c> * * lock: The big kernel lock is held. * * Check permission before initializing a kernel module. * Return 0 if permission is granted. */ int (* init_module) (const char *name, struct module *mod); /** * delete_module - check permission when removing a module * @name: module name * * called: sys_delete_module <kernel/module.c> * * lock: The big kernel lock is held. * * Check permission before removing a kernel module. * Return 0 if permission is granted. */ int (* delete_module) (const char *name); }; /** * Security hooks affecting all System V IPC operations. */ struct ipc_security_ops { /** * permission - check IPC permissions * @ipcp: IPC permission set * @flag: desired (requested) permission set * * called: ipcperms <ipc/util.c> * * Check user, group, and other permissions for access to ipc * resources. Return 0 if permission is granted. */ int (* permission) (struct kern_ipc_perm *ipcp, short flag); /** * getinfo - check retrieval permission * @id: resource identifier * @cmd: operation to be performed * * called: sys_msgctl <ipc/msg.c> * called: semctl_nolock <ipc/sem.c> by: sys_semctl <ipc/sem.c> * called: sys_shmctl <ipc/shm.c> * called: sys_shmctl <ipc/shm.c> * * Check permission to retrieve information on previously * allocated IPC resources. Called by the IPC resource * control syscalls, shmctl, msgctl, semctl with a @cmd * argument of: IPC_INFO, SEM_INFO, MSG_INFO, or SHM_INFO as * appropriate. Return 0 if permission is granted. */ int (* getinfo) (int id, int cmd); }; /** * Security hooks for individual Messages held in System V IPC Message Queues */ struct msg_msg_security_ops { /** * alloc_security - allocate security structure for this message * @msg: message structure to be modified * * called: load_msg <ipc/msg.c> * * Allocate and attach a security structure to the * msg->security field. The security field is initialized to * NULL when the structure is first created. Return 0 if * operation was successful and permission is granted. */ int (* alloc_security) (struct msg_msg *msg); /** * free_security - deallocate security structure for this message * @msg: message structure to be modified * * called: free_msg <ipc/msg.c> */ void (* free_security) (struct msg_msg *msg); }; /** * Security hooks for System V IPC Message Queues */ struct msg_queue_security_ops { /** * alloc_security - allocate security structure for this message queue * @msq: message queue structure to be modified * * called: newque <ipc/msg.c> * * Allocate and attach a security structure to the * msq->q_perm.security field. The security field is * initialized to NULL when the structure is first created. * Return 0 if operation was successful and permission is * granted. */ int (* alloc_security) (struct msg_queue *msq); /** * free_security - deallocate security structure for this message queue * @msq: message queue structure to be modified * * called: free_msg <ipc/msg.c> */ void (* free_security) (struct msg_queue *msq); /** * associate - check resource associate permission * @msq: message queue to act upon * @msqid: resource identifier * @msqflg: operation control flags * * called: sys_msgget <ipc/msg.c> * * lock: msg_lock() has been called, so there is a spin_lock * held on 'struct ipc_ids msg_ids' * * Check permission when a message queue is requested through * the msgget system call. This hook is only called when * returning the message queue identifier for an existing * message queue, not when a new message queue is created. * Return 0 if permission is granted. */ int (* associate) (struct msg_queue *msq, int msqid, int msqflg); /** * msgctl - check permission for message queue control operations * @msq: message queue to act upon * @msqid: resource identifier * @cmd: operation to be performed * * called: sys_msgctl <ipc/msg.c> * called: sys_msgctl <ipc/msg.c> * called: sys_msgctl <ipc/msg.c> * * lock: depending on @cmd, msg_lock() may have been called, * so there may be a spin_lock held on 'struct ipc_ids * msg_ids' * * Check permission when a message control operation specified * by @cmd is to be performed on the message queue @msq, with * identifier @msqid. Return 0 if permission is granted. */ int (* msgctl) (struct msg_queue *msq, int msqid, int cmd); /** * msgsnd - check permission when sending a message to a queue * @msq: message queue to send message to * @msg: message to be enqueued * @msqid: resource identifier * @msqflg: operational flags * * called: sys_msgsnd <ipc/msg.c> * * lock: msg_lock() has been called, so there is a spin_lock * held on 'struct ipc_ids msg_ids' * * Check permission before a message, @msg, is enqueued on the * message queue, @msq, whose identifier is specified by the * value of @msqid. Return 0 if permission is granted. */ int (* msgsnd) (struct msg_queue *msq, struct msg_msg *msg, int msqid, int msqflg); /** * msgrcv - check permission when receiving a message from a queue * @msq: message queue to retrieve message from * @msg: message destination * @target: task structure for recipient process * @type: type of message requested * @mode: operational flags * * called: pipelined_send <ipc/msg.c> * called: sys_msgrcv <ipc/msg.c> * * lock: msg_lock() has been called, so there is a spin_lock * held on 'struct ipc_ids msg_ids' * * Check permission before a message, @msg, is removed from the * message queue, @msq, whose identifier is specified by the * value of @msqid. The @target task structure contains a * pointer to the process that will be receiving the message * (not equal to the current process when inline receives are * being performed). Return 0 if permission is granted. */ int (* msgrcv) (struct msg_queue *msq, struct msg_msg *msg, struct task_struct *target, long type, int mode); }; /** * Security hooks for System V Shared Memory Segments */ struct shm_security_ops { /** * alloc_security - allocate security structure for this memory segment * @shp: shared memory structure to be modified * * called: newseg <ipc/shm.c> * * Allocate and attach a security structure to the * shp->shm_perm.security field. The security field is * initialized to NULL when the structure is first created. * Return 0 if operation was successful and permission is * granted. */ int (* alloc_security) (struct shmid_kernel *shp); /** * free_security - deallocate security struct for this memory segment * @shp: shared memory structure to be modified * * called: shm_destroy <ipc/shm.c> */ void (* free_security) (struct shmid_kernel *shp); /** * associate - check resource associate permission * @shp: shared memory structure to be modified * @shmid: resource identifier * @shmflg: operation control flags * * called: sys_shmget <ipc/shm.c> * * lock: shm_lock() has been called, so there is a spin_lock * held on 'struct shmid_kernel shm_ids' * * Check permission when a shared memory region is requested * through the shmget system call. This hook is only called * when returning the shared memory region identifier for an * existing region, not when a new shared memory region is * created. Return 0 if permission is granted. */ int (* associate) (struct shmid_kernel *shp, int shmid, int shmflg); /** * shmctl - check permission for shared memory control operations * @shp: shared memory structure to be modified * @shmid: resource identifier * @cmd: operation to be performed * * called: sys_shmctl <ipc/shm.c> * called: sys_shmctl <ipc/shm.c> * called: sys_shmctl <ipc/shm.c> * called: sys_shmctl <ipc/shm.c> * * lock: depending on @cmd, shm_lock() may have been called, * so there may be a spin_lock held on 'struct shmid_kernel * shm_ids' * * Check permission when a shared memory control operation * specified by @cmd is to be performed on the shared memory * region @shp, with identifier @shmid. Return 0 if * permission is granted. */ int (* shmctl) (struct shmid_kernel *shp, int shmid, int cmd); /** shmat - check permissions when attaching a memory segment * @shp: shared memory structure to be modified * @shmid: resource identifier * @shmaddr: address to attach memory region to * @shmflg: operational flags * * called: sys_shmat <ipc/shm.c> * * lock: shm_lock() has been called, so there is a spin_lock * held on 'struct shmid_kernel shm_ids' * * Check permissions prior to allowing the shmat system call * to attach the shared memory segment @shp, identified by * @shmid, to the data segment of the calling process. The * attaching address is specified by @shmaddr. Return 0 if * permission is granted. */ int (* shmat) (struct shmid_kernel *shp, int shmid, char *shmaddr, int shmflg); }; /** * Security hooks for System V Semaphores */ struct sem_security_ops { /** * alloc_security - allocate security structure for this semaphore * @sma: semaphore structure * * called: newary <ipc/sem.c> * * Allocate and attach a security structure to the * sma->sem_perm.security field. The security field is * initialized to NULL when the structure is first created. * Return 0 if operation was successful and permission is * granted. */ int (* alloc_security) (struct sem_array *sma); /** * free_security - deallocate security struct for this semaphore * @sma: semaphore structure * * called: freeary <ipc/sem.c> */ void (* free_security) (struct sem_array *sma); /** * associate - check resource associate permission * @sma: semaphore structure * @semid: resource identifier * @semflg: operation control flags * * called: sys_semget <ipc/sem.c> * * lock: sem_lock() has been called, so there is a spin_lock * held on 'struct sem_array sem_ids' * * Check permission when a semaphore is requested through the * semget system call. This hook is only called when * returning the semaphore identifier for an existing * semaphore, not when a new one must be created. Return 0 if * permission is granted. */ int (* associate) (struct sem_array *sma, int semid, int semflg); /** * semctl - check permission for semaphore control operations * @sma: semaphore structure * @semid: resource identifier * @cmd: operation to be performed * * called: semctl_nolock <ipc/sem.c> by: sys_semctl <ipc/sem.c> * called: semctl_main <ipc/sem.c> by: sys_semctl <ipc/sem.c> * called: semctl_down <ipc/sem.c> by: sys_semctl <ipc/sem.c> * * lock: depending on @cmd, sem_lock() may have been called, * so there may be a spin_lock held on 'sem_array sem_ids' * * Check permission when a semaphore operation specified by * @cmd is to be performed on the semaphore @sma, with * identifier @semid. Return 0 if permission is granted. */ int (* semctl) (struct sem_array *sma, int semid, int cmd); /** semop - check permission for semaphore operations * @sma: semaphore structure * @semid: resource identifier * @sops: operations to perform * @nsops: number of operations to perform * @alter: flag indicating whether changes are to be made * * called: sys_semop <ipc/sem.c> * * Check permissions before performing operations on members * of the semaphore set @sma, identified by @semid. If the * @alter flag is nonzero, the semaphore set may be modified. * Return 0 if permission is granted. */ int (* semop) (struct sem_array *sma, int semid, struct sembuf *sops, unsigned nsops, int alter); }; struct nfsctl_arg; /* forward declare to avoid warnings */ struct security_operations { int version; /** * sethostname - check permission when setting the hostname * @hostname: new hostname * * called: sys_sethostname <kernel/sys.c> * * Check permission before the hostname is set to @hostname. * Return 0 if permission is granted. */ int (* sethostname) (char *hostname); /** * setdomainname - check permission when setting the domainname * @domainname: new domainname * * called: sys_setdomainname <kernel/sys.c> * * Check permission before the domainname is set to @domainname. * Return 0 if permission is granted. */ int (* setdomainname) (char *domainname); /** * reboot - check permission when rebooting or enabling/disabling Ctrl-Alt-Del * @cmd: reboot command * * called: sys_reboot <kernel/sys.c> * * Check permission before rebooting or enabling/disabling the * Ctrl-Alt-Del key sequence. Return 0 if permission is granted. * The values for @cmd are defined in the reboot(2) manual page. */ int (* reboot) (unsigned int cmd); /** * ioperm - check permission when setting port input/output permissions * @from: starting port address * @num: number of bytes starting from @from * @turn_on: permissions value * * called: sys_ioperm <arch/i386/kernel/ioport.c> * * Check permission before setting port input/output permissions * for the process for @num bytes starting from the port address * @from to the value @turn_on. Return 0 if permission is granted. */ int (* ioperm) (unsigned long from, unsigned long num, int turn_on); /** * iopl - check permission when changing input/output privilege level * @old: old level * @level: new level * * called: sys_iopl <arch/i386/kernel/ioport.c> * called: sys_iopl <arch/ia64/ia32/sys_ia32.c> * * Check permission before changing the I/O privilege level of the * current process from @old to @level. Return 0 if permission is * granted. */ int (* iopl) (unsigned int old, unsigned int level); /** * ptrace - check permission when tracing a process * @parent: task_struct structure for parent process * @child: task_struct structure for child process * * called: ptrace_attach <kernel/ptrace.c> * called: sys_ptrace <arch/i386/kernel/ptrace.c> * called: sys_ptrace <arch/ia64/kernel/ptrace.c> * called: MAY_PTRACE <fs/proc/base.c> * * locks: task_lock is called by ptrace_attach on the child task. * The big kernel lock is held by sys_ptrace. * * Check permission before allowing the @parent process to trace * the @child process. Return 0 if permission is granted. * * Security modules may also want to perform a process tracing * check during an execve in the set_security or compute_creds * hooks of binprm_security_ops if the process is being traced * and its security attributes would be changed by the execve. */ int (* ptrace) (struct task_struct *parent, struct task_struct *child); /** * capget - get the capability sets for a process * @target: task_struct structure for target process * @effective: effective capability set * @inheritable: inheritable capability set * @permitted: permitted capability set * * called: sys_capget <kernel/capability.c> * * locks: The task_capability_lock is held by sys_capget. * The tasklist_lock is read-locked by sys_capget * unless @target is the current process. * * Get the @effective, @inheritable, and @permitted capability * sets for the @target process. The hook may also perform * permission checking to determine if the current process is * allowed to see the capability sets of the @target process. * Return 0 if the capability sets were successfully obtained. */ int (*capget) (struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted); /** * capset_check - check permission when setting capability sets * @target: task_struct structure for target process * @effective: effective capability set * @inheritable: inheritable capability set * @permitted: permitted capability set * * called: sys_capset <kernel/capability.c> * * locks: The task_capability_lock is held by sys_capset. * The tasklist_lock is read-locked by sys_capset if * a single target process other than current was * specified. * * Check permission before setting the @effective, @inheritable, and * @permitted capability sets for the @target process. Return 0 * if permission is granted. * * Caveat: @target is also set to current if a set of processes * is specified (i.e. all processes other than current and init or * a particular process group). Hence, the capset_set hook may need * to revalidate permission to the actual target process. */ int (*capset_check) (struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted); /** * capset_set - Set the capability sets for a process * @target: task_struct structure for target process * @effective: effective capability set * @inheritable: inheritable capability set * @permitted: permitted capability set * * called: sys_capset <kernel/capability.c> * called: cap_set_pg <kernel/capability.c> * called: cap_set_all <kernel/capability.c> * * locks: The task_capability_lock is held by sys_capset. * The tasklist_lock is read-locked unless only the * capability sets for current are being set. * * Set the @effective, @inheritable, and @permitted capability sets * for the @target process. Since capset_check cannot always check * permission to the real @target process, this hook may also perform * permission checking to determine if the current process is * allowed to set the capability sets of the @target process. * However, this hook has no way of returning an error due to * the structure of the sys_capset code. */ void (*capset_set) (struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted); /** * acct - Check permission when enabling or disabling process accounting * @file: file structure for the accounting file (may be NULL) * * called: sys_acct <kernel/acct.c> * * Check permission before enabling or disabling process accounting. * If accounting is being enabled, then @file refers to the open * file used to store accounting records. If accounting is being * disabled, then @file is NULL. Return 0 if permission is granted. */ int (* acct) (struct file *file); /** * sysctl - Check permission when accessing a sysctl variable * @table: the ctl_table structure for the sysctl variable * @op: the operation (001 = search, 002 = write, 004 = read) * * called: ctl_perm <kernel/sysctl.c> * * Check permission before accessing the @table sysctl variable * in the manner specified by @op. Return 0 if permission is granted. */ int (* sysctl) (ctl_table * table, int op); /** * capable - Check a particular capability for a process * @tsk: the task_struct for the process * @cap: the capability <include/linux/capability.h> * * called: capable <security/security.c> * called: must_not_trace_exec <fs/exec.c> * called: badness <mm/oom_kill.c> * called: oom_kill_task <mm/oom_kill.c> * * Check whether the @tsk process has the @cap capability. * Return 0 if the capability is granted for @tsk. */ int (* capable) (struct task_struct *tsk, int cap); /** * sys_security - Security system call multiplexor * @id: security module identifier * @call: call value * @args: call arguments (user space pointer) * * called: sys_security <security/security.c> * * Security modules may use this hook to implement new system * calls for security-aware applications. The interface is similar * to socketcall, but with an @id parameter to help identify the * security module whose call is being invoked. The module is * responsible for interpreting the parameters, and must copy in the * @args array from user space if it is used. The module should * return -ENOSYS if it does not implement any new system calls. */ int (* sys_security) (unsigned int id, unsigned call, unsigned long *args); /** * swapon - Check permission before enabling swapping to a file/device. * @dentry: dentry structure for the swap file or device * * called: sys_swapon <mm/swapfile.c> * * lock: The big kernel lock is held by sys_swapon. * * Check permission before enabling swapping to the file * or block device identified by @dentry. Return 0 if * permission is granted. */ int (* swapon) (struct dentry *dentry); /** * swapoff - Check permission before disabling swapping to a file/device. * @dentry: dentry structure for the swap file or device * * called: sys_swapoff <mm/swapfile.c> * * Check permission before disabling swapping to the file * or block device identified by @dentry. Return 0 if * permission is granted. */ int (* swapoff) (struct dentry *dentry); /** * nfsservctl - Check permission before accessing the kernel NFS daemon * @cmd: command value * @arg: command arguments * * called: handle_sys_nfsservctl <fs/nfsd/nfsctl.c> * * lock: The big kernel lock is held. * * Check permission before having the kernel NFS daemon * perform command @cmd with arguments @arg. Return 0 if * permission is granted. See the nfsservctl(2) manual page * for an explanation of @cmd and @arg values. */ int (* nfsservctl) (int cmd, struct nfsctl_arg *arg); /** * quotactl - Check permission before manipulating disk quotas * @cmd: command value * @type: type of quota (USRQUOTA or GRPQUOTA) * @id: user or group identifier * @sb: super_block structure for the filesystem (may be NULL) * * called: sys_quotactl <fs/dquot.c> * * Check permission before performing the quota operation * identified by @cmd for the specified @type, @id, and * @sb. The @sb parameter may be NULL, e.g. for the Q_SYNC * and Q_GETSTATS commands. Return 0 if permission is granted. */ int (* quotactl) (int cmds, int type, int id, struct super_block *sb); /** * quota_on - Check permission when enabling quotas * @f: the open file for storing quotas * * called: quota_on <fs/dquot.c> * * Check permission before enabling quotas for a file * system using @f as the quota file. Return 0 if permission * is granted. */ int (* quota_on) (struct file *f); /** * bdflush - Check permission before tuning the bdflush daemon * @func: the tuning function * @data: tuning parameter pointer (user space pointer) or value * * called: sys_bdflush <fs/buffer.c> * * Check permission before tuning the bdflush parameter. * See the bdflush(2) manual page for an explanation of * the @func and @data parameters. The @data parameter * should only be used by the module if it is an input * value. Return 0 if permission is granted. */ int (* bdflush) (int func, long data); /** * syslog - Check permission before accessing the kernel message ring * @type: the type of action * * called: do_syslog <kernel/printk.c> * * Check permission before accessing the kernel message ring or * changing logging to the console. Return 0 if permission is * granted. See the syslog(2) manual page for an explanation of * the @type values. */ int (* syslog) (int type); /** * netlink_send - Save security information for a netlink message. * @skb: the sk_buff structure for the netlink message * * called: netlink_sendmsg <net/netlink/af_netlink.c> * * Save security information for a netlink message so that * permission checking can be performed when the message * is processed. The security information can either be * saved using the existing eff_cap field of the netlink_skb_parms * structure or it can be saved using the skbuff lsm_security field. * Return 0 if the information was successfully saved. */ int (* netlink_send) (struct sk_buff *skb); /** * netlink_recv - Check permission when receiving a netlink message * @skb: the sk_buff structure for the netlink message * * called: rtnetlink_rcv_msg <net/core/rtnetlink.c> * called: netlink_receive_user_skb <net/ipv4/netfilter/ip_queue.c> * * Check permission before processing the received netlink message * in @skb. Return 0 if permission is granted. */ int (* netlink_recv) (struct sk_buff *skb); struct binprm_security_ops * bprm_ops; struct super_block_security_ops * sb_ops; struct inode_security_ops * inode_ops; struct file_security_ops * file_ops; struct task_security_ops * task_ops; struct socket_security_ops * socket_ops; struct skb_security_ops * skb_ops; struct ip_security_ops * ip_ops; struct netdev_security_ops * netdev_ops; struct module_security_ops * module_ops; struct ipc_security_ops * ipc_ops; struct msg_msg_security_ops * msg_msg_ops; struct msg_queue_security_ops * msg_queue_ops; struct shm_security_ops * shm_ops; struct sem_security_ops * sem_ops; /* allow module stacking */ int (* register_security) (const char *name, struct security_operations *ops); int (* unregister_security) (const char *name, struct security_operations *ops); }; /* prototypes */ extern int security_scaffolding_startup (void); extern int register_security (struct security_operations *ops); extern int unregister_security (struct security_operations *ops); extern int mod_reg_security (const char *name, struct security_operations *ops); extern int mod_unreg_security (const char *name, struct security_operations *ops); extern int capable (int cap); /* global variables */ extern struct security_operations *security_ops; #endif /* __KERNEL__ */ #endif /* ! __LINUX_SECURITY_H */