summaryrefslogtreecommitdiff
path: root/include/linux/security.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/security.h')
-rw-r--r--include/linux/security.h275
1 files changed, 129 insertions, 146 deletions
diff --git a/include/linux/security.h b/include/linux/security.h
index b42095a68b1c..f7e0ae018712 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -30,6 +30,7 @@
#include <linux/shm.h>
#include <linux/msg.h>
#include <linux/sched.h>
+#include <linux/key.h>
struct ctl_table;
@@ -250,29 +251,37 @@ struct swap_info_struct;
* @inode contains the inode structure.
* Deallocate the inode security structure and set @inode->i_security to
* NULL.
+ * @inode_init_security:
+ * Obtain the security attribute name suffix and value to set on a newly
+ * created inode and set up the incore security field for the new inode.
+ * This hook is called by the fs code as part of the inode creation
+ * transaction and provides for atomic labeling of the inode, unlike
+ * the post_create/mkdir/... hooks called by the VFS. The hook function
+ * is expected to allocate the name and value via kmalloc, with the caller
+ * being responsible for calling kfree after using them.
+ * If the security module does not use security attributes or does
+ * not wish to put a security attribute on this particular inode,
+ * then it should return -EOPNOTSUPP to skip this processing.
+ * @inode contains the inode structure of the newly created inode.
+ * @dir contains the inode structure of the parent directory.
+ * @name will be set to the allocated name suffix (e.g. selinux).
+ * @value will be set to the allocated attribute value.
+ * @len will be set to the length of the value.
+ * Returns 0 if @name and @value have been successfully set,
+ * -EOPNOTSUPP if no security attribute is needed, or
+ * -ENOMEM on memory allocation failure.
* @inode_create:
* Check permission to create a regular file.
* @dir contains inode structure of the parent of the new file.
* @dentry contains the dentry structure for the file to be created.
* @mode contains the file mode of the file to be created.
* Return 0 if permission is granted.
- * @inode_post_create:
- * Set the security attributes on a newly created regular file. This hook
- * is called after a file has been successfully created.
- * @dir contains the inode structure of the parent directory of the new file.
- * @dentry contains the the dentry structure for the newly created file.
- * @mode contains the file mode.
* @inode_link:
* Check permission before creating a new hard link to a file.
* @old_dentry contains the dentry structure for an existing link to the file.
* @dir contains the inode structure of the parent directory of the new link.
* @new_dentry contains the dentry structure for the new link.
* Return 0 if permission is granted.
- * @inode_post_link:
- * Set security attributes for a new hard link to a file.
- * @old_dentry contains the dentry structure for the existing link.
- * @dir contains the inode structure of the parent directory of the new file.
- * @new_dentry contains the dentry structure for the new file link.
* @inode_unlink:
* Check the permission to remove a hard link to a file.
* @dir contains the inode structure of parent directory of the file.
@@ -284,13 +293,6 @@ struct swap_info_struct;
* @dentry contains the dentry structure of the symbolic link.
* @old_name contains the pathname of file.
* Return 0 if permission is granted.
- * @inode_post_symlink:
- * @dir contains the inode structure of the parent directory of the new link.
- * @dentry contains the dentry structure of new symbolic link.
- * @old_name contains the pathname of file.
- * 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).
* @inode_mkdir:
* Check permissions to create a new directory in the existing directory
* associated with inode strcture @dir.
@@ -298,11 +300,6 @@ struct swap_info_struct;
* @dentry contains the dentry structure of new directory.
* @mode contains the mode of new directory.
* Return 0 if permission is granted.
- * @inode_post_mkdir:
- * Set security attributes on a newly created directory.
- * @dir contains the inode structure of parent of the directory to be created.
- * @dentry contains the dentry structure of new directory.
- * @mode contains the mode of new directory.
* @inode_rmdir:
* Check the permission to remove a directory.
* @dir contains the inode structure of parent of the directory to be removed.
@@ -318,13 +315,6 @@ struct swap_info_struct;
* @mode contains the mode of the new file.
* @dev contains the the device number.
* Return 0 if permission is granted.
- * @inode_post_mknod:
- * Set security attributes on a newly created special file (or socket or
- * fifo file created via the mknod system call).
- * @dir contains the inode structure of parent of the new node.
- * @dentry contains the dentry structure of the new node.
- * @mode contains the mode of the new node.
- * @dev contains the the device number.
* @inode_rename:
* Check for permission to rename a file or directory.
* @old_dir contains the inode structure for parent of the old link.
@@ -332,12 +322,6 @@ struct swap_info_struct;
* @new_dir contains the inode structure for parent of the new link.
* @new_dentry contains the dentry structure of the new link.
* Return 0 if permission is granted.
- * @inode_post_rename:
- * Set security attributes on a renamed file or directory.
- * @old_dir contains the inode structure for parent of the old link.
- * @old_dentry contains the dentry structure of the old link.
- * @new_dir contains the inode structure for parent of the new link.
- * @new_dentry contains the dentry structure of the new link.
* @inode_readlink:
* Check the permission to read the symbolic link.
* @dentry contains the dentry structure for the file link.
@@ -402,6 +386,9 @@ struct swap_info_struct;
* NULL to request the size of the buffer required. @size indicates
* the size of @buffer in bytes. Note that @name is the remainder
* of the attribute name after the security. prefix has been removed.
+ * @err is the return value from the preceding fs getxattr call,
+ * and can be used by the security module to determine whether it
+ * should try and canonicalize the attribute value.
* Return number of bytes used/required on success.
* @inode_setsecurity:
* Set the security label associated with @name for @inode from the
@@ -802,6 +789,27 @@ struct swap_info_struct;
* @sk_free_security:
* Deallocate security structure.
*
+ * Security hooks affecting all Key Management operations
+ *
+ * @key_alloc:
+ * Permit allocation of a key and assign security data. Note that key does
+ * not have a serial number assigned at this point.
+ * @key points to the key.
+ * Return 0 if permission is granted, -ve error otherwise.
+ * @key_free:
+ * Notification of destruction; free security data.
+ * @key points to the key.
+ * No return value.
+ * @key_permission:
+ * See whether a specific operational right is granted to a process on a
+ * key.
+ * @key_ref refers to the key (key pointer + possession attribute bit).
+ * @context points to the process to provide the context against which to
+ * evaluate the security data on the key.
+ * @perm describes the combination of permissions required of this key.
+ * Return 1 if permission granted, 0 if permission denied and -ve it the
+ * normal permissions model should be effected.
+ *
* Security hooks affecting all System V IPC operations.
*
* @ipc_permission:
@@ -1080,34 +1088,21 @@ struct security_operations {
int (*inode_alloc_security) (struct inode *inode);
void (*inode_free_security) (struct inode *inode);
+ int (*inode_init_security) (struct inode *inode, struct inode *dir,
+ char **name, void **value, size_t *len);
int (*inode_create) (struct inode *dir,
struct dentry *dentry, int mode);
- void (*inode_post_create) (struct inode *dir,
- struct dentry *dentry, int mode);
int (*inode_link) (struct dentry *old_dentry,
struct inode *dir, struct dentry *new_dentry);
- void (*inode_post_link) (struct dentry *old_dentry,
- struct inode *dir, struct dentry *new_dentry);
int (*inode_unlink) (struct inode *dir, struct dentry *dentry);
int (*inode_symlink) (struct inode *dir,
struct dentry *dentry, const char *old_name);
- void (*inode_post_symlink) (struct inode *dir,
- struct dentry *dentry,
- const char *old_name);
int (*inode_mkdir) (struct inode *dir, struct dentry *dentry, int mode);
- void (*inode_post_mkdir) (struct inode *dir, struct dentry *dentry,
- int mode);
int (*inode_rmdir) (struct inode *dir, struct dentry *dentry);
int (*inode_mknod) (struct inode *dir, struct dentry *dentry,
int mode, dev_t dev);
- void (*inode_post_mknod) (struct inode *dir, struct dentry *dentry,
- int mode, dev_t dev);
int (*inode_rename) (struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry);
- void (*inode_post_rename) (struct inode *old_dir,
- struct dentry *old_dentry,
- struct inode *new_dir,
- struct dentry *new_dentry);
int (*inode_readlink) (struct dentry *dentry);
int (*inode_follow_link) (struct dentry *dentry, struct nameidata *nd);
int (*inode_permission) (struct inode *inode, int mask, struct nameidata *nd);
@@ -1121,7 +1116,7 @@ struct security_operations {
int (*inode_getxattr) (struct dentry *dentry, char *name);
int (*inode_listxattr) (struct dentry *dentry);
int (*inode_removexattr) (struct dentry *dentry, char *name);
- int (*inode_getsecurity)(struct inode *inode, const char *name, void *buffer, size_t size);
+ int (*inode_getsecurity)(struct inode *inode, const char *name, void *buffer, size_t size, int err);
int (*inode_setsecurity)(struct inode *inode, const char *name, const void *value, size_t size, int flags);
int (*inode_listsecurity)(struct inode *inode, char *buffer, size_t buffer_size);
@@ -1240,9 +1235,20 @@ struct security_operations {
int (*socket_shutdown) (struct socket * sock, int how);
int (*socket_sock_rcv_skb) (struct sock * sk, struct sk_buff * skb);
int (*socket_getpeersec) (struct socket *sock, char __user *optval, int __user *optlen, unsigned len);
- int (*sk_alloc_security) (struct sock *sk, int family, int priority);
+ int (*sk_alloc_security) (struct sock *sk, int family, gfp_t priority);
void (*sk_free_security) (struct sock *sk);
#endif /* CONFIG_SECURITY_NETWORK */
+
+ /* key management security hooks */
+#ifdef CONFIG_KEYS
+ int (*key_alloc)(struct key *key);
+ void (*key_free)(struct key *key);
+ int (*key_permission)(key_ref_t key_ref,
+ struct task_struct *context,
+ key_perm_t perm);
+
+#endif /* CONFIG_KEYS */
+
};
/* global variables */
@@ -1442,6 +1448,17 @@ static inline void security_inode_free (struct inode *inode)
return;
security_ops->inode_free_security (inode);
}
+
+static inline int security_inode_init_security (struct inode *inode,
+ struct inode *dir,
+ char **name,
+ void **value,
+ size_t *len)
+{
+ if (unlikely (IS_PRIVATE (inode)))
+ return -EOPNOTSUPP;
+ return security_ops->inode_init_security (inode, dir, name, value, len);
+}
static inline int security_inode_create (struct inode *dir,
struct dentry *dentry,
@@ -1452,15 +1469,6 @@ static inline int security_inode_create (struct inode *dir,
return security_ops->inode_create (dir, dentry, mode);
}
-static inline void security_inode_post_create (struct inode *dir,
- struct dentry *dentry,
- int mode)
-{
- if (dentry->d_inode && unlikely (IS_PRIVATE (dentry->d_inode)))
- return;
- security_ops->inode_post_create (dir, dentry, mode);
-}
-
static inline int security_inode_link (struct dentry *old_dentry,
struct inode *dir,
struct dentry *new_dentry)
@@ -1470,15 +1478,6 @@ static inline int security_inode_link (struct dentry *old_dentry,
return security_ops->inode_link (old_dentry, dir, new_dentry);
}
-static inline void security_inode_post_link (struct dentry *old_dentry,
- struct inode *dir,
- struct dentry *new_dentry)
-{
- if (new_dentry->d_inode && unlikely (IS_PRIVATE (new_dentry->d_inode)))
- return;
- security_ops->inode_post_link (old_dentry, dir, new_dentry);
-}
-
static inline int security_inode_unlink (struct inode *dir,
struct dentry *dentry)
{
@@ -1496,15 +1495,6 @@ static inline int security_inode_symlink (struct inode *dir,
return security_ops->inode_symlink (dir, dentry, old_name);
}
-static inline void security_inode_post_symlink (struct inode *dir,
- struct dentry *dentry,
- const char *old_name)
-{
- if (dentry->d_inode && unlikely (IS_PRIVATE (dentry->d_inode)))
- return;
- security_ops->inode_post_symlink (dir, dentry, old_name);
-}
-
static inline int security_inode_mkdir (struct inode *dir,
struct dentry *dentry,
int mode)
@@ -1514,15 +1504,6 @@ static inline int security_inode_mkdir (struct inode *dir,
return security_ops->inode_mkdir (dir, dentry, mode);
}
-static inline void security_inode_post_mkdir (struct inode *dir,
- struct dentry *dentry,
- int mode)
-{
- if (dentry->d_inode && unlikely (IS_PRIVATE (dentry->d_inode)))
- return;
- security_ops->inode_post_mkdir (dir, dentry, mode);
-}
-
static inline int security_inode_rmdir (struct inode *dir,
struct dentry *dentry)
{
@@ -1540,15 +1521,6 @@ static inline int security_inode_mknod (struct inode *dir,
return security_ops->inode_mknod (dir, dentry, mode, dev);
}
-static inline void security_inode_post_mknod (struct inode *dir,
- struct dentry *dentry,
- int mode, dev_t dev)
-{
- if (dentry->d_inode && unlikely (IS_PRIVATE (dentry->d_inode)))
- return;
- security_ops->inode_post_mknod (dir, dentry, mode, dev);
-}
-
static inline int security_inode_rename (struct inode *old_dir,
struct dentry *old_dentry,
struct inode *new_dir,
@@ -1561,18 +1533,6 @@ static inline int security_inode_rename (struct inode *old_dir,
new_dir, new_dentry);
}
-static inline void security_inode_post_rename (struct inode *old_dir,
- struct dentry *old_dentry,
- struct inode *new_dir,
- struct dentry *new_dentry)
-{
- if (unlikely (IS_PRIVATE (old_dentry->d_inode) ||
- (new_dentry->d_inode && IS_PRIVATE (new_dentry->d_inode))))
- return;
- security_ops->inode_post_rename (old_dir, old_dentry,
- new_dir, new_dentry);
-}
-
static inline int security_inode_readlink (struct dentry *dentry)
{
if (unlikely (IS_PRIVATE (dentry->d_inode)))
@@ -1656,11 +1616,11 @@ static inline int security_inode_removexattr (struct dentry *dentry, char *name)
return security_ops->inode_removexattr (dentry, name);
}
-static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size)
+static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err)
{
if (unlikely (IS_PRIVATE (inode)))
return 0;
- return security_ops->inode_getsecurity(inode, name, buffer, size);
+ return security_ops->inode_getsecurity(inode, name, buffer, size, err);
}
static inline int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags)
@@ -1983,6 +1943,11 @@ 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 struct dentry *securityfs_create_file(const char *name, mode_t mode,
+ struct dentry *parent, void *data,
+ struct file_operations *fops);
+extern struct dentry *securityfs_create_dir(const char *name, struct dentry *parent);
+extern void securityfs_remove(struct dentry *dentry);
#else /* CONFIG_SECURITY */
@@ -2171,6 +2136,15 @@ static inline int security_inode_alloc (struct inode *inode)
static inline void security_inode_free (struct inode *inode)
{ }
+
+static inline int security_inode_init_security (struct inode *inode,
+ struct inode *dir,
+ char **name,
+ void **value,
+ size_t *len)
+{
+ return -EOPNOTSUPP;
+}
static inline int security_inode_create (struct inode *dir,
struct dentry *dentry,
@@ -2179,11 +2153,6 @@ static inline int security_inode_create (struct inode *dir,
return 0;
}
-static inline void security_inode_post_create (struct inode *dir,
- struct dentry *dentry,
- int mode)
-{ }
-
static inline int security_inode_link (struct dentry *old_dentry,
struct inode *dir,
struct dentry *new_dentry)
@@ -2191,11 +2160,6 @@ static inline int security_inode_link (struct dentry *old_dentry,
return 0;
}
-static inline void security_inode_post_link (struct dentry *old_dentry,
- struct inode *dir,
- struct dentry *new_dentry)
-{ }
-
static inline int security_inode_unlink (struct inode *dir,
struct dentry *dentry)
{
@@ -2209,11 +2173,6 @@ static inline int security_inode_symlink (struct inode *dir,
return 0;
}
-static inline void security_inode_post_symlink (struct inode *dir,
- struct dentry *dentry,
- const char *old_name)
-{ }
-
static inline int security_inode_mkdir (struct inode *dir,
struct dentry *dentry,
int mode)
@@ -2221,11 +2180,6 @@ static inline int security_inode_mkdir (struct inode *dir,
return 0;
}
-static inline void security_inode_post_mkdir (struct inode *dir,
- struct dentry *dentry,
- int mode)
-{ }
-
static inline int security_inode_rmdir (struct inode *dir,
struct dentry *dentry)
{
@@ -2239,11 +2193,6 @@ static inline int security_inode_mknod (struct inode *dir,
return 0;
}
-static inline void security_inode_post_mknod (struct inode *dir,
- struct dentry *dentry,
- int mode, dev_t dev)
-{ }
-
static inline int security_inode_rename (struct inode *old_dir,
struct dentry *old_dentry,
struct inode *new_dir,
@@ -2252,12 +2201,6 @@ static inline int security_inode_rename (struct inode *old_dir,
return 0;
}
-static inline void security_inode_post_rename (struct inode *old_dir,
- struct dentry *old_dentry,
- struct inode *new_dir,
- struct dentry *new_dentry)
-{ }
-
static inline int security_inode_readlink (struct dentry *dentry)
{
return 0;
@@ -2315,7 +2258,7 @@ static inline int security_inode_removexattr (struct dentry *dentry, char *name)
return cap_inode_removexattr(dentry, name);
}
-static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size)
+static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err)
{
return -EOPNOTSUPP;
}
@@ -2727,7 +2670,7 @@ static inline int security_socket_getpeersec(struct socket *sock, char __user *o
return security_ops->socket_getpeersec(sock, optval, optlen, len);
}
-static inline int security_sk_alloc(struct sock *sk, int family, int priority)
+static inline int security_sk_alloc(struct sock *sk, int family, gfp_t priority)
{
return security_ops->sk_alloc_security(sk, family, priority);
}
@@ -2844,7 +2787,7 @@ static inline int security_socket_getpeersec(struct socket *sock, char __user *o
return -ENOPROTOOPT;
}
-static inline int security_sk_alloc(struct sock *sk, int family, int priority)
+static inline int security_sk_alloc(struct sock *sk, int family, gfp_t priority)
{
return 0;
}
@@ -2854,5 +2797,45 @@ static inline void security_sk_free(struct sock *sk)
}
#endif /* CONFIG_SECURITY_NETWORK */
+#ifdef CONFIG_KEYS
+#ifdef CONFIG_SECURITY
+static inline int security_key_alloc(struct key *key)
+{
+ return security_ops->key_alloc(key);
+}
+
+static inline void security_key_free(struct key *key)
+{
+ security_ops->key_free(key);
+}
+
+static inline int security_key_permission(key_ref_t key_ref,
+ struct task_struct *context,
+ key_perm_t perm)
+{
+ return security_ops->key_permission(key_ref, context, perm);
+}
+
+#else
+
+static inline int security_key_alloc(struct key *key)
+{
+ return 0;
+}
+
+static inline void security_key_free(struct key *key)
+{
+}
+
+static inline int security_key_permission(key_ref_t key_ref,
+ struct task_struct *context,
+ key_perm_t perm)
+{
+ return 0;
+}
+
+#endif
+#endif /* CONFIG_KEYS */
+
#endif /* ! __LINUX_SECURITY_H */