![[LWN Logo]](/images/lcorner.png) |
|
![[LWN.net]](/images/Included.png) |
/*
* 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 */