summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2008-10-20 19:17:22 +1100
committerStephen Rothwell <sfr@canb.auug.org.au>2008-10-20 19:17:22 +1100
commitc72181026d0989608a43a9a7eda4a8044cf34c18 (patch)
tree1cead9d83222e9f401bac884aa751c9fc1b02d82 /include
parentc4052e69f851e1ca5d787b7e15a51eaf8176e5eb (diff)
parentb84a6734984c2d19db6326513f94ec4a792a443d (diff)
Merge commit 'creds/next-creds-subsys'
Conflicts: fs/devpts/inode.c fs/namespace.c fs/nfsd/nfs4recover.c include/linux/sched.h kernel/exit.c kernel/fork.c kernel/signal.c net/9p/client.c security/selinux/hooks.c
Diffstat (limited to 'include')
-rw-r--r--include/keys/keyring-type.h31
-rw-r--r--include/linux/binfmts.h16
-rw-r--r--include/linux/capability.h2
-rw-r--r--include/linux/cred.h340
-rw-r--r--include/linux/fs.h8
-rw-r--r--include/linux/init_task.h13
-rw-r--r--include/linux/key-ui.h66
-rw-r--r--include/linux/key.h32
-rw-r--r--include/linux/keyctl.h4
-rw-r--r--include/linux/sched.h64
-rw-r--r--include/linux/securebits.h2
-rw-r--r--include/linux/security.h326
-rw-r--r--include/net/scm.h4
13 files changed, 540 insertions, 368 deletions
diff --git a/include/keys/keyring-type.h b/include/keys/keyring-type.h
new file mode 100644
index 000000000000..843f872a4b63
--- /dev/null
+++ b/include/keys/keyring-type.h
@@ -0,0 +1,31 @@
+/* Keyring key type
+ *
+ * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * 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 _KEYS_KEYRING_TYPE_H
+#define _KEYS_KEYRING_TYPE_H
+
+#include <linux/key.h>
+#include <linux/rcupdate.h>
+
+/*
+ * the keyring payload contains a list of the keys to which the keyring is
+ * subscribed
+ */
+struct keyring_list {
+ struct rcu_head rcu; /* RCU deletion hook */
+ unsigned short maxkeys; /* max keys this list can hold */
+ unsigned short nkeys; /* number of keys currently held */
+ unsigned short delkey; /* key to be unlinked by RCU */
+ struct key *keys[0];
+};
+
+
+#endif /* _KEYS_KEYRING_TYPE_H */
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
index 7394b5b349ff..6cbfbe297180 100644
--- a/include/linux/binfmts.h
+++ b/include/linux/binfmts.h
@@ -35,16 +35,20 @@ struct linux_binprm{
struct mm_struct *mm;
unsigned long p; /* current top of mem */
unsigned int sh_bang:1,
- misc_bang:1;
+ misc_bang:1,
+ cred_prepared:1,/* true if creds already prepared (multiple
+ * preps happen for interpreters) */
+ cap_effective:1;/* true if has elevated effective capabilities,
+ * false if not; except for init which inherits
+ * its parent's caps anyway */
#ifdef __alpha__
unsigned int taso:1;
#endif
unsigned int recursion_depth;
struct file * file;
- int e_uid, e_gid;
- kernel_cap_t cap_post_exec_permitted;
- bool cap_effective;
- void *security;
+ struct cred *cred; /* new credentials */
+ int unsafe; /* how unsafe this exec is (mask of LSM_UNSAFE_*) */
+ unsigned int per_clear; /* bits to clear in current->personality */
int argc, envc;
char * filename; /* Name of binary as seen by procps */
char * interp; /* Name of the binary really executed. Most
@@ -101,7 +105,7 @@ extern int setup_arg_pages(struct linux_binprm * bprm,
int executable_stack);
extern int bprm_mm_init(struct linux_binprm *bprm);
extern int copy_strings_kernel(int argc,char ** argv,struct linux_binprm *bprm);
-extern void compute_creds(struct linux_binprm *binprm);
+extern void install_exec_creds(struct linux_binprm *bprm);
extern int do_coredump(long signr, int exit_code, struct pt_regs * regs);
extern int set_binfmt(struct linux_binfmt *new);
extern void free_bprm(struct linux_binprm *);
diff --git a/include/linux/capability.h b/include/linux/capability.h
index 9d1fe30b6f6c..a7fe01ca3609 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -501,8 +501,6 @@ extern const kernel_cap_t __cap_empty_set;
extern const kernel_cap_t __cap_full_set;
extern const kernel_cap_t __cap_init_eff_set;
-kernel_cap_t cap_set_effective(const kernel_cap_t pE_new);
-
/**
* has_capability - Determine if a task has a superior capability available
* @t: The task in question
diff --git a/include/linux/cred.h b/include/linux/cred.h
index b69222cc1fd2..26c1ab179946 100644
--- a/include/linux/cred.h
+++ b/include/linux/cred.h
@@ -1,4 +1,4 @@
-/* Credentials management
+/* Credentials management - see Documentation/credentials.txt
*
* Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
@@ -12,39 +12,333 @@
#ifndef _LINUX_CRED_H
#define _LINUX_CRED_H
-#define get_current_user() (get_uid(current->user))
+#include <linux/capability.h>
+#include <linux/key.h>
+#include <asm/atomic.h>
-#define task_uid(task) ((task)->uid)
-#define task_gid(task) ((task)->gid)
-#define task_euid(task) ((task)->euid)
-#define task_egid(task) ((task)->egid)
+struct user_struct;
+struct cred;
+struct inode;
-#define current_uid() (current->uid)
-#define current_gid() (current->gid)
-#define current_euid() (current->euid)
-#define current_egid() (current->egid)
-#define current_suid() (current->suid)
-#define current_sgid() (current->sgid)
-#define current_fsuid() (current->fsuid)
-#define current_fsgid() (current->fsgid)
-#define current_cap() (current->cap_effective)
+/*
+ * COW Supplementary groups list
+ */
+#define NGROUPS_SMALL 32
+#define NGROUPS_PER_BLOCK ((unsigned int)(PAGE_SIZE / sizeof(gid_t)))
+
+struct group_info {
+ atomic_t usage;
+ int ngroups;
+ int nblocks;
+ gid_t small_block[NGROUPS_SMALL];
+ gid_t *blocks[0];
+};
+
+/**
+ * get_group_info - Get a reference to a group info structure
+ * @group_info: The group info to reference
+ *
+ * This gets a reference to a set of supplementary groups.
+ *
+ * If the caller is accessing a task's credentials, they must hold the RCU read
+ * lock when reading.
+ */
+static inline struct group_info *get_group_info(struct group_info *gi)
+{
+ atomic_inc(&gi->usage);
+ return gi;
+}
+
+/**
+ * put_group_info - Release a reference to a group info structure
+ * @group_info: The group info to release
+ */
+#define put_group_info(group_info) \
+do { \
+ if (atomic_dec_and_test(&(group_info)->usage)) \
+ groups_free(group_info); \
+} while (0)
+
+extern struct group_info *groups_alloc(int);
+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 groups_search(const struct group_info *, gid_t);
+
+/* access the groups "array" with this macro */
+#define GROUP_AT(gi, i) \
+ ((gi)->blocks[(i) / NGROUPS_PER_BLOCK][(i) % NGROUPS_PER_BLOCK])
+
+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
+ *
+ * The parts of the context break down into two categories:
+ *
+ * (1) The objective context of a task. These parts are used when some other
+ * task is attempting to affect this one.
+ *
+ * (2) The subjective context. These details are used when the task is acting
+ * upon another object, be that a file, a task, a key or whatever.
+ *
+ * Note that some members of this structure belong to both categories - the
+ * LSM security pointer for instance.
+ *
+ * A task has two security pointers. task->real_cred points to the objective
+ * context that defines that task's actual details. The objective part of this
+ * context is used whenever that task is acted upon.
+ *
+ * task->cred points to the subjective context that defines the details of how
+ * that task is going to act upon another object. This may be overridden
+ * temporarily to point to another security context, but normally points to the
+ * same context as task->real_cred.
+ */
+struct cred {
+ atomic_t usage;
+ uid_t uid; /* real UID of the task */
+ gid_t gid; /* real GID of the task */
+ uid_t suid; /* saved UID of the task */
+ gid_t sgid; /* saved GID of the task */
+ uid_t euid; /* effective UID of the task */
+ gid_t egid; /* effective GID of the task */
+ uid_t fsuid; /* UID for VFS ops */
+ gid_t fsgid; /* GID for VFS ops */
+ unsigned securebits; /* SUID-less security management */
+ kernel_cap_t cap_inheritable; /* caps our children can inherit */
+ kernel_cap_t cap_permitted; /* caps we're permitted */
+ kernel_cap_t cap_effective; /* caps we can actually use */
+ kernel_cap_t cap_bset; /* capability bounding set */
+#ifdef CONFIG_KEYS
+ unsigned char jit_keyring; /* default keyring to attach requested
+ * 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 */
+#endif
+ 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 */
+};
+
+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
+ * @cred: The credentials to reference
+ *
+ * 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 const struct cred *get_cred(const struct cred *cred)
+{
+ return get_new_cred((struct cred *) cred);
+}
+
+/**
+ * put_cred - Release a reference to a set of credentials
+ * @cred: The credentials to release
+ *
+ * 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(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 subjective credentials
+ *
+ * Access the subjective credentials of the current task.
+ */
+#define current_cred() \
+ (current->cred)
+
+/**
+ * __task_cred - Access a task's objective credentials
+ * @task: The task to query
+ *
+ * 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)->real_cred)))
+
+/**
+ * get_task_cred - Get another task's objective credentials
+ * @task: The task to query
+ *
+ * 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.
+ */
+#define get_task_cred(task) \
+({ \
+ struct cred *__cred; \
+ rcu_read_lock(); \
+ __cred = (struct cred *) __task_cred((task)); \
+ get_cred(__cred); \
+ rcu_read_unlock(); \
+ __cred; \
+})
+
+/**
+ * get_current_cred - Get the current task's subjective credentials
+ *
+ * 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()))
+
+/**
+ * get_current_user - Get the current task's user_struct
+ *
+ * Get the user record of the current task, pinning it so that it can't go
+ * away.
+ */
+#define get_current_user() \
+({ \
+ struct user_struct *__u; \
+ struct cred *__cred; \
+ __cred = (struct cred *) current_cred(); \
+ __u = get_uid(__cred->user); \
+ __u; \
+})
+
+/**
+ * get_current_groups - Get the current task's supplementary group list
+ *
+ * Get the supplementary group list of the current task, pinning it so that it
+ * can't go away.
+ */
+#define get_current_groups() \
+({ \
+ struct group_info *__groups; \
+ struct cred *__cred; \
+ __cred = (struct cred *) current_cred(); \
+ __groups = get_group_info(__cred->group_info); \
+ __groups; \
+})
+
+#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 task_euid(task) (task_cred_xxx((task), euid))
+
+#define current_cred_xxx(xxx) \
+({ \
+ current->cred->xxx; \
+})
+
+#define current_uid() (current_cred_xxx(uid))
+#define current_gid() (current_cred_xxx(gid))
+#define current_euid() (current_cred_xxx(euid))
+#define current_egid() (current_cred_xxx(egid))
+#define current_suid() (current_cred_xxx(suid))
+#define current_sgid() (current_cred_xxx(sgid))
+#define current_fsuid() (current_cred_xxx(fsuid))
+#define current_fsgid() (current_cred_xxx(fsgid))
+#define current_cap() (current_cred_xxx(cap_effective))
+#define current_user() (current_cred_xxx(user))
+#define current_security() (current_cred_xxx(security))
#define current_uid_gid(_uid, _gid) \
do { \
- *(_uid) = current->uid; \
- *(_gid) = current->gid; \
+ const struct cred *__cred; \
+ __cred = current_cred(); \
+ *(_uid) = __cred->uid; \
+ *(_gid) = __cred->gid; \
} while(0)
-#define current_euid_egid(_uid, _gid) \
+#define current_euid_egid(_euid, _egid) \
do { \
- *(_uid) = current->euid; \
- *(_gid) = current->egid; \
+ const struct cred *__cred; \
+ __cred = current_cred(); \
+ *(_euid) = __cred->euid; \
+ *(_egid) = __cred->egid; \
} while(0)
-#define current_fsuid_fsgid(_uid, _gid) \
+#define current_fsuid_fsgid(_fsuid, _fsgid) \
do { \
- *(_uid) = current->fsuid; \
- *(_gid) = current->fsgid; \
+ const struct cred *__cred; \
+ __cred = current_cred(); \
+ *(_fsuid) = __cred->fsuid; \
+ *(_fsgid) = __cred->fsgid; \
} while(0)
#endif /* _LINUX_CRED_H */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index dd4d47c943f7..27177f42881e 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -310,6 +310,7 @@ struct poll_table_struct;
struct kstatfs;
struct vm_area_struct;
struct vfsmount;
+struct cred;
extern void __init inode_init(void);
extern void __init inode_init_early(void);
@@ -828,7 +829,7 @@ struct file {
mode_t f_mode;
loff_t f_pos;
struct fown_struct f_owner;
- unsigned int f_uid, f_gid;
+ const struct cred *f_cred;
struct file_ra_state f_ra;
u64 f_version;
@@ -1195,7 +1196,7 @@ enum {
#define has_fs_excl() atomic_read(&current->fs_excl)
#define is_owner_or_cap(inode) \
- ((current->fsuid == (inode)->i_uid) || capable(CAP_FOWNER))
+ ((current_fsuid() == (inode)->i_uid) || capable(CAP_FOWNER))
/* not quite ready to be deprecated, but... */
extern void lock_super(struct super_block *);
@@ -1688,7 +1689,8 @@ extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
extern long do_sys_open(int dfd, const char __user *filename, int flags,
int mode);
extern struct file *filp_open(const char *, int, int);
-extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
+extern struct file * dentry_open(struct dentry *, struct vfsmount *, int,
+ const struct cred *);
extern int filp_close(struct file *, fl_owner_t id);
extern char * getname(const char __user *);
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index 23fd8909b9e5..2597858035cd 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -113,6 +113,8 @@ extern struct group_info init_groups;
# define CAP_INIT_BSET CAP_INIT_EFF_SET
#endif
+extern struct cred init_cred;
+
/*
* INIT_TASK is used to set up the first task table, touch at
* your own risk!. Base=0, limit=0x1fffff (=2MB)
@@ -147,13 +149,10 @@ extern struct group_info init_groups;
.children = LIST_HEAD_INIT(tsk.children), \
.sibling = LIST_HEAD_INIT(tsk.sibling), \
.group_leader = &tsk, \
- .group_info = &init_groups, \
- .cap_effective = CAP_INIT_EFF_SET, \
- .cap_inheritable = CAP_INIT_INH_SET, \
- .cap_permitted = CAP_FULL_SET, \
- .cap_bset = CAP_INIT_BSET, \
- .securebits = SECUREBITS_DEFAULT, \
- .user = INIT_USER, \
+ .real_cred = &init_cred, \
+ .cred = &init_cred, \
+ .cred_exec_mutex = \
+ __MUTEX_INITIALIZER(tsk.cred_exec_mutex), \
.comm = "swapper", \
.thread = INIT_THREAD, \
.fs = &init_fs, \
diff --git a/include/linux/key-ui.h b/include/linux/key-ui.h
deleted file mode 100644
index e8b8a7a5c496..000000000000
--- a/include/linux/key-ui.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* key-ui.h: key userspace interface stuff
- *
- * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * 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_KEY_UI_H
-#define _LINUX_KEY_UI_H
-
-#include <linux/key.h>
-
-/* the key tree */
-extern struct rb_root key_serial_tree;
-extern spinlock_t key_serial_lock;
-
-/* required permissions */
-#define KEY_VIEW 0x01 /* require permission to view attributes */
-#define KEY_READ 0x02 /* require permission to read content */
-#define KEY_WRITE 0x04 /* require permission to update / modify */
-#define KEY_SEARCH 0x08 /* require permission to search (keyring) or find (key) */
-#define KEY_LINK 0x10 /* require permission to link */
-#define KEY_SETATTR 0x20 /* require permission to change attributes */
-#define KEY_ALL 0x3f /* all the above permissions */
-
-/*
- * the keyring payload contains a list of the keys to which the keyring is
- * subscribed
- */
-struct keyring_list {
- struct rcu_head rcu; /* RCU deletion hook */
- unsigned short maxkeys; /* max keys this list can hold */
- unsigned short nkeys; /* number of keys currently held */
- unsigned short delkey; /* key to be unlinked by RCU */
- struct key *keys[0];
-};
-
-/*
- * check to see whether permission is granted to use a key in the desired way
- */
-extern int key_task_permission(const key_ref_t key_ref,
- struct task_struct *context,
- key_perm_t perm);
-
-static inline int key_permission(const key_ref_t key_ref, key_perm_t perm)
-{
- return key_task_permission(key_ref, current, perm);
-}
-
-extern key_ref_t lookup_user_key(struct task_struct *context,
- key_serial_t id, int create, int partial,
- key_perm_t perm);
-
-extern long join_session_keyring(const char *name);
-
-extern struct key_type *key_type_lookup(const char *type);
-extern void key_type_put(struct key_type *ktype);
-
-#define key_negative_timeout 60 /* default timeout on a negative key's existence */
-
-
-#endif /* _LINUX_KEY_UI_H */
diff --git a/include/linux/key.h b/include/linux/key.h
index 1b70e35a71e3..21d32a142c00 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -73,6 +73,7 @@ struct key;
struct seq_file;
struct user_struct;
struct signal_struct;
+struct cred;
struct key_type;
struct key_owner;
@@ -181,7 +182,7 @@ struct key {
extern struct key *key_alloc(struct key_type *type,
const char *desc,
uid_t uid, gid_t gid,
- struct task_struct *ctx,
+ const struct cred *cred,
key_perm_t perm,
unsigned long flags);
@@ -249,7 +250,7 @@ extern int key_unlink(struct key *keyring,
struct key *key);
extern struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
- struct task_struct *ctx,
+ const struct cred *cred,
unsigned long flags,
struct key *dest);
@@ -276,24 +277,11 @@ extern ctl_table key_sysctls[];
/*
* the userspace interface
*/
-extern void switch_uid_keyring(struct user_struct *new_user);
-extern int copy_keys(unsigned long clone_flags, struct task_struct *tsk);
-extern int copy_thread_group_keys(struct task_struct *tsk);
-extern void exit_keys(struct task_struct *tsk);
-extern void exit_thread_group_keys(struct signal_struct *tg);
-extern int suid_keys(struct task_struct *tsk);
-extern int exec_keys(struct task_struct *tsk);
+extern int install_thread_keyring_to_cred(struct cred *cred);
extern void key_fsuid_changed(struct task_struct *tsk);
extern void key_fsgid_changed(struct task_struct *tsk);
extern void key_init(void);
-#define __install_session_keyring(tsk, keyring) \
-({ \
- struct key *old_session = tsk->signal->session_keyring; \
- tsk->signal->session_keyring = keyring; \
- old_session; \
-})
-
#else /* CONFIG_KEYS */
#define key_validate(k) 0
@@ -302,17 +290,9 @@ extern void key_init(void);
#define key_revoke(k) do { } while(0)
#define key_put(k) do { } while(0)
#define key_ref_put(k) do { } while(0)
-#define make_key_ref(k, p) ({ NULL; })
-#define key_ref_to_ptr(k) ({ NULL; })
+#define make_key_ref(k, p) NULL
+#define key_ref_to_ptr(k) NULL
#define is_key_possessed(k) 0
-#define switch_uid_keyring(u) do { } while(0)
-#define __install_session_keyring(t, k) ({ NULL; })
-#define copy_keys(f,t) 0
-#define copy_thread_group_keys(t) 0
-#define exit_keys(t) do { } while(0)
-#define exit_thread_group_keys(tg) do { } while(0)
-#define suid_keys(t) do { } while(0)
-#define exec_keys(t) do { } while(0)
#define key_fsuid_changed(t) do { } while(0)
#define key_fsgid_changed(t) do { } while(0)
#define key_init() do { } while(0)
diff --git a/include/linux/keyctl.h b/include/linux/keyctl.h
index 656ee6b77a4a..c0688eb72093 100644
--- a/include/linux/keyctl.h
+++ b/include/linux/keyctl.h
@@ -1,6 +1,6 @@
/* keyctl.h: keyctl command IDs
*
- * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2004, 2008 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
@@ -20,6 +20,7 @@
#define KEY_SPEC_USER_SESSION_KEYRING -5 /* - key ID for UID-session keyring */
#define KEY_SPEC_GROUP_KEYRING -6 /* - key ID for GID-specific keyring */
#define KEY_SPEC_REQKEY_AUTH_KEY -7 /* - key ID for assumed request_key auth key */
+#define KEY_SPEC_REQUESTOR_KEYRING -8 /* - key ID for request_key() dest keyring */
/* request-key default keyrings */
#define KEY_REQKEY_DEFL_NO_CHANGE -1
@@ -30,6 +31,7 @@
#define KEY_REQKEY_DEFL_USER_KEYRING 4
#define KEY_REQKEY_DEFL_USER_SESSION_KEYRING 5
#define KEY_REQKEY_DEFL_GROUP_KEYRING 6
+#define KEY_REQKEY_DEFL_REQUESTOR_KEYRING 7
/* keyctl commands */
#define KEYCTL_GET_KEYRING_ID 0 /* ask for a keyring's ID */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index b7b4dccd3d0a..09bdc05a6767 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -563,12 +563,6 @@ struct signal_struct {
*/
struct rlimit rlim[RLIM_NLIMITS];
- /* keep the process-shared keyrings here so that they do the right
- * thing in threads created with CLONE_THREAD */
-#ifdef CONFIG_KEYS
- struct key *session_keyring; /* keyring inherited over fork */
- struct key *process_keyring; /* keyring private to this process */
-#endif
#ifdef CONFIG_BSD_PROCESS_ACCT
struct pacct_struct pacct; /* per-process accounting information */
#endif
@@ -652,6 +646,7 @@ extern struct user_struct *find_user(uid_t);
extern struct user_struct root_user;
#define INIT_USER (&root_user)
+
struct backing_dev_info;
struct reclaim_state;
@@ -879,38 +874,7 @@ partition_sched_domains(int ndoms_new, cpumask_t *doms_new,
#endif /* !CONFIG_SMP */
struct io_context; /* See blkdev.h */
-#define NGROUPS_SMALL 32
-#define NGROUPS_PER_BLOCK ((unsigned int)(PAGE_SIZE / sizeof(gid_t)))
-struct group_info {
- int ngroups;
- atomic_t usage;
- gid_t small_block[NGROUPS_SMALL];
- int nblocks;
- gid_t *blocks[0];
-};
-/*
- * get_group_info() must be called with the owning task locked (via task_lock())
- * when task != current. The reason being that the vast majority of callers are
- * looking at current->group_info, which can not be changed except by the
- * current task. Changing current->group_info requires the task lock, too.
- */
-#define get_group_info(group_info) do { \
- atomic_inc(&(group_info)->usage); \
-} while (0)
-
-#define put_group_info(group_info) do { \
- if (atomic_dec_and_test(&(group_info)->usage)) \
- groups_free(group_info); \
-} while (0)
-
-extern struct group_info *groups_alloc(int gidsetsize);
-extern void groups_free(struct group_info *group_info);
-extern int set_current_groups(struct group_info *group_info);
-extern int groups_search(struct group_info *group_info, gid_t grp);
-/* access the groups "array" with this macro */
-#define GROUP_AT(gi, i) \
- ((gi)->blocks[(i)/NGROUPS_PER_BLOCK][(i)%NGROUPS_PER_BLOCK])
#ifdef ARCH_HAS_PREFETCH_SWITCH_STACK
extern void prefetch_stack(struct task_struct *t);
@@ -1174,17 +1138,12 @@ struct task_struct {
struct list_head cpu_timers[3];
/* process credentials */
- uid_t uid,euid,suid,fsuid;
- gid_t gid,egid,sgid,fsgid;
- struct group_info *group_info;
- kernel_cap_t cap_effective, cap_inheritable, cap_permitted, cap_bset;
- struct user_struct *user;
- unsigned securebits;
-#ifdef CONFIG_KEYS
- unsigned char jit_keyring; /* default keyring to attach requested keys to */
- struct key *request_key_auth; /* assumed request_key authority */
- struct key *thread_keyring; /* keyring private to this thread */
-#endif
+ const struct cred *real_cred; /* objective and real subjective task
+ * credentials (COW) */
+ const struct cred *cred; /* effective (overridable) subjective task
+ * credentials (COW) */
+ struct mutex cred_exec_mutex; /* execve vs ptrace cred calculation mutex */
+
char comm[TASK_COMM_LEN]; /* executable name excluding path
- access with [gs]et_task_comm (which lock
it with task_lock())
@@ -1221,9 +1180,6 @@ struct task_struct {
int (*notifier)(void *priv);
void *notifier_data;
sigset_t *notifier_mask;
-#ifdef CONFIG_SECURITY
- void *security;
-#endif
struct audit_context *audit_context;
#ifdef CONFIG_AUDITSYSCALL
uid_t loginuid;
@@ -1760,7 +1716,6 @@ static inline struct user_struct *get_uid(struct user_struct *u)
return u;
}
extern void free_uid(struct user_struct *);
-extern void switch_uid(struct user_struct *);
extern void release_uids(struct user_namespace *ns);
#include <asm/current.h>
@@ -1779,9 +1734,6 @@ extern void wake_up_new_task(struct task_struct *tsk,
extern void sched_fork(struct task_struct *p, int clone_flags);
extern void sched_dead(struct task_struct *p);
-extern int in_group_p(gid_t);
-extern int in_egroup_p(gid_t);
-
extern void proc_caches_init(void);
extern void flush_signals(struct task_struct *);
extern void ignore_signals(struct task_struct *);
@@ -1913,6 +1865,8 @@ static inline unsigned long wait_task_inactive(struct task_struct *p,
#define for_each_process(p) \
for (p = &init_task ; (p = next_task(p)) != &init_task ; )
+extern bool is_single_threaded(struct task_struct *);
+
/*
* Careful: do_each_thread/while_each_thread is a double loop so
* 'break' will not work as expected - use goto instead.
diff --git a/include/linux/securebits.h b/include/linux/securebits.h
index 92f09bdf1175..d2c5ed845bcc 100644
--- a/include/linux/securebits.h
+++ b/include/linux/securebits.h
@@ -32,7 +32,7 @@
setting is locked or not. A setting which is locked cannot be
changed from user-level. */
#define issecure_mask(X) (1 << (X))
-#define issecure(X) (issecure_mask(X) & current->securebits)
+#define issecure(X) (issecure_mask(X) & current_cred_xxx(securebits))
#define SECURE_ALL_BITS (issecure_mask(SECURE_NOROOT) | \
issecure_mask(SECURE_NO_SETUID_FIXUP) | \
diff --git a/include/linux/security.h b/include/linux/security.h
index f5c4a51eb42e..438958c4eef0 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -49,20 +49,20 @@ extern int cap_settime(struct timespec *ts, struct timezone *tz);
extern int cap_ptrace_may_access(struct task_struct *child, unsigned int mode);
extern int cap_ptrace_traceme(struct task_struct *parent);
extern int cap_capget(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted);
-extern int cap_capset_check(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted);
-extern void cap_capset_set(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted);
-extern int cap_bprm_set_security(struct linux_binprm *bprm);
-extern void cap_bprm_apply_creds(struct linux_binprm *bprm, int unsafe);
+extern int cap_capset(struct cred *new, const struct cred *old,
+ const kernel_cap_t *effective,
+ const kernel_cap_t *inheritable,
+ const kernel_cap_t *permitted);
+extern int cap_bprm_set_creds(struct linux_binprm *bprm);
extern int cap_bprm_secureexec(struct linux_binprm *bprm);
extern int cap_inode_setxattr(struct dentry *dentry, const char *name,
const void *value, size_t size, int flags);
extern int cap_inode_removexattr(struct dentry *dentry, const char *name);
extern int cap_inode_need_killpriv(struct dentry *dentry);
extern int cap_inode_killpriv(struct dentry *dentry);
-extern int cap_task_post_setuid(uid_t old_ruid, uid_t old_euid, uid_t old_suid, int flags);
-extern void cap_task_reparent_to_init(struct task_struct *p);
+extern int cap_task_fix_setuid(struct cred *new, const struct cred *old, int flags);
extern int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
- unsigned long arg4, unsigned long arg5, long *rc_p);
+ unsigned long arg4, unsigned long arg5);
extern int cap_task_setscheduler(struct task_struct *p, int policy, struct sched_param *lp);
extern int cap_task_setioprio(struct task_struct *p, int ioprio);
extern int cap_task_setnice(struct task_struct *p, int nice);
@@ -105,7 +105,7 @@ extern unsigned long mmap_min_addr;
struct sched_param;
struct request_sock;
-/* bprm_apply_creds unsafe reasons */
+/* bprm->unsafe reasons */
#define LSM_UNSAFE_SHARE 1
#define LSM_UNSAFE_PTRACE 2
#define LSM_UNSAFE_PTRACE_CAP 4
@@ -149,36 +149,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
*
* Security hooks for program execution operations.
*
- * @bprm_alloc_security:
- * Allocate and attach a security structure to the @bprm->security field.
- * The security field is initialized to NULL when the bprm structure is
- * allocated.
- * @bprm contains the linux_binprm structure to be modified.
- * Return 0 if operation was successful.
- * @bprm_free_security:
- * @bprm contains the linux_binprm structure to be modified.
- * Deallocate and clear the @bprm->security field.
- * @bprm_apply_creds:
- * 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.
- * bprm_apply_creds is called under task_lock. @unsafe indicates various
- * reasons why it may be unsafe to change security state.
- * @bprm contains the linux_binprm structure.
- * @bprm_post_apply_creds:
- * Runs after bprm_apply_creds with the task_lock dropped, so that
- * functions which cannot be called safely under the task_lock can
- * be used. This hook is a good place to perform state changes on
- * the process such as closing open file descriptors to which access
- * is no longer granted if the attributes were changed.
- * Note that a security module might need to save state between
- * bprm_apply_creds and bprm_post_apply_creds to store the decision
- * on whether the process may proceed.
- * @bprm contains the linux_binprm structure.
- * @bprm_set_security:
+ * @bprm_set_creds:
* Save security information in the bprm->security field, typically based
* on information about the bprm->file, for later use by the apply_creds
* hook. This hook may also optionally check permissions (e.g. for
@@ -191,15 +162,30 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
* @bprm contains the linux_binprm structure.
* Return 0 if the hook is successful and permission is granted.
* @bprm_check_security:
- * This hook mediates the point when a search for a binary handler will
- * begin. It allows a check the @bprm->security value which is set in
- * the preceding set_security call. The primary difference from
- * set_security is that the argv list and envp list are reliably
- * available in @bprm. This hook may be called multiple times
- * during a single execve; and in each pass set_security is called
- * first.
+ * This hook mediates the point when a search for a binary handler will
+ * begin. It allows a check the @bprm->security value which is set in the
+ * preceding set_creds call. The primary difference from set_creds is
+ * that the argv list and envp list are reliably available in @bprm. This
+ * hook may be called multiple times during a single execve; and in each
+ * pass set_creds is called first.
* @bprm contains the linux_binprm structure.
* Return 0 if the hook is successful and permission is granted.
+ * @bprm_committing_creds:
+ * Prepare to install the new security attributes of a process being
+ * transformed by an execve operation, based on the old credentials
+ * pointed to by @current->cred and the information set in @bprm->cred by
+ * the bprm_set_creds hook. @bprm points to the linux_binprm structure.
+ * This hook is a good place to perform state changes on the process such
+ * as closing open file descriptors to which access will no longer be
+ * granted when the attributes are changed. This is called immediately
+ * before commit_creds().
+ * @bprm_committed_creds:
+ * Tidy up after the installation of the new security attributes of a
+ * process being transformed by an execve operation. The new credentials
+ * have, by this point, been set to @current->cred. @bprm points to the
+ * linux_binprm structure. This hook is a good place to perform state
+ * changes on the process such as clearing out non-inheritable signal
+ * state. This is called immediately after commit_creds().
* @bprm_secureexec:
* Return a boolean value (0 or 1) indicating whether a "secure exec"
* is required. The flag is passed in the auxiliary table
@@ -585,15 +571,31 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
* manual page for definitions of the @clone_flags.
* @clone_flags contains the flags indicating what should be shared.
* Return 0 if permission is granted.
- * @task_alloc_security:
- * @p contains the task_struct for child process.
- * 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.
- * @task_free_security:
- * @p contains the task_struct for process.
- * Deallocate and clear the p->security field.
+ * @cred_free:
+ * @cred points to the credentials.
+ * Deallocate and clear the cred->security field in a set of credentials.
+ * @cred_prepare:
+ * @new points to the new credentials.
+ * @old points to the original credentials.
+ * @gfp indicates the atomicity of any memory allocations.
+ * Prepare a new set of credentials by copying the data from the old set.
+ * @cred_commit:
+ * @new points to the new credentials.
+ * @old points to the original credentials.
+ * Install a new set of credentials.
+ * @kernel_act_as:
+ * Set the credentials for a kernel service to act as (subjective context).
+ * @new points to the credentials to be modified.
+ * @secid specifies the security ID to be set
+ * The current task must be the one that nominated @secid.
+ * Return 0 if successful.
+ * @kernel_create_files_as:
+ * Set the file creation context in a set of credentials to be the same as
+ * the objective context of the specified inode.
+ * @new points to the credentials to be modified.
+ * @inode points to the inode to use as a reference.
+ * The current task must be the one that nominated @inode.
+ * Return 0 if successful.
* @task_setuid:
* Check permission before setting one or more of the user identity
* attributes of the current process. The @flags parameter indicates
@@ -606,15 +608,13 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
* @id2 contains a uid.
* @flags contains one of the LSM_SETID_* values.
* Return 0 if permission is granted.
- * @task_post_setuid:
+ * @task_fix_setuid:
* 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.
- * @old_ruid contains the old real uid (or fs uid if LSM_SETID_FS).
- * @old_euid contains the old effective uid (or -1 if LSM_SETID_FS).
- * @old_suid contains the old saved uid (or -1 if LSM_SETID_FS).
+ * @new is the set of credentials that will be installed. Modifications
+ * should be made to this rather than to @current->cred.
+ * @old is the set of credentials that are being replaces
* @flags contains one of the LSM_SETID_* values.
* Return 0 on success.
* @task_setgid:
@@ -717,13 +717,8 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
* @arg3 contains a argument.
* @arg4 contains a argument.
* @arg5 contains a argument.
- * @rc_p contains a pointer to communicate back the forced return code
- * Return 0 if permission is granted, and non-zero if the security module
- * has taken responsibility (setting *rc_p) for the prctl call.
- * @task_reparent_to_init:
- * Set the security attributes in @p->security for a kernel thread that
- * is being reparented to the init task.
- * @p contains the task_struct for the kernel thread.
+ * Return -ENOSYS if no-one wanted to handle this op, any other value to
+ * cause prctl() to return immediately with that value.
* @task_to_inode:
* Set the security attributes for an inode based on an associated task's
* security attributes, e.g. for /proc/pid inodes.
@@ -1000,7 +995,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
* 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
+ * @cred points to the credentials 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
@@ -1162,6 +1157,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
* @child process.
* Security modules may also want to perform a process tracing check
* during an execve in the set_security or apply_creds hooks of
+ * tracing check during an execve in the bprm_set_creds hook of
* binprm_security_ops if the process is being traced and its security
* attributes would be changed by the execve.
* @child contains the task_struct structure for the target process.
@@ -1185,29 +1181,15 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
* @inheritable contains the inheritable capability set.
* @permitted contains the permitted capability set.
* Return 0 if the capability sets were successfully obtained.
- * @capset_check:
- * Check permission before setting the @effective, @inheritable, and
- * @permitted capability sets for the @target process.
- * 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.
- * @target contains the task_struct structure for target process.
- * @effective contains the effective capability set.
- * @inheritable contains the inheritable capability set.
- * @permitted contains the permitted capability set.
- * Return 0 if permission is granted.
- * @capset_set:
+ * @capset:
* 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.
- * @target contains the task_struct structure for target process.
+ * the current process.
+ * @new contains the new credentials structure for target process.
+ * @old contains the current credentials structure for target process.
* @effective contains the effective capability set.
* @inheritable contains the inheritable capability set.
* @permitted contains the permitted capability set.
+ * Return 0 and update @new if permission is granted.
* @capable:
* Check whether the @tsk process has the @cap capability.
* @tsk contains the task_struct for the process.
@@ -1299,14 +1281,11 @@ struct security_operations {
int (*capget) (struct task_struct *target,
kernel_cap_t *effective,
kernel_cap_t *inheritable, kernel_cap_t *permitted);
- int (*capset_check) (struct task_struct *target,
- kernel_cap_t *effective,
- kernel_cap_t *inheritable,
- kernel_cap_t *permitted);
- void (*capset_set) (struct task_struct *target,
- kernel_cap_t *effective,
- kernel_cap_t *inheritable,
- kernel_cap_t *permitted);
+ int (*capset) (struct cred *new,
+ const struct cred *old,
+ const kernel_cap_t *effective,
+ const kernel_cap_t *inheritable,
+ const kernel_cap_t *permitted);
int (*capable) (struct task_struct *tsk, int cap);
int (*acct) (struct file *file);
int (*sysctl) (struct ctl_table *table, int op);
@@ -1316,13 +1295,11 @@ struct security_operations {
int (*settime) (struct timespec *ts, struct timezone *tz);
int (*vm_enough_memory) (struct mm_struct *mm, long pages);
- int (*bprm_alloc_security) (struct linux_binprm *bprm);
- void (*bprm_free_security) (struct linux_binprm *bprm);
- void (*bprm_apply_creds) (struct linux_binprm *bprm, int unsafe);
- void (*bprm_post_apply_creds) (struct linux_binprm *bprm);
- int (*bprm_set_security) (struct linux_binprm *bprm);
+ int (*bprm_set_creds) (struct linux_binprm *bprm);
int (*bprm_check_security) (struct linux_binprm *bprm);
int (*bprm_secureexec) (struct linux_binprm *bprm);
+ void (*bprm_committing_creds) (struct linux_binprm *bprm);
+ void (*bprm_committed_creds) (struct linux_binprm *bprm);
int (*sb_alloc_security) (struct super_block *sb);
void (*sb_free_security) (struct super_block *sb);
@@ -1406,14 +1383,18 @@ struct security_operations {
int (*file_send_sigiotask) (struct task_struct *tsk,
struct fown_struct *fown, int sig);
int (*file_receive) (struct file *file);
- int (*dentry_open) (struct file *file);
+ int (*dentry_open) (struct file *file, const struct cred *cred);
int (*task_create) (unsigned long clone_flags);
- int (*task_alloc_security) (struct task_struct *p);
- void (*task_free_security) (struct task_struct *p);
+ void (*cred_free) (struct cred *cred);
+ int (*cred_prepare)(struct cred *new, const struct cred *old,
+ gfp_t gfp);
+ void (*cred_commit)(struct cred *new, const struct cred *old);
+ int (*kernel_act_as)(struct cred *new, u32 secid);
+ int (*kernel_create_files_as)(struct cred *new, struct inode *inode);
int (*task_setuid) (uid_t id0, uid_t id1, uid_t id2, int flags);
- int (*task_post_setuid) (uid_t old_ruid /* or fsuid */ ,
- uid_t old_euid, uid_t old_suid, int flags);
+ int (*task_fix_setuid) (struct cred *new, const struct cred *old,
+ int flags);
int (*task_setgid) (gid_t id0, gid_t id1, gid_t id2, int flags);
int (*task_setpgid) (struct task_struct *p, pid_t pgid);
int (*task_getpgid) (struct task_struct *p);
@@ -1433,8 +1414,7 @@ struct security_operations {
int (*task_wait) (struct task_struct *p);
int (*task_prctl) (int option, unsigned long arg2,
unsigned long arg3, unsigned long arg4,
- unsigned long arg5, long *rc_p);
- void (*task_reparent_to_init) (struct task_struct *p);
+ unsigned long arg5);
void (*task_to_inode) (struct task_struct *p, struct inode *inode);
int (*ipc_permission) (struct kern_ipc_perm *ipcp, short flag);
@@ -1539,10 +1519,10 @@ struct security_operations {
/* key management security hooks */
#ifdef CONFIG_KEYS
- int (*key_alloc) (struct key *key, struct task_struct *tsk, unsigned long flags);
+ int (*key_alloc) (struct key *key, const struct cred *cred, unsigned long flags);
void (*key_free) (struct key *key);
int (*key_permission) (key_ref_t key_ref,
- struct task_struct *context,
+ const struct cred *cred,
key_perm_t perm);
int (*key_getsecurity)(struct key *key, char **_buffer);
#endif /* CONFIG_KEYS */
@@ -1568,14 +1548,10 @@ int security_capget(struct task_struct *target,
kernel_cap_t *effective,
kernel_cap_t *inheritable,
kernel_cap_t *permitted);
-int security_capset_check(struct task_struct *target,
- kernel_cap_t *effective,
- kernel_cap_t *inheritable,
- kernel_cap_t *permitted);
-void security_capset_set(struct task_struct *target,
- kernel_cap_t *effective,
- kernel_cap_t *inheritable,
- kernel_cap_t *permitted);
+int security_capset(struct cred *new, const struct cred *old,
+ const kernel_cap_t *effective,
+ const kernel_cap_t *inheritable,
+ const kernel_cap_t *permitted);
int security_capable(struct task_struct *tsk, int cap);
int security_acct(struct file *file);
int security_sysctl(struct ctl_table *table, int op);
@@ -1585,12 +1561,10 @@ int security_syslog(int type);
int security_settime(struct timespec *ts, struct timezone *tz);
int security_vm_enough_memory(long pages);
int security_vm_enough_memory_mm(struct mm_struct *mm, long pages);
-int security_bprm_alloc(struct linux_binprm *bprm);
-void security_bprm_free(struct linux_binprm *bprm);
-void security_bprm_apply_creds(struct linux_binprm *bprm, int unsafe);
-void security_bprm_post_apply_creds(struct linux_binprm *bprm);
-int security_bprm_set(struct linux_binprm *bprm);
+int security_bprm_set_creds(struct linux_binprm *bprm);
int security_bprm_check(struct linux_binprm *bprm);
+void security_bprm_committing_creds(struct linux_binprm *bprm);
+void security_bprm_committed_creds(struct linux_binprm *bprm);
int security_bprm_secureexec(struct linux_binprm *bprm);
int security_sb_alloc(struct super_block *sb);
void security_sb_free(struct super_block *sb);
@@ -1662,13 +1636,16 @@ int security_file_set_fowner(struct file *file);
int security_file_send_sigiotask(struct task_struct *tsk,
struct fown_struct *fown, int sig);
int security_file_receive(struct file *file);
-int security_dentry_open(struct file *file);
+int security_dentry_open(struct file *file, const struct cred *cred);
int security_task_create(unsigned long clone_flags);
-int security_task_alloc(struct task_struct *p);
-void security_task_free(struct task_struct *p);
+void security_cred_free(struct cred *cred);
+int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp);
+void security_commit_creds(struct cred *new, const struct cred *old);
+int security_kernel_act_as(struct cred *new, u32 secid);
+int security_kernel_create_files_as(struct cred *new, struct inode *inode);
int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags);
-int security_task_post_setuid(uid_t old_ruid, uid_t old_euid,
- uid_t old_suid, int flags);
+int security_task_fix_setuid(struct cred *new, const struct cred *old,
+ int flags);
int security_task_setgid(gid_t id0, gid_t id1, gid_t id2, int flags);
int security_task_setpgid(struct task_struct *p, pid_t pgid);
int security_task_getpgid(struct task_struct *p);
@@ -1687,8 +1664,7 @@ int security_task_kill(struct task_struct *p, struct siginfo *info,
int sig, u32 secid);
int security_task_wait(struct task_struct *p);
int security_task_prctl(int option, unsigned long arg2, unsigned long arg3,
- unsigned long arg4, unsigned long arg5, long *rc_p);
-void security_task_reparent_to_init(struct task_struct *p);
+ unsigned long arg4, unsigned long arg5);
void security_task_to_inode(struct task_struct *p, struct inode *inode);
int security_ipc_permission(struct kern_ipc_perm *ipcp, short flag);
void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid);
@@ -1763,20 +1739,13 @@ static inline int security_capget(struct task_struct *target,
return cap_capget(target, effective, inheritable, permitted);
}
-static inline int security_capset_check(struct task_struct *target,
- kernel_cap_t *effective,
- kernel_cap_t *inheritable,
- kernel_cap_t *permitted)
-{
- return cap_capset_check(target, effective, inheritable, permitted);
-}
-
-static inline void security_capset_set(struct task_struct *target,
- kernel_cap_t *effective,
- kernel_cap_t *inheritable,
- kernel_cap_t *permitted)
+static inline int security_capset(struct cred *new,
+ const struct cred *old,
+ const kernel_cap_t *effective,
+ const kernel_cap_t *inheritable,
+ const kernel_cap_t *permitted)
{
- cap_capset_set(target, effective, inheritable, permitted);
+ return cap_capset(new, old, effective, inheritable, permitted);
}
static inline int security_capable(struct task_struct *tsk, int cap)
@@ -1825,32 +1794,22 @@ static inline int security_vm_enough_memory_mm(struct mm_struct *mm, long pages)
return cap_vm_enough_memory(mm, pages);
}
-static inline int security_bprm_alloc(struct linux_binprm *bprm)
-{
- return 0;
-}
-
-static inline void security_bprm_free(struct linux_binprm *bprm)
-{ }
-
-static inline void security_bprm_apply_creds(struct linux_binprm *bprm, int unsafe)
+static inline int security_bprm_set_creds(struct linux_binprm *bprm)
{
- cap_bprm_apply_creds(bprm, unsafe);
+ return cap_bprm_set_creds(bprm);
}
-static inline void security_bprm_post_apply_creds(struct linux_binprm *bprm)
+static inline int security_bprm_check(struct linux_binprm *bprm)
{
- return;
+ return 0;
}
-static inline int security_bprm_set(struct linux_binprm *bprm)
+static inline void security_bprm_committing_creds(struct linux_binprm *bprm)
{
- return cap_bprm_set_security(bprm);
}
-static inline int security_bprm_check(struct linux_binprm *bprm)
+static inline void security_bprm_committed_creds(struct linux_binprm *bprm)
{
- return 0;
}
static inline int security_bprm_secureexec(struct linux_binprm *bprm)
@@ -2167,7 +2126,8 @@ static inline int security_file_receive(struct file *file)
return 0;
}
-static inline int security_dentry_open(struct file *file)
+static inline int security_dentry_open(struct file *file,
+ const struct cred *cred)
{
return 0;
}
@@ -2177,13 +2137,31 @@ static inline int security_task_create(unsigned long clone_flags)
return 0;
}
-static inline int security_task_alloc(struct task_struct *p)
+static inline void security_cred_free(struct cred *cred)
+{ }
+
+static inline int security_prepare_creds(struct cred *new,
+ const struct cred *old,
+ gfp_t gfp)
{
return 0;
}
-static inline void security_task_free(struct task_struct *p)
-{ }
+static inline void security_commit_creds(struct cred *new,
+ const struct cred *old)
+{
+}
+
+static inline int security_kernel_act_as(struct cred *cred, u32 secid)
+{
+ return 0;
+}
+
+static inline int security_kernel_create_files_as(struct cred *cred,
+ struct inode *inode)
+{
+ return 0;
+}
static inline int security_task_setuid(uid_t id0, uid_t id1, uid_t id2,
int flags)
@@ -2191,10 +2169,11 @@ static inline int security_task_setuid(uid_t id0, uid_t id1, uid_t id2,
return 0;
}
-static inline int security_task_post_setuid(uid_t old_ruid, uid_t old_euid,
- uid_t old_suid, int flags)
+static inline int security_task_fix_setuid(struct cred *new,
+ const struct cred *old,
+ int flags)
{
- return cap_task_post_setuid(old_ruid, old_euid, old_suid, flags);
+ return cap_task_fix_setuid(new, old, flags);
}
static inline int security_task_setgid(gid_t id0, gid_t id1, gid_t id2,
@@ -2281,14 +2260,9 @@ static inline int security_task_wait(struct task_struct *p)
static inline int security_task_prctl(int option, unsigned long arg2,
unsigned long arg3,
unsigned long arg4,
- unsigned long arg5, long *rc_p)
-{
- return cap_task_prctl(option, arg2, arg3, arg3, arg5, rc_p);
-}
-
-static inline void security_task_reparent_to_init(struct task_struct *p)
+ unsigned long arg5)
{
- cap_task_reparent_to_init(p);
+ return cap_task_prctl(option, arg2, arg3, arg3, arg5);
}
static inline void security_task_to_inode(struct task_struct *p, struct inode *inode)
@@ -2714,16 +2688,16 @@ static inline void security_skb_classify_flow(struct sk_buff *skb, struct flowi
#ifdef CONFIG_KEYS
#ifdef CONFIG_SECURITY
-int security_key_alloc(struct key *key, struct task_struct *tsk, unsigned long flags);
+int security_key_alloc(struct key *key, const struct cred *cred, unsigned long flags);
void security_key_free(struct key *key);
int security_key_permission(key_ref_t key_ref,
- struct task_struct *context, key_perm_t perm);
+ const struct cred *cred, key_perm_t perm);
int security_key_getsecurity(struct key *key, char **_buffer);
#else
static inline int security_key_alloc(struct key *key,
- struct task_struct *tsk,
+ const struct cred *cred,
unsigned long flags)
{
return 0;
@@ -2734,7 +2708,7 @@ static inline void security_key_free(struct key *key)
}
static inline int security_key_permission(key_ref_t key_ref,
- struct task_struct *context,
+ const struct cred *cred,
key_perm_t perm)
{
return 0;
diff --git a/include/net/scm.h b/include/net/scm.h
index 06df126103ca..f160116db54a 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -54,8 +54,8 @@ static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
struct scm_cookie *scm)
{
struct task_struct *p = current;
- scm->creds.uid = p->uid;
- scm->creds.gid = p->gid;
+ scm->creds.uid = current_uid();
+ scm->creds.gid = current_gid();
scm->creds.pid = task_tgid_vnr(p);
scm->fp = NULL;
scm->seq = 0;