Commit 78ee8b1b authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'next-general' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security

Pull security subsystem updates from James Morris:
 "Just a few bugfixes and documentation updates"

* 'next-general' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security:
  seccomp: fix up grammar in comment
  Revert "security: inode: fix a missing check for securityfs_create_file"
  Yama: mark function as static
  security: inode: fix a missing check for securityfs_create_file
  keys: safe concurrent user->{session,uid}_keyring access
  security: don't use RCU accessors for cred->session_keyring
  Yama: mark local symbols as static
  LSM: lsm_hooks.h: fix documentation format
  LSM: fix documentation for the shm_* hooks
  LSM: fix documentation for the sem_* hooks
  LSM: fix documentation for the msg_queue_* hooks
  LSM: fix documentation for the audit_* hooks
  LSM: fix documentation for the path_chmod hook
  LSM: fix documentation for the socket_getpeersec_dgram hook
  LSM: fix documentation for the task_setscheduler hook
  LSM: fix documentation for the socket_post_create hook
  LSM: fix documentation for the syslog hook
  LSM: fix documentation for sb_copy_data hook
parents 9bff9dfc 6beff00b
...@@ -138,7 +138,7 @@ struct cred { ...@@ -138,7 +138,7 @@ struct cred {
#ifdef CONFIG_KEYS #ifdef CONFIG_KEYS
unsigned char jit_keyring; /* default keyring to attach requested unsigned char jit_keyring; /* default keyring to attach requested
* keys to */ * keys to */
struct key __rcu *session_keyring; /* keyring inherited over fork */ struct key *session_keyring; /* keyring inherited over fork */
struct key *process_keyring; /* keyring private to this process */ struct key *process_keyring; /* keyring private to this process */
struct key *thread_keyring; /* keyring private to this thread */ struct key *thread_keyring; /* keyring private to this thread */
struct key *request_key_auth; /* assumed request_key authority */ struct key *request_key_auth; /* assumed request_key authority */
......
...@@ -127,7 +127,6 @@ ...@@ -127,7 +127,6 @@
* options cleanly (a filesystem may modify the data e.g. with strsep()). * options cleanly (a filesystem may modify the data e.g. with strsep()).
* This also allows the original mount data to be stripped of security- * This also allows the original mount data to be stripped of security-
* specific options to avoid having to make filesystems aware of them. * specific options to avoid having to make filesystems aware of them.
* @type the type of filesystem being mounted.
* @orig the original mount data copied from userspace. * @orig the original mount data copied from userspace.
* @copy copied data which will be passed to the security module. * @copy copied data which will be passed to the security module.
* Returns 0 if the copy was successful. * Returns 0 if the copy was successful.
...@@ -320,10 +319,11 @@ ...@@ -320,10 +319,11 @@
* @new_dentry contains the dentry structure of the new link. * @new_dentry contains the dentry structure of the new link.
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @path_chmod: * @path_chmod:
* Check for permission to change DAC's permission of a file or directory. * Check for permission to change a mode of the file @path. The new
* @dentry contains the dentry structure. * mode is specified in @mode.
* @mnt contains the vfsmnt structure. * @path contains the path structure of the file to change the mode.
* @mode contains DAC's mode. * @mode contains the new DAC's permission, which is a bitmask of
* constants from <include/uapi/linux/stat.h>
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @path_chown: * @path_chown:
* Check for permission to change owner/group of a file or directory. * Check for permission to change owner/group of a file or directory.
...@@ -502,7 +502,7 @@ ...@@ -502,7 +502,7 @@
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @file_lock: * @file_lock:
* Check permission before performing file locking operations. * Check permission before performing file locking operations.
* Note: this hook mediates both flock and fcntl style locks. * Note the hook mediates both flock and fcntl style locks.
* @file contains the file structure. * @file contains the file structure.
* @cmd contains the posix-translated lock operation to perform * @cmd contains the posix-translated lock operation to perform
* (e.g. F_RDLCK, F_WRLCK). * (e.g. F_RDLCK, F_WRLCK).
...@@ -645,12 +645,12 @@ ...@@ -645,12 +645,12 @@
* @p contains the task_struct of process. * @p contains the task_struct of process.
* @nice contains the new nice value. * @nice contains the new nice value.
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @task_setioprio * @task_setioprio:
* Check permission before setting the ioprio value of @p to @ioprio. * Check permission before setting the ioprio value of @p to @ioprio.
* @p contains the task_struct of process. * @p contains the task_struct of process.
* @ioprio contains the new ioprio value * @ioprio contains the new ioprio value
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @task_getioprio * @task_getioprio:
* Check permission before getting the ioprio value of @p. * Check permission before getting the ioprio value of @p.
* @p contains the task_struct of process. * @p contains the task_struct of process.
* Return 0 if permission is granted. * Return 0 if permission is granted.
...@@ -672,17 +672,15 @@ ...@@ -672,17 +672,15 @@
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @task_setscheduler: * @task_setscheduler:
* Check permission before setting scheduling policy and/or parameters of * Check permission before setting scheduling policy and/or parameters of
* process @p based on @policy and @lp. * process @p.
* @p contains the task_struct for process. * @p contains the task_struct for process.
* @policy contains the scheduling policy.
* @lp contains the scheduling parameters.
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @task_getscheduler: * @task_getscheduler:
* Check permission before obtaining scheduling information for process * Check permission before obtaining scheduling information for process
* @p. * @p.
* @p contains the task_struct for process. * @p contains the task_struct for process.
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @task_movememory * @task_movememory:
* Check permission before moving memory owned by process @p. * Check permission before moving memory owned by process @p.
* @p contains the task_struct for process. * @p contains the task_struct for process.
* Return 0 if permission is granted. * Return 0 if permission is granted.
...@@ -769,9 +767,9 @@ ...@@ -769,9 +767,9 @@
* socket structure, but rather, the socket security information is stored * socket structure, but rather, the socket security information is stored
* in the associated inode. Typically, the inode alloc_security hook will * in the associated inode. Typically, the inode alloc_security hook will
* allocate and and attach security information to * allocate and and attach security information to
* sock->inode->i_security. This hook may be used to update the * SOCK_INODE(sock)->i_security. This hook may be used to update the
* sock->inode->i_security field with additional information that wasn't * SOCK_INODE(sock)->i_security field with additional information that
* available when the inode was allocated. * wasn't available when the inode was allocated.
* @sock contains the newly created socket structure. * @sock contains the newly created socket structure.
* @family contains the requested protocol family. * @family contains the requested protocol family.
* @type contains the requested communications type. * @type contains the requested communications type.
...@@ -880,9 +878,9 @@ ...@@ -880,9 +878,9 @@
* the IP_PASSSEC option via getsockopt. It can then retrieve the * the IP_PASSSEC option via getsockopt. It can then retrieve the
* security state returned by this hook for a packet via the SCM_SECURITY * security state returned by this hook for a packet via the SCM_SECURITY
* ancillary message type. * ancillary message type.
* @skb is the skbuff for the packet being queried * @sock contains the peer socket. May be NULL.
* @secdata is a pointer to a buffer in which to copy the security data * @skb is the sk_buff for the packet being queried. May be NULL.
* @seclen is the maximum length for @secdata * @secid pointer to store the secid of the packet.
* Return 0 on success, error on failure. * Return 0 on success, error on failure.
* @sk_alloc_security: * @sk_alloc_security:
* Allocate and attach a security structure to the sk->sk_security field, * Allocate and attach a security structure to the sk->sk_security field,
...@@ -906,9 +904,9 @@ ...@@ -906,9 +904,9 @@
* @secmark_relabel_packet: * @secmark_relabel_packet:
* check if the process should be allowed to relabel packets to * check if the process should be allowed to relabel packets to
* the given secid * the given secid
* @security_secmark_refcount_inc * @secmark_refcount_inc:
* tells the LSM to increment the number of secmark labeling rules loaded * tells the LSM to increment the number of secmark labeling rules loaded
* @security_secmark_refcount_dec * @secmark_refcount_dec:
* tells the LSM to decrement the number of secmark labeling rules loaded * tells the LSM to decrement the number of secmark labeling rules loaded
* @req_classify_flow: * @req_classify_flow:
* Sets the flow's sid to the openreq sid. * Sets the flow's sid to the openreq sid.
...@@ -1113,41 +1111,41 @@ ...@@ -1113,41 +1111,41 @@
* *
* @msg_queue_alloc_security: * @msg_queue_alloc_security:
* Allocate and attach a security structure to the * Allocate and attach a security structure to the
* msq->q_perm.security field. The security field is initialized to * @perm->security field. The security field is initialized to
* NULL when the structure is first created. * NULL when the structure is first created.
* @msq contains the message queue structure to be modified. * @perm contains the IPC permissions of the message queue.
* Return 0 if operation was successful and permission is granted. * Return 0 if operation was successful and permission is granted.
* @msg_queue_free_security: * @msg_queue_free_security:
* Deallocate security structure for this message queue. * Deallocate security field @perm->security for the message queue.
* @msq contains the message queue structure to be modified. * @perm contains the IPC permissions of the message queue.
* @msg_queue_associate: * @msg_queue_associate:
* Check permission when a message queue is requested through the * Check permission when a message queue is requested through the
* msgget system call. This hook is only called when returning the * msgget system call. This hook is only called when returning the
* message queue identifier for an existing message queue, not when a * message queue identifier for an existing message queue, not when a
* new message queue is created. * new message queue is created.
* @msq contains the message queue to act upon. * @perm contains the IPC permissions of the message queue.
* @msqflg contains the operation control flags. * @msqflg contains the operation control flags.
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @msg_queue_msgctl: * @msg_queue_msgctl:
* Check permission when a message control operation specified by @cmd * Check permission when a message control operation specified by @cmd
* is to be performed on the message queue @msq. * is to be performed on the message queue with permissions @perm.
* The @msq may be NULL, e.g. for IPC_INFO or MSG_INFO. * The @perm may be NULL, e.g. for IPC_INFO or MSG_INFO.
* @msq contains the message queue to act upon. May be NULL. * @perm contains the IPC permissions of the msg queue. May be NULL.
* @cmd contains the operation to be performed. * @cmd contains the operation to be performed.
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @msg_queue_msgsnd: * @msg_queue_msgsnd:
* Check permission before a message, @msg, is enqueued on the message * Check permission before a message, @msg, is enqueued on the message
* queue, @msq. * queue with permissions @perm.
* @msq contains the message queue to send message to. * @perm contains the IPC permissions of the message queue.
* @msg contains the message to be enqueued. * @msg contains the message to be enqueued.
* @msqflg contains operational flags. * @msqflg contains operational flags.
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @msg_queue_msgrcv: * @msg_queue_msgrcv:
* Check permission before a message, @msg, is removed from the message * Check permission before a message, @msg, is removed from the message
* queue, @msq. The @target task structure contains a pointer to the * queue. The @target task structure contains a pointer to the
* process that will be receiving the message (not equal to the current * process that will be receiving the message (not equal to the current
* process when inline receives are being performed). * process when inline receives are being performed).
* @msq contains the message queue to retrieve message from. * @perm contains the IPC permissions of the message queue.
* @msg contains the message destination. * @msg contains the message destination.
* @target contains the task structure for recipient process. * @target contains the task structure for recipient process.
* @type contains the type of message requested. * @type contains the type of message requested.
...@@ -1157,34 +1155,34 @@ ...@@ -1157,34 +1155,34 @@
* Security hooks for System V Shared Memory Segments * Security hooks for System V Shared Memory Segments
* *
* @shm_alloc_security: * @shm_alloc_security:
* Allocate and attach a security structure to the shp->shm_perm.security * Allocate and attach a security structure to the @perm->security
* field. The security field is initialized to NULL when the structure is * field. The security field is initialized to NULL when the structure is
* first created. * first created.
* @shp contains the shared memory structure to be modified. * @perm contains the IPC permissions of the shared memory structure.
* Return 0 if operation was successful and permission is granted. * Return 0 if operation was successful and permission is granted.
* @shm_free_security: * @shm_free_security:
* Deallocate the security struct for this memory segment. * Deallocate the security structure @perm->security for the memory segment.
* @shp contains the shared memory structure to be modified. * @perm contains the IPC permissions of the shared memory structure.
* @shm_associate: * @shm_associate:
* Check permission when a shared memory region is requested through the * Check permission when a shared memory region is requested through the
* shmget system call. This hook is only called when returning the shared * 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 identifier for an existing region, not when a new shared
* memory region is created. * memory region is created.
* @shp contains the shared memory structure to be modified. * @perm contains the IPC permissions of the shared memory structure.
* @shmflg contains the operation control flags. * @shmflg contains the operation control flags.
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @shm_shmctl: * @shm_shmctl:
* Check permission when a shared memory control operation specified by * Check permission when a shared memory control operation specified by
* @cmd is to be performed on the shared memory region @shp. * @cmd is to be performed on the shared memory region with permissions @perm.
* The @shp may be NULL, e.g. for IPC_INFO or SHM_INFO. * The @perm may be NULL, e.g. for IPC_INFO or SHM_INFO.
* @shp contains shared memory structure to be modified. * @perm contains the IPC permissions of the shared memory structure.
* @cmd contains the operation to be performed. * @cmd contains the operation to be performed.
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @shm_shmat: * @shm_shmat:
* Check permissions prior to allowing the shmat system call to attach the * Check permissions prior to allowing the shmat system call to attach the
* shared memory segment @shp to the data segment of the calling process. * shared memory segment with permissions @perm to the data segment of the
* The attaching address is specified by @shmaddr. * calling process. The attaching address is specified by @shmaddr.
* @shp contains the shared memory structure to be modified. * @perm contains the IPC permissions of the shared memory structure.
* @shmaddr contains the address to attach memory region to. * @shmaddr contains the address to attach memory region to.
* @shmflg contains the operational flags. * @shmflg contains the operational flags.
* Return 0 if permission is granted. * Return 0 if permission is granted.
...@@ -1192,34 +1190,34 @@ ...@@ -1192,34 +1190,34 @@
* Security hooks for System V Semaphores * Security hooks for System V Semaphores
* *
* @sem_alloc_security: * @sem_alloc_security:
* Allocate and attach a security structure to the sma->sem_perm.security * Allocate and attach a security structure to the @perm->security
* field. The security field is initialized to NULL when the structure is * field. The security field is initialized to NULL when the structure is
* first created. * first created.
* @sma contains the semaphore structure * @perm contains the IPC permissions of the semaphore.
* Return 0 if operation was successful and permission is granted. * Return 0 if operation was successful and permission is granted.
* @sem_free_security: * @sem_free_security:
* deallocate security struct for this semaphore * Deallocate security structure @perm->security for the semaphore.
* @sma contains the semaphore structure. * @perm contains the IPC permissions of the semaphore.
* @sem_associate: * @sem_associate:
* Check permission when a semaphore is requested through the semget * Check permission when a semaphore is requested through the semget
* system call. This hook is only called when returning the semaphore * system call. This hook is only called when returning the semaphore
* identifier for an existing semaphore, not when a new one must be * identifier for an existing semaphore, not when a new one must be
* created. * created.
* @sma contains the semaphore structure. * @perm contains the IPC permissions of the semaphore.
* @semflg contains the operation control flags. * @semflg contains the operation control flags.
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @sem_semctl: * @sem_semctl:
* Check permission when a semaphore operation specified by @cmd is to be * Check permission when a semaphore operation specified by @cmd is to be
* performed on the semaphore @sma. The @sma may be NULL, e.g. for * performed on the semaphore. The @perm may be NULL, e.g. for
* IPC_INFO or SEM_INFO. * IPC_INFO or SEM_INFO.
* @sma contains the semaphore structure. May be NULL. * @perm contains the IPC permissions of the semaphore. May be NULL.
* @cmd contains the operation to be performed. * @cmd contains the operation to be performed.
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @sem_semop: * @sem_semop:
* Check permissions before performing operations on members of the * Check permissions before performing operations on members of the
* semaphore set @sma. If the @alter flag is nonzero, the semaphore set * semaphore set. If the @alter flag is nonzero, the semaphore set
* may be modified. * may be modified.
* @sma contains the semaphore structure. * @perm contains the IPC permissions of the semaphore.
* @sops contains the operations to perform. * @sops contains the operations to perform.
* @nsops contains the number of operations to perform. * @nsops contains the number of operations to perform.
* @alter contains the flag indicating whether changes are to be made. * @alter contains the flag indicating whether changes are to be made.
...@@ -1292,13 +1290,12 @@ ...@@ -1292,13 +1290,12 @@
* Check permission before accessing the kernel message ring or changing * Check permission before accessing the kernel message ring or changing
* logging to the console. * logging to the console.
* See the syslog(2) manual page for an explanation of the @type values. * See the syslog(2) manual page for an explanation of the @type values.
* @type contains the type of action. * @type contains the SYSLOG_ACTION_* constant from <include/linux/syslog.h>
* @from_file indicates the context of action (if it came from /proc).
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @settime: * @settime:
* Check permission to change the system time. * Check permission to change the system time.
* struct timespec64 is defined in include/linux/time64.h and timezone * struct timespec64 is defined in <include/linux/time64.h> and timezone
* is defined in include/linux/time.h * is defined in <include/linux/time.h>
* @ts contains new time * @ts contains new time
* @tz contains new timezone * @tz contains new timezone
* Return 0 if permission is granted. * Return 0 if permission is granted.
...@@ -1340,7 +1337,7 @@ ...@@ -1340,7 +1337,7 @@
* @audit_rule_init: * @audit_rule_init:
* Allocate and initialize an LSM audit rule structure. * Allocate and initialize an LSM audit rule structure.
* @field contains the required Audit action. * @field contains the required Audit action.
* Fields flags are defined in include/linux/audit.h * Fields flags are defined in <include/linux/audit.h>
* @op contains the operator the rule uses. * @op contains the operator the rule uses.
* @rulestr contains the context where the rule will be applied to. * @rulestr contains the context where the rule will be applied to.
* @lsmrule contains a pointer to receive the result. * @lsmrule contains a pointer to receive the result.
...@@ -1348,9 +1345,9 @@ ...@@ -1348,9 +1345,9 @@
* -EINVAL in case of an invalid rule. * -EINVAL in case of an invalid rule.
* *
* @audit_rule_known: * @audit_rule_known:
* Specifies whether given @rule contains any fields related to * Specifies whether given @krule contains any fields related to
* current LSM. * current LSM.
* @rule contains the audit rule of interest. * @krule contains the audit rule of interest.
* Return 1 in case of relation found, 0 otherwise. * Return 1 in case of relation found, 0 otherwise.
* *
* @audit_rule_match: * @audit_rule_match:
...@@ -1359,13 +1356,13 @@ ...@@ -1359,13 +1356,13 @@
* @secid contains the security id in question. * @secid contains the security id in question.
* @field contains the field which relates to current LSM. * @field contains the field which relates to current LSM.
* @op contains the operator that will be used for matching. * @op contains the operator that will be used for matching.
* @rule points to the audit rule that will be checked against. * @lrule points to the audit rule that will be checked against.
* Return 1 if secid matches the rule, 0 if it does not, -ERRNO on failure. * Return 1 if secid matches the rule, 0 if it does not, -ERRNO on failure.
* *
* @audit_rule_free: * @audit_rule_free:
* Deallocate the LSM audit rule structure previously allocated by * Deallocate the LSM audit rule structure previously allocated by
* audit_rule_init. * audit_rule_init.
* @rule contains the allocated rule * @lsmrule contains the allocated rule
* *
* @inode_invalidate_secctx: * @inode_invalidate_secctx:
* Notify the security module that it must revalidate the security context * Notify the security module that it must revalidate the security context
...@@ -1378,9 +1375,7 @@ ...@@ -1378,9 +1375,7 @@
* this hook to initialize the security context in its incore inode to the * this hook to initialize the security context in its incore inode to the
* value provided by the server for the file when the server returned the * value provided by the server for the file when the server returned the
* file's attributes to the client. * file's attributes to the client.
*
* Must be called with inode->i_mutex locked. * Must be called with inode->i_mutex locked.
*
* @inode we wish to set the security context of. * @inode we wish to set the security context of.
* @ctx contains the string which we wish to set in the inode. * @ctx contains the string which we wish to set in the inode.
* @ctxlen contains the length of @ctx. * @ctxlen contains the length of @ctx.
...@@ -1393,9 +1388,7 @@ ...@@ -1393,9 +1388,7 @@
* this hook to change the security context in its incore inode and on the * this hook to change the security context in its incore inode and on the
* backing filesystem to a value provided by the client on a SETATTR * backing filesystem to a value provided by the client on a SETATTR
* operation. * operation.
*
* Must be called with inode->i_mutex locked. * Must be called with inode->i_mutex locked.
*
* @dentry contains the inode we wish to set the security context of. * @dentry contains the inode we wish to set the security context of.
* @ctx contains the string which we wish to set in the inode. * @ctx contains the string which we wish to set in the inode.
* @ctxlen contains the length of @ctx. * @ctxlen contains the length of @ctx.
...@@ -1403,7 +1396,6 @@ ...@@ -1403,7 +1396,6 @@
* @inode_getsecctx: * @inode_getsecctx:
* On success, returns 0 and fills out @ctx and @ctxlen with the security * On success, returns 0 and fills out @ctx and @ctxlen with the security
* context for the given @inode. * context for the given @inode.
*
* @inode we wish to get the security context of. * @inode we wish to get the security context of.
* @ctx is a pointer in which to place the allocated security context. * @ctx is a pointer in which to place the allocated security context.
* @ctxlen points to the place to put the length of @ctx. * @ctxlen points to the place to put the length of @ctx.
...@@ -1640,28 +1632,28 @@ union security_list_options { ...@@ -1640,28 +1632,28 @@ union security_list_options {
int (*msg_msg_alloc_security)(struct msg_msg *msg); int (*msg_msg_alloc_security)(struct msg_msg *msg);
void (*msg_msg_free_security)(struct msg_msg *msg); void (*msg_msg_free_security)(struct msg_msg *msg);
int (*msg_queue_alloc_security)(struct kern_ipc_perm *msq); int (*msg_queue_alloc_security)(struct kern_ipc_perm *perm);
void (*msg_queue_free_security)(struct kern_ipc_perm *msq); void (*msg_queue_free_security)(struct kern_ipc_perm *perm);
int (*msg_queue_associate)(struct kern_ipc_perm *msq, int msqflg); int (*msg_queue_associate)(struct kern_ipc_perm *perm, int msqflg);
int (*msg_queue_msgctl)(struct kern_ipc_perm *msq, int cmd); int (*msg_queue_msgctl)(struct kern_ipc_perm *perm, int cmd);
int (*msg_queue_msgsnd)(struct kern_ipc_perm *msq, struct msg_msg *msg, int (*msg_queue_msgsnd)(struct kern_ipc_perm *perm, struct msg_msg *msg,
int msqflg); int msqflg);
int (*msg_queue_msgrcv)(struct kern_ipc_perm *msq, struct msg_msg *msg, int (*msg_queue_msgrcv)(struct kern_ipc_perm *perm, struct msg_msg *msg,
struct task_struct *target, long type, struct task_struct *target, long type,
int mode); int mode);
int (*shm_alloc_security)(struct kern_ipc_perm *shp); int (*shm_alloc_security)(struct kern_ipc_perm *perm);
void (*shm_free_security)(struct kern_ipc_perm *shp); void (*shm_free_security)(struct kern_ipc_perm *perm);
int (*shm_associate)(struct kern_ipc_perm *shp, int shmflg); int (*shm_associate)(struct kern_ipc_perm *perm, int shmflg);
int (*shm_shmctl)(struct kern_ipc_perm *shp, int cmd); int (*shm_shmctl)(struct kern_ipc_perm *perm, int cmd);
int (*shm_shmat)(struct kern_ipc_perm *shp, char __user *shmaddr, int (*shm_shmat)(struct kern_ipc_perm *perm, char __user *shmaddr,
int shmflg); int shmflg);
int (*sem_alloc_security)(struct kern_ipc_perm *sma); int (*sem_alloc_security)(struct kern_ipc_perm *perm);
void (*sem_free_security)(struct kern_ipc_perm *sma); void (*sem_free_security)(struct kern_ipc_perm *perm);
int (*sem_associate)(struct kern_ipc_perm *sma, int semflg); int (*sem_associate)(struct kern_ipc_perm *perm, int semflg);
int (*sem_semctl)(struct kern_ipc_perm *sma, int cmd); int (*sem_semctl)(struct kern_ipc_perm *perm, int cmd);
int (*sem_semop)(struct kern_ipc_perm *sma, struct sembuf *sops, int (*sem_semop)(struct kern_ipc_perm *perm, struct sembuf *sops,
unsigned nsops, int alter); unsigned nsops, int alter);
int (*netlink_send)(struct sock *sk, struct sk_buff *skb); int (*netlink_send)(struct sock *sk, struct sk_buff *skb);
......
...@@ -31,6 +31,13 @@ struct user_struct { ...@@ -31,6 +31,13 @@ struct user_struct {
atomic_long_t pipe_bufs; /* how many pages are allocated in pipe buffers */ atomic_long_t pipe_bufs; /* how many pages are allocated in pipe buffers */
#ifdef CONFIG_KEYS #ifdef CONFIG_KEYS
/*
* These pointers can only change from NULL to a non-NULL value once.
* Writes are protected by key_user_keyring_mutex.
* Unlocked readers should use READ_ONCE() unless they know that
* install_user_keyrings() has been called successfully (which sets
* these members to non-NULL values, preventing further modifications).
*/
struct key *uid_keyring; /* UID specific keyring */ struct key *uid_keyring; /* UID specific keyring */
struct key *session_keyring; /* UID's default session keyring */ struct key *session_keyring; /* UID's default session keyring */
#endif #endif
......
...@@ -331,7 +331,7 @@ static int is_ancestor(struct seccomp_filter *parent, ...@@ -331,7 +331,7 @@ static int is_ancestor(struct seccomp_filter *parent,
* Expects sighand and cred_guard_mutex locks to be held. * Expects sighand and cred_guard_mutex locks to be held.
* *
* Returns 0 on success, -ve on error, or the pid of a thread which was * Returns 0 on success, -ve on error, or the pid of a thread which was
* either not in the correct seccomp mode or it did not have an ancestral * either not in the correct seccomp mode or did not have an ancestral
* seccomp filter. * seccomp filter.
*/ */
static inline pid_t seccomp_can_sync_threads(void) static inline pid_t seccomp_can_sync_threads(void)
......
...@@ -58,7 +58,7 @@ int install_user_keyrings(void) ...@@ -58,7 +58,7 @@ int install_user_keyrings(void)
kenter("%p{%u}", user, uid); kenter("%p{%u}", user, uid);
if (user->uid_keyring && user->session_keyring) { if (READ_ONCE(user->uid_keyring) && READ_ONCE(user->session_keyring)) {
kleave(" = 0 [exist]"); kleave(" = 0 [exist]");
return 0; return 0;
} }
...@@ -111,8 +111,10 @@ int install_user_keyrings(void) ...@@ -111,8 +111,10 @@ int install_user_keyrings(void)
} }
/* install the keyrings */ /* install the keyrings */
user->uid_keyring = uid_keyring; /* paired with READ_ONCE() */
user->session_keyring = session_keyring; smp_store_release(&user->uid_keyring, uid_keyring);
/* paired with READ_ONCE() */
smp_store_release(&user->session_keyring, session_keyring);
} }
mutex_unlock(&key_user_keyring_mutex); mutex_unlock(&key_user_keyring_mutex);
...@@ -227,6 +229,7 @@ static int install_process_keyring(void) ...@@ -227,6 +229,7 @@ static int install_process_keyring(void)
* Install the given keyring as the session keyring of the given credentials * Install the given keyring as the session keyring of the given credentials
* struct, replacing the existing one if any. If the given keyring is NULL, * struct, replacing the existing one if any. If the given keyring is NULL,
* then install a new anonymous session keyring. * then install a new anonymous session keyring.
* @cred can not be in use by any task yet.
* *
* Return: 0 on success; -errno on failure. * Return: 0 on success; -errno on failure.
*/ */
...@@ -254,7 +257,7 @@ int install_session_keyring_to_cred(struct cred *cred, struct key *keyring) ...@@ -254,7 +257,7 @@ int install_session_keyring_to_cred(struct cred *cred, struct key *keyring)
/* install the keyring */ /* install the keyring */
old = cred->session_keyring; old = cred->session_keyring;
rcu_assign_pointer(cred->session_keyring, keyring); cred->session_keyring = keyring;
if (old) if (old)
key_put(old); key_put(old);
...@@ -339,6 +342,7 @@ void key_fsgid_changed(struct task_struct *tsk) ...@@ -339,6 +342,7 @@ void key_fsgid_changed(struct task_struct *tsk)
key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx) key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx)
{ {
key_ref_t key_ref, ret, err; key_ref_t key_ref, ret, err;
const struct cred *cred = ctx->cred;
/* we want to return -EAGAIN or -ENOKEY if any of the keyrings were /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were
* searchable, but we failed to find a key or we found a negative key; * searchable, but we failed to find a key or we found a negative key;
...@@ -352,9 +356,9 @@ key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx) ...@@ -352,9 +356,9 @@ key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx)
err = ERR_PTR(-EAGAIN); err = ERR_PTR(-EAGAIN);
/* search the thread keyring first */ /* search the thread keyring first */
if (ctx->cred->thread_keyring) { if (cred->thread_keyring) {
key_ref = keyring_search_aux( key_ref = keyring_search_aux(
make_key_ref(ctx->cred->thread_keyring, 1), ctx); make_key_ref(cred->thread_keyring, 1), ctx);
if (!IS_ERR(key_ref)) if (!IS_ERR(key_ref))
goto found; goto found;
...@@ -370,9 +374,9 @@ key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx) ...@@ -370,9 +374,9 @@ key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx)
} }
/* search the process keyring second */ /* search the process keyring second */
if (ctx->cred->process_keyring) { if (cred->process_keyring) {
key_ref = keyring_search_aux( key_ref = keyring_search_aux(
make_key_ref(ctx->cred->process_keyring, 1), ctx); make_key_ref(cred->process_keyring, 1), ctx);
if (!IS_ERR(key_ref)) if (!IS_ERR(key_ref))
goto found; goto found;
...@@ -391,12 +395,9 @@ key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx) ...@@ -391,12 +395,9 @@ key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx)
} }
/* search the session keyring */ /* search the session keyring */
if (ctx->cred->session_keyring) { if (cred->session_keyring) {
rcu_read_lock();
key_ref = keyring_search_aux( key_ref = keyring_search_aux(
make_key_ref(rcu_dereference(ctx->cred->session_keyring), 1), make_key_ref(cred->session_keyring, 1), ctx);
ctx);
rcu_read_unlock();
if (!IS_ERR(key_ref)) if (!IS_ERR(key_ref))
goto found; goto found;
...@@ -415,9 +416,9 @@ key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx) ...@@ -415,9 +416,9 @@ key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx)
} }
} }
/* or search the user-session keyring */ /* or search the user-session keyring */
else if (ctx->cred->user->session_keyring) { else if (READ_ONCE(cred->user->session_keyring)) {
key_ref = keyring_search_aux( key_ref = keyring_search_aux(
make_key_ref(ctx->cred->user->session_keyring, 1), make_key_ref(READ_ONCE(cred->user->session_keyring), 1),
ctx); ctx);
if (!IS_ERR(key_ref)) if (!IS_ERR(key_ref))
goto found; goto found;
...@@ -604,7 +605,7 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags, ...@@ -604,7 +605,7 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags,
goto error; goto error;
goto reget_creds; goto reget_creds;
} else if (ctx.cred->session_keyring == } else if (ctx.cred->session_keyring ==
ctx.cred->user->session_keyring && READ_ONCE(ctx.cred->user->session_keyring) &&
lflags & KEY_LOOKUP_CREATE) { lflags & KEY_LOOKUP_CREATE) {
ret = join_session_keyring(NULL); ret = join_session_keyring(NULL);
if (ret < 0) if (ret < 0)
...@@ -612,15 +613,13 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags, ...@@ -612,15 +613,13 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags,
goto reget_creds; goto reget_creds;
} }
rcu_read_lock(); key = ctx.cred->session_keyring;
key = rcu_dereference(ctx.cred->session_keyring);
__key_get(key); __key_get(key);
rcu_read_unlock();
key_ref = make_key_ref(key, 1); key_ref = make_key_ref(key, 1);
break; break;
case KEY_SPEC_USER_KEYRING: case KEY_SPEC_USER_KEYRING:
if (!ctx.cred->user->uid_keyring) { if (!READ_ONCE(ctx.cred->user->uid_keyring)) {
ret = install_user_keyrings(); ret = install_user_keyrings();
if (ret < 0) if (ret < 0)
goto error; goto error;
...@@ -632,7 +631,7 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags, ...@@ -632,7 +631,7 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags,
break; break;
case KEY_SPEC_USER_SESSION_KEYRING: case KEY_SPEC_USER_SESSION_KEYRING:
if (!ctx.cred->user->session_keyring) { if (!READ_ONCE(ctx.cred->user->session_keyring)) {
ret = install_user_keyrings(); ret = install_user_keyrings();
if (ret < 0) if (ret < 0)
goto error; goto error;
......
...@@ -142,12 +142,10 @@ static int call_sbin_request_key(struct key *authkey, void *aux) ...@@ -142,12 +142,10 @@ static int call_sbin_request_key(struct key *authkey, void *aux)
prkey = cred->process_keyring->serial; prkey = cred->process_keyring->serial;
sprintf(keyring_str[1], "%d", prkey); sprintf(keyring_str[1], "%d", prkey);
rcu_read_lock(); session = cred->session_keyring;
session = rcu_dereference(cred->session_keyring);
if (!session) if (!session)
session = cred->user->session_keyring; session = cred->user->session_keyring;
sskey = session->serial; sskey = session->serial;
rcu_read_unlock();
sprintf(keyring_str[2], "%d", sskey); sprintf(keyring_str[2], "%d", sskey);
...@@ -287,10 +285,7 @@ static int construct_get_dest_keyring(struct key **_dest_keyring) ...@@ -287,10 +285,7 @@ static int construct_get_dest_keyring(struct key **_dest_keyring)
/* fall through */ /* fall through */
case KEY_REQKEY_DEFL_SESSION_KEYRING: case KEY_REQKEY_DEFL_SESSION_KEYRING:
rcu_read_lock(); dest_keyring = key_get(cred->session_keyring);
dest_keyring = key_get(
rcu_dereference(cred->session_keyring));
rcu_read_unlock();
if (dest_keyring) if (dest_keyring)
break; break;
...@@ -298,11 +293,12 @@ static int construct_get_dest_keyring(struct key **_dest_keyring) ...@@ -298,11 +293,12 @@ static int construct_get_dest_keyring(struct key **_dest_keyring)
/* fall through */ /* fall through */
case KEY_REQKEY_DEFL_USER_SESSION_KEYRING: case KEY_REQKEY_DEFL_USER_SESSION_KEYRING:
dest_keyring = dest_keyring =
key_get(cred->user->session_keyring); key_get(READ_ONCE(cred->user->session_keyring));
break; break;
case KEY_REQKEY_DEFL_USER_KEYRING: case KEY_REQKEY_DEFL_USER_KEYRING:
dest_keyring = key_get(cred->user->uid_keyring); dest_keyring =
key_get(READ_ONCE(cred->user->uid_keyring));
break; break;
case KEY_REQKEY_DEFL_GROUP_KEYRING: case KEY_REQKEY_DEFL_GROUP_KEYRING:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment