-/* Credentials management
+/* Credentials management - see Documentation/credentials.txt
*
* Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
struct user_struct;
struct cred;
+struct inode;
/*
* COW Supplementary groups list
} while (0)
extern struct group_info *groups_alloc(int);
+extern struct group_info init_groups;
extern void groups_free(struct group_info *);
extern int set_current_groups(struct group_info *);
extern int set_groups(struct cred *, struct group_info *);
extern int in_group_p(gid_t);
extern int in_egroup_p(gid_t);
+/*
+ * The common credentials for a thread group
+ * - shared by CLONE_THREAD
+ */
+#ifdef CONFIG_KEYS
+struct thread_group_cred {
+ atomic_t usage;
+ pid_t tgid; /* thread group process ID */
+ spinlock_t lock;
+ struct key *session_keyring; /* keyring inherited over fork */
+ struct key *process_keyring; /* keyring private to this process */
+ struct rcu_head rcu; /* RCU deletion hook */
+};
+#endif
+
/*
* The security context of a task
*
* keys to */
struct key *thread_keyring; /* keyring private to this thread */
struct key *request_key_auth; /* assumed request_key authority */
+ struct thread_group_cred *tgcred; /* thread-group shared credentials */
#endif
#ifdef CONFIG_SECURITY
void *security; /* subjective LSM security */
struct user_struct *user; /* real user ID subscription */
struct group_info *group_info; /* supplementary groups for euid/fsgid */
struct rcu_head rcu; /* RCU deletion hook */
- spinlock_t lock; /* lock for pointer changes */
};
extern void __put_cred(struct cred *);
extern int copy_creds(struct task_struct *, unsigned long);
+extern struct cred *prepare_creds(void);
+extern struct cred *prepare_exec_creds(void);
+extern struct cred *prepare_usermodehelper_creds(void);
+extern int commit_creds(struct cred *);
+extern void abort_creds(struct cred *);
+extern const struct cred *override_creds(const struct cred *);
+extern void revert_creds(const struct cred *);
+extern struct cred *prepare_kernel_cred(struct task_struct *);
+extern int change_create_files_as(struct cred *, struct inode *);
+extern int set_security_override(struct cred *, u32);
+extern int set_security_override_from_ctx(struct cred *, const char *);
+extern int set_create_files_as(struct cred *, struct inode *);
+extern void __init cred_init(void);
+
+/**
+ * get_new_cred - Get a reference on a new set of credentials
+ * @cred: The new credentials to reference
+ *
+ * Get a reference on the specified set of new credentials. The caller must
+ * release the reference.
+ */
+static inline struct cred *get_new_cred(struct cred *cred)
+{
+ atomic_inc(&cred->usage);
+ return cred;
+}
/**
* get_cred - Get a reference on a set of credentials
*
* Get a reference on the specified set of credentials. The caller must
* release the reference.
+ *
+ * This is used to deal with a committed set of credentials. Although the
+ * pointer is const, this will temporarily discard the const and increment the
+ * usage count. The purpose of this is to attempt to catch at compile time the
+ * accidental alteration of a set of credentials that should be considered
+ * immutable.
*/
-static inline struct cred *get_cred(struct cred *cred)
+static inline const struct cred *get_cred(const struct cred *cred)
{
- atomic_inc(&cred->usage);
- return cred;
+ return get_new_cred((struct cred *) cred);
}
/**
*
* Release a reference to a set of credentials, deleting them when the last ref
* is released.
+ *
+ * This takes a const pointer to a set of credentials because the credentials
+ * on task_struct are attached by const pointers to prevent accidental
+ * alteration of otherwise immutable credential sets.
*/
-static inline void put_cred(struct cred *cred)
+static inline void put_cred(const struct cred *_cred)
{
+ struct cred *cred = (struct cred *) _cred;
+
+ BUG_ON(atomic_read(&(cred)->usage) <= 0);
if (atomic_dec_and_test(&(cred)->usage))
__put_cred(cred);
}
/**
- * current_cred - Access the current task's credentials
+ * current_cred - Access the current task's subjective credentials
*
- * Access the credentials of the current task.
+ * Access the subjective credentials of the current task.
*/
#define current_cred() \
(current->cred)
/**
- * __task_cred - Access another task's credentials
+ * __task_cred - Access a task's objective credentials
* @task: The task to query
*
- * Access the credentials of another task. The caller must hold the
- * RCU readlock.
+ * Access the objective credentials of a task. The caller must hold the RCU
+ * readlock.
*
* The caller must make sure task doesn't go away, either by holding a ref on
* task or by holding tasklist_lock to prevent it from being unlinked.
*/
#define __task_cred(task) \
- ((const struct cred *)(rcu_dereference((task)->cred)))
+ ((const struct cred *)(rcu_dereference((task)->real_cred)))
/**
- * get_task_cred - Get another task's credentials
+ * get_task_cred - Get another task's objective credentials
* @task: The task to query
*
- * Get the credentials of a task, pinning them so that they can't go away.
- * Accessing a task's credentials directly is not permitted.
+ * Get the objective credentials of a task, pinning them so that they can't go
+ * away. Accessing a task's credentials directly is not permitted.
*
* The caller must make sure task doesn't go away, either by holding a ref on
* task or by holding tasklist_lock to prevent it from being unlinked.
})
/**
- * get_current_cred - Get the current task's credentials
+ * get_current_cred - Get the current task's subjective credentials
*
- * Get the credentials of the current task, pinning them so that they can't go
- * away. Accessing the current task's credentials directly is not permitted.
+ * Get the subjective credentials of the current task, pinning them so that
+ * they can't go away. Accessing the current task's credentials directly is
+ * not permitted.
*/
#define get_current_cred() \
(get_cred(current_cred()))
__groups; \
})
-#define task_cred_xxx(task, xxx) \
-({ \
- __typeof__(task->cred->xxx) ___val; \
- rcu_read_lock(); \
- ___val = __task_cred((task))->xxx; \
- rcu_read_unlock(); \
- ___val; \
+#define task_cred_xxx(task, xxx) \
+({ \
+ __typeof__(((struct cred *)NULL)->xxx) ___val; \
+ rcu_read_lock(); \
+ ___val = __task_cred((task))->xxx; \
+ rcu_read_unlock(); \
+ ___val; \
})
#define task_uid(task) (task_cred_xxx((task), uid))
#define current_fsgid() (current_cred_xxx(fsgid))
#define current_cap() (current_cred_xxx(cap_effective))
#define current_user() (current_cred_xxx(user))
+#define current_user_ns() (current_cred_xxx(user)->user_ns)
#define current_security() (current_cred_xxx(security))
#define current_uid_gid(_uid, _gid) \