aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2008-11-13 18:39:23 -0500
committerJames Morris <jmorris@namei.org>2008-11-13 18:39:23 -0500
commitd84f4f992cbd76e8f39c488cf0c5d123843923b1 (patch)
treefc4a0349c42995715b93d0f7a3c78e9ea9b3f36e
parent745ca2475a6ac596e3d8d37c2759c0fbe2586227 (diff)
CRED: Inaugurate COW credentials
Inaugurate copy-on-write credentials management. This uses RCU to manage the credentials pointer in the task_struct with respect to accesses by other tasks. A process may only modify its own credentials, and so does not need locking to access or modify its own credentials. A mutex (cred_replace_mutex) is added to the task_struct to control the effect of PTRACE_ATTACHED on credential calculations, particularly with respect to execve(). With this patch, the contents of an active credentials struct may not be changed directly; rather a new set of credentials must be prepared, modified and committed using something like the following sequence of events: struct cred *new = prepare_creds(); int ret = blah(new); if (ret < 0) { abort_creds(new); return ret; } return commit_creds(new); There are some exceptions to this rule: the keyrings pointed to by the active credentials may be instantiated - keyrings violate the COW rule as managing COW keyrings is tricky, given that it is possible for a task to directly alter the keys in a keyring in use by another task. To help enforce this, various pointers to sets of credentials, such as those in the task_struct, are declared const. The purpose of this is compile-time discouragement of altering credentials through those pointers. Once a set of credentials has been made public through one of these pointers, it may not be modified, except under special circumstances: (1) Its reference count may incremented and decremented. (2) The keyrings to which it points may be modified, but not replaced. The only safe way to modify anything else is to create a replacement and commit using the functions described in Documentation/credentials.txt (which will be added by a later patch). This patch and the preceding patches have been tested with the LTP SELinux testsuite. This patch makes several logical sets of alteration: (1) execve(). This now prepares and commits credentials in various places in the security code rather than altering the current creds directly. (2) Temporary credential overrides. do_coredump() and sys_faccessat() now prepare their own credentials and temporarily override the ones currently on the acting thread, whilst preventing interference from other threads by holding cred_replace_mutex on the thread being dumped. This will be replaced in a future patch by something that hands down the credentials directly to the functions being called, rather than altering the task's objective credentials. (3) LSM interface. A number of functions have been changed, added or removed: (*) security_capset_check(), ->capset_check() (*) security_capset_set(), ->capset_set() Removed in favour of security_capset(). (*) security_capset(), ->capset() New. This is passed a pointer to the new creds, a pointer to the old creds and the proposed capability sets. It should fill in the new creds or return an error. All pointers, barring the pointer to the new creds, are now const. (*) security_bprm_apply_creds(), ->bprm_apply_creds() Changed; now returns a value, which will cause the process to be killed if it's an error. (*) security_task_alloc(), ->task_alloc_security() Removed in favour of security_prepare_creds(). (*) security_cred_free(), ->cred_free() New. Free security data attached to cred->security. (*) security_prepare_creds(), ->cred_prepare() New. Duplicate any security data attached to cred->security. (*) security_commit_creds(), ->cred_commit() New. Apply any security effects for the upcoming installation of new security by commit_creds(). (*) security_task_post_setuid(), ->task_post_setuid() Removed in favour of security_task_fix_setuid(). (*) security_task_fix_setuid(), ->task_fix_setuid() Fix up the proposed new credentials for setuid(). This is used by cap_set_fix_setuid() to implicitly adjust capabilities in line with setuid() changes. Changes are made to the new credentials, rather than the task itself as in security_task_post_setuid(). (*) security_task_reparent_to_init(), ->task_reparent_to_init() Removed. Instead the task being reparented to init is referred directly to init's credentials. NOTE! This results in the loss of some state: SELinux's osid no longer records the sid of the thread that forked it. (*) security_key_alloc(), ->key_alloc() (*) security_key_permission(), ->key_permission() Changed. These now take cred pointers rather than task pointers to refer to the security context. (4) sys_capset(). This has been simplified and uses less locking. The LSM functions it calls have been merged. (5) reparent_to_kthreadd(). This gives the current thread the same credentials as init by simply using commit_thread() to point that way. (6) __sigqueue_alloc() and switch_uid() __sigqueue_alloc() can't stop the target task from changing its creds beneath it, so this function gets a reference to the currently applicable user_struct which it then passes into the sigqueue struct it returns if successful. switch_uid() is now called from commit_creds(), and possibly should be folded into that. commit_creds() should take care of protecting __sigqueue_alloc(). (7) [sg]et[ug]id() and co and [sg]et_current_groups. The set functions now all use prepare_creds(), commit_creds() and abort_creds() to build and check a new set of credentials before applying it. security_task_set[ug]id() is called inside the prepared section. This guarantees that nothing else will affect the creds until we've finished. The calling of set_dumpable() has been moved into commit_creds(). Much of the functionality of set_user() has been moved into commit_creds(). The get functions all simply access the data directly. (8) security_task_prctl() and cap_task_prctl(). security_task_prctl() has been modified to return -ENOSYS if it doesn't want to handle a function, or otherwise return the return value directly rather than through an argument. Additionally, cap_task_prctl() now prepares a new set of credentials, even if it doesn't end up using it. (9) Keyrings. A number of changes have been made to the keyrings code: (a) switch_uid_keyring(), copy_keys(), exit_keys() and suid_keys() have all been dropped and built in to the credentials functions directly. They may want separating out again later. (b) key_alloc() and search_process_keyrings() now take a cred pointer rather than a task pointer to specify the security context. (c) copy_creds() gives a new thread within the same thread group a new thread keyring if its parent had one, otherwise it discards the thread keyring. (d) The authorisation key now points directly to the credentials to extend the search into rather pointing to the task that carries them. (e) Installing thread, process or session keyrings causes a new set of credentials to be created, even though it's not strictly necessary for process or session keyrings (they're shared). (10) Usermode helper. The usermode helper code now carries a cred struct pointer in its subprocess_info struct instead of a new session keyring pointer. This set of credentials is derived from init_cred and installed on the new process after it has been cloned. call_usermodehelper_setup() allocates the new credentials and call_usermodehelper_freeinfo() discards them if they haven't been used. A special cred function (prepare_usermodeinfo_creds()) is provided specifically for call_usermodehelper_setup() to call. call_usermodehelper_setkeys() adjusts the credentials to sport the supplied keyring as the new session keyring. (11) SELinux. SELinux has a number of changes, in addition to those to support the LSM interface changes mentioned above: (a) selinux_setprocattr() no longer does its check for whether the current ptracer can access processes with the new SID inside the lock that covers getting the ptracer's SID. Whilst this lock ensures that the check is done with the ptracer pinned, the result is only valid until the lock is released, so there's no point doing it inside the lock. (12) is_single_threaded(). This function has been extracted from selinux_setprocattr() and put into a file of its own in the lib/ directory as join_session_keyring() now wants to use it too. The code in SELinux just checked to see whether a task shared mm_structs with other tasks (CLONE_VM), but that isn't good enough. We really want to know if they're part of the same thread group (CLONE_THREAD). (13) nfsd. The NFS server daemon now has to use the COW credentials to set the credentials it is going to use. It really needs to pass the credentials down to the functions it calls, but it can't do that until other patches in this series have been applied. Signed-off-by: David Howells <dhowells@redhat.com> Acked-by: James Morris <jmorris@namei.org> Signed-off-by: James Morris <jmorris@namei.org>
-rw-r--r--fs/exec.c31
-rw-r--r--fs/nfsd/auth.c92
-rw-r--r--fs/nfsd/nfs4recover.c68
-rw-r--r--fs/nfsd/nfsfh.c11
-rw-r--r--fs/open.c31
-rw-r--r--include/linux/audit.h22
-rw-r--r--include/linux/capability.h2
-rw-r--r--include/linux/cred.h44
-rw-r--r--include/linux/init_task.h2
-rw-r--r--include/linux/key.h22
-rw-r--r--include/linux/sched.h6
-rw-r--r--include/linux/security.h178
-rw-r--r--init/main.c1
-rw-r--r--kernel/auditsc.c42
-rw-r--r--kernel/capability.c78
-rw-r--r--kernel/cred-internals.h21
-rw-r--r--kernel/cred.c321
-rw-r--r--kernel/exit.c9
-rw-r--r--kernel/fork.c7
-rw-r--r--kernel/kmod.c30
-rw-r--r--kernel/ptrace.c9
-rw-r--r--kernel/signal.c10
-rw-r--r--kernel/sys.c450
-rw-r--r--kernel/user.c37
-rw-r--r--kernel/user_namespace.c12
-rw-r--r--lib/Makefile2
-rw-r--r--net/rxrpc/ar-key.c6
-rw-r--r--security/capability.c21
-rw-r--r--security/commoncap.c265
-rw-r--r--security/keys/internal.h17
-rw-r--r--security/keys/key.c25
-rw-r--r--security/keys/keyctl.c95
-rw-r--r--security/keys/keyring.c14
-rw-r--r--security/keys/permission.c24
-rw-r--r--security/keys/proc.c8
-rw-r--r--security/keys/process_keys.c333
-rw-r--r--security/keys/request_key.c29
-rw-r--r--security/keys/request_key_auth.c41
-rw-r--r--security/security.c58
-rw-r--r--security/selinux/hooks.c286
-rw-r--r--security/smack/smack_lsm.c82
41 files changed, 1603 insertions, 1239 deletions
diff --git a/fs/exec.c b/fs/exec.c
index a5330e1a2216..9bd3559ddece 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1007,13 +1007,12 @@ int flush_old_exec(struct linux_binprm * bprm)
1007 */ 1007 */
1008 current->mm->task_size = TASK_SIZE; 1008 current->mm->task_size = TASK_SIZE;
1009 1009
1010 if (bprm->e_uid != current_euid() || bprm->e_gid != current_egid()) { 1010 if (bprm->e_uid != current_euid() ||
1011 suid_keys(current); 1011 bprm->e_gid != current_egid()) {
1012 set_dumpable(current->mm, suid_dumpable); 1012 set_dumpable(current->mm, suid_dumpable);
1013 current->pdeath_signal = 0; 1013 current->pdeath_signal = 0;
1014 } else if (file_permission(bprm->file, MAY_READ) || 1014 } else if (file_permission(bprm->file, MAY_READ) ||
1015 (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)) { 1015 (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)) {
1016 suid_keys(current);
1017 set_dumpable(current->mm, suid_dumpable); 1016 set_dumpable(current->mm, suid_dumpable);
1018 } 1017 }
1019 1018
@@ -1096,10 +1095,8 @@ void compute_creds(struct linux_binprm *bprm)
1096{ 1095{
1097 int unsafe; 1096 int unsafe;
1098 1097
1099 if (bprm->e_uid != current_uid()) { 1098 if (bprm->e_uid != current_uid())
1100 suid_keys(current);
1101 current->pdeath_signal = 0; 1099 current->pdeath_signal = 0;
1102 }
1103 exec_keys(current); 1100 exec_keys(current);
1104 1101
1105 task_lock(current); 1102 task_lock(current);
@@ -1709,8 +1706,9 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
1709 struct linux_binfmt * binfmt; 1706 struct linux_binfmt * binfmt;
1710 struct inode * inode; 1707 struct inode * inode;
1711 struct file * file; 1708 struct file * file;
1709 const struct cred *old_cred;
1710 struct cred *cred;
1712 int retval = 0; 1711 int retval = 0;
1713 int fsuid = current_fsuid();
1714 int flag = 0; 1712 int flag = 0;
1715 int ispipe = 0; 1713 int ispipe = 0;
1716 unsigned long core_limit = current->signal->rlim[RLIMIT_CORE].rlim_cur; 1714 unsigned long core_limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
@@ -1723,12 +1721,20 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
1723 binfmt = current->binfmt; 1721 binfmt = current->binfmt;
1724 if (!binfmt || !binfmt->core_dump) 1722 if (!binfmt || !binfmt->core_dump)
1725 goto fail; 1723 goto fail;
1724
1725 cred = prepare_creds();
1726 if (!cred) {
1727 retval = -ENOMEM;
1728 goto fail;
1729 }
1730
1726 down_write(&mm->mmap_sem); 1731 down_write(&mm->mmap_sem);
1727 /* 1732 /*
1728 * If another thread got here first, or we are not dumpable, bail out. 1733 * If another thread got here first, or we are not dumpable, bail out.
1729 */ 1734 */
1730 if (mm->core_state || !get_dumpable(mm)) { 1735 if (mm->core_state || !get_dumpable(mm)) {
1731 up_write(&mm->mmap_sem); 1736 up_write(&mm->mmap_sem);
1737 put_cred(cred);
1732 goto fail; 1738 goto fail;
1733 } 1739 }
1734 1740
@@ -1739,12 +1745,16 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
1739 */ 1745 */
1740 if (get_dumpable(mm) == 2) { /* Setuid core dump mode */ 1746 if (get_dumpable(mm) == 2) { /* Setuid core dump mode */
1741 flag = O_EXCL; /* Stop rewrite attacks */ 1747 flag = O_EXCL; /* Stop rewrite attacks */
1742 current->cred->fsuid = 0; /* Dump root private */ 1748 cred->fsuid = 0; /* Dump root private */
1743 } 1749 }
1744 1750
1745 retval = coredump_wait(exit_code, &core_state); 1751 retval = coredump_wait(exit_code, &core_state);
1746 if (retval < 0) 1752 if (retval < 0) {
1753 put_cred(cred);
1747 goto fail; 1754 goto fail;
1755 }
1756
1757 old_cred = override_creds(cred);
1748 1758
1749 /* 1759 /*
1750 * Clear any false indication of pending signals that might 1760 * Clear any false indication of pending signals that might
@@ -1835,7 +1845,8 @@ fail_unlock:
1835 if (helper_argv) 1845 if (helper_argv)
1836 argv_free(helper_argv); 1846 argv_free(helper_argv);
1837 1847
1838 current->cred->fsuid = fsuid; 1848 revert_creds(old_cred);
1849 put_cred(cred);
1839 coredump_finish(mm); 1850 coredump_finish(mm);
1840fail: 1851fail:
1841 return retval; 1852 return retval;
diff --git a/fs/nfsd/auth.c b/fs/nfsd/auth.c
index 808fc03a6fbd..836ffa1047d9 100644
--- a/fs/nfsd/auth.c
+++ b/fs/nfsd/auth.c
@@ -27,55 +27,67 @@ int nfsexp_flags(struct svc_rqst *rqstp, struct svc_export *exp)
27 27
28int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp) 28int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
29{ 29{
30 struct cred *act_as = current->cred ; 30 struct group_info *rqgi;
31 struct svc_cred cred = rqstp->rq_cred; 31 struct group_info *gi;
32 struct cred *new;
32 int i; 33 int i;
33 int flags = nfsexp_flags(rqstp, exp); 34 int flags = nfsexp_flags(rqstp, exp);
34 int ret; 35 int ret;
35 36
37 new = prepare_creds();
38 if (!new)
39 return -ENOMEM;
40
41 new->fsuid = rqstp->rq_cred.cr_uid;
42 new->fsgid = rqstp->rq_cred.cr_gid;
43
44 rqgi = rqstp->rq_cred.cr_group_info;
45
36 if (flags & NFSEXP_ALLSQUASH) { 46 if (flags & NFSEXP_ALLSQUASH) {
37 cred.cr_uid = exp->ex_anon_uid; 47 new->fsuid = exp->ex_anon_uid;
38 cred.cr_gid = exp->ex_anon_gid; 48 new->fsgid = exp->ex_anon_gid;
39 cred.cr_group_info = groups_alloc(0); 49 gi = groups_alloc(0);
40 } else if (flags & NFSEXP_ROOTSQUASH) { 50 } else if (flags & NFSEXP_ROOTSQUASH) {
41 struct group_info *gi; 51 if (!new->fsuid)
42 if (!cred.cr_uid) 52 new->fsuid = exp->ex_anon_uid;
43 cred.cr_uid = exp->ex_anon_uid; 53 if (!new->fsgid)
44 if (!cred.cr_gid) 54 new->fsgid = exp->ex_anon_gid;
45 cred.cr_gid = exp->ex_anon_gid;
46 gi = groups_alloc(cred.cr_group_info->ngroups);
47 if (gi)
48 for (i = 0; i < cred.cr_group_info->ngroups; i++) {
49 if (!GROUP_AT(cred.cr_group_info, i))
50 GROUP_AT(gi, i) = exp->ex_anon_gid;
51 else
52 GROUP_AT(gi, i) = GROUP_AT(cred.cr_group_info, i);
53 }
54 cred.cr_group_info = gi;
55 } else
56 get_group_info(cred.cr_group_info);
57
58 if (cred.cr_uid != (uid_t) -1)
59 act_as->fsuid = cred.cr_uid;
60 else
61 act_as->fsuid = exp->ex_anon_uid;
62 if (cred.cr_gid != (gid_t) -1)
63 act_as->fsgid = cred.cr_gid;
64 else
65 act_as->fsgid = exp->ex_anon_gid;
66 55
67 if (!cred.cr_group_info) 56 gi = groups_alloc(rqgi->ngroups);
68 return -ENOMEM; 57 if (!gi)
69 ret = set_groups(act_as, cred.cr_group_info); 58 goto oom;
70 put_group_info(cred.cr_group_info); 59
71 if ((cred.cr_uid)) { 60 for (i = 0; i < rqgi->ngroups; i++) {
72 act_as->cap_effective = 61 if (!GROUP_AT(rqgi, i))
73 cap_drop_nfsd_set(act_as->cap_effective); 62 GROUP_AT(gi, i) = exp->ex_anon_gid;
63 else
64 GROUP_AT(gi, i) = GROUP_AT(rqgi, i);
65 }
74 } else { 66 } else {
75 act_as->cap_effective = 67 gi = get_group_info(rqgi);
76 cap_raise_nfsd_set(act_as->cap_effective,
77 act_as->cap_permitted);
78 } 68 }
69
70 if (new->fsuid == (uid_t) -1)
71 new->fsuid = exp->ex_anon_uid;
72 if (new->fsgid == (gid_t) -1)
73 new->fsgid = exp->ex_anon_gid;
74
75 ret = set_groups(new, gi);
76 put_group_info(gi);
77 if (!ret)
78 goto error;
79
80 if (new->uid)
81 new->cap_effective = cap_drop_nfsd_set(new->cap_effective);
82 else
83 new->cap_effective = cap_raise_nfsd_set(new->cap_effective,
84 new->cap_permitted);
85 return commit_creds(new);
86
87oom:
88 ret = -ENOMEM;
89error:
90 abort_creds(new);
79 return ret; 91 return ret;
80} 92}
81 93
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 632a50b4b371..9371ea12d7fa 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -54,20 +54,26 @@
54static struct path rec_dir; 54static struct path rec_dir;
55static int rec_dir_init = 0; 55static int rec_dir_init = 0;
56 56
57static void 57static int
58nfs4_save_user(uid_t *saveuid, gid_t *savegid) 58nfs4_save_creds(const struct cred **original_creds)
59{ 59{
60 *saveuid = current->cred->fsuid; 60 struct cred *new;
61 *savegid = current->cred->fsgid; 61
62 current->cred->fsuid = 0; 62 new = prepare_creds();
63 current->cred->fsgid = 0; 63 if (!new)
64 return -ENOMEM;
65
66 new->fsuid = 0;
67 new->fsgid = 0;
68 *original_creds = override_creds(new);
69 put_cred(new);
70 return 0;
64} 71}
65 72
66static void 73static void
67nfs4_reset_user(uid_t saveuid, gid_t savegid) 74nfs4_reset_creds(const struct cred *original)
68{ 75{
69 current->cred->fsuid = saveuid; 76 revert_creds(original);
70 current->cred->fsgid = savegid;
71} 77}
72 78
73static void 79static void
@@ -129,10 +135,9 @@ nfsd4_sync_rec_dir(void)
129int 135int
130nfsd4_create_clid_dir(struct nfs4_client *clp) 136nfsd4_create_clid_dir(struct nfs4_client *clp)
131{ 137{
138 const struct cred *original_cred;
132 char *dname = clp->cl_recdir; 139 char *dname = clp->cl_recdir;
133 struct dentry *dentry; 140 struct dentry *dentry;
134 uid_t uid;
135 gid_t gid;
136 int status; 141 int status;
137 142
138 dprintk("NFSD: nfsd4_create_clid_dir for \"%s\"\n", dname); 143 dprintk("NFSD: nfsd4_create_clid_dir for \"%s\"\n", dname);
@@ -140,7 +145,9 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
140 if (!rec_dir_init || clp->cl_firststate) 145 if (!rec_dir_init || clp->cl_firststate)
141 return 0; 146 return 0;
142 147
143 nfs4_save_user(&uid, &gid); 148 status = nfs4_save_creds(&original_cred);
149 if (status < 0)
150 return status;
144 151
145 /* lock the parent */ 152 /* lock the parent */
146 mutex_lock(&rec_dir.dentry->d_inode->i_mutex); 153 mutex_lock(&rec_dir.dentry->d_inode->i_mutex);
@@ -168,7 +175,7 @@ out_unlock:
168 clp->cl_firststate = 1; 175 clp->cl_firststate = 1;
169 nfsd4_sync_rec_dir(); 176 nfsd4_sync_rec_dir();
170 } 177 }
171 nfs4_reset_user(uid, gid); 178 nfs4_reset_creds(original_cred);
172 dprintk("NFSD: nfsd4_create_clid_dir returns %d\n", status); 179 dprintk("NFSD: nfsd4_create_clid_dir returns %d\n", status);
173 return status; 180 return status;
174} 181}
@@ -211,20 +218,21 @@ nfsd4_build_dentrylist(void *arg, const char *name, int namlen,
211static int 218static int
212nfsd4_list_rec_dir(struct dentry *dir, recdir_func *f) 219nfsd4_list_rec_dir(struct dentry *dir, recdir_func *f)
213{ 220{
221 const struct cred *original_cred;
214 struct file *filp; 222 struct file *filp;
215 struct dentry_list_arg dla = { 223 struct dentry_list_arg dla = {
216 .parent = dir, 224 .parent = dir,
217 }; 225 };
218 struct list_head *dentries = &dla.dentries; 226 struct list_head *dentries = &dla.dentries;
219 struct dentry_list *child; 227 struct dentry_list *child;
220 uid_t uid;
221 gid_t gid;
222 int status; 228 int status;
223 229
224 if (!rec_dir_init) 230 if (!rec_dir_init)
225 return 0; 231 return 0;
226 232
227 nfs4_save_user(&uid, &gid); 233 status = nfs4_save_creds(&original_cred);
234 if (status < 0)
235 return status;
228 236
229 filp = dentry_open(dget(dir), mntget(rec_dir.mnt), O_RDONLY, 237 filp = dentry_open(dget(dir), mntget(rec_dir.mnt), O_RDONLY,
230 current_cred()); 238 current_cred());
@@ -250,7 +258,7 @@ out:
250 dput(child->dentry); 258 dput(child->dentry);
251 kfree(child); 259 kfree(child);
252 } 260 }
253 nfs4_reset_user(uid, gid); 261 nfs4_reset_creds(original_cred);
254 return status; 262 return status;
255} 263}
256 264
@@ -312,8 +320,7 @@ out:
312void 320void
313nfsd4_remove_clid_dir(struct nfs4_client *clp) 321nfsd4_remove_clid_dir(struct nfs4_client *clp)
314{ 322{
315 uid_t uid; 323 const struct cred *original_cred;
316 gid_t gid;
317 int status; 324 int status;
318 325
319 if (!rec_dir_init || !clp->cl_firststate) 326 if (!rec_dir_init || !clp->cl_firststate)
@@ -323,9 +330,13 @@ nfsd4_remove_clid_dir(struct nfs4_client *clp)
323 if (status) 330 if (status)
324 goto out; 331 goto out;
325 clp->cl_firststate = 0; 332 clp->cl_firststate = 0;
326 nfs4_save_user(&uid, &gid); 333
334 status = nfs4_save_creds(&original_cred);
335 if (status < 0)
336 goto out;
337
327 status = nfsd4_unlink_clid_dir(clp->cl_recdir, HEXDIR_LEN-1); 338 status = nfsd4_unlink_clid_dir(clp->cl_recdir, HEXDIR_LEN-1);
328 nfs4_reset_user(uid, gid); 339 nfs4_reset_creds(original_cred);
329 if (status == 0) 340 if (status == 0)
330 nfsd4_sync_rec_dir(); 341 nfsd4_sync_rec_dir();
331 mnt_drop_write(rec_dir.mnt); 342 mnt_drop_write(rec_dir.mnt);
@@ -402,16 +413,21 @@ nfsd4_recdir_load(void) {
402void 413void
403nfsd4_init_recdir(char *rec_dirname) 414nfsd4_init_recdir(char *rec_dirname)
404{ 415{
405 uid_t uid = 0; 416 const struct cred *original_cred;
406 gid_t gid = 0; 417 int status;
407 int status;
408 418
409 printk("NFSD: Using %s as the NFSv4 state recovery directory\n", 419 printk("NFSD: Using %s as the NFSv4 state recovery directory\n",
410 rec_dirname); 420 rec_dirname);
411 421
412 BUG_ON(rec_dir_init); 422 BUG_ON(rec_dir_init);
413 423
414 nfs4_save_user(&uid, &gid); 424 status = nfs4_save_creds(&original_cred);
425 if (status < 0) {
426 printk("NFSD: Unable to change credentials to find recovery"
427 " directory: error %d\n",
428 status);
429 return;
430 }
415 431
416 status = kern_path(rec_dirname, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, 432 status = kern_path(rec_dirname, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
417 &rec_dir); 433 &rec_dir);
@@ -421,7 +437,7 @@ nfsd4_init_recdir(char *rec_dirname)
421 437
422 if (!status) 438 if (!status)
423 rec_dir_init = 1; 439 rec_dir_init = 1;
424 nfs4_reset_user(uid, gid); 440 nfs4_reset_creds(original_cred);
425} 441}
426 442
427void 443void
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index e67cfaea0865..f0da7d9c3a92 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -186,9 +186,14 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp)
186 * access control settings being in effect, we cannot 186 * access control settings being in effect, we cannot
187 * fix that case easily. 187 * fix that case easily.
188 */ 188 */
189 current->cred->cap_effective = 189 struct cred *new = prepare_creds();
190 cap_raise_nfsd_set(current->cred->cap_effective, 190 if (!new)
191 current->cred->cap_permitted); 191 return nfserrno(-ENOMEM);
192 new->cap_effective =
193 cap_raise_nfsd_set(new->cap_effective,
194 new->cap_permitted);
195 put_cred(override_creds(new));
196 put_cred(new);
192 } else { 197 } else {
193 error = nfsd_setuser_and_check_port(rqstp, exp); 198 error = nfsd_setuser_and_check_port(rqstp, exp);
194 if (error) 199 if (error)
diff --git a/fs/open.c b/fs/open.c
index f96eaab280a3..c0a426d5766c 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -425,30 +425,33 @@ out:
425 */ 425 */
426asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode) 426asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode)
427{ 427{
428 struct cred *cred = current->cred; 428 const struct cred *old_cred;
429 struct cred *override_cred;
429 struct path path; 430 struct path path;
430 struct inode *inode; 431 struct inode *inode;
431 int old_fsuid, old_fsgid;
432 kernel_cap_t uninitialized_var(old_cap); /* !SECURE_NO_SETUID_FIXUP */
433 int res; 432 int res;
434 433
435 if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ 434 if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
436 return -EINVAL; 435 return -EINVAL;
437 436
438 old_fsuid = cred->fsuid; 437 override_cred = prepare_creds();
439 old_fsgid = cred->fsgid; 438 if (!override_cred)
439 return -ENOMEM;
440 440
441 cred->fsuid = cred->uid; 441 override_cred->fsuid = override_cred->uid;
442 cred->fsgid = cred->gid; 442 override_cred->fsgid = override_cred->gid;
443 443
444 if (!issecure(SECURE_NO_SETUID_FIXUP)) { 444 if (!issecure(SECURE_NO_SETUID_FIXUP)) {
445 /* Clear the capabilities if we switch to a non-root user */ 445 /* Clear the capabilities if we switch to a non-root user */
446 if (current->cred->uid) 446 if (override_cred->uid)
447 old_cap = cap_set_effective(__cap_empty_set); 447 cap_clear(override_cred->cap_effective);
448 else 448 else
449 old_cap = cap_set_effective(cred->cap_permitted); 449 override_cred->cap_effective =
450 override_cred->cap_permitted;
450 } 451 }
451 452
453 old_cred = override_creds(override_cred);
454
452 res = user_path_at(dfd, filename, LOOKUP_FOLLOW, &path); 455 res = user_path_at(dfd, filename, LOOKUP_FOLLOW, &path);
453 if (res) 456 if (res)
454 goto out; 457 goto out;
@@ -485,12 +488,8 @@ asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode)
485out_path_release: 488out_path_release:
486 path_put(&path); 489 path_put(&path);
487out: 490out:
488 cred->fsuid = old_fsuid; 491 revert_creds(old_cred);
489 cred->fsgid = old_fsgid; 492 put_cred(override_cred);
490
491 if (!issecure(SECURE_NO_SETUID_FIXUP))
492 cap_set_effective(old_cap);
493
494 return res; 493 return res;
495} 494}
496 495
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 6fbebac7b1bf..0b2fcb698a63 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -454,8 +454,10 @@ extern int __audit_mq_timedsend(mqd_t mqdes, size_t msg_len, unsigned int msg_pr
454extern int __audit_mq_timedreceive(mqd_t mqdes, size_t msg_len, unsigned int __user *u_msg_prio, const struct timespec __user *u_abs_timeout); 454extern int __audit_mq_timedreceive(mqd_t mqdes, size_t msg_len, unsigned int __user *u_msg_prio, const struct timespec __user *u_abs_timeout);
455extern int __audit_mq_notify(mqd_t mqdes, const struct sigevent __user *u_notification); 455extern int __audit_mq_notify(mqd_t mqdes, const struct sigevent __user *u_notification);
456extern int __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat); 456extern int __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat);
457extern void __audit_log_bprm_fcaps(struct linux_binprm *bprm, kernel_cap_t *pP, kernel_cap_t *pE); 457extern int __audit_log_bprm_fcaps(struct linux_binprm *bprm,
458extern int __audit_log_capset(pid_t pid, kernel_cap_t *eff, kernel_cap_t *inh, kernel_cap_t *perm); 458 const struct cred *new,
459 const struct cred *old);
460extern int __audit_log_capset(pid_t pid, const struct cred *new, const struct cred *old);
459 461
460static inline int audit_ipc_obj(struct kern_ipc_perm *ipcp) 462static inline int audit_ipc_obj(struct kern_ipc_perm *ipcp)
461{ 463{
@@ -522,16 +524,20 @@ static inline int audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat)
522 * 524 *
523 * -Eric 525 * -Eric
524 */ 526 */
525static inline void audit_log_bprm_fcaps(struct linux_binprm *bprm, kernel_cap_t *pP, kernel_cap_t *pE) 527static inline int audit_log_bprm_fcaps(struct linux_binprm *bprm,
528 const struct cred *new,
529 const struct cred *old)
526{ 530{
527 if (unlikely(!audit_dummy_context())) 531 if (unlikely(!audit_dummy_context()))
528 __audit_log_bprm_fcaps(bprm, pP, pE); 532 return __audit_log_bprm_fcaps(bprm, new, old);
533 return 0;
529} 534}
530 535
531static inline int audit_log_capset(pid_t pid, kernel_cap_t *eff, kernel_cap_t *inh, kernel_cap_t *perm) 536static inline int audit_log_capset(pid_t pid, const struct cred *new,
537 const struct cred *old)
532{ 538{
533 if (unlikely(!audit_dummy_context())) 539 if (unlikely(!audit_dummy_context()))
534 return __audit_log_capset(pid, eff, inh, perm); 540 return __audit_log_capset(pid, new, old);
535 return 0; 541 return 0;
536} 542}
537 543
@@ -566,8 +572,8 @@ extern int audit_signals;
566#define audit_mq_timedreceive(d,l,p,t) ({ 0; }) 572#define audit_mq_timedreceive(d,l,p,t) ({ 0; })
567#define audit_mq_notify(d,n) ({ 0; }) 573#define audit_mq_notify(d,n) ({ 0; })
568#define audit_mq_getsetattr(d,s) ({ 0; }) 574#define audit_mq_getsetattr(d,s) ({ 0; })
569#define audit_log_bprm_fcaps(b, p, e) do { ; } while (0) 575#define audit_log_bprm_fcaps(b, ncr, ocr) ({ 0; })
570#define audit_log_capset(pid, e, i, p) ({ 0; }) 576#define audit_log_capset(pid, ncr, ocr) ({ 0; })
571#define audit_ptrace(t) ((void)0) 577#define audit_ptrace(t) ((void)0)
572#define audit_n_rules 0 578#define audit_n_rules 0
573#define audit_signals 0 579#define audit_signals 0
diff --git a/include/linux/capability.h b/include/linux/capability.h
index 7f26580a5a4d..e22f48c2a46f 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -519,8 +519,6 @@ extern const kernel_cap_t __cap_empty_set;
519extern const kernel_cap_t __cap_full_set; 519extern const kernel_cap_t __cap_full_set;
520extern const kernel_cap_t __cap_init_eff_set; 520extern const kernel_cap_t __cap_init_eff_set;
521 521
522kernel_cap_t cap_set_effective(const kernel_cap_t pE_new);
523
524/** 522/**
525 * has_capability - Determine if a task has a superior capability available 523 * has_capability - Determine if a task has a superior capability available
526 * @t: The task in question 524 * @t: The task in question
diff --git a/include/linux/cred.h b/include/linux/cred.h
index 62b9e532422d..eaf6fa695a04 100644
--- a/include/linux/cred.h
+++ b/include/linux/cred.h
@@ -84,6 +84,8 @@ struct thread_group_cred {
84 struct key *process_keyring; /* keyring private to this process */ 84 struct key *process_keyring; /* keyring private to this process */
85 struct rcu_head rcu; /* RCU deletion hook */ 85 struct rcu_head rcu; /* RCU deletion hook */
86}; 86};
87
88extern void release_tgcred(struct cred *cred);
87#endif 89#endif
88 90
89/* 91/*
@@ -137,11 +139,30 @@ struct cred {
137 struct user_struct *user; /* real user ID subscription */ 139 struct user_struct *user; /* real user ID subscription */
138 struct group_info *group_info; /* supplementary groups for euid/fsgid */ 140 struct group_info *group_info; /* supplementary groups for euid/fsgid */
139 struct rcu_head rcu; /* RCU deletion hook */ 141 struct rcu_head rcu; /* RCU deletion hook */
140 spinlock_t lock; /* lock for pointer changes */
141}; 142};
142 143
143extern void __put_cred(struct cred *); 144extern void __put_cred(struct cred *);
144extern int copy_creds(struct task_struct *, unsigned long); 145extern int copy_creds(struct task_struct *, unsigned long);
146extern struct cred *prepare_creds(void);
147extern struct cred *prepare_usermodehelper_creds(void);
148extern int commit_creds(struct cred *);
149extern void abort_creds(struct cred *);
150extern const struct cred *override_creds(const struct cred *) __deprecated;
151extern void revert_creds(const struct cred *) __deprecated;
152extern void __init cred_init(void);
153
154/**
155 * get_new_cred - Get a reference on a new set of credentials
156 * @cred: The new credentials to reference
157 *
158 * Get a reference on the specified set of new credentials. The caller must
159 * release the reference.
160 */
161static inline struct cred *get_new_cred(struct cred *cred)
162{
163 atomic_inc(&cred->usage);
164 return cred;
165}
145 166
146/** 167/**
147 * get_cred - Get a reference on a set of credentials 168 * get_cred - Get a reference on a set of credentials
@@ -150,10 +171,9 @@ extern int copy_creds(struct task_struct *, unsigned long);
150 * Get a reference on the specified set of credentials. The caller must 171 * Get a reference on the specified set of credentials. The caller must
151 * release the reference. 172 * release the reference.
152 */ 173 */
153static inline struct cred *get_cred(struct cred *cred) 174static inline const struct cred *get_cred(const struct cred *cred)
154{ 175{
155 atomic_inc(&cred->usage); 176 return get_new_cred((struct cred *) cred);
156 return cred;
157} 177}
158 178
159/** 179/**
@@ -166,6 +186,8 @@ static inline struct cred *get_cred(struct cred *cred)
166static inline void put_cred(const struct cred *_cred) 186static inline void put_cred(const struct cred *_cred)
167{ 187{
168 struct cred *cred = (struct cred *) _cred; 188 struct cred *cred = (struct cred *) _cred;
189
190 BUG_ON(atomic_read(&(cred)->usage) <= 0);
169 if (atomic_dec_and_test(&(cred)->usage)) 191 if (atomic_dec_and_test(&(cred)->usage))
170 __put_cred(cred); 192 __put_cred(cred);
171} 193}
@@ -250,13 +272,13 @@ static inline void put_cred(const struct cred *_cred)
250 __groups; \ 272 __groups; \
251}) 273})
252 274
253#define task_cred_xxx(task, xxx) \ 275#define task_cred_xxx(task, xxx) \
254({ \ 276({ \
255 __typeof__(task->cred->xxx) ___val; \ 277 __typeof__(((struct cred *)NULL)->xxx) ___val; \
256 rcu_read_lock(); \ 278 rcu_read_lock(); \
257 ___val = __task_cred((task))->xxx; \ 279 ___val = __task_cred((task))->xxx; \
258 rcu_read_unlock(); \ 280 rcu_read_unlock(); \
259 ___val; \ 281 ___val; \
260}) 282})
261 283
262#define task_uid(task) (task_cred_xxx((task), uid)) 284#define task_uid(task) (task_cred_xxx((task), uid))
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index 5e24c54b6dfd..08c3b24ad9a8 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -150,6 +150,8 @@ extern struct cred init_cred;
150 .sibling = LIST_HEAD_INIT(tsk.sibling), \ 150 .sibling = LIST_HEAD_INIT(tsk.sibling), \
151 .group_leader = &tsk, \ 151 .group_leader = &tsk, \
152 .cred = &init_cred, \ 152 .cred = &init_cred, \
153 .cred_exec_mutex = \
154 __MUTEX_INITIALIZER(tsk.cred_exec_mutex), \
153 .comm = "swapper", \ 155 .comm = "swapper", \
154 .thread = INIT_THREAD, \ 156 .thread = INIT_THREAD, \
155 .fs = &init_fs, \ 157 .fs = &init_fs, \
diff --git a/include/linux/key.h b/include/linux/key.h
index 0836cc838b0c..69ecf0934b02 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -73,6 +73,7 @@ struct key;
73struct seq_file; 73struct seq_file;
74struct user_struct; 74struct user_struct;
75struct signal_struct; 75struct signal_struct;
76struct cred;
76 77
77struct key_type; 78struct key_type;
78struct key_owner; 79struct key_owner;
@@ -181,7 +182,7 @@ struct key {
181extern struct key *key_alloc(struct key_type *type, 182extern struct key *key_alloc(struct key_type *type,
182 const char *desc, 183 const char *desc,
183 uid_t uid, gid_t gid, 184 uid_t uid, gid_t gid,
184 struct task_struct *ctx, 185 const struct cred *cred,
185 key_perm_t perm, 186 key_perm_t perm,
186 unsigned long flags); 187 unsigned long flags);
187 188
@@ -249,7 +250,7 @@ extern int key_unlink(struct key *keyring,
249 struct key *key); 250 struct key *key);
250 251
251extern struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid, 252extern struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
252 struct task_struct *ctx, 253 const struct cred *cred,
253 unsigned long flags, 254 unsigned long flags,
254 struct key *dest); 255 struct key *dest);
255 256
@@ -276,22 +277,12 @@ extern ctl_table key_sysctls[];
276/* 277/*
277 * the userspace interface 278 * the userspace interface
278 */ 279 */
279extern void switch_uid_keyring(struct user_struct *new_user); 280extern int install_thread_keyring_to_cred(struct cred *cred);
280extern int copy_keys(unsigned long clone_flags, struct task_struct *tsk);
281extern void exit_keys(struct task_struct *tsk);
282extern int suid_keys(struct task_struct *tsk);
283extern int exec_keys(struct task_struct *tsk); 281extern int exec_keys(struct task_struct *tsk);
284extern void key_fsuid_changed(struct task_struct *tsk); 282extern void key_fsuid_changed(struct task_struct *tsk);
285extern void key_fsgid_changed(struct task_struct *tsk); 283extern void key_fsgid_changed(struct task_struct *tsk);
286extern void key_init(void); 284extern void key_init(void);
287 285
288#define __install_session_keyring(keyring) \
289({ \
290 struct key *old_session = current->cred->tgcred->session_keyring; \
291 current->cred->tgcred->session_keyring = keyring; \
292 old_session; \
293})
294
295#else /* CONFIG_KEYS */ 286#else /* CONFIG_KEYS */
296 287
297#define key_validate(k) 0 288#define key_validate(k) 0
@@ -303,11 +294,6 @@ extern void key_init(void);
303#define make_key_ref(k, p) NULL 294#define make_key_ref(k, p) NULL
304#define key_ref_to_ptr(k) NULL 295#define key_ref_to_ptr(k) NULL
305#define is_key_possessed(k) 0 296#define is_key_possessed(k) 0
306#define switch_uid_keyring(u) do { } while(0)
307#define __install_session_keyring(k) ({ NULL; })
308#define copy_keys(f,t) 0
309#define exit_keys(t) do { } while(0)
310#define suid_keys(t) do { } while(0)
311#define exec_keys(t) do { } while(0) 297#define exec_keys(t) do { } while(0)
312#define key_fsuid_changed(t) do { } while(0) 298#define key_fsuid_changed(t) do { } while(0)
313#define key_fsgid_changed(t) do { } while(0) 299#define key_fsgid_changed(t) do { } while(0)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 2913252989b3..121d655e460d 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1145,7 +1145,8 @@ struct task_struct {
1145 struct list_head cpu_timers[3]; 1145 struct list_head cpu_timers[3];
1146 1146
1147/* process credentials */ 1147/* process credentials */
1148 struct cred *cred; /* actual/objective task credentials */ 1148 const struct cred *cred; /* actual/objective task credentials (COW) */
1149 struct mutex cred_exec_mutex; /* execve vs ptrace cred calculation mutex */
1149 1150
1150 char comm[TASK_COMM_LEN]; /* executable name excluding path 1151 char comm[TASK_COMM_LEN]; /* executable name excluding path
1151 - access with [gs]et_task_comm (which lock 1152 - access with [gs]et_task_comm (which lock
@@ -1720,7 +1721,6 @@ static inline struct user_struct *get_uid(struct user_struct *u)
1720 return u; 1721 return u;
1721} 1722}
1722extern void free_uid(struct user_struct *); 1723extern void free_uid(struct user_struct *);
1723extern void switch_uid(struct user_struct *);
1724extern void release_uids(struct user_namespace *ns); 1724extern void release_uids(struct user_namespace *ns);
1725 1725
1726#include <asm/current.h> 1726#include <asm/current.h>
@@ -1870,6 +1870,8 @@ static inline unsigned long wait_task_inactive(struct task_struct *p,
1870#define for_each_process(p) \ 1870#define for_each_process(p) \
1871 for (p = &init_task ; (p = next_task(p)) != &init_task ; ) 1871 for (p = &init_task ; (p = next_task(p)) != &init_task ; )
1872 1872
1873extern bool is_single_threaded(struct task_struct *);
1874
1873/* 1875/*
1874 * Careful: do_each_thread/while_each_thread is a double loop so 1876 * Careful: do_each_thread/while_each_thread is a double loop so
1875 * 'break' will not work as expected - use goto instead. 1877 * 'break' will not work as expected - use goto instead.
diff --git a/include/linux/security.h b/include/linux/security.h
index 7e9fe046a0d1..68be11251447 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -53,24 +53,21 @@ extern int cap_settime(struct timespec *ts, struct timezone *tz);
53extern int cap_ptrace_may_access(struct task_struct *child, unsigned int mode); 53extern int cap_ptrace_may_access(struct task_struct *child, unsigned int mode);
54extern int cap_ptrace_traceme(struct task_struct *parent); 54extern int cap_ptrace_traceme(struct task_struct *parent);
55extern int cap_capget(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted); 55extern int cap_capget(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted);
56extern int cap_capset_check(const kernel_cap_t *effective, 56extern int cap_capset(struct cred *new, const struct cred *old,
57 const kernel_cap_t *inheritable, 57 const kernel_cap_t *effective,
58 const kernel_cap_t *permitted); 58 const kernel_cap_t *inheritable,
59extern void cap_capset_set(const kernel_cap_t *effective, 59 const kernel_cap_t *permitted);
60 const kernel_cap_t *inheritable,
61 const kernel_cap_t *permitted);
62extern int cap_bprm_set_security(struct linux_binprm *bprm); 60extern int cap_bprm_set_security(struct linux_binprm *bprm);
63extern void cap_bprm_apply_creds(struct linux_binprm *bprm, int unsafe); 61extern int cap_bprm_apply_creds(struct linux_binprm *bprm, int unsafe);
64extern int cap_bprm_secureexec(struct linux_binprm *bprm); 62extern int cap_bprm_secureexec(struct linux_binprm *bprm);
65extern int cap_inode_setxattr(struct dentry *dentry, const char *name, 63extern int cap_inode_setxattr(struct dentry *dentry, const char *name,
66 const void *value, size_t size, int flags); 64 const void *value, size_t size, int flags);
67extern int cap_inode_removexattr(struct dentry *dentry, const char *name); 65extern int cap_inode_removexattr(struct dentry *dentry, const char *name);
68extern int cap_inode_need_killpriv(struct dentry *dentry); 66extern int cap_inode_need_killpriv(struct dentry *dentry);
69extern int cap_inode_killpriv(struct dentry *dentry); 67extern int cap_inode_killpriv(struct dentry *dentry);
70extern int cap_task_post_setuid(uid_t old_ruid, uid_t old_euid, uid_t old_suid, int flags); 68extern int cap_task_fix_setuid(struct cred *new, const struct cred *old, int flags);
71extern void cap_task_reparent_to_init(struct task_struct *p);
72extern int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, 69extern int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
73 unsigned long arg4, unsigned long arg5, long *rc_p); 70 unsigned long arg4, unsigned long arg5);
74extern int cap_task_setscheduler(struct task_struct *p, int policy, struct sched_param *lp); 71extern int cap_task_setscheduler(struct task_struct *p, int policy, struct sched_param *lp);
75extern int cap_task_setioprio(struct task_struct *p, int ioprio); 72extern int cap_task_setioprio(struct task_struct *p, int ioprio);
76extern int cap_task_setnice(struct task_struct *p, int nice); 73extern int cap_task_setnice(struct task_struct *p, int nice);
@@ -170,8 +167,8 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
170 * Compute and set the security attributes of a process being transformed 167 * Compute and set the security attributes of a process being transformed
171 * by an execve operation based on the old attributes (current->security) 168 * by an execve operation based on the old attributes (current->security)
172 * and the information saved in @bprm->security by the set_security hook. 169 * and the information saved in @bprm->security by the set_security hook.
173 * Since this hook function (and its caller) are void, this hook can not 170 * Since this function may return an error, in which case the process will
174 * return an error. However, it can leave the security attributes of the 171 * be killed. However, it can leave the security attributes of the
175 * process unchanged if an access failure occurs at this point. 172 * process unchanged if an access failure occurs at this point.
176 * bprm_apply_creds is called under task_lock. @unsafe indicates various 173 * bprm_apply_creds is called under task_lock. @unsafe indicates various
177 * reasons why it may be unsafe to change security state. 174 * reasons why it may be unsafe to change security state.
@@ -593,15 +590,18 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
593 * manual page for definitions of the @clone_flags. 590 * manual page for definitions of the @clone_flags.
594 * @clone_flags contains the flags indicating what should be shared. 591 * @clone_flags contains the flags indicating what should be shared.
595 * Return 0 if permission is granted. 592 * Return 0 if permission is granted.
596 * @cred_alloc_security:
597 * @cred contains the cred struct for child process.
598 * Allocate and attach a security structure to the cred->security field.
599 * The security field is initialized to NULL when the task structure is
600 * allocated.
601 * Return 0 if operation was successful.
602 * @cred_free: 593 * @cred_free:
603 * @cred points to the credentials. 594 * @cred points to the credentials.
604 * Deallocate and clear the cred->security field in a set of credentials. 595 * Deallocate and clear the cred->security field in a set of credentials.
596 * @cred_prepare:
597 * @new points to the new credentials.
598 * @old points to the original credentials.
599 * @gfp indicates the atomicity of any memory allocations.
600 * Prepare a new set of credentials by copying the data from the old set.
601 * @cred_commit:
602 * @new points to the new credentials.
603 * @old points to the original credentials.
604 * Install a new set of credentials.
605 * @task_setuid: 605 * @task_setuid:
606 * Check permission before setting one or more of the user identity 606 * Check permission before setting one or more of the user identity
607 * attributes of the current process. The @flags parameter indicates 607 * attributes of the current process. The @flags parameter indicates
@@ -614,15 +614,13 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
614 * @id2 contains a uid. 614 * @id2 contains a uid.
615 * @flags contains one of the LSM_SETID_* values. 615 * @flags contains one of the LSM_SETID_* values.
616 * Return 0 if permission is granted. 616 * Return 0 if permission is granted.
617 * @task_post_setuid: 617 * @task_fix_setuid:
618 * Update the module's state after setting one or more of the user 618 * Update the module's state after setting one or more of the user
619 * identity attributes of the current process. The @flags parameter 619 * identity attributes of the current process. The @flags parameter
620 * indicates which of the set*uid system calls invoked this hook. If 620 * indicates which of the set*uid system calls invoked this hook. If
621 * @flags is LSM_SETID_FS, then @old_ruid is the old fs uid and the other 621 * @new is the set of credentials that will be installed. Modifications
622 * parameters are not used. 622 * should be made to this rather than to @current->cred.
623 * @old_ruid contains the old real uid (or fs uid if LSM_SETID_FS). 623 * @old is the set of credentials that are being replaces
624 * @old_euid contains the old effective uid (or -1 if LSM_SETID_FS).
625 * @old_suid contains the old saved uid (or -1 if LSM_SETID_FS).
626 * @flags contains one of the LSM_SETID_* values. 624 * @flags contains one of the LSM_SETID_* values.
627 * Return 0 on success. 625 * Return 0 on success.
628 * @task_setgid: 626 * @task_setgid:
@@ -725,13 +723,8 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
725 * @arg3 contains a argument. 723 * @arg3 contains a argument.
726 * @arg4 contains a argument. 724 * @arg4 contains a argument.
727 * @arg5 contains a argument. 725 * @arg5 contains a argument.
728 * @rc_p contains a pointer to communicate back the forced return code 726 * Return -ENOSYS if no-one wanted to handle this op, any other value to
729 * Return 0 if permission is granted, and non-zero if the security module 727 * cause prctl() to return immediately with that value.
730 * has taken responsibility (setting *rc_p) for the prctl call.
731 * @task_reparent_to_init:
732 * Set the security attributes in @p->security for a kernel thread that
733 * is being reparented to the init task.
734 * @p contains the task_struct for the kernel thread.
735 * @task_to_inode: 728 * @task_to_inode:
736 * Set the security attributes for an inode based on an associated task's 729 * Set the security attributes for an inode based on an associated task's
737 * security attributes, e.g. for /proc/pid inodes. 730 * security attributes, e.g. for /proc/pid inodes.
@@ -1008,7 +1001,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
1008 * See whether a specific operational right is granted to a process on a 1001 * See whether a specific operational right is granted to a process on a
1009 * key. 1002 * key.
1010 * @key_ref refers to the key (key pointer + possession attribute bit). 1003 * @key_ref refers to the key (key pointer + possession attribute bit).
1011 * @context points to the process to provide the context against which to 1004 * @cred points to the credentials to provide the context against which to
1012 * evaluate the security data on the key. 1005 * evaluate the security data on the key.
1013 * @perm describes the combination of permissions required of this key. 1006 * @perm describes the combination of permissions required of this key.
1014 * Return 1 if permission granted, 0 if permission denied and -ve it the 1007 * Return 1 if permission granted, 0 if permission denied and -ve it the
@@ -1170,6 +1163,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
1170 * @child process. 1163 * @child process.
1171 * Security modules may also want to perform a process tracing check 1164 * Security modules may also want to perform a process tracing check
1172 * during an execve in the set_security or apply_creds hooks of 1165 * during an execve in the set_security or apply_creds hooks of
1166 * tracing check during an execve in the bprm_set_creds hook of
1173 * binprm_security_ops if the process is being traced and its security 1167 * binprm_security_ops if the process is being traced and its security
1174 * attributes would be changed by the execve. 1168 * attributes would be changed by the execve.
1175 * @child contains the task_struct structure for the target process. 1169 * @child contains the task_struct structure for the target process.
@@ -1193,19 +1187,15 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
1193 * @inheritable contains the inheritable capability set. 1187 * @inheritable contains the inheritable capability set.
1194 * @permitted contains the permitted capability set. 1188 * @permitted contains the permitted capability set.
1195 * Return 0 if the capability sets were successfully obtained. 1189 * Return 0 if the capability sets were successfully obtained.
1196 * @capset_check: 1190 * @capset:
1197 * Check permission before setting the @effective, @inheritable, and
1198 * @permitted capability sets for the current process.
1199 * @effective contains the effective capability set.
1200 * @inheritable contains the inheritable capability set.
1201 * @permitted contains the permitted capability set.
1202 * Return 0 if permission is granted.
1203 * @capset_set:
1204 * Set the @effective, @inheritable, and @permitted capability sets for 1191 * Set the @effective, @inheritable, and @permitted capability sets for
1205 * the current process. 1192 * the current process.
1193 * @new contains the new credentials structure for target process.
1194 * @old contains the current credentials structure for target process.
1206 * @effective contains the effective capability set. 1195 * @effective contains the effective capability set.
1207 * @inheritable contains the inheritable capability set. 1196 * @inheritable contains the inheritable capability set.
1208 * @permitted contains the permitted capability set. 1197 * @permitted contains the permitted capability set.
1198 * Return 0 and update @new if permission is granted.
1209 * @capable: 1199 * @capable:
1210 * Check whether the @tsk process has the @cap capability. 1200 * Check whether the @tsk process has the @cap capability.
1211 * @tsk contains the task_struct for the process. 1201 * @tsk contains the task_struct for the process.
@@ -1297,12 +1287,11 @@ struct security_operations {
1297 int (*capget) (struct task_struct *target, 1287 int (*capget) (struct task_struct *target,
1298 kernel_cap_t *effective, 1288 kernel_cap_t *effective,
1299 kernel_cap_t *inheritable, kernel_cap_t *permitted); 1289 kernel_cap_t *inheritable, kernel_cap_t *permitted);
1300 int (*capset_check) (const kernel_cap_t *effective, 1290 int (*capset) (struct cred *new,
1301 const kernel_cap_t *inheritable, 1291 const struct cred *old,
1302 const kernel_cap_t *permitted); 1292 const kernel_cap_t *effective,
1303 void (*capset_set) (const kernel_cap_t *effective, 1293 const kernel_cap_t *inheritable,
1304 const kernel_cap_t *inheritable, 1294 const kernel_cap_t *permitted);
1305 const kernel_cap_t *permitted);
1306 int (*capable) (struct task_struct *tsk, int cap, int audit); 1295 int (*capable) (struct task_struct *tsk, int cap, int audit);
1307 int (*acct) (struct file *file); 1296 int (*acct) (struct file *file);
1308 int (*sysctl) (struct ctl_table *table, int op); 1297 int (*sysctl) (struct ctl_table *table, int op);
@@ -1314,7 +1303,7 @@ struct security_operations {
1314 1303
1315 int (*bprm_alloc_security) (struct linux_binprm *bprm); 1304 int (*bprm_alloc_security) (struct linux_binprm *bprm);
1316 void (*bprm_free_security) (struct linux_binprm *bprm); 1305 void (*bprm_free_security) (struct linux_binprm *bprm);
1317 void (*bprm_apply_creds) (struct linux_binprm *bprm, int unsafe); 1306 int (*bprm_apply_creds) (struct linux_binprm *bprm, int unsafe);
1318 void (*bprm_post_apply_creds) (struct linux_binprm *bprm); 1307 void (*bprm_post_apply_creds) (struct linux_binprm *bprm);
1319 int (*bprm_set_security) (struct linux_binprm *bprm); 1308 int (*bprm_set_security) (struct linux_binprm *bprm);
1320 int (*bprm_check_security) (struct linux_binprm *bprm); 1309 int (*bprm_check_security) (struct linux_binprm *bprm);
@@ -1405,11 +1394,13 @@ struct security_operations {
1405 int (*dentry_open) (struct file *file, const struct cred *cred); 1394 int (*dentry_open) (struct file *file, const struct cred *cred);
1406 1395
1407 int (*task_create) (unsigned long clone_flags); 1396 int (*task_create) (unsigned long clone_flags);
1408 int (*cred_alloc_security) (struct cred *cred);
1409 void (*cred_free) (struct cred *cred); 1397 void (*cred_free) (struct cred *cred);
1398 int (*cred_prepare)(struct cred *new, const struct cred *old,
1399 gfp_t gfp);
1400 void (*cred_commit)(struct cred *new, const struct cred *old);
1410 int (*task_setuid) (uid_t id0, uid_t id1, uid_t id2, int flags); 1401 int (*task_setuid) (uid_t id0, uid_t id1, uid_t id2, int flags);
1411 int (*task_post_setuid) (uid_t old_ruid /* or fsuid */ , 1402 int (*task_fix_setuid) (struct cred *new, const struct cred *old,
1412 uid_t old_euid, uid_t old_suid, int flags); 1403 int flags);
1413 int (*task_setgid) (gid_t id0, gid_t id1, gid_t id2, int flags); 1404 int (*task_setgid) (gid_t id0, gid_t id1, gid_t id2, int flags);
1414 int (*task_setpgid) (struct task_struct *p, pid_t pgid); 1405 int (*task_setpgid) (struct task_struct *p, pid_t pgid);
1415 int (*task_getpgid) (struct task_struct *p); 1406 int (*task_getpgid) (struct task_struct *p);
@@ -1429,8 +1420,7 @@ struct security_operations {
1429 int (*task_wait) (struct task_struct *p); 1420 int (*task_wait) (struct task_struct *p);
1430 int (*task_prctl) (int option, unsigned long arg2, 1421 int (*task_prctl) (int option, unsigned long arg2,
1431 unsigned long arg3, unsigned long arg4, 1422 unsigned long arg3, unsigned long arg4,
1432 unsigned long arg5, long *rc_p); 1423 unsigned long arg5);
1433 void (*task_reparent_to_init) (struct task_struct *p);
1434 void (*task_to_inode) (struct task_struct *p, struct inode *inode); 1424 void (*task_to_inode) (struct task_struct *p, struct inode *inode);
1435 1425
1436 int (*ipc_permission) (struct kern_ipc_perm *ipcp, short flag); 1426 int (*ipc_permission) (struct kern_ipc_perm *ipcp, short flag);
@@ -1535,10 +1525,10 @@ struct security_operations {
1535 1525
1536 /* key management security hooks */ 1526 /* key management security hooks */
1537#ifdef CONFIG_KEYS 1527#ifdef CONFIG_KEYS
1538 int (*key_alloc) (struct key *key, struct task_struct *tsk, unsigned long flags); 1528 int (*key_alloc) (struct key *key, const struct cred *cred, unsigned long flags);
1539 void (*key_free) (struct key *key); 1529 void (*key_free) (struct key *key);
1540 int (*key_permission) (key_ref_t key_ref, 1530 int (*key_permission) (key_ref_t key_ref,
1541 struct task_struct *context, 1531 const struct cred *cred,
1542 key_perm_t perm); 1532 key_perm_t perm);
1543 int (*key_getsecurity)(struct key *key, char **_buffer); 1533 int (*key_getsecurity)(struct key *key, char **_buffer);
1544#endif /* CONFIG_KEYS */ 1534#endif /* CONFIG_KEYS */
@@ -1564,12 +1554,10 @@ int security_capget(struct task_struct *target,
1564 kernel_cap_t *effective, 1554 kernel_cap_t *effective,
1565 kernel_cap_t *inheritable, 1555 kernel_cap_t *inheritable,
1566 kernel_cap_t *permitted); 1556 kernel_cap_t *permitted);
1567int security_capset_check(const kernel_cap_t *effective, 1557int security_capset(struct cred *new, const struct cred *old,
1568 const kernel_cap_t *inheritable, 1558 const kernel_cap_t *effective,
1569 const kernel_cap_t *permitted); 1559 const kernel_cap_t *inheritable,
1570void security_capset_set(const kernel_cap_t *effective, 1560 const kernel_cap_t *permitted);
1571 const kernel_cap_t *inheritable,
1572 const kernel_cap_t *permitted);
1573int security_capable(struct task_struct *tsk, int cap); 1561int security_capable(struct task_struct *tsk, int cap);
1574int security_capable_noaudit(struct task_struct *tsk, int cap); 1562int security_capable_noaudit(struct task_struct *tsk, int cap);
1575int security_acct(struct file *file); 1563int security_acct(struct file *file);
@@ -1583,7 +1571,7 @@ int security_vm_enough_memory_mm(struct mm_struct *mm, long pages);
1583int security_vm_enough_memory_kern(long pages); 1571int security_vm_enough_memory_kern(long pages);
1584int security_bprm_alloc(struct linux_binprm *bprm); 1572int security_bprm_alloc(struct linux_binprm *bprm);
1585void security_bprm_free(struct linux_binprm *bprm); 1573void security_bprm_free(struct linux_binprm *bprm);
1586void security_bprm_apply_creds(struct linux_binprm *bprm, int unsafe); 1574int security_bprm_apply_creds(struct linux_binprm *bprm, int unsafe);
1587void security_bprm_post_apply_creds(struct linux_binprm *bprm); 1575void security_bprm_post_apply_creds(struct linux_binprm *bprm);
1588int security_bprm_set(struct linux_binprm *bprm); 1576int security_bprm_set(struct linux_binprm *bprm);
1589int security_bprm_check(struct linux_binprm *bprm); 1577int security_bprm_check(struct linux_binprm *bprm);
@@ -1660,11 +1648,12 @@ int security_file_send_sigiotask(struct task_struct *tsk,
1660int security_file_receive(struct file *file); 1648int security_file_receive(struct file *file);
1661int security_dentry_open(struct file *file, const struct cred *cred); 1649int security_dentry_open(struct file *file, const struct cred *cred);
1662int security_task_create(unsigned long clone_flags); 1650int security_task_create(unsigned long clone_flags);
1663int security_cred_alloc(struct cred *cred);
1664void security_cred_free(struct cred *cred); 1651void security_cred_free(struct cred *cred);
1652int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp);
1653void security_commit_creds(struct cred *new, const struct cred *old);
1665int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags); 1654int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags);
1666int security_task_post_setuid(uid_t old_ruid, uid_t old_euid, 1655int security_task_fix_setuid(struct cred *new, const struct cred *old,
1667 uid_t old_suid, int flags); 1656 int flags);
1668int security_task_setgid(gid_t id0, gid_t id1, gid_t id2, int flags); 1657int security_task_setgid(gid_t id0, gid_t id1, gid_t id2, int flags);
1669int security_task_setpgid(struct task_struct *p, pid_t pgid); 1658int security_task_setpgid(struct task_struct *p, pid_t pgid);
1670int security_task_getpgid(struct task_struct *p); 1659int security_task_getpgid(struct task_struct *p);
@@ -1683,8 +1672,7 @@ int security_task_kill(struct task_struct *p, struct siginfo *info,
1683 int sig, u32 secid); 1672 int sig, u32 secid);
1684int security_task_wait(struct task_struct *p); 1673int security_task_wait(struct task_struct *p);
1685int security_task_prctl(int option, unsigned long arg2, unsigned long arg3, 1674int security_task_prctl(int option, unsigned long arg2, unsigned long arg3,
1686 unsigned long arg4, unsigned long arg5, long *rc_p); 1675 unsigned long arg4, unsigned long arg5);
1687void security_task_reparent_to_init(struct task_struct *p);
1688void security_task_to_inode(struct task_struct *p, struct inode *inode); 1676void security_task_to_inode(struct task_struct *p, struct inode *inode);
1689int security_ipc_permission(struct kern_ipc_perm *ipcp, short flag); 1677int security_ipc_permission(struct kern_ipc_perm *ipcp, short flag);
1690void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid); 1678void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid);
@@ -1759,18 +1747,13 @@ static inline int security_capget(struct task_struct *target,
1759 return cap_capget(target, effective, inheritable, permitted); 1747 return cap_capget(target, effective, inheritable, permitted);
1760} 1748}
1761 1749
1762static inline int security_capset_check(const kernel_cap_t *effective, 1750static inline int security_capset(struct cred *new,
1763 const kernel_cap_t *inheritable, 1751 const struct cred *old,
1764 const kernel_cap_t *permitted) 1752 const kernel_cap_t *effective,
1753 const kernel_cap_t *inheritable,
1754 const kernel_cap_t *permitted)
1765{ 1755{
1766 return cap_capset_check(effective, inheritable, permitted); 1756 return cap_capset(new, old, effective, inheritable, permitted);
1767}
1768
1769static inline void security_capset_set(const kernel_cap_t *effective,
1770 const kernel_cap_t *inheritable,
1771 const kernel_cap_t *permitted)
1772{
1773 cap_capset_set(effective, inheritable, permitted);
1774} 1757}
1775 1758
1776static inline int security_capable(struct task_struct *tsk, int cap) 1759static inline int security_capable(struct task_struct *tsk, int cap)
@@ -1837,9 +1820,9 @@ static inline int security_bprm_alloc(struct linux_binprm *bprm)
1837static inline void security_bprm_free(struct linux_binprm *bprm) 1820static inline void security_bprm_free(struct linux_binprm *bprm)
1838{ } 1821{ }
1839 1822
1840static inline void security_bprm_apply_creds(struct linux_binprm *bprm, int unsafe) 1823static inline int security_bprm_apply_creds(struct linux_binprm *bprm, int unsafe)
1841{ 1824{
1842 cap_bprm_apply_creds(bprm, unsafe); 1825 return cap_bprm_apply_creds(bprm, unsafe);
1843} 1826}
1844 1827
1845static inline void security_bprm_post_apply_creds(struct linux_binprm *bprm) 1828static inline void security_bprm_post_apply_creds(struct linux_binprm *bprm)
@@ -2182,13 +2165,20 @@ static inline int security_task_create(unsigned long clone_flags)
2182 return 0; 2165 return 0;
2183} 2166}
2184 2167
2185static inline int security_cred_alloc(struct cred *cred) 2168static inline void security_cred_free(struct cred *cred)
2169{ }
2170
2171static inline int security_prepare_creds(struct cred *new,
2172 const struct cred *old,
2173 gfp_t gfp)
2186{ 2174{
2187 return 0; 2175 return 0;
2188} 2176}
2189 2177
2190static inline void security_cred_free(struct cred *cred) 2178static inline void security_commit_creds(struct cred *new,
2191{ } 2179 const struct cred *old)
2180{
2181}
2192 2182
2193static inline int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, 2183static inline int security_task_setuid(uid_t id0, uid_t id1, uid_t id2,
2194 int flags) 2184 int flags)
@@ -2196,10 +2186,11 @@ static inline int security_task_setuid(uid_t id0, uid_t id1, uid_t id2,
2196 return 0; 2186 return 0;
2197} 2187}
2198 2188
2199static inline int security_task_post_setuid(uid_t old_ruid, uid_t old_euid, 2189static inline int security_task_fix_setuid(struct cred *new,
2200 uid_t old_suid, int flags) 2190 const struct cred *old,
2191 int flags)
2201{ 2192{
2202 return cap_task_post_setuid(old_ruid, old_euid, old_suid, flags); 2193 return cap_task_fix_setuid(new, old, flags);
2203} 2194}
2204 2195
2205static inline int security_task_setgid(gid_t id0, gid_t id1, gid_t id2, 2196static inline int security_task_setgid(gid_t id0, gid_t id1, gid_t id2,
@@ -2286,14 +2277,9 @@ static inline int security_task_wait(struct task_struct *p)
2286static inline int security_task_prctl(int option, unsigned long arg2, 2277static inline int security_task_prctl(int option, unsigned long arg2,
2287 unsigned long arg3, 2278 unsigned long arg3,
2288 unsigned long arg4, 2279 unsigned long arg4,
2289 unsigned long arg5, long *rc_p) 2280 unsigned long arg5)
2290{
2291 return cap_task_prctl(option, arg2, arg3, arg3, arg5, rc_p);
2292}
2293
2294static inline void security_task_reparent_to_init(struct task_struct *p)
2295{ 2281{
2296 cap_task_reparent_to_init(p); 2282 return cap_task_prctl(option, arg2, arg3, arg3, arg5);
2297} 2283}
2298 2284
2299static inline void security_task_to_inode(struct task_struct *p, struct inode *inode) 2285static inline void security_task_to_inode(struct task_struct *p, struct inode *inode)
@@ -2719,16 +2705,16 @@ static inline void security_skb_classify_flow(struct sk_buff *skb, struct flowi
2719#ifdef CONFIG_KEYS 2705#ifdef CONFIG_KEYS
2720#ifdef CONFIG_SECURITY 2706#ifdef CONFIG_SECURITY
2721 2707
2722int security_key_alloc(struct key *key, struct task_struct *tsk, unsigned long flags); 2708int security_key_alloc(struct key *key, const struct cred *cred, unsigned long flags);
2723void security_key_free(struct key *key); 2709void security_key_free(struct key *key);
2724int security_key_permission(key_ref_t key_ref, 2710int security_key_permission(key_ref_t key_ref,
2725 struct task_struct *context, key_perm_t perm); 2711 const struct cred *cred, key_perm_t perm);
2726int security_key_getsecurity(struct key *key, char **_buffer); 2712int security_key_getsecurity(struct key *key, char **_buffer);
2727 2713
2728#else 2714#else
2729 2715
2730static inline int security_key_alloc(struct key *key, 2716static inline int security_key_alloc(struct key *key,
2731 struct task_struct *tsk, 2717 const struct cred *cred,
2732 unsigned long flags) 2718 unsigned long flags)
2733{ 2719{
2734 return 0; 2720 return 0;
@@ -2739,7 +2725,7 @@ static inline void security_key_free(struct key *key)
2739} 2725}
2740 2726
2741static inline int security_key_permission(key_ref_t key_ref, 2727static inline int security_key_permission(key_ref_t key_ref,
2742 struct task_struct *context, 2728 const struct cred *cred,
2743 key_perm_t perm) 2729 key_perm_t perm)
2744{ 2730{
2745 return 0; 2731 return 0;
diff --git a/init/main.c b/init/main.c
index 7e117a231af1..db843bff5732 100644
--- a/init/main.c
+++ b/init/main.c
@@ -669,6 +669,7 @@ asmlinkage void __init start_kernel(void)
669 efi_enter_virtual_mode(); 669 efi_enter_virtual_mode();
670#endif 670#endif
671 thread_info_cache_init(); 671 thread_info_cache_init();
672 cred_init();
672 fork_init(num_physpages); 673 fork_init(num_physpages);
673 proc_caches_init(); 674 proc_caches_init();
674 buffer_init(); 675 buffer_init();
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index ae8ef88ade3f..bc1e2d854bf6 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -2546,18 +2546,17 @@ int __audit_signal_info(int sig, struct task_struct *t)
2546 2546
2547/** 2547/**
2548 * __audit_log_bprm_fcaps - store information about a loading bprm and relevant fcaps 2548 * __audit_log_bprm_fcaps - store information about a loading bprm and relevant fcaps
2549 * @bprm pointer to the bprm being processed 2549 * @bprm: pointer to the bprm being processed
2550 * @caps the caps read from the disk 2550 * @new: the proposed new credentials
2551 * @old: the old credentials
2551 * 2552 *
2552 * Simply check if the proc already has the caps given by the file and if not 2553 * Simply check if the proc already has the caps given by the file and if not
2553 * store the priv escalation info for later auditing at the end of the syscall 2554 * store the priv escalation info for later auditing at the end of the syscall
2554 * 2555 *
2555 * this can fail and we don't care. See the note in audit.h for
2556 * audit_log_bprm_fcaps() for my explaination....
2557 *
2558 * -Eric 2556 * -Eric
2559 */ 2557 */
2560void __audit_log_bprm_fcaps(struct linux_binprm *bprm, kernel_cap_t *pP, kernel_cap_t *pE) 2558int __audit_log_bprm_fcaps(struct linux_binprm *bprm,
2559 const struct cred *new, const struct cred *old)
2561{ 2560{
2562 struct audit_aux_data_bprm_fcaps *ax; 2561 struct audit_aux_data_bprm_fcaps *ax;
2563 struct audit_context *context = current->audit_context; 2562 struct audit_context *context = current->audit_context;
@@ -2566,7 +2565,7 @@ void __audit_log_bprm_fcaps(struct linux_binprm *bprm, kernel_cap_t *pP, kernel_
2566 2565
2567 ax = kmalloc(sizeof(*ax), GFP_KERNEL); 2566 ax = kmalloc(sizeof(*ax), GFP_KERNEL);
2568 if (!ax) 2567 if (!ax)
2569 return; 2568 return -ENOMEM;
2570 2569
2571 ax->d.type = AUDIT_BPRM_FCAPS; 2570 ax->d.type = AUDIT_BPRM_FCAPS;
2572 ax->d.next = context->aux; 2571 ax->d.next = context->aux;
@@ -2581,26 +2580,27 @@ void __audit_log_bprm_fcaps(struct linux_binprm *bprm, kernel_cap_t *pP, kernel_
2581 ax->fcap.fE = !!(vcaps.magic_etc & VFS_CAP_FLAGS_EFFECTIVE); 2580 ax->fcap.fE = !!(vcaps.magic_etc & VFS_CAP_FLAGS_EFFECTIVE);
2582 ax->fcap_ver = (vcaps.magic_etc & VFS_CAP_REVISION_MASK) >> VFS_CAP_REVISION_SHIFT; 2581 ax->fcap_ver = (vcaps.magic_etc & VFS_CAP_REVISION_MASK) >> VFS_CAP_REVISION_SHIFT;
2583 2582
2584 ax->old_pcap.permitted = *pP; 2583 ax->old_pcap.permitted = old->cap_permitted;
2585 ax->old_pcap.inheritable = current->cred->cap_inheritable; 2584 ax->old_pcap.inheritable = old->cap_inheritable;
2586 ax->old_pcap.effective = *pE; 2585 ax->old_pcap.effective = old->cap_effective;
2587 2586
2588 ax->new_pcap.permitted = current->cred->cap_permitted; 2587 ax->new_pcap.permitted = new->cap_permitted;
2589 ax->new_pcap.inheritable = current->cred->cap_inheritable; 2588 ax->new_pcap.inheritable = new->cap_inheritable;
2590 ax->new_pcap.effective = current->cred->cap_effective; 2589 ax->new_pcap.effective = new->cap_effective;
2590 return 0;
2591} 2591}
2592 2592
2593/** 2593/**
2594 * __audit_log_capset - store information about the arguments to the capset syscall 2594 * __audit_log_capset - store information about the arguments to the capset syscall
2595 * @pid target pid of the capset call 2595 * @pid: target pid of the capset call
2596 * @eff effective cap set 2596 * @new: the new credentials
2597 * @inh inheritible cap set 2597 * @old: the old (current) credentials
2598 * @perm permited cap set
2599 * 2598 *
2600 * Record the aguments userspace sent to sys_capset for later printing by the 2599 * Record the aguments userspace sent to sys_capset for later printing by the
2601 * audit system if applicable 2600 * audit system if applicable
2602 */ 2601 */
2603int __audit_log_capset(pid_t pid, kernel_cap_t *eff, kernel_cap_t *inh, kernel_cap_t *perm) 2602int __audit_log_capset(pid_t pid,
2603 const struct cred *new, const struct cred *old)
2604{ 2604{
2605 struct audit_aux_data_capset *ax; 2605 struct audit_aux_data_capset *ax;
2606 struct audit_context *context = current->audit_context; 2606 struct audit_context *context = current->audit_context;
@@ -2617,9 +2617,9 @@ int __audit_log_capset(pid_t pid, kernel_cap_t *eff, kernel_cap_t *inh, kernel_c
2617 context->aux = (void *)ax; 2617 context->aux = (void *)ax;
2618 2618
2619 ax->pid = pid; 2619 ax->pid = pid;
2620 ax->cap.effective = *eff; 2620 ax->cap.effective = new->cap_effective;
2621 ax->cap.inheritable = *eff; 2621 ax->cap.inheritable = new->cap_effective;
2622 ax->cap.permitted = *perm; 2622 ax->cap.permitted = new->cap_permitted;
2623 2623
2624 return 0; 2624 return 0;
2625} 2625}
diff --git a/kernel/capability.c b/kernel/capability.c
index a404b980b1bd..36b4b4daebec 100644
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -15,12 +15,7 @@
15#include <linux/syscalls.h> 15#include <linux/syscalls.h>
16#include <linux/pid_namespace.h> 16#include <linux/pid_namespace.h>
17#include <asm/uaccess.h> 17#include <asm/uaccess.h>
18 18#include "cred-internals.h"
19/*
20 * This lock protects task->cap_* for all tasks including current.
21 * Locking rule: acquire this prior to tasklist_lock.
22 */
23static DEFINE_SPINLOCK(task_capability_lock);
24 19
25/* 20/*
26 * Leveraged for setting/resetting capabilities 21 * Leveraged for setting/resetting capabilities
@@ -128,12 +123,11 @@ static int cap_validate_magic(cap_user_header_t header, unsigned *tocopy)
128} 123}
129 124
130/* 125/*
131 * If we have configured with filesystem capability support, then the 126 * The only thing that can change the capabilities of the current
132 * only thing that can change the capabilities of the current process 127 * process is the current process. As such, we can't be in this code
133 * is the current process. As such, we can't be in this code at the 128 * at the same time as we are in the process of setting capabilities
134 * same time as we are in the process of setting capabilities in this 129 * in this process. The net result is that we can limit our use of
135 * process. The net result is that we can limit our use of locks to 130 * locks to when we are reading the caps of another process.
136 * when we are reading the caps of another process.
137 */ 131 */
138static inline int cap_get_target_pid(pid_t pid, kernel_cap_t *pEp, 132static inline int cap_get_target_pid(pid_t pid, kernel_cap_t *pEp,
139 kernel_cap_t *pIp, kernel_cap_t *pPp) 133 kernel_cap_t *pIp, kernel_cap_t *pPp)
@@ -143,7 +137,6 @@ static inline int cap_get_target_pid(pid_t pid, kernel_cap_t *pEp,
143 if (pid && (pid != task_pid_vnr(current))) { 137 if (pid && (pid != task_pid_vnr(current))) {
144 struct task_struct *target; 138 struct task_struct *target;
145 139
146 spin_lock(&task_capability_lock);
147 read_lock(&tasklist_lock); 140 read_lock(&tasklist_lock);
148 141
149 target = find_task_by_vpid(pid); 142 target = find_task_by_vpid(pid);
@@ -153,34 +146,12 @@ static inline int cap_get_target_pid(pid_t pid, kernel_cap_t *pEp,
153 ret = security_capget(target, pEp, pIp, pPp); 146 ret = security_capget(target, pEp, pIp, pPp);
154 147
155 read_unlock(&tasklist_lock); 148 read_unlock(&tasklist_lock);
156 spin_unlock(&task_capability_lock);
157 } else 149 } else
158 ret = security_capget(current, pEp, pIp, pPp); 150 ret = security_capget(current, pEp, pIp, pPp);
159 151
160 return ret; 152 return ret;
161} 153}
162 154
163/*
164 * Atomically modify the effective capabilities returning the original
165 * value. No permission check is performed here - it is assumed that the
166 * caller is permitted to set the desired effective capabilities.
167 */
168kernel_cap_t cap_set_effective(const kernel_cap_t pE_new)
169{
170 kernel_cap_t pE_old;
171
172 spin_lock(&task_capability_lock);
173
174 pE_old = current->cred->cap_effective;
175 current->cred->cap_effective = pE_new;
176
177 spin_unlock(&task_capability_lock);
178
179 return pE_old;
180}
181
182EXPORT_SYMBOL(cap_set_effective);
183
184/** 155/**
185 * sys_capget - get the capabilities of a given process. 156 * sys_capget - get the capabilities of a given process.
186 * @header: pointer to struct that contains capability version and 157 * @header: pointer to struct that contains capability version and
@@ -208,7 +179,6 @@ asmlinkage long sys_capget(cap_user_header_t header, cap_user_data_t dataptr)
208 return -EINVAL; 179 return -EINVAL;
209 180
210 ret = cap_get_target_pid(pid, &pE, &pI, &pP); 181 ret = cap_get_target_pid(pid, &pE, &pI, &pP);
211
212 if (!ret) { 182 if (!ret) {
213 struct __user_cap_data_struct kdata[_KERNEL_CAPABILITY_U32S]; 183 struct __user_cap_data_struct kdata[_KERNEL_CAPABILITY_U32S];
214 unsigned i; 184 unsigned i;
@@ -270,6 +240,7 @@ asmlinkage long sys_capset(cap_user_header_t header, const cap_user_data_t data)
270 struct __user_cap_data_struct kdata[_KERNEL_CAPABILITY_U32S]; 240 struct __user_cap_data_struct kdata[_KERNEL_CAPABILITY_U32S];
271 unsigned i, tocopy; 241 unsigned i, tocopy;
272 kernel_cap_t inheritable, permitted, effective; 242 kernel_cap_t inheritable, permitted, effective;
243 struct cred *new;
273 int ret; 244 int ret;
274 pid_t pid; 245 pid_t pid;
275 246
@@ -284,8 +255,8 @@ asmlinkage long sys_capset(cap_user_header_t header, const cap_user_data_t data)
284 if (pid != 0 && pid != task_pid_vnr(current)) 255 if (pid != 0 && pid != task_pid_vnr(current))
285 return -EPERM; 256 return -EPERM;
286 257
287 if (copy_from_user(&kdata, data, tocopy 258 if (copy_from_user(&kdata, data,
288 * sizeof(struct __user_cap_data_struct))) 259 tocopy * sizeof(struct __user_cap_data_struct)))
289 return -EFAULT; 260 return -EFAULT;
290 261
291 for (i = 0; i < tocopy; i++) { 262 for (i = 0; i < tocopy; i++) {
@@ -300,24 +271,23 @@ asmlinkage long sys_capset(cap_user_header_t header, const cap_user_data_t data)
300 i++; 271 i++;
301 } 272 }
302 273
303 ret = audit_log_capset(pid, &effective, &inheritable, &permitted); 274 new = prepare_creds();
304 if (ret) 275 if (!new)
276 return -ENOMEM;
277
278 ret = security_capset(new, current_cred(),
279 &effective, &inheritable, &permitted);
280 if (ret < 0)
281 goto error;
282
283 ret = audit_log_capset(pid, new, current_cred());
284 if (ret < 0)
305 return ret; 285 return ret;
306 286
307 /* This lock is required even when filesystem capability support is 287 return commit_creds(new);
308 * configured - it protects the sys_capget() call from returning 288
309 * incorrect data in the case that the targeted process is not the 289error:
310 * current one. 290 abort_creds(new);
311 */
312 spin_lock(&task_capability_lock);
313
314 ret = security_capset_check(&effective, &inheritable, &permitted);
315 /* Having verified that the proposed changes are legal, we now put them
316 * into effect.
317 */
318 if (!ret)
319 security_capset_set(&effective, &inheritable, &permitted);
320 spin_unlock(&task_capability_lock);
321 return ret; 291 return ret;
322} 292}
323 293
diff --git a/kernel/cred-internals.h b/kernel/cred-internals.h
new file mode 100644
index 000000000000..2dc4fc2d0bf1
--- /dev/null
+++ b/kernel/cred-internals.h
@@ -0,0 +1,21 @@
1/* Internal credentials stuff
2 *
3 * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11
12/*
13 * user.c
14 */
15static inline void sched_switch_user(struct task_struct *p)
16{
17#ifdef CONFIG_USER_SCHED
18 sched_move_task(p);
19#endif /* CONFIG_USER_SCHED */
20}
21
diff --git a/kernel/cred.c b/kernel/cred.c
index ac73e3617684..cb6b5eda978d 100644
--- a/kernel/cred.c
+++ b/kernel/cred.c
@@ -15,6 +15,10 @@
15#include <linux/keyctl.h> 15#include <linux/keyctl.h>
16#include <linux/init_task.h> 16#include <linux/init_task.h>
17#include <linux/security.h> 17#include <linux/security.h>
18#include <linux/cn_proc.h>
19#include "cred-internals.h"
20
21static struct kmem_cache *cred_jar;
18 22
19/* 23/*
20 * The common credentials for the initial task's thread group 24 * The common credentials for the initial task's thread group
@@ -64,7 +68,7 @@ static void release_tgcred_rcu(struct rcu_head *rcu)
64/* 68/*
65 * Release a set of thread group credentials. 69 * Release a set of thread group credentials.
66 */ 70 */
67static void release_tgcred(struct cred *cred) 71void release_tgcred(struct cred *cred)
68{ 72{
69#ifdef CONFIG_KEYS 73#ifdef CONFIG_KEYS
70 struct thread_group_cred *tgcred = cred->tgcred; 74 struct thread_group_cred *tgcred = cred->tgcred;
@@ -81,79 +85,322 @@ static void put_cred_rcu(struct rcu_head *rcu)
81{ 85{
82 struct cred *cred = container_of(rcu, struct cred, rcu); 86 struct cred *cred = container_of(rcu, struct cred, rcu);
83 87
84 BUG_ON(atomic_read(&cred->usage) != 0); 88 if (atomic_read(&cred->usage) != 0)
89 panic("CRED: put_cred_rcu() sees %p with usage %d\n",
90 cred, atomic_read(&cred->usage));
85 91
92 security_cred_free(cred);
86 key_put(cred->thread_keyring); 93 key_put(cred->thread_keyring);
87 key_put(cred->request_key_auth); 94 key_put(cred->request_key_auth);
88 release_tgcred(cred); 95 release_tgcred(cred);
89 put_group_info(cred->group_info); 96 put_group_info(cred->group_info);
90 free_uid(cred->user); 97 free_uid(cred->user);
91 security_cred_free(cred); 98 kmem_cache_free(cred_jar, cred);
92 kfree(cred);
93} 99}
94 100
95/** 101/**
96 * __put_cred - Destroy a set of credentials 102 * __put_cred - Destroy a set of credentials
97 * @sec: The record to release 103 * @cred: The record to release
98 * 104 *
99 * Destroy a set of credentials on which no references remain. 105 * Destroy a set of credentials on which no references remain.
100 */ 106 */
101void __put_cred(struct cred *cred) 107void __put_cred(struct cred *cred)
102{ 108{
109 BUG_ON(atomic_read(&cred->usage) != 0);
110
103 call_rcu(&cred->rcu, put_cred_rcu); 111 call_rcu(&cred->rcu, put_cred_rcu);
104} 112}
105EXPORT_SYMBOL(__put_cred); 113EXPORT_SYMBOL(__put_cred);
106 114
115/**
116 * prepare_creds - Prepare a new set of credentials for modification
117 *
118 * Prepare a new set of task credentials for modification. A task's creds
119 * shouldn't generally be modified directly, therefore this function is used to
120 * prepare a new copy, which the caller then modifies and then commits by
121 * calling commit_creds().
122 *
123 * Returns a pointer to the new creds-to-be if successful, NULL otherwise.
124 *
125 * Call commit_creds() or abort_creds() to clean up.
126 */
127struct cred *prepare_creds(void)
128{
129 struct task_struct *task = current;
130 const struct cred *old;
131 struct cred *new;
132
133 BUG_ON(atomic_read(&task->cred->usage) < 1);
134
135 new = kmem_cache_alloc(cred_jar, GFP_KERNEL);
136 if (!new)
137 return NULL;
138
139 old = task->cred;
140 memcpy(new, old, sizeof(struct cred));
141
142 atomic_set(&new->usage, 1);
143 get_group_info(new->group_info);
144 get_uid(new->user);
145
146#ifdef CONFIG_KEYS
147 key_get(new->thread_keyring);
148 key_get(new->request_key_auth);
149 atomic_inc(&new->tgcred->usage);
150#endif
151
152#ifdef CONFIG_SECURITY
153 new->security = NULL;
154#endif
155
156 if (security_prepare_creds(new, old, GFP_KERNEL) < 0)
157 goto error;
158 return new;
159
160error:
161 abort_creds(new);
162 return NULL;
163}
164EXPORT_SYMBOL(prepare_creds);
165
166/*
167 * prepare new credentials for the usermode helper dispatcher
168 */
169struct cred *prepare_usermodehelper_creds(void)
170{
171#ifdef CONFIG_KEYS
172 struct thread_group_cred *tgcred = NULL;
173#endif
174 struct cred *new;
175
176#ifdef CONFIG_KEYS
177 tgcred = kzalloc(sizeof(*new->tgcred), GFP_ATOMIC);
178 if (!tgcred)
179 return NULL;
180#endif
181
182 new = kmem_cache_alloc(cred_jar, GFP_ATOMIC);
183 if (!new)
184 return NULL;
185
186 memcpy(new, &init_cred, sizeof(struct cred));
187
188 atomic_set(&new->usage, 1);
189 get_group_info(new->group_info);
190 get_uid(new->user);
191
192#ifdef CONFIG_KEYS
193 new->thread_keyring = NULL;
194 new->request_key_auth = NULL;
195 new->jit_keyring = KEY_REQKEY_DEFL_DEFAULT;
196
197 atomic_set(&tgcred->usage, 1);
198 spin_lock_init(&tgcred->lock);
199 new->tgcred = tgcred;
200#endif
201
202#ifdef CONFIG_SECURITY
203 new->security = NULL;
204#endif
205 if (security_prepare_creds(new, &init_cred, GFP_ATOMIC) < 0)
206 goto error;
207
208 BUG_ON(atomic_read(&new->usage) != 1);
209 return new;
210
211error:
212 put_cred(new);
213 return NULL;
214}
215
107/* 216/*
108 * Copy credentials for the new process created by fork() 217 * Copy credentials for the new process created by fork()
218 *
219 * We share if we can, but under some circumstances we have to generate a new
220 * set.
109 */ 221 */
110int copy_creds(struct task_struct *p, unsigned long clone_flags) 222int copy_creds(struct task_struct *p, unsigned long clone_flags)
111{ 223{
112 struct cred *pcred; 224#ifdef CONFIG_KEYS
113 int ret; 225 struct thread_group_cred *tgcred;
226#endif
227 struct cred *new;
228
229 mutex_init(&p->cred_exec_mutex);
114 230
115 pcred = kmemdup(p->cred, sizeof(*p->cred), GFP_KERNEL); 231 if (
116 if (!pcred) 232#ifdef CONFIG_KEYS
233 !p->cred->thread_keyring &&
234#endif
235 clone_flags & CLONE_THREAD
236 ) {
237 get_cred(p->cred);
238 atomic_inc(&p->cred->user->processes);
239 return 0;
240 }
241
242 new = prepare_creds();
243 if (!new)
117 return -ENOMEM; 244 return -ENOMEM;
118 245
119#ifdef CONFIG_KEYS 246#ifdef CONFIG_KEYS
120 if (clone_flags & CLONE_THREAD) { 247 /* new threads get their own thread keyrings if their parent already
121 atomic_inc(&pcred->tgcred->usage); 248 * had one */
122 } else { 249 if (new->thread_keyring) {
123 pcred->tgcred = kmalloc(sizeof(struct cred), GFP_KERNEL); 250 key_put(new->thread_keyring);
124 if (!pcred->tgcred) { 251 new->thread_keyring = NULL;
125 kfree(pcred); 252 if (clone_flags & CLONE_THREAD)
253 install_thread_keyring_to_cred(new);
254 }
255
256 /* we share the process and session keyrings between all the threads in
257 * a process - this is slightly icky as we violate COW credentials a
258 * bit */
259 if (!(clone_flags & CLONE_THREAD)) {
260 tgcred = kmalloc(sizeof(*tgcred), GFP_KERNEL);
261 if (!tgcred) {
262 put_cred(new);
126 return -ENOMEM; 263 return -ENOMEM;
127 } 264 }
128 atomic_set(&pcred->tgcred->usage, 1); 265 atomic_set(&tgcred->usage, 1);
129 spin_lock_init(&pcred->tgcred->lock); 266 spin_lock_init(&tgcred->lock);
130 pcred->tgcred->process_keyring = NULL; 267 tgcred->process_keyring = NULL;
131 pcred->tgcred->session_keyring = 268 tgcred->session_keyring = key_get(new->tgcred->session_keyring);
132 key_get(p->cred->tgcred->session_keyring); 269
270 release_tgcred(new);
271 new->tgcred = tgcred;
133 } 272 }
134#endif 273#endif
135 274
136#ifdef CONFIG_SECURITY 275 atomic_inc(&new->user->processes);
137 pcred->security = NULL; 276 p->cred = new;
138#endif 277 return 0;
278}
139 279
140 ret = security_cred_alloc(pcred); 280/**
141 if (ret < 0) { 281 * commit_creds - Install new credentials upon the current task
142 release_tgcred(pcred); 282 * @new: The credentials to be assigned
143 kfree(pcred); 283 *
144 return ret; 284 * Install a new set of credentials to the current task, using RCU to replace
285 * the old set.
286 *
287 * This function eats the caller's reference to the new credentials.
288 *
289 * Always returns 0 thus allowing this function to be tail-called at the end
290 * of, say, sys_setgid().
291 */
292int commit_creds(struct cred *new)
293{
294 struct task_struct *task = current;
295 const struct cred *old;
296
297 BUG_ON(atomic_read(&new->usage) < 1);
298 BUG_ON(atomic_read(&task->cred->usage) < 1);
299
300 old = task->cred;
301 security_commit_creds(new, old);
302
303 /* dumpability changes */
304 if (old->euid != new->euid ||
305 old->egid != new->egid ||
306 old->fsuid != new->fsuid ||
307 old->fsgid != new->fsgid ||
308 !cap_issubset(new->cap_permitted, old->cap_permitted)) {
309 set_dumpable(task->mm, suid_dumpable);
310 task->pdeath_signal = 0;
311 smp_wmb();
145 } 312 }
146 313
147 atomic_set(&pcred->usage, 1); 314 /* alter the thread keyring */
148 get_group_info(pcred->group_info); 315 if (new->fsuid != old->fsuid)
149 get_uid(pcred->user); 316 key_fsuid_changed(task);
150 key_get(pcred->thread_keyring); 317 if (new->fsgid != old->fsgid)
151 key_get(pcred->request_key_auth); 318 key_fsgid_changed(task);
319
320 /* do it
321 * - What if a process setreuid()'s and this brings the
322 * new uid over his NPROC rlimit? We can check this now
323 * cheaply with the new uid cache, so if it matters
324 * we should be checking for it. -DaveM
325 */
326 if (new->user != old->user)
327 atomic_inc(&new->user->processes);
328 rcu_assign_pointer(task->cred, new);
329 if (new->user != old->user)
330 atomic_dec(&old->user->processes);
331
332 sched_switch_user(task);
333
334 /* send notifications */
335 if (new->uid != old->uid ||
336 new->euid != old->euid ||
337 new->suid != old->suid ||
338 new->fsuid != old->fsuid)
339 proc_id_connector(task, PROC_EVENT_UID);
152 340
153 atomic_inc(&pcred->user->processes); 341 if (new->gid != old->gid ||
342 new->egid != old->egid ||
343 new->sgid != old->sgid ||
344 new->fsgid != old->fsgid)
345 proc_id_connector(task, PROC_EVENT_GID);
154 346
155 /* RCU assignment is unneeded here as no-one can have accessed this 347 put_cred(old);
156 * pointer yet, barring us */
157 p->cred = pcred;
158 return 0; 348 return 0;
159} 349}
350EXPORT_SYMBOL(commit_creds);
351
352/**
353 * abort_creds - Discard a set of credentials and unlock the current task
354 * @new: The credentials that were going to be applied
355 *
356 * Discard a set of credentials that were under construction and unlock the
357 * current task.
358 */
359void abort_creds(struct cred *new)
360{
361 BUG_ON(atomic_read(&new->usage) < 1);
362 put_cred(new);
363}
364EXPORT_SYMBOL(abort_creds);
365
366/**
367 * override_creds - Temporarily override the current process's credentials
368 * @new: The credentials to be assigned
369 *
370 * Install a set of temporary override credentials on the current process,
371 * returning the old set for later reversion.
372 */
373const struct cred *override_creds(const struct cred *new)
374{
375 const struct cred *old = current->cred;
376
377 rcu_assign_pointer(current->cred, get_cred(new));
378 return old;
379}
380EXPORT_SYMBOL(override_creds);
381
382/**
383 * revert_creds - Revert a temporary credentials override
384 * @old: The credentials to be restored
385 *
386 * Revert a temporary set of override credentials to an old set, discarding the
387 * override set.
388 */
389void revert_creds(const struct cred *old)
390{
391 const struct cred *override = current->cred;
392
393 rcu_assign_pointer(current->cred, old);
394 put_cred(override);
395}
396EXPORT_SYMBOL(revert_creds);
397
398/*
399 * initialise the credentials stuff
400 */
401void __init cred_init(void)
402{
403 /* allocate a slab in which we can store credentials */
404 cred_jar = kmem_cache_create("cred_jar", sizeof(struct cred),
405 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
406}
diff --git a/kernel/exit.c b/kernel/exit.c
index bbc22530f2c1..c0711da15486 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -47,12 +47,14 @@
47#include <linux/blkdev.h> 47#include <linux/blkdev.h>
48#include <linux/task_io_accounting_ops.h> 48#include <linux/task_io_accounting_ops.h>
49#include <linux/tracehook.h> 49#include <linux/tracehook.h>
50#include <linux/init_task.h>
50#include <trace/sched.h> 51#include <trace/sched.h>
51 52
52#include <asm/uaccess.h> 53#include <asm/uaccess.h>
53#include <asm/unistd.h> 54#include <asm/unistd.h>
54#include <asm/pgtable.h> 55#include <asm/pgtable.h>
55#include <asm/mmu_context.h> 56#include <asm/mmu_context.h>
57#include "cred-internals.h"
56 58
57static void exit_mm(struct task_struct * tsk); 59static void exit_mm(struct task_struct * tsk);
58 60
@@ -338,12 +340,12 @@ static void reparent_to_kthreadd(void)
338 /* cpus_allowed? */ 340 /* cpus_allowed? */
339 /* rt_priority? */ 341 /* rt_priority? */
340 /* signals? */ 342 /* signals? */
341 security_task_reparent_to_init(current);
342 memcpy(current->signal->rlim, init_task.signal->rlim, 343 memcpy(current->signal->rlim, init_task.signal->rlim,
343 sizeof(current->signal->rlim)); 344 sizeof(current->signal->rlim));
344 atomic_inc(&(INIT_USER->__count)); 345
346 atomic_inc(&init_cred.usage);
347 commit_creds(&init_cred);
345 write_unlock_irq(&tasklist_lock); 348 write_unlock_irq(&tasklist_lock);
346 switch_uid(INIT_USER);
347} 349}
348 350
349void __set_special_pids(struct pid *pid) 351void __set_special_pids(struct pid *pid)
@@ -1085,7 +1087,6 @@ NORET_TYPE void do_exit(long code)
1085 check_stack_usage(); 1087 check_stack_usage();
1086 exit_thread(); 1088 exit_thread();
1087 cgroup_exit(tsk, 1); 1089 cgroup_exit(tsk, 1);
1088 exit_keys(tsk);
1089 1090
1090 if (group_dead && tsk->signal->leader) 1091 if (group_dead && tsk->signal->leader)
1091 disassociate_ctty(1); 1092 disassociate_ctty(1);
diff --git a/kernel/fork.c b/kernel/fork.c
index ded1972672a3..82a7948a664e 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1084,10 +1084,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1084 goto bad_fork_cleanup_sighand; 1084 goto bad_fork_cleanup_sighand;
1085 if ((retval = copy_mm(clone_flags, p))) 1085 if ((retval = copy_mm(clone_flags, p)))
1086 goto bad_fork_cleanup_signal; 1086 goto bad_fork_cleanup_signal;
1087 if ((retval = copy_keys(clone_flags, p)))
1088 goto bad_fork_cleanup_mm;
1089 if ((retval = copy_namespaces(clone_flags, p))) 1087 if ((retval = copy_namespaces(clone_flags, p)))
1090 goto bad_fork_cleanup_keys; 1088 goto bad_fork_cleanup_mm;
1091 if ((retval = copy_io(clone_flags, p))) 1089 if ((retval = copy_io(clone_flags, p)))
1092 goto bad_fork_cleanup_namespaces; 1090 goto bad_fork_cleanup_namespaces;
1093 retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs); 1091 retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);
@@ -1252,8 +1250,6 @@ bad_fork_cleanup_io:
1252 put_io_context(p->io_context); 1250 put_io_context(p->io_context);
1253bad_fork_cleanup_namespaces: 1251bad_fork_cleanup_namespaces:
1254 exit_task_namespaces(p); 1252 exit_task_namespaces(p);
1255bad_fork_cleanup_keys:
1256 exit_keys(p);
1257bad_fork_cleanup_mm: 1253bad_fork_cleanup_mm:
1258 if (p->mm) 1254 if (p->mm)
1259 mmput(p->mm); 1255 mmput(p->mm);
@@ -1281,6 +1277,7 @@ bad_fork_cleanup_cgroup:
1281bad_fork_cleanup_put_domain: 1277bad_fork_cleanup_put_domain:
1282 module_put(task_thread_info(p)->exec_domain->module); 1278 module_put(task_thread_info(p)->exec_domain->module);
1283bad_fork_cleanup_count: 1279bad_fork_cleanup_count:
1280 atomic_dec(&p->cred->user->processes);
1284 put_cred(p->cred); 1281 put_cred(p->cred);
1285bad_fork_free: 1282bad_fork_free:
1286 free_task(p); 1283 free_task(p);
diff --git a/kernel/kmod.c b/kernel/kmod.c
index f044f8f57703..b46dbb908669 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -118,10 +118,10 @@ EXPORT_SYMBOL(request_module);
118struct subprocess_info { 118struct subprocess_info {
119 struct work_struct work; 119 struct work_struct work;
120 struct completion *complete; 120 struct completion *complete;
121 struct cred *cred;
121 char *path; 122 char *path;
122 char **argv; 123 char **argv;
123 char **envp; 124 char **envp;
124 struct key *ring;
125 enum umh_wait wait; 125 enum umh_wait wait;
126 int retval; 126 int retval;
127 struct file *stdin; 127 struct file *stdin;
@@ -134,19 +134,20 @@ struct subprocess_info {
134static int ____call_usermodehelper(void *data) 134static int ____call_usermodehelper(void *data)
135{ 135{
136 struct subprocess_info *sub_info = data; 136 struct subprocess_info *sub_info = data;
137 struct key *new_session, *old_session;
138 int retval; 137 int retval;
139 138
140 /* Unblock all signals and set the session keyring. */ 139 BUG_ON(atomic_read(&sub_info->cred->usage) != 1);
141 new_session = key_get(sub_info->ring); 140
141 /* Unblock all signals */
142 spin_lock_irq(&current->sighand->siglock); 142 spin_lock_irq(&current->sighand->siglock);
143 old_session = __install_session_keyring(new_session);
144 flush_signal_handlers(current, 1); 143 flush_signal_handlers(current, 1);
145 sigemptyset(&current->blocked); 144 sigemptyset(&current->blocked);
146 recalc_sigpending(); 145 recalc_sigpending();
147 spin_unlock_irq(&current->sighand->siglock); 146 spin_unlock_irq(&current->sighand->siglock);
148 147
149 key_put(old_session); 148 /* Install the credentials */
149 commit_creds(sub_info->cred);
150 sub_info->cred = NULL;
150 151
151 /* Install input pipe when needed */ 152 /* Install input pipe when needed */
152 if (sub_info->stdin) { 153 if (sub_info->stdin) {
@@ -185,6 +186,8 @@ void call_usermodehelper_freeinfo(struct subprocess_info *info)
185{ 186{
186 if (info->cleanup) 187 if (info->cleanup)
187 (*info->cleanup)(info->argv, info->envp); 188 (*info->cleanup)(info->argv, info->envp);
189 if (info->cred)
190 put_cred(info->cred);
188 kfree(info); 191 kfree(info);
189} 192}
190EXPORT_SYMBOL(call_usermodehelper_freeinfo); 193EXPORT_SYMBOL(call_usermodehelper_freeinfo);
@@ -240,6 +243,8 @@ static void __call_usermodehelper(struct work_struct *work)
240 pid_t pid; 243 pid_t pid;
241 enum umh_wait wait = sub_info->wait; 244 enum umh_wait wait = sub_info->wait;
242 245
246 BUG_ON(atomic_read(&sub_info->cred->usage) != 1);
247
243 /* CLONE_VFORK: wait until the usermode helper has execve'd 248 /* CLONE_VFORK: wait until the usermode helper has execve'd
244 * successfully We need the data structures to stay around 249 * successfully We need the data structures to stay around
245 * until that is done. */ 250 * until that is done. */
@@ -362,6 +367,9 @@ struct subprocess_info *call_usermodehelper_setup(char *path, char **argv,
362 sub_info->path = path; 367 sub_info->path = path;
363 sub_info->argv = argv; 368 sub_info->argv = argv;
364 sub_info->envp = envp; 369 sub_info->envp = envp;
370 sub_info->cred = prepare_usermodehelper_creds();
371 if (!sub_info->cred)
372 return NULL;
365 373
366 out: 374 out:
367 return sub_info; 375 return sub_info;
@@ -376,7 +384,13 @@ EXPORT_SYMBOL(call_usermodehelper_setup);
376void call_usermodehelper_setkeys(struct subprocess_info *info, 384void call_usermodehelper_setkeys(struct subprocess_info *info,
377 struct key *session_keyring) 385 struct key *session_keyring)
378{ 386{
379 info->ring = session_keyring; 387#ifdef CONFIG_KEYS
388 struct thread_group_cred *tgcred = info->cred->tgcred;
389 key_put(tgcred->session_keyring);
390 tgcred->session_keyring = key_get(session_keyring);
391#else
392 BUG();
393#endif
380} 394}
381EXPORT_SYMBOL(call_usermodehelper_setkeys); 395EXPORT_SYMBOL(call_usermodehelper_setkeys);
382 396
@@ -444,6 +458,8 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info,
444 DECLARE_COMPLETION_ONSTACK(done); 458 DECLARE_COMPLETION_ONSTACK(done);
445 int retval = 0; 459 int retval = 0;
446 460
461 BUG_ON(atomic_read(&sub_info->cred->usage) != 1);
462
447 helper_lock(); 463 helper_lock();
448 if (sub_info->path[0] == '\0') 464 if (sub_info->path[0] == '\0')
449 goto out; 465 goto out;
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index b9d5f4e4f6a4..f764b8806955 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -171,6 +171,14 @@ int ptrace_attach(struct task_struct *task)
171 if (same_thread_group(task, current)) 171 if (same_thread_group(task, current))
172 goto out; 172 goto out;
173 173
174 /* Protect exec's credential calculations against our interference;
175 * SUID, SGID and LSM creds get determined differently under ptrace.
176 */
177 retval = mutex_lock_interruptible(&current->cred_exec_mutex);
178 if (retval < 0)
179 goto out;
180
181 retval = -EPERM;
174repeat: 182repeat:
175 /* 183 /*
176 * Nasty, nasty. 184 * Nasty, nasty.
@@ -210,6 +218,7 @@ repeat:
210bad: 218bad:
211 write_unlock_irqrestore(&tasklist_lock, flags); 219 write_unlock_irqrestore(&tasklist_lock, flags);
212 task_unlock(task); 220 task_unlock(task);
221 mutex_unlock(&current->cred_exec_mutex);
213out: 222out:
214 return retval; 223 return retval;
215} 224}
diff --git a/kernel/signal.c b/kernel/signal.c
index 84989124bafb..2a64304ed54b 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -180,7 +180,7 @@ int next_signal(struct sigpending *pending, sigset_t *mask)
180/* 180/*
181 * allocate a new signal queue record 181 * allocate a new signal queue record
182 * - this may be called without locks if and only if t == current, otherwise an 182 * - this may be called without locks if and only if t == current, otherwise an
183 * appopriate lock must be held to protect t's user_struct 183 * appopriate lock must be held to stop the target task from exiting
184 */ 184 */
185static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags, 185static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags,
186 int override_rlimit) 186 int override_rlimit)
@@ -194,7 +194,7 @@ static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags,
194 * caller must be holding the RCU readlock (by way of a spinlock) and 194 * caller must be holding the RCU readlock (by way of a spinlock) and
195 * we use RCU protection here 195 * we use RCU protection here
196 */ 196 */
197 user = __task_cred(t)->user; 197 user = get_uid(__task_cred(t)->user);
198 atomic_inc(&user->sigpending); 198 atomic_inc(&user->sigpending);
199 if (override_rlimit || 199 if (override_rlimit ||
200 atomic_read(&user->sigpending) <= 200 atomic_read(&user->sigpending) <=
@@ -202,12 +202,14 @@ static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags,
202 q = kmem_cache_alloc(sigqueue_cachep, flags); 202 q = kmem_cache_alloc(sigqueue_cachep, flags);
203 if (unlikely(q == NULL)) { 203 if (unlikely(q == NULL)) {
204 atomic_dec(&user->sigpending); 204 atomic_dec(&user->sigpending);
205 free_uid(user);
205 } else { 206 } else {
206 INIT_LIST_HEAD(&q->list); 207 INIT_LIST_HEAD(&q->list);
207 q->flags = 0; 208 q->flags = 0;
208 q->user = get_uid(user); 209 q->user = user;
209 } 210 }
210 return(q); 211
212 return q;
211} 213}
212 214
213static void __sigqueue_free(struct sigqueue *q) 215static void __sigqueue_free(struct sigqueue *q)
diff --git a/kernel/sys.c b/kernel/sys.c
index ccc9eb736d35..ab735040468a 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -180,7 +180,7 @@ asmlinkage long sys_setpriority(int which, int who, int niceval)
180 } while_each_pid_thread(pgrp, PIDTYPE_PGID, p); 180 } while_each_pid_thread(pgrp, PIDTYPE_PGID, p);
181 break; 181 break;
182 case PRIO_USER: 182 case PRIO_USER:
183 user = cred->user; 183 user = (struct user_struct *) cred->user;
184 if (!who) 184 if (!who)
185 who = cred->uid; 185 who = cred->uid;
186 else if ((who != cred->uid) && 186 else if ((who != cred->uid) &&
@@ -479,47 +479,48 @@ void ctrl_alt_del(void)
479 */ 479 */
480asmlinkage long sys_setregid(gid_t rgid, gid_t egid) 480asmlinkage long sys_setregid(gid_t rgid, gid_t egid)
481{ 481{
482 struct cred *cred = current->cred; 482 const struct cred *old;
483 int old_rgid = cred->gid; 483 struct cred *new;
484 int old_egid = cred->egid;
485 int new_rgid = old_rgid;
486 int new_egid = old_egid;
487 int retval; 484 int retval;
488 485
486 new = prepare_creds();
487 if (!new)
488 return -ENOMEM;
489 old = current_cred();
490
489 retval = security_task_setgid(rgid, egid, (gid_t)-1, LSM_SETID_RE); 491 retval = security_task_setgid(rgid, egid, (gid_t)-1, LSM_SETID_RE);
490 if (retval) 492 if (retval)
491 return retval; 493 goto error;
492 494
495 retval = -EPERM;
493 if (rgid != (gid_t) -1) { 496 if (rgid != (gid_t) -1) {
494 if ((old_rgid == rgid) || 497 if (old->gid == rgid ||
495 (cred->egid == rgid) || 498 old->egid == rgid ||
496 capable(CAP_SETGID)) 499 capable(CAP_SETGID))
497 new_rgid = rgid; 500 new->gid = rgid;
498 else 501 else
499 return -EPERM; 502 goto error;
500 } 503 }
501 if (egid != (gid_t) -1) { 504 if (egid != (gid_t) -1) {
502 if ((old_rgid == egid) || 505 if (old->gid == egid ||
503 (cred->egid == egid) || 506 old->egid == egid ||
504 (cred->sgid == egid) || 507 old->sgid == egid ||
505 capable(CAP_SETGID)) 508 capable(CAP_SETGID))
506 new_egid = egid; 509 new->egid = egid;
507 else 510 else
508 return -EPERM; 511 goto error;
509 }
510 if (new_egid != old_egid) {
511 set_dumpable(current->mm, suid_dumpable);
512 smp_wmb();
513 } 512 }
513
514 if (rgid != (gid_t) -1 || 514 if (rgid != (gid_t) -1 ||
515 (egid != (gid_t) -1 && egid != old_rgid)) 515 (egid != (gid_t) -1 && egid != old->gid))
516 cred->sgid = new_egid; 516 new->sgid = new->egid;
517 cred->fsgid = new_egid; 517 new->fsgid = new->egid;
518 cred->egid = new_egid; 518
519 cred->gid = new_rgid; 519 return commit_creds(new);
520 key_fsgid_changed(current); 520
521 proc_id_connector(current, PROC_EVENT_GID); 521error:
522 return 0; 522 abort_creds(new);
523 return retval;
523} 524}
524 525
525/* 526/*
@@ -529,40 +530,42 @@ asmlinkage long sys_setregid(gid_t rgid, gid_t egid)
529 */ 530 */
530asmlinkage long sys_setgid(gid_t gid) 531asmlinkage long sys_setgid(gid_t gid)
531{ 532{
532 struct cred *cred = current->cred; 533 const struct cred *old;
533 int old_egid = cred->egid; 534 struct cred *new;
534 int retval; 535 int retval;
535 536
537 new = prepare_creds();
538 if (!new)
539 return -ENOMEM;
540 old = current_cred();
541
536 retval = security_task_setgid(gid, (gid_t)-1, (gid_t)-1, LSM_SETID_ID); 542 retval = security_task_setgid(gid, (gid_t)-1, (gid_t)-1, LSM_SETID_ID);
537 if (retval) 543 if (retval)
538 return retval; 544 goto error;
539 545
540 if (capable(CAP_SETGID)) { 546 retval = -EPERM;
541 if (old_egid != gid) { 547 if (capable(CAP_SETGID))
542 set_dumpable(current->mm, suid_dumpable); 548 new->gid = new->egid = new->sgid = new->fsgid = gid;
543 smp_wmb(); 549 else if (gid == old->gid || gid == old->sgid)
544 } 550 new->egid = new->fsgid = gid;
545 cred->gid = cred->egid = cred->sgid = cred->fsgid = gid;
546 } else if ((gid == cred->gid) || (gid == cred->sgid)) {
547 if (old_egid != gid) {
548 set_dumpable(current->mm, suid_dumpable);
549 smp_wmb();
550 }
551 cred->egid = cred->fsgid = gid;
552 }
553 else 551 else
554 return -EPERM; 552 goto error;
555 553
556 key_fsgid_changed(current); 554 return commit_creds(new);
557 proc_id_connector(current, PROC_EVENT_GID); 555
558 return 0; 556error:
557 abort_creds(new);
558 return retval;
559} 559}
560 560
561static int set_user(uid_t new_ruid, int dumpclear) 561/*
562 * change the user struct in a credentials set to match the new UID
563 */
564static int set_user(struct cred *new)
562{ 565{
563 struct user_struct *new_user; 566 struct user_struct *new_user;
564 567
565 new_user = alloc_uid(current->nsproxy->user_ns, new_ruid); 568 new_user = alloc_uid(current->nsproxy->user_ns, new->uid);
566 if (!new_user) 569 if (!new_user)
567 return -EAGAIN; 570 return -EAGAIN;
568 571
@@ -573,13 +576,8 @@ static int set_user(uid_t new_ruid, int dumpclear)
573 return -EAGAIN; 576 return -EAGAIN;
574 } 577 }
575 578
576 switch_uid(new_user); 579 free_uid(new->user);
577 580 new->user = new_user;
578 if (dumpclear) {
579 set_dumpable(current->mm, suid_dumpable);
580 smp_wmb();
581 }
582 current->cred->uid = new_ruid;
583 return 0; 581 return 0;
584} 582}
585 583
@@ -600,55 +598,56 @@ static int set_user(uid_t new_ruid, int dumpclear)
600 */ 598 */
601asmlinkage long sys_setreuid(uid_t ruid, uid_t euid) 599asmlinkage long sys_setreuid(uid_t ruid, uid_t euid)
602{ 600{
603 struct cred *cred = current->cred; 601 const struct cred *old;
604 int old_ruid, old_euid, old_suid, new_ruid, new_euid; 602 struct cred *new;
605 int retval; 603 int retval;
606 604
605 new = prepare_creds();
606 if (!new)
607 return -ENOMEM;
608 old = current_cred();
609
607 retval = security_task_setuid(ruid, euid, (uid_t)-1, LSM_SETID_RE); 610 retval = security_task_setuid(ruid, euid, (uid_t)-1, LSM_SETID_RE);
608 if (retval) 611 if (retval)
609 return retval; 612 goto error;
610
611 new_ruid = old_ruid = cred->uid;
612 new_euid = old_euid = cred->euid;
613 old_suid = cred->suid;
614 613
614 retval = -EPERM;
615 if (ruid != (uid_t) -1) { 615 if (ruid != (uid_t) -1) {
616 new_ruid = ruid; 616 new->uid = ruid;
617 if ((old_ruid != ruid) && 617 if (old->uid != ruid &&
618 (cred->euid != ruid) && 618 old->euid != ruid &&
619 !capable(CAP_SETUID)) 619 !capable(CAP_SETUID))
620 return -EPERM; 620 goto error;
621 } 621 }
622 622
623 if (euid != (uid_t) -1) { 623 if (euid != (uid_t) -1) {
624 new_euid = euid; 624 new->euid = euid;
625 if ((old_ruid != euid) && 625 if (old->uid != euid &&
626 (cred->euid != euid) && 626 old->euid != euid &&
627 (cred->suid != euid) && 627 old->suid != euid &&
628 !capable(CAP_SETUID)) 628 !capable(CAP_SETUID))
629 return -EPERM; 629 goto error;
630 } 630 }
631 631
632 if (new_ruid != old_ruid && set_user(new_ruid, new_euid != old_euid) < 0) 632 retval = -EAGAIN;
633 return -EAGAIN; 633 if (new->uid != old->uid && set_user(new) < 0)
634 goto error;
634 635
635 if (new_euid != old_euid) {
636 set_dumpable(current->mm, suid_dumpable);
637 smp_wmb();
638 }
639 cred->fsuid = cred->euid = new_euid;
640 if (ruid != (uid_t) -1 || 636 if (ruid != (uid_t) -1 ||
641 (euid != (uid_t) -1 && euid != old_ruid)) 637 (euid != (uid_t) -1 && euid != old->uid))
642 cred->suid = cred->euid; 638 new->suid = new->euid;
643 cred->fsuid = cred->euid; 639 new->fsuid = new->euid;
644
645 key_fsuid_changed(current);
646 proc_id_connector(current, PROC_EVENT_UID);
647 640
648 return security_task_post_setuid(old_ruid, old_euid, old_suid, LSM_SETID_RE); 641 retval = security_task_fix_setuid(new, old, LSM_SETID_RE);
649} 642 if (retval < 0)
643 goto error;
650 644
645 return commit_creds(new);
651 646
647error:
648 abort_creds(new);
649 return retval;
650}
652 651
653/* 652/*
654 * setuid() is implemented like SysV with SAVED_IDS 653 * setuid() is implemented like SysV with SAVED_IDS
@@ -663,37 +662,41 @@ asmlinkage long sys_setreuid(uid_t ruid, uid_t euid)
663 */ 662 */
664asmlinkage long sys_setuid(uid_t uid) 663asmlinkage long sys_setuid(uid_t uid)
665{ 664{
666 struct cred *cred = current->cred; 665 const struct cred *old;
667 int old_euid = cred->euid; 666 struct cred *new;
668 int old_ruid, old_suid, new_suid;
669 int retval; 667 int retval;
670 668
669 new = prepare_creds();
670 if (!new)
671 return -ENOMEM;
672 old = current_cred();
673
671 retval = security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_ID); 674 retval = security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_ID);
672 if (retval) 675 if (retval)
673 return retval; 676 goto error;
674 677
675 old_ruid = cred->uid; 678 retval = -EPERM;
676 old_suid = cred->suid;
677 new_suid = old_suid;
678
679 if (capable(CAP_SETUID)) { 679 if (capable(CAP_SETUID)) {
680 if (uid != old_ruid && set_user(uid, old_euid != uid) < 0) 680 new->suid = new->uid = uid;
681 return -EAGAIN; 681 if (uid != old->uid && set_user(new) < 0) {
682 new_suid = uid; 682 retval = -EAGAIN;
683 } else if ((uid != cred->uid) && (uid != new_suid)) 683 goto error;
684 return -EPERM; 684 }
685 685 } else if (uid != old->uid && uid != new->suid) {
686 if (old_euid != uid) { 686 goto error;
687 set_dumpable(current->mm, suid_dumpable);
688 smp_wmb();
689 } 687 }
690 cred->fsuid = cred->euid = uid;
691 cred->suid = new_suid;
692 688
693 key_fsuid_changed(current); 689 new->fsuid = new->euid = uid;
694 proc_id_connector(current, PROC_EVENT_UID); 690
691 retval = security_task_fix_setuid(new, old, LSM_SETID_ID);
692 if (retval < 0)
693 goto error;
694
695 return commit_creds(new);
695 696
696 return security_task_post_setuid(old_ruid, old_euid, old_suid, LSM_SETID_ID); 697error:
698 abort_creds(new);
699 return retval;
697} 700}
698 701
699 702
@@ -703,47 +706,53 @@ asmlinkage long sys_setuid(uid_t uid)
703 */ 706 */
704asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid) 707asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
705{ 708{
706 struct cred *cred = current->cred; 709 const struct cred *old;
707 int old_ruid = cred->uid; 710 struct cred *new;
708 int old_euid = cred->euid;
709 int old_suid = cred->suid;
710 int retval; 711 int retval;
711 712
713 new = prepare_creds();
714 if (!new)
715 return -ENOMEM;
716
712 retval = security_task_setuid(ruid, euid, suid, LSM_SETID_RES); 717 retval = security_task_setuid(ruid, euid, suid, LSM_SETID_RES);
713 if (retval) 718 if (retval)
714 return retval; 719 goto error;
720 old = current_cred();
715 721
722 retval = -EPERM;
716 if (!capable(CAP_SETUID)) { 723 if (!capable(CAP_SETUID)) {
717 if ((ruid != (uid_t) -1) && (ruid != cred->uid) && 724 if (ruid != (uid_t) -1 && ruid != old->uid &&
718 (ruid != cred->euid) && (ruid != cred->suid)) 725 ruid != old->euid && ruid != old->suid)
719 return -EPERM; 726 goto error;
720 if ((euid != (uid_t) -1) && (euid != cred->uid) && 727 if (euid != (uid_t) -1 && euid != old->uid &&
721 (euid != cred->euid) && (euid != cred->suid)) 728 euid != old->euid && euid != old->suid)
722 return -EPERM; 729 goto error;
723 if ((suid != (uid_t) -1) && (suid != cred->uid) && 730 if (suid != (uid_t) -1 && suid != old->uid &&
724 (suid != cred->euid) && (suid != cred->suid)) 731 suid != old->euid && suid != old->suid)
725 return -EPERM; 732 goto error;
726 } 733 }
734
735 retval = -EAGAIN;
727 if (ruid != (uid_t) -1) { 736 if (ruid != (uid_t) -1) {
728 if (ruid != cred->uid && 737 new->uid = ruid;
729 set_user(ruid, euid != cred->euid) < 0) 738 if (ruid != old->uid && set_user(new) < 0)
730 return -EAGAIN; 739 goto error;
731 } 740 }
732 if (euid != (uid_t) -1) { 741 if (euid != (uid_t) -1)
733 if (euid != cred->euid) { 742 new->euid = euid;
734 set_dumpable(current->mm, suid_dumpable);
735 smp_wmb();
736 }
737 cred->euid = euid;
738 }
739 cred->fsuid = cred->euid;
740 if (suid != (uid_t) -1) 743 if (suid != (uid_t) -1)
741 cred->suid = suid; 744 new->suid = suid;
745 new->fsuid = new->euid;
742 746
743 key_fsuid_changed(current); 747 retval = security_task_fix_setuid(new, old, LSM_SETID_RES);
744 proc_id_connector(current, PROC_EVENT_UID); 748 if (retval < 0)
749 goto error;
745 750
746 return security_task_post_setuid(old_ruid, old_euid, old_suid, LSM_SETID_RES); 751 return commit_creds(new);
752
753error:
754 abort_creds(new);
755 return retval;
747} 756}
748 757
749asmlinkage long sys_getresuid(uid_t __user *ruid, uid_t __user *euid, uid_t __user *suid) 758asmlinkage long sys_getresuid(uid_t __user *ruid, uid_t __user *euid, uid_t __user *suid)
@@ -763,40 +772,45 @@ asmlinkage long sys_getresuid(uid_t __user *ruid, uid_t __user *euid, uid_t __us
763 */ 772 */
764asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid) 773asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
765{ 774{
766 struct cred *cred = current->cred; 775 const struct cred *old;
776 struct cred *new;
767 int retval; 777 int retval;
768 778
779 new = prepare_creds();
780 if (!new)
781 return -ENOMEM;
782 old = current_cred();
783
769 retval = security_task_setgid(rgid, egid, sgid, LSM_SETID_RES); 784 retval = security_task_setgid(rgid, egid, sgid, LSM_SETID_RES);
770 if (retval) 785 if (retval)
771 return retval; 786 goto error;
772 787
788 retval = -EPERM;
773 if (!capable(CAP_SETGID)) { 789 if (!capable(CAP_SETGID)) {
774 if ((rgid != (gid_t) -1) && (rgid != cred->gid) && 790 if (rgid != (gid_t) -1 && rgid != old->gid &&
775 (rgid != cred->egid) && (rgid != cred->sgid)) 791 rgid != old->egid && rgid != old->sgid)
776 return -EPERM; 792 goto error;
777 if ((egid != (gid_t) -1) && (egid != cred->gid) && 793 if (egid != (gid_t) -1 && egid != old->gid &&
778 (egid != cred->egid) && (egid != cred->sgid)) 794 egid != old->egid && egid != old->sgid)
779 return -EPERM; 795 goto error;
780 if ((sgid != (gid_t) -1) && (sgid != cred->gid) && 796 if (sgid != (gid_t) -1 && sgid != old->gid &&
781 (sgid != cred->egid) && (sgid != cred->sgid)) 797 sgid != old->egid && sgid != old->sgid)
782 return -EPERM; 798 goto error;
783 } 799 }
784 if (egid != (gid_t) -1) { 800
785 if (egid != cred->egid) {
786 set_dumpable(current->mm, suid_dumpable);
787 smp_wmb();
788 }
789 cred->egid = egid;
790 }
791 cred->fsgid = cred->egid;
792 if (rgid != (gid_t) -1) 801 if (rgid != (gid_t) -1)
793 cred->gid = rgid; 802 new->gid = rgid;
803 if (egid != (gid_t) -1)
804 new->egid = egid;
794 if (sgid != (gid_t) -1) 805 if (sgid != (gid_t) -1)
795 cred->sgid = sgid; 806 new->sgid = sgid;
807 new->fsgid = new->egid;
796 808
797 key_fsgid_changed(current); 809 return commit_creds(new);
798 proc_id_connector(current, PROC_EVENT_GID); 810
799 return 0; 811error:
812 abort_creds(new);
813 return retval;
800} 814}
801 815
802asmlinkage long sys_getresgid(gid_t __user *rgid, gid_t __user *egid, gid_t __user *sgid) 816asmlinkage long sys_getresgid(gid_t __user *rgid, gid_t __user *egid, gid_t __user *sgid)
@@ -820,28 +834,35 @@ asmlinkage long sys_getresgid(gid_t __user *rgid, gid_t __user *egid, gid_t __us
820 */ 834 */
821asmlinkage long sys_setfsuid(uid_t uid) 835asmlinkage long sys_setfsuid(uid_t uid)
822{ 836{
823 struct cred *cred = current->cred; 837 const struct cred *old;
824 int old_fsuid; 838 struct cred *new;
839 uid_t old_fsuid;
840
841 new = prepare_creds();
842 if (!new)
843 return current_fsuid();
844 old = current_cred();
845 old_fsuid = old->fsuid;
825 846
826 old_fsuid = cred->fsuid; 847 if (security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS) < 0)
827 if (security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS)) 848 goto error;
828 return old_fsuid;
829 849
830 if (uid == cred->uid || uid == cred->euid || 850 if (uid == old->uid || uid == old->euid ||
831 uid == cred->suid || uid == cred->fsuid || 851 uid == old->suid || uid == old->fsuid ||
832 capable(CAP_SETUID)) { 852 capable(CAP_SETUID)) {
833 if (uid != old_fsuid) { 853 if (uid != old_fsuid) {
834 set_dumpable(current->mm, suid_dumpable); 854 new->fsuid = uid;
835 smp_wmb(); 855 if (security_task_fix_setuid(new, old, LSM_SETID_FS) == 0)
856 goto change_okay;
836 } 857 }
837 cred->fsuid = uid;
838 } 858 }
839 859
840 key_fsuid_changed(current); 860error:
841 proc_id_connector(current, PROC_EVENT_UID); 861 abort_creds(new);
842 862 return old_fsuid;
843 security_task_post_setuid(old_fsuid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS);
844 863
864change_okay:
865 commit_creds(new);
845 return old_fsuid; 866 return old_fsuid;
846} 867}
847 868
@@ -850,24 +871,34 @@ asmlinkage long sys_setfsuid(uid_t uid)
850 */ 871 */
851asmlinkage long sys_setfsgid(gid_t gid) 872asmlinkage long sys_setfsgid(gid_t gid)
852{ 873{
853 struct cred *cred = current->cred; 874 const struct cred *old;
854 int old_fsgid; 875 struct cred *new;
876 gid_t old_fsgid;
877
878 new = prepare_creds();
879 if (!new)
880 return current_fsgid();
881 old = current_cred();
882 old_fsgid = old->fsgid;
855 883
856 old_fsgid = cred->fsgid;
857 if (security_task_setgid(gid, (gid_t)-1, (gid_t)-1, LSM_SETID_FS)) 884 if (security_task_setgid(gid, (gid_t)-1, (gid_t)-1, LSM_SETID_FS))
858 return old_fsgid; 885 goto error;
859 886
860 if (gid == cred->gid || gid == cred->egid || 887 if (gid == old->gid || gid == old->egid ||
861 gid == cred->sgid || gid == cred->fsgid || 888 gid == old->sgid || gid == old->fsgid ||
862 capable(CAP_SETGID)) { 889 capable(CAP_SETGID)) {
863 if (gid != old_fsgid) { 890 if (gid != old_fsgid) {
864 set_dumpable(current->mm, suid_dumpable); 891 new->fsgid = gid;
865 smp_wmb(); 892 goto change_okay;
866 } 893 }
867 cred->fsgid = gid;
868 key_fsgid_changed(current);
869 proc_id_connector(current, PROC_EVENT_GID);
870 } 894 }
895
896error:
897 abort_creds(new);
898 return old_fsgid;
899
900change_okay:
901 commit_creds(new);
871 return old_fsgid; 902 return old_fsgid;
872} 903}
873 904
@@ -1136,7 +1167,7 @@ EXPORT_SYMBOL(groups_free);
1136 1167
1137/* export the group_info to a user-space array */ 1168/* export the group_info to a user-space array */
1138static int groups_to_user(gid_t __user *grouplist, 1169static int groups_to_user(gid_t __user *grouplist,
1139 struct group_info *group_info) 1170 const struct group_info *group_info)
1140{ 1171{
1141 int i; 1172 int i;
1142 unsigned int count = group_info->ngroups; 1173 unsigned int count = group_info->ngroups;
@@ -1227,31 +1258,25 @@ int groups_search(const struct group_info *group_info, gid_t grp)
1227} 1258}
1228 1259
1229/** 1260/**
1230 * set_groups - Change a group subscription in a security record 1261 * set_groups - Change a group subscription in a set of credentials
1231 * @sec: The security record to alter 1262 * @new: The newly prepared set of credentials to alter
1232 * @group_info: The group list to impose 1263 * @group_info: The group list to install
1233 * 1264 *
1234 * Validate a group subscription and, if valid, impose it upon a task security 1265 * Validate a group subscription and, if valid, insert it into a set
1235 * record. 1266 * of credentials.
1236 */ 1267 */
1237int set_groups(struct cred *cred, struct group_info *group_info) 1268int set_groups(struct cred *new, struct group_info *group_info)
1238{ 1269{
1239 int retval; 1270 int retval;
1240 struct group_info *old_info;
1241 1271
1242 retval = security_task_setgroups(group_info); 1272 retval = security_task_setgroups(group_info);
1243 if (retval) 1273 if (retval)
1244 return retval; 1274 return retval;
1245 1275
1276 put_group_info(new->group_info);
1246 groups_sort(group_info); 1277 groups_sort(group_info);
1247 get_group_info(group_info); 1278 get_group_info(group_info);
1248 1279 new->group_info = group_info;
1249 spin_lock(&cred->lock);
1250 old_info = cred->group_info;
1251 cred->group_info = group_info;
1252 spin_unlock(&cred->lock);
1253
1254 put_group_info(old_info);
1255 return 0; 1280 return 0;
1256} 1281}
1257 1282
@@ -1266,7 +1291,20 @@ EXPORT_SYMBOL(set_groups);
1266 */ 1291 */
1267int set_current_groups(struct group_info *group_info) 1292int set_current_groups(struct group_info *group_info)
1268{ 1293{
1269 return set_groups(current->cred, group_info); 1294 struct cred *new;
1295 int ret;
1296
1297 new = prepare_creds();
1298 if (!new)
1299 return -ENOMEM;
1300
1301 ret = set_groups(new, group_info);
1302 if (ret < 0) {
1303 abort_creds(new);
1304 return ret;
1305 }
1306
1307 return commit_creds(new);
1270} 1308}
1271 1309
1272EXPORT_SYMBOL(set_current_groups); 1310EXPORT_SYMBOL(set_current_groups);
@@ -1666,9 +1704,11 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3,
1666 unsigned char comm[sizeof(me->comm)]; 1704 unsigned char comm[sizeof(me->comm)];
1667 long error; 1705 long error;
1668 1706
1669 if (security_task_prctl(option, arg2, arg3, arg4, arg5, &error)) 1707 error = security_task_prctl(option, arg2, arg3, arg4, arg5);
1708 if (error != -ENOSYS)
1670 return error; 1709 return error;
1671 1710
1711 error = 0;
1672 switch (option) { 1712 switch (option) {
1673 case PR_SET_PDEATHSIG: 1713 case PR_SET_PDEATHSIG:
1674 if (!valid_signal(arg2)) { 1714 if (!valid_signal(arg2)) {
diff --git a/kernel/user.c b/kernel/user.c
index 104d22ac84d5..d476307dd4b0 100644
--- a/kernel/user.c
+++ b/kernel/user.c
@@ -16,6 +16,7 @@
16#include <linux/interrupt.h> 16#include <linux/interrupt.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/user_namespace.h> 18#include <linux/user_namespace.h>
19#include "cred-internals.h"
19 20
20struct user_namespace init_user_ns = { 21struct user_namespace init_user_ns = {
21 .kref = { 22 .kref = {
@@ -104,16 +105,10 @@ static int sched_create_user(struct user_struct *up)
104 return rc; 105 return rc;
105} 106}
106 107
107static void sched_switch_user(struct task_struct *p)
108{
109 sched_move_task(p);
110}
111
112#else /* CONFIG_USER_SCHED */ 108#else /* CONFIG_USER_SCHED */
113 109
114static void sched_destroy_user(struct user_struct *up) { } 110static void sched_destroy_user(struct user_struct *up) { }
115static int sched_create_user(struct user_struct *up) { return 0; } 111static int sched_create_user(struct user_struct *up) { return 0; }
116static void sched_switch_user(struct task_struct *p) { }
117 112
118#endif /* CONFIG_USER_SCHED */ 113#endif /* CONFIG_USER_SCHED */
119 114
@@ -448,36 +443,6 @@ out_unlock:
448 return NULL; 443 return NULL;
449} 444}
450 445
451void switch_uid(struct user_struct *new_user)
452{
453 struct user_struct *old_user;
454
455 /* What if a process setreuid()'s and this brings the
456 * new uid over his NPROC rlimit? We can check this now
457 * cheaply with the new uid cache, so if it matters
458 * we should be checking for it. -DaveM
459 */
460 old_user = current->cred->user;
461 atomic_inc(&new_user->processes);
462 atomic_dec(&old_user->processes);
463 switch_uid_keyring(new_user);
464 current->cred->user = new_user;
465 sched_switch_user(current);
466
467 /*
468 * We need to synchronize with __sigqueue_alloc()
469 * doing a get_uid(p->user).. If that saw the old
470 * user value, we need to wait until it has exited
471 * its critical region before we can free the old
472 * structure.
473 */
474 smp_mb();
475 spin_unlock_wait(&current->sighand->siglock);
476
477 free_uid(old_user);
478 suid_keys(current);
479}
480
481#ifdef CONFIG_USER_NS 446#ifdef CONFIG_USER_NS
482void release_uids(struct user_namespace *ns) 447void release_uids(struct user_namespace *ns)
483{ 448{
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index f82730adea00..0d9c51d67333 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -19,6 +19,7 @@ static struct user_namespace *clone_user_ns(struct user_namespace *old_ns)
19{ 19{
20 struct user_namespace *ns; 20 struct user_namespace *ns;
21 struct user_struct *new_user; 21 struct user_struct *new_user;
22 struct cred *new;
22 int n; 23 int n;
23 24
24 ns = kmalloc(sizeof(struct user_namespace), GFP_KERNEL); 25 ns = kmalloc(sizeof(struct user_namespace), GFP_KERNEL);
@@ -45,7 +46,16 @@ static struct user_namespace *clone_user_ns(struct user_namespace *old_ns)
45 return ERR_PTR(-ENOMEM); 46 return ERR_PTR(-ENOMEM);
46 } 47 }
47 48
48 switch_uid(new_user); 49 /* Install the new user */
50 new = prepare_creds();
51 if (!new) {
52 free_uid(new_user);
53 free_uid(ns->root_user);
54 kfree(ns);
55 }
56 free_uid(new->user);
57 new->user = new_user;
58 commit_creds(new);
49 return ns; 59 return ns;
50} 60}
51 61
diff --git a/lib/Makefile b/lib/Makefile
index 7cb65d85aeb0..80fe8a3ec12a 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -11,7 +11,7 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \
11 rbtree.o radix-tree.o dump_stack.o \ 11 rbtree.o radix-tree.o dump_stack.o \
12 idr.o int_sqrt.o extable.o prio_tree.o \ 12 idr.o int_sqrt.o extable.o prio_tree.o \
13 sha1.o irq_regs.o reciprocal_div.o argv_split.o \ 13 sha1.o irq_regs.o reciprocal_div.o argv_split.o \
14 proportions.o prio_heap.o ratelimit.o show_mem.o 14 proportions.o prio_heap.o ratelimit.o show_mem.o is_single_threaded.o
15 15
16lib-$(CONFIG_MMU) += ioremap.o 16lib-$(CONFIG_MMU) += ioremap.o
17lib-$(CONFIG_SMP) += cpumask.o 17lib-$(CONFIG_SMP) += cpumask.o
diff --git a/net/rxrpc/ar-key.c b/net/rxrpc/ar-key.c
index 9a8ff684da79..ad8c7a782da1 100644
--- a/net/rxrpc/ar-key.c
+++ b/net/rxrpc/ar-key.c
@@ -287,6 +287,7 @@ int rxrpc_get_server_data_key(struct rxrpc_connection *conn,
287 time_t expiry, 287 time_t expiry,
288 u32 kvno) 288 u32 kvno)
289{ 289{
290 const struct cred *cred = current_cred();
290 struct key *key; 291 struct key *key;
291 int ret; 292 int ret;
292 293
@@ -297,7 +298,7 @@ int rxrpc_get_server_data_key(struct rxrpc_connection *conn,
297 298
298 _enter(""); 299 _enter("");
299 300
300 key = key_alloc(&key_type_rxrpc, "x", 0, 0, current, 0, 301 key = key_alloc(&key_type_rxrpc, "x", 0, 0, cred, 0,
301 KEY_ALLOC_NOT_IN_QUOTA); 302 KEY_ALLOC_NOT_IN_QUOTA);
302 if (IS_ERR(key)) { 303 if (IS_ERR(key)) {
303 _leave(" = -ENOMEM [alloc %ld]", PTR_ERR(key)); 304 _leave(" = -ENOMEM [alloc %ld]", PTR_ERR(key));
@@ -340,10 +341,11 @@ EXPORT_SYMBOL(rxrpc_get_server_data_key);
340 */ 341 */
341struct key *rxrpc_get_null_key(const char *keyname) 342struct key *rxrpc_get_null_key(const char *keyname)
342{ 343{
344 const struct cred *cred = current_cred();
343 struct key *key; 345 struct key *key;
344 int ret; 346 int ret;
345 347
346 key = key_alloc(&key_type_rxrpc, keyname, 0, 0, current, 348 key = key_alloc(&key_type_rxrpc, keyname, 0, 0, cred,
347 KEY_POS_SEARCH, KEY_ALLOC_NOT_IN_QUOTA); 349 KEY_POS_SEARCH, KEY_ALLOC_NOT_IN_QUOTA);
348 if (IS_ERR(key)) 350 if (IS_ERR(key))
349 return key; 351 return key;
diff --git a/security/capability.c b/security/capability.c
index fac2f61b69a9..efeb6d9e0e6a 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -340,12 +340,16 @@ static int cap_task_create(unsigned long clone_flags)
340 return 0; 340 return 0;
341} 341}
342 342
343static int cap_cred_alloc_security(struct cred *cred) 343static void cap_cred_free(struct cred *cred)
344{
345}
346
347static int cap_cred_prepare(struct cred *new, const struct cred *old, gfp_t gfp)
344{ 348{
345 return 0; 349 return 0;
346} 350}
347 351
348static void cap_cred_free(struct cred *cred) 352static void cap_cred_commit(struct cred *new, const struct cred *old)
349{ 353{
350} 354}
351 355
@@ -750,7 +754,7 @@ static void cap_release_secctx(char *secdata, u32 seclen)
750} 754}
751 755
752#ifdef CONFIG_KEYS 756#ifdef CONFIG_KEYS
753static int cap_key_alloc(struct key *key, struct task_struct *ctx, 757static int cap_key_alloc(struct key *key, const struct cred *cred,
754 unsigned long flags) 758 unsigned long flags)
755{ 759{
756 return 0; 760 return 0;
@@ -760,7 +764,7 @@ static void cap_key_free(struct key *key)
760{ 764{
761} 765}
762 766
763static int cap_key_permission(key_ref_t key_ref, struct task_struct *context, 767static int cap_key_permission(key_ref_t key_ref, const struct cred *cred,
764 key_perm_t perm) 768 key_perm_t perm)
765{ 769{
766 return 0; 770 return 0;
@@ -814,8 +818,7 @@ void security_fixup_ops(struct security_operations *ops)
814 set_to_cap_if_null(ops, ptrace_may_access); 818 set_to_cap_if_null(ops, ptrace_may_access);
815 set_to_cap_if_null(ops, ptrace_traceme); 819 set_to_cap_if_null(ops, ptrace_traceme);
816 set_to_cap_if_null(ops, capget); 820 set_to_cap_if_null(ops, capget);
817 set_to_cap_if_null(ops, capset_check); 821 set_to_cap_if_null(ops, capset);
818 set_to_cap_if_null(ops, capset_set);
819 set_to_cap_if_null(ops, acct); 822 set_to_cap_if_null(ops, acct);
820 set_to_cap_if_null(ops, capable); 823 set_to_cap_if_null(ops, capable);
821 set_to_cap_if_null(ops, quotactl); 824 set_to_cap_if_null(ops, quotactl);
@@ -890,10 +893,11 @@ void security_fixup_ops(struct security_operations *ops)
890 set_to_cap_if_null(ops, file_receive); 893 set_to_cap_if_null(ops, file_receive);
891 set_to_cap_if_null(ops, dentry_open); 894 set_to_cap_if_null(ops, dentry_open);
892 set_to_cap_if_null(ops, task_create); 895 set_to_cap_if_null(ops, task_create);
893 set_to_cap_if_null(ops, cred_alloc_security);
894 set_to_cap_if_null(ops, cred_free); 896 set_to_cap_if_null(ops, cred_free);
897 set_to_cap_if_null(ops, cred_prepare);
898 set_to_cap_if_null(ops, cred_commit);
895 set_to_cap_if_null(ops, task_setuid); 899 set_to_cap_if_null(ops, task_setuid);
896 set_to_cap_if_null(ops, task_post_setuid); 900 set_to_cap_if_null(ops, task_fix_setuid);
897 set_to_cap_if_null(ops, task_setgid); 901 set_to_cap_if_null(ops, task_setgid);
898 set_to_cap_if_null(ops, task_setpgid); 902 set_to_cap_if_null(ops, task_setpgid);
899 set_to_cap_if_null(ops, task_getpgid); 903 set_to_cap_if_null(ops, task_getpgid);
@@ -910,7 +914,6 @@ void security_fixup_ops(struct security_operations *ops)
910 set_to_cap_if_null(ops, task_wait); 914 set_to_cap_if_null(ops, task_wait);
911 set_to_cap_if_null(ops, task_kill); 915 set_to_cap_if_null(ops, task_kill);
912 set_to_cap_if_null(ops, task_prctl); 916 set_to_cap_if_null(ops, task_prctl);
913 set_to_cap_if_null(ops, task_reparent_to_init);
914 set_to_cap_if_null(ops, task_to_inode); 917 set_to_cap_if_null(ops, task_to_inode);
915 set_to_cap_if_null(ops, ipc_permission); 918 set_to_cap_if_null(ops, ipc_permission);
916 set_to_cap_if_null(ops, ipc_getsecid); 919 set_to_cap_if_null(ops, ipc_getsecid);
diff --git a/security/commoncap.c b/security/commoncap.c
index 0384bf95db68..b5419273f92d 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -72,8 +72,8 @@ int cap_ptrace_may_access(struct task_struct *child, unsigned int mode)
72 int ret = 0; 72 int ret = 0;
73 73
74 rcu_read_lock(); 74 rcu_read_lock();
75 if (!cap_issubset(child->cred->cap_permitted, 75 if (!cap_issubset(__task_cred(child)->cap_permitted,
76 current->cred->cap_permitted) && 76 current_cred()->cap_permitted) &&
77 !capable(CAP_SYS_PTRACE)) 77 !capable(CAP_SYS_PTRACE))
78 ret = -EPERM; 78 ret = -EPERM;
79 rcu_read_unlock(); 79 rcu_read_unlock();
@@ -85,8 +85,8 @@ int cap_ptrace_traceme(struct task_struct *parent)
85 int ret = 0; 85 int ret = 0;
86 86
87 rcu_read_lock(); 87 rcu_read_lock();
88 if (!cap_issubset(current->cred->cap_permitted, 88 if (!cap_issubset(current_cred()->cap_permitted,
89 parent->cred->cap_permitted) && 89 __task_cred(parent)->cap_permitted) &&
90 !has_capability(parent, CAP_SYS_PTRACE)) 90 !has_capability(parent, CAP_SYS_PTRACE))
91 ret = -EPERM; 91 ret = -EPERM;
92 rcu_read_unlock(); 92 rcu_read_unlock();
@@ -117,7 +117,7 @@ static inline int cap_inh_is_capped(void)
117 * to the old permitted set. That is, if the current task 117 * to the old permitted set. That is, if the current task
118 * does *not* possess the CAP_SETPCAP capability. 118 * does *not* possess the CAP_SETPCAP capability.
119 */ 119 */
120 return (cap_capable(current, CAP_SETPCAP, SECURITY_CAP_AUDIT) != 0); 120 return cap_capable(current, CAP_SETPCAP, SECURITY_CAP_AUDIT) != 0;
121} 121}
122 122
123static inline int cap_limit_ptraced_target(void) { return 1; } 123static inline int cap_limit_ptraced_target(void) { return 1; }
@@ -132,52 +132,39 @@ static inline int cap_limit_ptraced_target(void)
132 132
133#endif /* def CONFIG_SECURITY_FILE_CAPABILITIES */ 133#endif /* def CONFIG_SECURITY_FILE_CAPABILITIES */
134 134
135int cap_capset_check(const kernel_cap_t *effective, 135int cap_capset(struct cred *new,
136 const kernel_cap_t *inheritable, 136 const struct cred *old,
137 const kernel_cap_t *permitted) 137 const kernel_cap_t *effective,
138 const kernel_cap_t *inheritable,
139 const kernel_cap_t *permitted)
138{ 140{
139 const struct cred *cred = current->cred; 141 if (cap_inh_is_capped() &&
140 142 !cap_issubset(*inheritable,
141 if (cap_inh_is_capped() 143 cap_combine(old->cap_inheritable,
142 && !cap_issubset(*inheritable, 144 old->cap_permitted)))
143 cap_combine(cred->cap_inheritable,
144 cred->cap_permitted))) {
145 /* incapable of using this inheritable set */ 145 /* incapable of using this inheritable set */
146 return -EPERM; 146 return -EPERM;
147 } 147
148 if (!cap_issubset(*inheritable, 148 if (!cap_issubset(*inheritable,
149 cap_combine(cred->cap_inheritable, 149 cap_combine(old->cap_inheritable,
150 cred->cap_bset))) { 150 old->cap_bset)))
151 /* no new pI capabilities outside bounding set */ 151 /* no new pI capabilities outside bounding set */
152 return -EPERM; 152 return -EPERM;
153 }
154 153
155 /* verify restrictions on target's new Permitted set */ 154 /* verify restrictions on target's new Permitted set */
156 if (!cap_issubset (*permitted, 155 if (!cap_issubset(*permitted, old->cap_permitted))
157 cap_combine (cred->cap_permitted,
158 cred->cap_permitted))) {
159 return -EPERM; 156 return -EPERM;
160 }
161 157
162 /* verify the _new_Effective_ is a subset of the _new_Permitted_ */ 158 /* verify the _new_Effective_ is a subset of the _new_Permitted_ */
163 if (!cap_issubset (*effective, *permitted)) { 159 if (!cap_issubset(*effective, *permitted))
164 return -EPERM; 160 return -EPERM;
165 }
166 161
162 new->cap_effective = *effective;
163 new->cap_inheritable = *inheritable;
164 new->cap_permitted = *permitted;
167 return 0; 165 return 0;
168} 166}
169 167
170void cap_capset_set(const kernel_cap_t *effective,
171 const kernel_cap_t *inheritable,
172 const kernel_cap_t *permitted)
173{
174 struct cred *cred = current->cred;
175
176 cred->cap_effective = *effective;
177 cred->cap_inheritable = *inheritable;
178 cred->cap_permitted = *permitted;
179}
180
181static inline void bprm_clear_caps(struct linux_binprm *bprm) 168static inline void bprm_clear_caps(struct linux_binprm *bprm)
182{ 169{
183 cap_clear(bprm->cap_post_exec_permitted); 170 cap_clear(bprm->cap_post_exec_permitted);
@@ -382,41 +369,46 @@ int cap_bprm_set_security (struct linux_binprm *bprm)
382 return ret; 369 return ret;
383} 370}
384 371
385void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe) 372int cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
386{ 373{
387 struct cred *cred = current->cred; 374 const struct cred *old = current_cred();
375 struct cred *new;
376
377 new = prepare_creds();
378 if (!new)
379 return -ENOMEM;
388 380
389 if (bprm->e_uid != cred->uid || bprm->e_gid != cred->gid || 381 if (bprm->e_uid != old->uid || bprm->e_gid != old->gid ||
390 !cap_issubset(bprm->cap_post_exec_permitted, 382 !cap_issubset(bprm->cap_post_exec_permitted,
391 cred->cap_permitted)) { 383 old->cap_permitted)) {
392 set_dumpable(current->mm, suid_dumpable); 384 set_dumpable(current->mm, suid_dumpable);
393 current->pdeath_signal = 0; 385 current->pdeath_signal = 0;
394 386
395 if (unsafe & ~LSM_UNSAFE_PTRACE_CAP) { 387 if (unsafe & ~LSM_UNSAFE_PTRACE_CAP) {
396 if (!capable(CAP_SETUID)) { 388 if (!capable(CAP_SETUID)) {
397 bprm->e_uid = cred->uid; 389 bprm->e_uid = old->uid;
398 bprm->e_gid = cred->gid; 390 bprm->e_gid = old->gid;
399 } 391 }
400 if (cap_limit_ptraced_target()) { 392 if (cap_limit_ptraced_target()) {
401 bprm->cap_post_exec_permitted = cap_intersect( 393 bprm->cap_post_exec_permitted = cap_intersect(
402 bprm->cap_post_exec_permitted, 394 bprm->cap_post_exec_permitted,
403 cred->cap_permitted); 395 new->cap_permitted);
404 } 396 }
405 } 397 }
406 } 398 }
407 399
408 cred->suid = cred->euid = cred->fsuid = bprm->e_uid; 400 new->suid = new->euid = new->fsuid = bprm->e_uid;
409 cred->sgid = cred->egid = cred->fsgid = bprm->e_gid; 401 new->sgid = new->egid = new->fsgid = bprm->e_gid;
410 402
411 /* For init, we want to retain the capabilities set 403 /* For init, we want to retain the capabilities set
412 * in the init_task struct. Thus we skip the usual 404 * in the init_task struct. Thus we skip the usual
413 * capability rules */ 405 * capability rules */
414 if (!is_global_init(current)) { 406 if (!is_global_init(current)) {
415 cred->cap_permitted = bprm->cap_post_exec_permitted; 407 new->cap_permitted = bprm->cap_post_exec_permitted;
416 if (bprm->cap_effective) 408 if (bprm->cap_effective)
417 cred->cap_effective = bprm->cap_post_exec_permitted; 409 new->cap_effective = bprm->cap_post_exec_permitted;
418 else 410 else
419 cap_clear(cred->cap_effective); 411 cap_clear(new->cap_effective);
420 } 412 }
421 413
422 /* 414 /*
@@ -431,15 +423,15 @@ void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
431 * Number 1 above might fail if you don't have a full bset, but I think 423 * Number 1 above might fail if you don't have a full bset, but I think
432 * that is interesting information to audit. 424 * that is interesting information to audit.
433 */ 425 */
434 if (!cap_isclear(cred->cap_effective)) { 426 if (!cap_isclear(new->cap_effective)) {
435 if (!cap_issubset(CAP_FULL_SET, cred->cap_effective) || 427 if (!cap_issubset(CAP_FULL_SET, new->cap_effective) ||
436 (bprm->e_uid != 0) || (cred->uid != 0) || 428 bprm->e_uid != 0 || new->uid != 0 ||
437 issecure(SECURE_NOROOT)) 429 issecure(SECURE_NOROOT))
438 audit_log_bprm_fcaps(bprm, &cred->cap_permitted, 430 audit_log_bprm_fcaps(bprm, new, old);
439 &cred->cap_effective);
440 } 431 }
441 432
442 cred->securebits &= ~issecure_mask(SECURE_KEEP_CAPS); 433 new->securebits &= ~issecure_mask(SECURE_KEEP_CAPS);
434 return commit_creds(new);
443} 435}
444 436
445int cap_bprm_secureexec (struct linux_binprm *bprm) 437int cap_bprm_secureexec (struct linux_binprm *bprm)
@@ -514,65 +506,49 @@ int cap_inode_removexattr(struct dentry *dentry, const char *name)
514 * files.. 506 * files..
515 * Thanks to Olaf Kirch and Peter Benie for spotting this. 507 * Thanks to Olaf Kirch and Peter Benie for spotting this.
516 */ 508 */
517static inline void cap_emulate_setxuid (int old_ruid, int old_euid, 509static inline void cap_emulate_setxuid(struct cred *new, const struct cred *old)
518 int old_suid)
519{ 510{
520 struct cred *cred = current->cred; 511 if ((old->uid == 0 || old->euid == 0 || old->suid == 0) &&
521 512 (new->uid != 0 && new->euid != 0 && new->suid != 0) &&
522 if ((old_ruid == 0 || old_euid == 0 || old_suid == 0) &&
523 (cred->uid != 0 && cred->euid != 0 && cred->suid != 0) &&
524 !issecure(SECURE_KEEP_CAPS)) { 513 !issecure(SECURE_KEEP_CAPS)) {
525 cap_clear(cred->cap_permitted); 514 cap_clear(new->cap_permitted);
526 cap_clear(cred->cap_effective); 515 cap_clear(new->cap_effective);
527 }
528 if (old_euid == 0 && cred->euid != 0) {
529 cap_clear(cred->cap_effective);
530 }
531 if (old_euid != 0 && cred->euid == 0) {
532 cred->cap_effective = cred->cap_permitted;
533 } 516 }
517 if (old->euid == 0 && new->euid != 0)
518 cap_clear(new->cap_effective);
519 if (old->euid != 0 && new->euid == 0)
520 new->cap_effective = new->cap_permitted;
534} 521}
535 522
536int cap_task_post_setuid (uid_t old_ruid, uid_t old_euid, uid_t old_suid, 523int cap_task_fix_setuid(struct cred *new, const struct cred *old, int flags)
537 int flags)
538{ 524{
539 struct cred *cred = current->cred;
540
541 switch (flags) { 525 switch (flags) {
542 case LSM_SETID_RE: 526 case LSM_SETID_RE:
543 case LSM_SETID_ID: 527 case LSM_SETID_ID:
544 case LSM_SETID_RES: 528 case LSM_SETID_RES:
545 /* Copied from kernel/sys.c:setreuid/setuid/setresuid. */ 529 /* Copied from kernel/sys.c:setreuid/setuid/setresuid. */
546 if (!issecure (SECURE_NO_SETUID_FIXUP)) { 530 if (!issecure(SECURE_NO_SETUID_FIXUP))
547 cap_emulate_setxuid (old_ruid, old_euid, old_suid); 531 cap_emulate_setxuid(new, old);
548 }
549 break; 532 break;
550 case LSM_SETID_FS: 533 case LSM_SETID_FS:
551 { 534 /* Copied from kernel/sys.c:setfsuid. */
552 uid_t old_fsuid = old_ruid;
553
554 /* Copied from kernel/sys.c:setfsuid. */
555 535
556 /* 536 /*
557 * FIXME - is fsuser used for all CAP_FS_MASK capabilities? 537 * FIXME - is fsuser used for all CAP_FS_MASK capabilities?
558 * if not, we might be a bit too harsh here. 538 * if not, we might be a bit too harsh here.
559 */ 539 */
560 540 if (!issecure(SECURE_NO_SETUID_FIXUP)) {
561 if (!issecure (SECURE_NO_SETUID_FIXUP)) { 541 if (old->fsuid == 0 && new->fsuid != 0) {
562 if (old_fsuid == 0 && cred->fsuid != 0) { 542 new->cap_effective =
563 cred->cap_effective = 543 cap_drop_fs_set(new->cap_effective);
564 cap_drop_fs_set( 544 }
565 cred->cap_effective); 545 if (old->fsuid != 0 && new->fsuid == 0) {
566 } 546 new->cap_effective =
567 if (old_fsuid != 0 && cred->fsuid == 0) { 547 cap_raise_fs_set(new->cap_effective,
568 cred->cap_effective = 548 new->cap_permitted);
569 cap_raise_fs_set(
570 cred->cap_effective,
571 cred->cap_permitted);
572 }
573 } 549 }
574 break;
575 } 550 }
551 break;
576 default: 552 default:
577 return -EINVAL; 553 return -EINVAL;
578 } 554 }
@@ -628,13 +604,14 @@ int cap_task_setnice (struct task_struct *p, int nice)
628 * this task could get inconsistent info. There can be no 604 * this task could get inconsistent info. There can be no
629 * racing writer bc a task can only change its own caps. 605 * racing writer bc a task can only change its own caps.
630 */ 606 */
631static long cap_prctl_drop(unsigned long cap) 607static long cap_prctl_drop(struct cred *new, unsigned long cap)
632{ 608{
633 if (!capable(CAP_SETPCAP)) 609 if (!capable(CAP_SETPCAP))
634 return -EPERM; 610 return -EPERM;
635 if (!cap_valid(cap)) 611 if (!cap_valid(cap))
636 return -EINVAL; 612 return -EINVAL;
637 cap_lower(current->cred->cap_bset, cap); 613
614 cap_lower(new->cap_bset, cap);
638 return 0; 615 return 0;
639} 616}
640 617
@@ -655,22 +632,29 @@ int cap_task_setnice (struct task_struct *p, int nice)
655#endif 632#endif
656 633
657int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, 634int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
658 unsigned long arg4, unsigned long arg5, long *rc_p) 635 unsigned long arg4, unsigned long arg5)
659{ 636{
660 struct cred *cred = current_cred(); 637 struct cred *new;
661 long error = 0; 638 long error = 0;
662 639
640 new = prepare_creds();
641 if (!new)
642 return -ENOMEM;
643
663 switch (option) { 644 switch (option) {
664 case PR_CAPBSET_READ: 645 case PR_CAPBSET_READ:
646 error = -EINVAL;
665 if (!cap_valid(arg2)) 647 if (!cap_valid(arg2))
666 error = -EINVAL; 648 goto error;
667 else 649 error = !!cap_raised(new->cap_bset, arg2);
668 error = !!cap_raised(cred->cap_bset, arg2); 650 goto no_change;
669 break; 651
670#ifdef CONFIG_SECURITY_FILE_CAPABILITIES 652#ifdef CONFIG_SECURITY_FILE_CAPABILITIES
671 case PR_CAPBSET_DROP: 653 case PR_CAPBSET_DROP:
672 error = cap_prctl_drop(arg2); 654 error = cap_prctl_drop(new, arg2);
673 break; 655 if (error < 0)
656 goto error;
657 goto changed;
674 658
675 /* 659 /*
676 * The next four prctl's remain to assist with transitioning a 660 * The next four prctl's remain to assist with transitioning a
@@ -692,12 +676,12 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
692 * capability-based-privilege environment. 676 * capability-based-privilege environment.
693 */ 677 */
694 case PR_SET_SECUREBITS: 678 case PR_SET_SECUREBITS:
695 if ((((cred->securebits & SECURE_ALL_LOCKS) >> 1) 679 error = -EPERM;
696 & (cred->securebits ^ arg2)) /*[1]*/ 680 if ((((new->securebits & SECURE_ALL_LOCKS) >> 1)
697 || ((cred->securebits & SECURE_ALL_LOCKS 681 & (new->securebits ^ arg2)) /*[1]*/
698 & ~arg2)) /*[2]*/ 682 || ((new->securebits & SECURE_ALL_LOCKS & ~arg2)) /*[2]*/
699 || (arg2 & ~(SECURE_ALL_LOCKS | SECURE_ALL_BITS)) /*[3]*/ 683 || (arg2 & ~(SECURE_ALL_LOCKS | SECURE_ALL_BITS)) /*[3]*/
700 || (cap_capable(current, CAP_SETPCAP, SECURITY_CAP_AUDIT) != 0)) { /*[4]*/ 684 || (cap_capable(current, CAP_SETPCAP, SECURITY_CAP_AUDIT) != 0) /*[4]*/
701 /* 685 /*
702 * [1] no changing of bits that are locked 686 * [1] no changing of bits that are locked
703 * [2] no unlocking of locks 687 * [2] no unlocking of locks
@@ -705,50 +689,51 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
705 * [4] doing anything requires privilege (go read about 689 * [4] doing anything requires privilege (go read about
706 * the "sendmail capabilities bug") 690 * the "sendmail capabilities bug")
707 */ 691 */
708 error = -EPERM; /* cannot change a locked bit */ 692 )
709 } else { 693 /* cannot change a locked bit */
710 cred->securebits = arg2; 694 goto error;
711 } 695 new->securebits = arg2;
712 break; 696 goto changed;
697
713 case PR_GET_SECUREBITS: 698 case PR_GET_SECUREBITS:
714 error = cred->securebits; 699 error = new->securebits;
715 break; 700 goto no_change;
716 701
717#endif /* def CONFIG_SECURITY_FILE_CAPABILITIES */ 702#endif /* def CONFIG_SECURITY_FILE_CAPABILITIES */
718 703
719 case PR_GET_KEEPCAPS: 704 case PR_GET_KEEPCAPS:
720 if (issecure(SECURE_KEEP_CAPS)) 705 if (issecure(SECURE_KEEP_CAPS))
721 error = 1; 706 error = 1;
722 break; 707 goto no_change;
708
723 case PR_SET_KEEPCAPS: 709 case PR_SET_KEEPCAPS:
710 error = -EINVAL;
724 if (arg2 > 1) /* Note, we rely on arg2 being unsigned here */ 711 if (arg2 > 1) /* Note, we rely on arg2 being unsigned here */
725 error = -EINVAL; 712 goto error;
726 else if (issecure(SECURE_KEEP_CAPS_LOCKED)) 713 error = -EPERM;
727 error = -EPERM; 714 if (issecure(SECURE_KEEP_CAPS_LOCKED))
728 else if (arg2) 715 goto error;
729 cred->securebits |= issecure_mask(SECURE_KEEP_CAPS); 716 if (arg2)
717 new->securebits |= issecure_mask(SECURE_KEEP_CAPS);
730 else 718 else
731 cred->securebits &= ~issecure_mask(SECURE_KEEP_CAPS); 719 new->securebits &= ~issecure_mask(SECURE_KEEP_CAPS);
732 break; 720 goto changed;
733 721
734 default: 722 default:
735 /* No functionality available - continue with default */ 723 /* No functionality available - continue with default */
736 return 0; 724 error = -ENOSYS;
725 goto error;
737 } 726 }
738 727
739 /* Functionality provided */ 728 /* Functionality provided */
740 *rc_p = error; 729changed:
741 return 1; 730 return commit_creds(new);
742} 731
743 732no_change:
744void cap_task_reparent_to_init (struct task_struct *p) 733 error = 0;
745{ 734error:
746 struct cred *cred = p->cred; 735 abort_creds(new);
747 736 return error;
748 cap_set_init_eff(cred->cap_effective);
749 cap_clear(cred->cap_inheritable);
750 cap_set_full(cred->cap_permitted);
751 p->cred->securebits = SECUREBITS_DEFAULT;
752} 737}
753 738
754int cap_syslog (int type) 739int cap_syslog (int type)
diff --git a/security/keys/internal.h b/security/keys/internal.h
index d1586c629788..81932abefe7b 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -12,6 +12,7 @@
12#ifndef _INTERNAL_H 12#ifndef _INTERNAL_H
13#define _INTERNAL_H 13#define _INTERNAL_H
14 14
15#include <linux/sched.h>
15#include <linux/key-type.h> 16#include <linux/key-type.h>
16 17
17static inline __attribute__((format(printf, 1, 2))) 18static inline __attribute__((format(printf, 1, 2)))
@@ -25,7 +26,7 @@ void no_printk(const char *fmt, ...)
25#define kleave(FMT, ...) \ 26#define kleave(FMT, ...) \
26 printk(KERN_DEBUG "<== %s()"FMT"\n", __func__, ##__VA_ARGS__) 27 printk(KERN_DEBUG "<== %s()"FMT"\n", __func__, ##__VA_ARGS__)
27#define kdebug(FMT, ...) \ 28#define kdebug(FMT, ...) \
28 printk(KERN_DEBUG "xxx" FMT"yyy\n", ##__VA_ARGS__) 29 printk(KERN_DEBUG " "FMT"\n", ##__VA_ARGS__)
29#else 30#else
30#define kenter(FMT, ...) \ 31#define kenter(FMT, ...) \
31 no_printk(KERN_DEBUG "==> %s("FMT")\n", __func__, ##__VA_ARGS__) 32 no_printk(KERN_DEBUG "==> %s("FMT")\n", __func__, ##__VA_ARGS__)
@@ -97,7 +98,7 @@ extern struct key *keyring_search_instkey(struct key *keyring,
97typedef int (*key_match_func_t)(const struct key *, const void *); 98typedef int (*key_match_func_t)(const struct key *, const void *);
98 99
99extern key_ref_t keyring_search_aux(key_ref_t keyring_ref, 100extern key_ref_t keyring_search_aux(key_ref_t keyring_ref,
100 struct task_struct *tsk, 101 const struct cred *cred,
101 struct key_type *type, 102 struct key_type *type,
102 const void *description, 103 const void *description,
103 key_match_func_t match); 104 key_match_func_t match);
@@ -105,13 +106,13 @@ extern key_ref_t keyring_search_aux(key_ref_t keyring_ref,
105extern key_ref_t search_process_keyrings(struct key_type *type, 106extern key_ref_t search_process_keyrings(struct key_type *type,
106 const void *description, 107 const void *description,
107 key_match_func_t match, 108 key_match_func_t match,
108 struct task_struct *tsk); 109 const struct cred *cred);
109 110
110extern struct key *find_keyring_by_name(const char *name, bool skip_perm_check); 111extern struct key *find_keyring_by_name(const char *name, bool skip_perm_check);
111 112
112extern int install_user_keyrings(void); 113extern int install_user_keyrings(void);
113extern int install_thread_keyring(void); 114extern int install_thread_keyring_to_cred(struct cred *);
114extern int install_process_keyring(void); 115extern int install_process_keyring_to_cred(struct cred *);
115 116
116extern struct key *request_key_and_link(struct key_type *type, 117extern struct key *request_key_and_link(struct key_type *type,
117 const char *description, 118 const char *description,
@@ -130,12 +131,12 @@ extern long join_session_keyring(const char *name);
130 * check to see whether permission is granted to use a key in the desired way 131 * check to see whether permission is granted to use a key in the desired way
131 */ 132 */
132extern int key_task_permission(const key_ref_t key_ref, 133extern int key_task_permission(const key_ref_t key_ref,
133 struct task_struct *context, 134 const struct cred *cred,
134 key_perm_t perm); 135 key_perm_t perm);
135 136
136static inline int key_permission(const key_ref_t key_ref, key_perm_t perm) 137static inline int key_permission(const key_ref_t key_ref, key_perm_t perm)
137{ 138{
138 return key_task_permission(key_ref, current, perm); 139 return key_task_permission(key_ref, current_cred(), perm);
139} 140}
140 141
141/* required permissions */ 142/* required permissions */
@@ -153,7 +154,7 @@ static inline int key_permission(const key_ref_t key_ref, key_perm_t perm)
153struct request_key_auth { 154struct request_key_auth {
154 struct key *target_key; 155 struct key *target_key;
155 struct key *dest_keyring; 156 struct key *dest_keyring;
156 struct task_struct *context; 157 const struct cred *cred;
157 void *callout_info; 158 void *callout_info;
158 size_t callout_len; 159 size_t callout_len;
159 pid_t pid; 160 pid_t pid;
diff --git a/security/keys/key.c b/security/keys/key.c
index a6ca39ed3b0e..f76c8a546fd3 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -218,7 +218,7 @@ serial_exists:
218 * instantiate the key or discard it before returning 218 * instantiate the key or discard it before returning
219 */ 219 */
220struct key *key_alloc(struct key_type *type, const char *desc, 220struct key *key_alloc(struct key_type *type, const char *desc,
221 uid_t uid, gid_t gid, struct task_struct *ctx, 221 uid_t uid, gid_t gid, const struct cred *cred,
222 key_perm_t perm, unsigned long flags) 222 key_perm_t perm, unsigned long flags)
223{ 223{
224 struct key_user *user = NULL; 224 struct key_user *user = NULL;
@@ -294,7 +294,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
294#endif 294#endif
295 295
296 /* let the security module know about the key */ 296 /* let the security module know about the key */
297 ret = security_key_alloc(key, ctx, flags); 297 ret = security_key_alloc(key, cred, flags);
298 if (ret < 0) 298 if (ret < 0)
299 goto security_error; 299 goto security_error;
300 300
@@ -391,7 +391,7 @@ static int __key_instantiate_and_link(struct key *key,
391 const void *data, 391 const void *data,
392 size_t datalen, 392 size_t datalen,
393 struct key *keyring, 393 struct key *keyring,
394 struct key *instkey) 394 struct key *authkey)
395{ 395{
396 int ret, awaken; 396 int ret, awaken;
397 397
@@ -421,8 +421,8 @@ static int __key_instantiate_and_link(struct key *key,
421 ret = __key_link(keyring, key); 421 ret = __key_link(keyring, key);
422 422
423 /* disable the authorisation key */ 423 /* disable the authorisation key */
424 if (instkey) 424 if (authkey)
425 key_revoke(instkey); 425 key_revoke(authkey);
426 } 426 }
427 } 427 }
428 428
@@ -444,14 +444,14 @@ int key_instantiate_and_link(struct key *key,
444 const void *data, 444 const void *data,
445 size_t datalen, 445 size_t datalen,
446 struct key *keyring, 446 struct key *keyring,
447 struct key *instkey) 447 struct key *authkey)
448{ 448{
449 int ret; 449 int ret;
450 450
451 if (keyring) 451 if (keyring)
452 down_write(&keyring->sem); 452 down_write(&keyring->sem);
453 453
454 ret = __key_instantiate_and_link(key, data, datalen, keyring, instkey); 454 ret = __key_instantiate_and_link(key, data, datalen, keyring, authkey);
455 455
456 if (keyring) 456 if (keyring)
457 up_write(&keyring->sem); 457 up_write(&keyring->sem);
@@ -469,7 +469,7 @@ EXPORT_SYMBOL(key_instantiate_and_link);
469int key_negate_and_link(struct key *key, 469int key_negate_and_link(struct key *key,
470 unsigned timeout, 470 unsigned timeout,
471 struct key *keyring, 471 struct key *keyring,
472 struct key *instkey) 472 struct key *authkey)
473{ 473{
474 struct timespec now; 474 struct timespec now;
475 int ret, awaken; 475 int ret, awaken;
@@ -504,8 +504,8 @@ int key_negate_and_link(struct key *key,
504 ret = __key_link(keyring, key); 504 ret = __key_link(keyring, key);
505 505
506 /* disable the authorisation key */ 506 /* disable the authorisation key */
507 if (instkey) 507 if (authkey)
508 key_revoke(instkey); 508 key_revoke(authkey);
509 } 509 }
510 510
511 mutex_unlock(&key_construction_mutex); 511 mutex_unlock(&key_construction_mutex);
@@ -743,6 +743,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
743 key_perm_t perm, 743 key_perm_t perm,
744 unsigned long flags) 744 unsigned long flags)
745{ 745{
746 const struct cred *cred = current_cred();
746 struct key_type *ktype; 747 struct key_type *ktype;
747 struct key *keyring, *key = NULL; 748 struct key *keyring, *key = NULL;
748 key_ref_t key_ref; 749 key_ref_t key_ref;
@@ -802,8 +803,8 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
802 } 803 }
803 804
804 /* allocate a new key */ 805 /* allocate a new key */
805 key = key_alloc(ktype, description, current_fsuid(), current_fsgid(), 806 key = key_alloc(ktype, description, cred->fsuid, cred->fsgid, cred,
806 current, perm, flags); 807 perm, flags);
807 if (IS_ERR(key)) { 808 if (IS_ERR(key)) {
808 key_ref = ERR_CAST(key); 809 key_ref = ERR_CAST(key);
809 goto error_3; 810 goto error_3;
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 8833b447adef..7c72baa02f2e 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -866,6 +866,23 @@ static long get_instantiation_keyring(key_serial_t ringid,
866 return -ENOKEY; 866 return -ENOKEY;
867} 867}
868 868
869/*
870 * change the request_key authorisation key on the current process
871 */
872static int keyctl_change_reqkey_auth(struct key *key)
873{
874 struct cred *new;
875
876 new = prepare_creds();
877 if (!new)
878 return -ENOMEM;
879
880 key_put(new->request_key_auth);
881 new->request_key_auth = key_get(key);
882
883 return commit_creds(new);
884}
885
869/*****************************************************************************/ 886/*****************************************************************************/
870/* 887/*
871 * instantiate the key with the specified payload, and, if one is given, link 888 * instantiate the key with the specified payload, and, if one is given, link
@@ -876,12 +893,15 @@ long keyctl_instantiate_key(key_serial_t id,
876 size_t plen, 893 size_t plen,
877 key_serial_t ringid) 894 key_serial_t ringid)
878{ 895{
896 const struct cred *cred = current_cred();
879 struct request_key_auth *rka; 897 struct request_key_auth *rka;
880 struct key *instkey, *dest_keyring; 898 struct key *instkey, *dest_keyring;
881 void *payload; 899 void *payload;
882 long ret; 900 long ret;
883 bool vm = false; 901 bool vm = false;
884 902
903 kenter("%d,,%zu,%d", id, plen, ringid);
904
885 ret = -EINVAL; 905 ret = -EINVAL;
886 if (plen > 1024 * 1024 - 1) 906 if (plen > 1024 * 1024 - 1)
887 goto error; 907 goto error;
@@ -889,7 +909,7 @@ long keyctl_instantiate_key(key_serial_t id,
889 /* the appropriate instantiation authorisation key must have been 909 /* the appropriate instantiation authorisation key must have been
890 * assumed before calling this */ 910 * assumed before calling this */
891 ret = -EPERM; 911 ret = -EPERM;
892 instkey = current->cred->request_key_auth; 912 instkey = cred->request_key_auth;
893 if (!instkey) 913 if (!instkey)
894 goto error; 914 goto error;
895 915
@@ -931,10 +951,8 @@ long keyctl_instantiate_key(key_serial_t id,
931 951
932 /* discard the assumed authority if it's just been disabled by 952 /* discard the assumed authority if it's just been disabled by
933 * instantiation of the key */ 953 * instantiation of the key */
934 if (ret == 0) { 954 if (ret == 0)
935 key_put(current->cred->request_key_auth); 955 keyctl_change_reqkey_auth(NULL);
936 current->cred->request_key_auth = NULL;
937 }
938 956
939error2: 957error2:
940 if (!vm) 958 if (!vm)
@@ -953,14 +971,17 @@ error:
953 */ 971 */
954long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid) 972long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
955{ 973{
974 const struct cred *cred = current_cred();
956 struct request_key_auth *rka; 975 struct request_key_auth *rka;
957 struct key *instkey, *dest_keyring; 976 struct key *instkey, *dest_keyring;
958 long ret; 977 long ret;
959 978
979 kenter("%d,%u,%d", id, timeout, ringid);
980
960 /* the appropriate instantiation authorisation key must have been 981 /* the appropriate instantiation authorisation key must have been
961 * assumed before calling this */ 982 * assumed before calling this */
962 ret = -EPERM; 983 ret = -EPERM;
963 instkey = current->cred->request_key_auth; 984 instkey = cred->request_key_auth;
964 if (!instkey) 985 if (!instkey)
965 goto error; 986 goto error;
966 987
@@ -982,10 +1003,8 @@ long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
982 1003
983 /* discard the assumed authority if it's just been disabled by 1004 /* discard the assumed authority if it's just been disabled by
984 * instantiation of the key */ 1005 * instantiation of the key */
985 if (ret == 0) { 1006 if (ret == 0)
986 key_put(current->cred->request_key_auth); 1007 keyctl_change_reqkey_auth(NULL);
987 current->cred->request_key_auth = NULL;
988 }
989 1008
990error: 1009error:
991 return ret; 1010 return ret;
@@ -999,36 +1018,56 @@ error:
999 */ 1018 */
1000long keyctl_set_reqkey_keyring(int reqkey_defl) 1019long keyctl_set_reqkey_keyring(int reqkey_defl)
1001{ 1020{
1002 struct cred *cred = current->cred; 1021 struct cred *new;
1003 int ret; 1022 int ret, old_setting;
1023
1024 old_setting = current_cred_xxx(jit_keyring);
1025
1026 if (reqkey_defl == KEY_REQKEY_DEFL_NO_CHANGE)
1027 return old_setting;
1028
1029 new = prepare_creds();
1030 if (!new)
1031 return -ENOMEM;
1004 1032
1005 switch (reqkey_defl) { 1033 switch (reqkey_defl) {
1006 case KEY_REQKEY_DEFL_THREAD_KEYRING: 1034 case KEY_REQKEY_DEFL_THREAD_KEYRING:
1007 ret = install_thread_keyring(); 1035 ret = install_thread_keyring_to_cred(new);
1008 if (ret < 0) 1036 if (ret < 0)
1009 return ret; 1037 goto error;
1010 goto set; 1038 goto set;
1011 1039
1012 case KEY_REQKEY_DEFL_PROCESS_KEYRING: 1040 case KEY_REQKEY_DEFL_PROCESS_KEYRING:
1013 ret = install_process_keyring(); 1041 ret = install_process_keyring_to_cred(new);
1014 if (ret < 0) 1042 if (ret < 0) {
1015 return ret; 1043 if (ret != -EEXIST)
1044 goto error;
1045 ret = 0;
1046 }
1047 goto set;
1016 1048
1017 case KEY_REQKEY_DEFL_DEFAULT: 1049 case KEY_REQKEY_DEFL_DEFAULT:
1018 case KEY_REQKEY_DEFL_SESSION_KEYRING: 1050 case KEY_REQKEY_DEFL_SESSION_KEYRING:
1019 case KEY_REQKEY_DEFL_USER_KEYRING: 1051 case KEY_REQKEY_DEFL_USER_KEYRING:
1020 case KEY_REQKEY_DEFL_USER_SESSION_KEYRING: 1052 case KEY_REQKEY_DEFL_USER_SESSION_KEYRING:
1021 set: 1053 case KEY_REQKEY_DEFL_REQUESTOR_KEYRING:
1022 cred->jit_keyring = reqkey_defl; 1054 goto set;
1023 1055
1024 case KEY_REQKEY_DEFL_NO_CHANGE: 1056 case KEY_REQKEY_DEFL_NO_CHANGE:
1025 return cred->jit_keyring;
1026
1027 case KEY_REQKEY_DEFL_GROUP_KEYRING: 1057 case KEY_REQKEY_DEFL_GROUP_KEYRING:
1028 default: 1058 default:
1029 return -EINVAL; 1059 ret = -EINVAL;
1060 goto error;
1030 } 1061 }
1031 1062
1063set:
1064 new->jit_keyring = reqkey_defl;
1065 commit_creds(new);
1066 return old_setting;
1067error:
1068 abort_creds(new);
1069 return -EINVAL;
1070
1032} /* end keyctl_set_reqkey_keyring() */ 1071} /* end keyctl_set_reqkey_keyring() */
1033 1072
1034/*****************************************************************************/ 1073/*****************************************************************************/
@@ -1087,9 +1126,7 @@ long keyctl_assume_authority(key_serial_t id)
1087 1126
1088 /* we divest ourselves of authority if given an ID of 0 */ 1127 /* we divest ourselves of authority if given an ID of 0 */
1089 if (id == 0) { 1128 if (id == 0) {
1090 key_put(current->cred->request_key_auth); 1129 ret = keyctl_change_reqkey_auth(NULL);
1091 current->cred->request_key_auth = NULL;
1092 ret = 0;
1093 goto error; 1130 goto error;
1094 } 1131 }
1095 1132
@@ -1104,10 +1141,12 @@ long keyctl_assume_authority(key_serial_t id)
1104 goto error; 1141 goto error;
1105 } 1142 }
1106 1143
1107 key_put(current->cred->request_key_auth); 1144 ret = keyctl_change_reqkey_auth(authkey);
1108 current->cred->request_key_auth = authkey; 1145 if (ret < 0)
1109 ret = authkey->serial; 1146 goto error;
1147 key_put(authkey);
1110 1148
1149 ret = authkey->serial;
1111error: 1150error:
1112 return ret; 1151 return ret;
1113 1152
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index fdf75f901991..ed851574d073 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -245,14 +245,14 @@ static long keyring_read(const struct key *keyring,
245 * allocate a keyring and link into the destination keyring 245 * allocate a keyring and link into the destination keyring
246 */ 246 */
247struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid, 247struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
248 struct task_struct *ctx, unsigned long flags, 248 const struct cred *cred, unsigned long flags,
249 struct key *dest) 249 struct key *dest)
250{ 250{
251 struct key *keyring; 251 struct key *keyring;
252 int ret; 252 int ret;
253 253
254 keyring = key_alloc(&key_type_keyring, description, 254 keyring = key_alloc(&key_type_keyring, description,
255 uid, gid, ctx, 255 uid, gid, cred,
256 (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL, 256 (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
257 flags); 257 flags);
258 258
@@ -281,7 +281,7 @@ struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
281 * - we propagate the possession attribute from the keyring ref to the key ref 281 * - we propagate the possession attribute from the keyring ref to the key ref
282 */ 282 */
283key_ref_t keyring_search_aux(key_ref_t keyring_ref, 283key_ref_t keyring_search_aux(key_ref_t keyring_ref,
284 struct task_struct *context, 284 const struct cred *cred,
285 struct key_type *type, 285 struct key_type *type,
286 const void *description, 286 const void *description,
287 key_match_func_t match) 287 key_match_func_t match)
@@ -304,7 +304,7 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
304 key_check(keyring); 304 key_check(keyring);
305 305
306 /* top keyring must have search permission to begin the search */ 306 /* top keyring must have search permission to begin the search */
307 err = key_task_permission(keyring_ref, context, KEY_SEARCH); 307 err = key_task_permission(keyring_ref, cred, KEY_SEARCH);
308 if (err < 0) { 308 if (err < 0) {
309 key_ref = ERR_PTR(err); 309 key_ref = ERR_PTR(err);
310 goto error; 310 goto error;
@@ -377,7 +377,7 @@ descend:
377 377
378 /* key must have search permissions */ 378 /* key must have search permissions */
379 if (key_task_permission(make_key_ref(key, possessed), 379 if (key_task_permission(make_key_ref(key, possessed),
380 context, KEY_SEARCH) < 0) 380 cred, KEY_SEARCH) < 0)
381 continue; 381 continue;
382 382
383 /* we set a different error code if we pass a negative key */ 383 /* we set a different error code if we pass a negative key */
@@ -404,7 +404,7 @@ ascend:
404 continue; 404 continue;
405 405
406 if (key_task_permission(make_key_ref(key, possessed), 406 if (key_task_permission(make_key_ref(key, possessed),
407 context, KEY_SEARCH) < 0) 407 cred, KEY_SEARCH) < 0)
408 continue; 408 continue;
409 409
410 /* stack the current position */ 410 /* stack the current position */
@@ -459,7 +459,7 @@ key_ref_t keyring_search(key_ref_t keyring,
459 if (!type->match) 459 if (!type->match)
460 return ERR_PTR(-ENOKEY); 460 return ERR_PTR(-ENOKEY);
461 461
462 return keyring_search_aux(keyring, current, 462 return keyring_search_aux(keyring, current->cred,
463 type, description, type->match); 463 type, description, type->match);
464 464
465} /* end keyring_search() */ 465} /* end keyring_search() */
diff --git a/security/keys/permission.c b/security/keys/permission.c
index 13c36164f284..5d9fc7b93f2e 100644
--- a/security/keys/permission.c
+++ b/security/keys/permission.c
@@ -14,24 +14,27 @@
14#include "internal.h" 14#include "internal.h"
15 15
16/*****************************************************************************/ 16/*****************************************************************************/
17/* 17/**
18 * check to see whether permission is granted to use a key in the desired way, 18 * key_task_permission - Check a key can be used
19 * but permit the security modules to override 19 * @key_ref: The key to check
20 * @cred: The credentials to use
21 * @perm: The permissions to check for
22 *
23 * Check to see whether permission is granted to use a key in the desired way,
24 * but permit the security modules to override.
25 *
26 * The caller must hold either a ref on cred or must hold the RCU readlock or a
27 * spinlock.
20 */ 28 */
21int key_task_permission(const key_ref_t key_ref, 29int key_task_permission(const key_ref_t key_ref, const struct cred *cred,
22 struct task_struct *context,
23 key_perm_t perm) 30 key_perm_t perm)
24{ 31{
25 const struct cred *cred;
26 struct key *key; 32 struct key *key;
27 key_perm_t kperm; 33 key_perm_t kperm;
28 int ret; 34 int ret;
29 35
30 key = key_ref_to_ptr(key_ref); 36 key = key_ref_to_ptr(key_ref);
31 37
32 rcu_read_lock();
33 cred = __task_cred(context);
34
35 /* use the second 8-bits of permissions for keys the caller owns */ 38 /* use the second 8-bits of permissions for keys the caller owns */
36 if (key->uid == cred->fsuid) { 39 if (key->uid == cred->fsuid) {
37 kperm = key->perm >> 16; 40 kperm = key->perm >> 16;
@@ -57,7 +60,6 @@ int key_task_permission(const key_ref_t key_ref,
57 kperm = key->perm; 60 kperm = key->perm;
58 61
59use_these_perms: 62use_these_perms:
60 rcu_read_lock();
61 63
62 /* use the top 8-bits of permissions for keys the caller possesses 64 /* use the top 8-bits of permissions for keys the caller possesses
63 * - possessor permissions are additive with other permissions 65 * - possessor permissions are additive with other permissions
@@ -71,7 +73,7 @@ use_these_perms:
71 return -EACCES; 73 return -EACCES;
72 74
73 /* let LSM be the final arbiter */ 75 /* let LSM be the final arbiter */
74 return security_key_permission(key_ref, context, perm); 76 return security_key_permission(key_ref, cred, perm);
75 77
76} /* end key_task_permission() */ 78} /* end key_task_permission() */
77 79
diff --git a/security/keys/proc.c b/security/keys/proc.c
index f619170da760..7f508def50e3 100644
--- a/security/keys/proc.c
+++ b/security/keys/proc.c
@@ -136,8 +136,12 @@ static int proc_keys_show(struct seq_file *m, void *v)
136 int rc; 136 int rc;
137 137
138 /* check whether the current task is allowed to view the key (assuming 138 /* check whether the current task is allowed to view the key (assuming
139 * non-possession) */ 139 * non-possession)
140 rc = key_task_permission(make_key_ref(key, 0), current, KEY_VIEW); 140 * - the caller holds a spinlock, and thus the RCU read lock, making our
141 * access to __current_cred() safe
142 */
143 rc = key_task_permission(make_key_ref(key, 0), current_cred(),
144 KEY_VIEW);
141 if (rc < 0) 145 if (rc < 0)
142 return 0; 146 return 0;
143 147
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 70ee93406f30..df329f684a65 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -42,11 +42,15 @@ struct key_user root_key_user = {
42 */ 42 */
43int install_user_keyrings(void) 43int install_user_keyrings(void)
44{ 44{
45 struct user_struct *user = current->cred->user; 45 struct user_struct *user;
46 const struct cred *cred;
46 struct key *uid_keyring, *session_keyring; 47 struct key *uid_keyring, *session_keyring;
47 char buf[20]; 48 char buf[20];
48 int ret; 49 int ret;
49 50
51 cred = current_cred();
52 user = cred->user;
53
50 kenter("%p{%u}", user, user->uid); 54 kenter("%p{%u}", user, user->uid);
51 55
52 if (user->uid_keyring) { 56 if (user->uid_keyring) {
@@ -67,7 +71,7 @@ int install_user_keyrings(void)
67 uid_keyring = find_keyring_by_name(buf, true); 71 uid_keyring = find_keyring_by_name(buf, true);
68 if (IS_ERR(uid_keyring)) { 72 if (IS_ERR(uid_keyring)) {
69 uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, 73 uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1,
70 current, KEY_ALLOC_IN_QUOTA, 74 cred, KEY_ALLOC_IN_QUOTA,
71 NULL); 75 NULL);
72 if (IS_ERR(uid_keyring)) { 76 if (IS_ERR(uid_keyring)) {
73 ret = PTR_ERR(uid_keyring); 77 ret = PTR_ERR(uid_keyring);
@@ -83,8 +87,7 @@ int install_user_keyrings(void)
83 if (IS_ERR(session_keyring)) { 87 if (IS_ERR(session_keyring)) {
84 session_keyring = 88 session_keyring =
85 keyring_alloc(buf, user->uid, (gid_t) -1, 89 keyring_alloc(buf, user->uid, (gid_t) -1,
86 current, KEY_ALLOC_IN_QUOTA, 90 cred, KEY_ALLOC_IN_QUOTA, NULL);
87 NULL);
88 if (IS_ERR(session_keyring)) { 91 if (IS_ERR(session_keyring)) {
89 ret = PTR_ERR(session_keyring); 92 ret = PTR_ERR(session_keyring);
90 goto error_release; 93 goto error_release;
@@ -116,142 +119,128 @@ error:
116 return ret; 119 return ret;
117} 120}
118 121
119/*****************************************************************************/
120/* 122/*
121 * deal with the UID changing 123 * install a fresh thread keyring directly to new credentials
122 */ 124 */
123void switch_uid_keyring(struct user_struct *new_user) 125int install_thread_keyring_to_cred(struct cred *new)
124{ 126{
125#if 0 /* do nothing for now */ 127 struct key *keyring;
126 struct key *old;
127
128 /* switch to the new user's session keyring if we were running under
129 * root's default session keyring */
130 if (new_user->uid != 0 &&
131 current->session_keyring == &root_session_keyring
132 ) {
133 atomic_inc(&new_user->session_keyring->usage);
134
135 task_lock(current);
136 old = current->session_keyring;
137 current->session_keyring = new_user->session_keyring;
138 task_unlock(current);
139 128
140 key_put(old); 129 keyring = keyring_alloc("_tid", new->uid, new->gid, new,
141 } 130 KEY_ALLOC_QUOTA_OVERRUN, NULL);
142#endif 131 if (IS_ERR(keyring))
132 return PTR_ERR(keyring);
143 133
144} /* end switch_uid_keyring() */ 134 new->thread_keyring = keyring;
135 return 0;
136}
145 137
146/*****************************************************************************/
147/* 138/*
148 * install a fresh thread keyring, discarding the old one 139 * install a fresh thread keyring, discarding the old one
149 */ 140 */
150int install_thread_keyring(void) 141static int install_thread_keyring(void)
151{ 142{
152 struct task_struct *tsk = current; 143 struct cred *new;
153 struct key *keyring, *old;
154 char buf[20];
155 int ret; 144 int ret;
156 145
157 sprintf(buf, "_tid.%u", tsk->pid); 146 new = prepare_creds();
147 if (!new)
148 return -ENOMEM;
158 149
159 keyring = keyring_alloc(buf, tsk->cred->uid, tsk->cred->gid, tsk, 150 BUG_ON(new->thread_keyring);
160 KEY_ALLOC_QUOTA_OVERRUN, NULL); 151
161 if (IS_ERR(keyring)) { 152 ret = install_thread_keyring_to_cred(new);
162 ret = PTR_ERR(keyring); 153 if (ret < 0) {
163 goto error; 154 abort_creds(new);
155 return ret;
164 } 156 }
165 157
166 task_lock(tsk); 158 return commit_creds(new);
167 old = tsk->cred->thread_keyring; 159}
168 tsk->cred->thread_keyring = keyring;
169 task_unlock(tsk);
170 160
171 ret = 0; 161/*
162 * install a process keyring directly to a credentials struct
163 * - returns -EEXIST if there was already a process keyring, 0 if one installed,
164 * and other -ve on any other error
165 */
166int install_process_keyring_to_cred(struct cred *new)
167{
168 struct key *keyring;
169 int ret;
172 170
173 key_put(old); 171 if (new->tgcred->process_keyring)
174error: 172 return -EEXIST;
173
174 keyring = keyring_alloc("_pid", new->uid, new->gid,
175 new, KEY_ALLOC_QUOTA_OVERRUN, NULL);
176 if (IS_ERR(keyring))
177 return PTR_ERR(keyring);
178
179 spin_lock_irq(&new->tgcred->lock);
180 if (!new->tgcred->process_keyring) {
181 new->tgcred->process_keyring = keyring;
182 keyring = NULL;
183 ret = 0;
184 } else {
185 ret = -EEXIST;
186 }
187 spin_unlock_irq(&new->tgcred->lock);
188 key_put(keyring);
175 return ret; 189 return ret;
190}
176 191
177} /* end install_thread_keyring() */
178
179/*****************************************************************************/
180/* 192/*
181 * make sure a process keyring is installed 193 * make sure a process keyring is installed
194 * - we
182 */ 195 */
183int install_process_keyring(void) 196static int install_process_keyring(void)
184{ 197{
185 struct task_struct *tsk = current; 198 struct cred *new;
186 struct key *keyring;
187 char buf[20];
188 int ret; 199 int ret;
189 200
190 might_sleep(); 201 new = prepare_creds();
191 202 if (!new)
192 if (!tsk->cred->tgcred->process_keyring) { 203 return -ENOMEM;
193 sprintf(buf, "_pid.%u", tsk->tgid);
194
195 keyring = keyring_alloc(buf, tsk->cred->uid, tsk->cred->gid, tsk,
196 KEY_ALLOC_QUOTA_OVERRUN, NULL);
197 if (IS_ERR(keyring)) {
198 ret = PTR_ERR(keyring);
199 goto error;
200 }
201
202 /* attach keyring */
203 spin_lock_irq(&tsk->cred->tgcred->lock);
204 if (!tsk->cred->tgcred->process_keyring) {
205 tsk->cred->tgcred->process_keyring = keyring;
206 keyring = NULL;
207 }
208 spin_unlock_irq(&tsk->cred->tgcred->lock);
209 204
210 key_put(keyring); 205 ret = install_process_keyring_to_cred(new);
206 if (ret < 0) {
207 abort_creds(new);
208 return ret != -EEXIST ?: 0;
211 } 209 }
212 210
213 ret = 0; 211 return commit_creds(new);
214error: 212}
215 return ret;
216
217} /* end install_process_keyring() */
218 213
219/*****************************************************************************/
220/* 214/*
221 * install a session keyring, discarding the old one 215 * install a session keyring directly to a credentials struct
222 * - if a keyring is not supplied, an empty one is invented
223 */ 216 */
224static int install_session_keyring(struct key *keyring) 217static int install_session_keyring_to_cred(struct cred *cred,
218 struct key *keyring)
225{ 219{
226 struct task_struct *tsk = current;
227 unsigned long flags; 220 unsigned long flags;
228 struct key *old; 221 struct key *old;
229 char buf[20];
230 222
231 might_sleep(); 223 might_sleep();
232 224
233 /* create an empty session keyring */ 225 /* create an empty session keyring */
234 if (!keyring) { 226 if (!keyring) {
235 sprintf(buf, "_ses.%u", tsk->tgid);
236
237 flags = KEY_ALLOC_QUOTA_OVERRUN; 227 flags = KEY_ALLOC_QUOTA_OVERRUN;
238 if (tsk->cred->tgcred->session_keyring) 228 if (cred->tgcred->session_keyring)
239 flags = KEY_ALLOC_IN_QUOTA; 229 flags = KEY_ALLOC_IN_QUOTA;
240 230
241 keyring = keyring_alloc(buf, tsk->cred->uid, tsk->cred->gid, 231 keyring = keyring_alloc("_ses", cred->uid, cred->gid,
242 tsk, flags, NULL); 232 cred, flags, NULL);
243 if (IS_ERR(keyring)) 233 if (IS_ERR(keyring))
244 return PTR_ERR(keyring); 234 return PTR_ERR(keyring);
245 } 235 } else {
246 else {
247 atomic_inc(&keyring->usage); 236 atomic_inc(&keyring->usage);
248 } 237 }
249 238
250 /* install the keyring */ 239 /* install the keyring */
251 spin_lock_irq(&tsk->cred->tgcred->lock); 240 spin_lock_irq(&cred->tgcred->lock);
252 old = tsk->cred->tgcred->session_keyring; 241 old = cred->tgcred->session_keyring;
253 rcu_assign_pointer(tsk->cred->tgcred->session_keyring, keyring); 242 rcu_assign_pointer(cred->tgcred->session_keyring, keyring);
254 spin_unlock_irq(&tsk->cred->tgcred->lock); 243 spin_unlock_irq(&cred->tgcred->lock);
255 244
256 /* we're using RCU on the pointer, but there's no point synchronising 245 /* we're using RCU on the pointer, but there's no point synchronising
257 * on it if it didn't previously point to anything */ 246 * on it if it didn't previously point to anything */
@@ -261,38 +250,29 @@ static int install_session_keyring(struct key *keyring)
261 } 250 }
262 251
263 return 0; 252 return 0;
253}
264 254
265} /* end install_session_keyring() */
266
267/*****************************************************************************/
268/* 255/*
269 * copy the keys for fork 256 * install a session keyring, discarding the old one
257 * - if a keyring is not supplied, an empty one is invented
270 */ 258 */
271int copy_keys(unsigned long clone_flags, struct task_struct *tsk) 259static int install_session_keyring(struct key *keyring)
272{ 260{
273 key_check(tsk->cred->thread_keyring); 261 struct cred *new;
274 key_check(tsk->cred->request_key_auth); 262 int ret;
275
276 /* no thread keyring yet */
277 tsk->cred->thread_keyring = NULL;
278
279 /* copy the request_key() authorisation for this thread */
280 key_get(tsk->cred->request_key_auth);
281
282 return 0;
283 263
284} /* end copy_keys() */ 264 new = prepare_creds();
265 if (!new)
266 return -ENOMEM;
285 267
286/*****************************************************************************/ 268 ret = install_session_keyring_to_cred(new, NULL);
287/* 269 if (ret < 0) {
288 * dispose of per-thread keys upon thread exit 270 abort_creds(new);
289 */ 271 return ret;
290void exit_keys(struct task_struct *tsk) 272 }
291{
292 key_put(tsk->cred->thread_keyring);
293 key_put(tsk->cred->request_key_auth);
294 273
295} /* end exit_keys() */ 274 return commit_creds(new);
275}
296 276
297/*****************************************************************************/ 277/*****************************************************************************/
298/* 278/*
@@ -300,38 +280,41 @@ void exit_keys(struct task_struct *tsk)
300 */ 280 */
301int exec_keys(struct task_struct *tsk) 281int exec_keys(struct task_struct *tsk)
302{ 282{
303 struct key *old; 283 struct thread_group_cred *tgcred = NULL;
284 struct cred *new;
304 285
305 /* newly exec'd tasks don't get a thread keyring */ 286#ifdef CONFIG_KEYS
306 task_lock(tsk); 287 tgcred = kmalloc(sizeof(*tgcred), GFP_KERNEL);
307 old = tsk->cred->thread_keyring; 288 if (!tgcred)
308 tsk->cred->thread_keyring = NULL; 289 return -ENOMEM;
309 task_unlock(tsk); 290#endif
310 291
311 key_put(old); 292 new = prepare_creds();
293 if (new < 0)
294 return -ENOMEM;
312 295
313 /* discard the process keyring from a newly exec'd task */ 296 /* newly exec'd tasks don't get a thread keyring */
314 spin_lock_irq(&tsk->cred->tgcred->lock); 297 key_put(new->thread_keyring);
315 old = tsk->cred->tgcred->process_keyring; 298 new->thread_keyring = NULL;
316 tsk->cred->tgcred->process_keyring = NULL;
317 spin_unlock_irq(&tsk->cred->tgcred->lock);
318 299
319 key_put(old); 300 /* create a new per-thread-group creds for all this set of threads to
301 * share */
302 memcpy(tgcred, new->tgcred, sizeof(struct thread_group_cred));
320 303
321 return 0; 304 atomic_set(&tgcred->usage, 1);
305 spin_lock_init(&tgcred->lock);
322 306
323} /* end exec_keys() */ 307 /* inherit the session keyring; new process keyring */
308 key_get(tgcred->session_keyring);
309 tgcred->process_keyring = NULL;
324 310
325/*****************************************************************************/ 311 release_tgcred(new);
326/* 312 new->tgcred = tgcred;
327 * deal with SUID programs 313
328 * - we might want to make this invent a new session keyring 314 commit_creds(new);
329 */
330int suid_keys(struct task_struct *tsk)
331{
332 return 0; 315 return 0;
333 316
334} /* end suid_keys() */ 317} /* end exec_keys() */
335 318
336/*****************************************************************************/ 319/*****************************************************************************/
337/* 320/*
@@ -376,16 +359,13 @@ void key_fsgid_changed(struct task_struct *tsk)
376key_ref_t search_process_keyrings(struct key_type *type, 359key_ref_t search_process_keyrings(struct key_type *type,
377 const void *description, 360 const void *description,
378 key_match_func_t match, 361 key_match_func_t match,
379 struct task_struct *context) 362 const struct cred *cred)
380{ 363{
381 struct request_key_auth *rka; 364 struct request_key_auth *rka;
382 struct cred *cred;
383 key_ref_t key_ref, ret, err; 365 key_ref_t key_ref, ret, err;
384 366
385 might_sleep(); 367 might_sleep();
386 368
387 cred = get_task_cred(context);
388
389 /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were 369 /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were
390 * searchable, but we failed to find a key or we found a negative key; 370 * searchable, but we failed to find a key or we found a negative key;
391 * otherwise we want to return a sample error (probably -EACCES) if 371 * otherwise we want to return a sample error (probably -EACCES) if
@@ -401,7 +381,7 @@ key_ref_t search_process_keyrings(struct key_type *type,
401 if (cred->thread_keyring) { 381 if (cred->thread_keyring) {
402 key_ref = keyring_search_aux( 382 key_ref = keyring_search_aux(
403 make_key_ref(cred->thread_keyring, 1), 383 make_key_ref(cred->thread_keyring, 1),
404 context, type, description, match); 384 cred, type, description, match);
405 if (!IS_ERR(key_ref)) 385 if (!IS_ERR(key_ref))
406 goto found; 386 goto found;
407 387
@@ -422,7 +402,7 @@ key_ref_t search_process_keyrings(struct key_type *type,
422 if (cred->tgcred->process_keyring) { 402 if (cred->tgcred->process_keyring) {
423 key_ref = keyring_search_aux( 403 key_ref = keyring_search_aux(
424 make_key_ref(cred->tgcred->process_keyring, 1), 404 make_key_ref(cred->tgcred->process_keyring, 1),
425 context, type, description, match); 405 cred, type, description, match);
426 if (!IS_ERR(key_ref)) 406 if (!IS_ERR(key_ref))
427 goto found; 407 goto found;
428 408
@@ -446,7 +426,7 @@ key_ref_t search_process_keyrings(struct key_type *type,
446 make_key_ref(rcu_dereference( 426 make_key_ref(rcu_dereference(
447 cred->tgcred->session_keyring), 427 cred->tgcred->session_keyring),
448 1), 428 1),
449 context, type, description, match); 429 cred, type, description, match);
450 rcu_read_unlock(); 430 rcu_read_unlock();
451 431
452 if (!IS_ERR(key_ref)) 432 if (!IS_ERR(key_ref))
@@ -468,7 +448,7 @@ key_ref_t search_process_keyrings(struct key_type *type,
468 else if (cred->user->session_keyring) { 448 else if (cred->user->session_keyring) {
469 key_ref = keyring_search_aux( 449 key_ref = keyring_search_aux(
470 make_key_ref(cred->user->session_keyring, 1), 450 make_key_ref(cred->user->session_keyring, 1),
471 context, type, description, match); 451 cred, type, description, match);
472 if (!IS_ERR(key_ref)) 452 if (!IS_ERR(key_ref))
473 goto found; 453 goto found;
474 454
@@ -490,7 +470,7 @@ key_ref_t search_process_keyrings(struct key_type *type,
490 * - we don't permit access to request_key auth keys via this method 470 * - we don't permit access to request_key auth keys via this method
491 */ 471 */
492 if (cred->request_key_auth && 472 if (cred->request_key_auth &&
493 context == current && 473 cred == current_cred() &&
494 type != &key_type_request_key_auth 474 type != &key_type_request_key_auth
495 ) { 475 ) {
496 /* defend against the auth key being revoked */ 476 /* defend against the auth key being revoked */
@@ -500,7 +480,7 @@ key_ref_t search_process_keyrings(struct key_type *type,
500 rka = cred->request_key_auth->payload.data; 480 rka = cred->request_key_auth->payload.data;
501 481
502 key_ref = search_process_keyrings(type, description, 482 key_ref = search_process_keyrings(type, description,
503 match, rka->context); 483 match, rka->cred);
504 484
505 up_read(&cred->request_key_auth->sem); 485 up_read(&cred->request_key_auth->sem);
506 486
@@ -527,7 +507,6 @@ key_ref_t search_process_keyrings(struct key_type *type,
527 key_ref = ret ? ret : err; 507 key_ref = ret ? ret : err;
528 508
529found: 509found:
530 put_cred(cred);
531 return key_ref; 510 return key_ref;
532 511
533} /* end search_process_keyrings() */ 512} /* end search_process_keyrings() */
@@ -552,8 +531,7 @@ key_ref_t lookup_user_key(key_serial_t id, int create, int partial,
552 key_perm_t perm) 531 key_perm_t perm)
553{ 532{
554 struct request_key_auth *rka; 533 struct request_key_auth *rka;
555 struct task_struct *t = current; 534 const struct cred *cred;
556 struct cred *cred;
557 struct key *key; 535 struct key *key;
558 key_ref_t key_ref, skey_ref; 536 key_ref_t key_ref, skey_ref;
559 int ret; 537 int ret;
@@ -608,6 +586,7 @@ try_again:
608 goto error; 586 goto error;
609 ret = install_session_keyring( 587 ret = install_session_keyring(
610 cred->user->session_keyring); 588 cred->user->session_keyring);
589
611 if (ret < 0) 590 if (ret < 0)
612 goto error; 591 goto error;
613 goto reget_creds; 592 goto reget_creds;
@@ -693,7 +672,7 @@ try_again:
693 /* check to see if we possess the key */ 672 /* check to see if we possess the key */
694 skey_ref = search_process_keyrings(key->type, key, 673 skey_ref = search_process_keyrings(key->type, key,
695 lookup_user_key_possessed, 674 lookup_user_key_possessed,
696 current); 675 cred);
697 676
698 if (!IS_ERR(skey_ref)) { 677 if (!IS_ERR(skey_ref)) {
699 key_put(key); 678 key_put(key);
@@ -725,7 +704,7 @@ try_again:
725 goto invalid_key; 704 goto invalid_key;
726 705
727 /* check the permissions */ 706 /* check the permissions */
728 ret = key_task_permission(key_ref, t, perm); 707 ret = key_task_permission(key_ref, cred, perm);
729 if (ret < 0) 708 if (ret < 0)
730 goto invalid_key; 709 goto invalid_key;
731 710
@@ -755,21 +734,33 @@ reget_creds:
755 */ 734 */
756long join_session_keyring(const char *name) 735long join_session_keyring(const char *name)
757{ 736{
758 struct task_struct *tsk = current; 737 const struct cred *old;
759 struct cred *cred = current->cred; 738 struct cred *new;
760 struct key *keyring; 739 struct key *keyring;
761 long ret; 740 long ret, serial;
741
742 /* only permit this if there's a single thread in the thread group -
743 * this avoids us having to adjust the creds on all threads and risking
744 * ENOMEM */
745 if (!is_single_threaded(current))
746 return -EMLINK;
747
748 new = prepare_creds();
749 if (!new)
750 return -ENOMEM;
751 old = current_cred();
762 752
763 /* if no name is provided, install an anonymous keyring */ 753 /* if no name is provided, install an anonymous keyring */
764 if (!name) { 754 if (!name) {
765 ret = install_session_keyring(NULL); 755 ret = install_session_keyring_to_cred(new, NULL);
766 if (ret < 0) 756 if (ret < 0)
767 goto error; 757 goto error;
768 758
769 rcu_read_lock(); 759 serial = new->tgcred->session_keyring->serial;
770 ret = rcu_dereference(cred->tgcred->session_keyring)->serial; 760 ret = commit_creds(new);
771 rcu_read_unlock(); 761 if (ret == 0)
772 goto error; 762 ret = serial;
763 goto okay;
773 } 764 }
774 765
775 /* allow the user to join or create a named keyring */ 766 /* allow the user to join or create a named keyring */
@@ -779,29 +770,33 @@ long join_session_keyring(const char *name)
779 keyring = find_keyring_by_name(name, false); 770 keyring = find_keyring_by_name(name, false);
780 if (PTR_ERR(keyring) == -ENOKEY) { 771 if (PTR_ERR(keyring) == -ENOKEY) {
781 /* not found - try and create a new one */ 772 /* not found - try and create a new one */
782 keyring = keyring_alloc(name, cred->uid, cred->gid, tsk, 773 keyring = keyring_alloc(name, old->uid, old->gid, old,
783 KEY_ALLOC_IN_QUOTA, NULL); 774 KEY_ALLOC_IN_QUOTA, NULL);
784 if (IS_ERR(keyring)) { 775 if (IS_ERR(keyring)) {
785 ret = PTR_ERR(keyring); 776 ret = PTR_ERR(keyring);
786 goto error2; 777 goto error2;
787 } 778 }
788 } 779 } else if (IS_ERR(keyring)) {
789 else if (IS_ERR(keyring)) {
790 ret = PTR_ERR(keyring); 780 ret = PTR_ERR(keyring);
791 goto error2; 781 goto error2;
792 } 782 }
793 783
794 /* we've got a keyring - now to install it */ 784 /* we've got a keyring - now to install it */
795 ret = install_session_keyring(keyring); 785 ret = install_session_keyring_to_cred(new, keyring);
796 if (ret < 0) 786 if (ret < 0)
797 goto error2; 787 goto error2;
798 788
789 commit_creds(new);
790 mutex_unlock(&key_session_mutex);
791
799 ret = keyring->serial; 792 ret = keyring->serial;
800 key_put(keyring); 793 key_put(keyring);
794okay:
795 return ret;
801 796
802error2: 797error2:
803 mutex_unlock(&key_session_mutex); 798 mutex_unlock(&key_session_mutex);
804error: 799error:
800 abort_creds(new);
805 return ret; 801 return ret;
806 802}
807} /* end join_session_keyring() */
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 3d12558362df..0e04f72ef2d4 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -83,8 +83,10 @@ static int call_sbin_request_key(struct key_construction *cons,
83 /* allocate a new session keyring */ 83 /* allocate a new session keyring */
84 sprintf(desc, "_req.%u", key->serial); 84 sprintf(desc, "_req.%u", key->serial);
85 85
86 keyring = keyring_alloc(desc, current_fsuid(), current_fsgid(), current, 86 cred = get_current_cred();
87 keyring = keyring_alloc(desc, cred->fsuid, cred->fsgid, cred,
87 KEY_ALLOC_QUOTA_OVERRUN, NULL); 88 KEY_ALLOC_QUOTA_OVERRUN, NULL);
89 put_cred(cred);
88 if (IS_ERR(keyring)) { 90 if (IS_ERR(keyring)) {
89 ret = PTR_ERR(keyring); 91 ret = PTR_ERR(keyring);
90 goto error_alloc; 92 goto error_alloc;
@@ -104,8 +106,7 @@ static int call_sbin_request_key(struct key_construction *cons,
104 106
105 /* we specify the process's default keyrings */ 107 /* we specify the process's default keyrings */
106 sprintf(keyring_str[0], "%d", 108 sprintf(keyring_str[0], "%d",
107 cred->thread_keyring ? 109 cred->thread_keyring ? cred->thread_keyring->serial : 0);
108 cred->thread_keyring->serial : 0);
109 110
110 prkey = 0; 111 prkey = 0;
111 if (cred->tgcred->process_keyring) 112 if (cred->tgcred->process_keyring)
@@ -155,8 +156,8 @@ error_link:
155 key_put(keyring); 156 key_put(keyring);
156 157
157error_alloc: 158error_alloc:
158 kleave(" = %d", ret);
159 complete_request_key(cons, ret); 159 complete_request_key(cons, ret);
160 kleave(" = %d", ret);
160 return ret; 161 return ret;
161} 162}
162 163
@@ -295,6 +296,7 @@ static int construct_alloc_key(struct key_type *type,
295 struct key_user *user, 296 struct key_user *user,
296 struct key **_key) 297 struct key **_key)
297{ 298{
299 const struct cred *cred = current_cred();
298 struct key *key; 300 struct key *key;
299 key_ref_t key_ref; 301 key_ref_t key_ref;
300 302
@@ -302,9 +304,8 @@ static int construct_alloc_key(struct key_type *type,
302 304
303 mutex_lock(&user->cons_lock); 305 mutex_lock(&user->cons_lock);
304 306
305 key = key_alloc(type, description, 307 key = key_alloc(type, description, cred->fsuid, cred->fsgid, cred,
306 current_fsuid(), current_fsgid(), current, KEY_POS_ALL, 308 KEY_POS_ALL, flags);
307 flags);
308 if (IS_ERR(key)) 309 if (IS_ERR(key))
309 goto alloc_failed; 310 goto alloc_failed;
310 311
@@ -317,8 +318,7 @@ static int construct_alloc_key(struct key_type *type,
317 * waited for locks */ 318 * waited for locks */
318 mutex_lock(&key_construction_mutex); 319 mutex_lock(&key_construction_mutex);
319 320
320 key_ref = search_process_keyrings(type, description, type->match, 321 key_ref = search_process_keyrings(type, description, type->match, cred);
321 current);
322 if (!IS_ERR(key_ref)) 322 if (!IS_ERR(key_ref))
323 goto key_already_present; 323 goto key_already_present;
324 324
@@ -363,6 +363,8 @@ static struct key *construct_key_and_link(struct key_type *type,
363 struct key *key; 363 struct key *key;
364 int ret; 364 int ret;
365 365
366 kenter("");
367
366 user = key_user_lookup(current_fsuid()); 368 user = key_user_lookup(current_fsuid());
367 if (!user) 369 if (!user)
368 return ERR_PTR(-ENOMEM); 370 return ERR_PTR(-ENOMEM);
@@ -376,17 +378,21 @@ static struct key *construct_key_and_link(struct key_type *type,
376 if (ret == 0) { 378 if (ret == 0) {
377 ret = construct_key(key, callout_info, callout_len, aux, 379 ret = construct_key(key, callout_info, callout_len, aux,
378 dest_keyring); 380 dest_keyring);
379 if (ret < 0) 381 if (ret < 0) {
382 kdebug("cons failed");
380 goto construction_failed; 383 goto construction_failed;
384 }
381 } 385 }
382 386
383 key_put(dest_keyring); 387 key_put(dest_keyring);
388 kleave(" = key %d", key_serial(key));
384 return key; 389 return key;
385 390
386construction_failed: 391construction_failed:
387 key_negate_and_link(key, key_negative_timeout, NULL, NULL); 392 key_negate_and_link(key, key_negative_timeout, NULL, NULL);
388 key_put(key); 393 key_put(key);
389 key_put(dest_keyring); 394 key_put(dest_keyring);
395 kleave(" = %d", ret);
390 return ERR_PTR(ret); 396 return ERR_PTR(ret);
391} 397}
392 398
@@ -405,6 +411,7 @@ struct key *request_key_and_link(struct key_type *type,
405 struct key *dest_keyring, 411 struct key *dest_keyring,
406 unsigned long flags) 412 unsigned long flags)
407{ 413{
414 const struct cred *cred = current_cred();
408 struct key *key; 415 struct key *key;
409 key_ref_t key_ref; 416 key_ref_t key_ref;
410 417
@@ -414,7 +421,7 @@ struct key *request_key_and_link(struct key_type *type,
414 421
415 /* search all the process keyrings for a key */ 422 /* search all the process keyrings for a key */
416 key_ref = search_process_keyrings(type, description, type->match, 423 key_ref = search_process_keyrings(type, description, type->match,
417 current); 424 cred);
418 425
419 if (!IS_ERR(key_ref)) { 426 if (!IS_ERR(key_ref)) {
420 key = key_ref_to_ptr(key_ref); 427 key = key_ref_to_ptr(key_ref);
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index 2125579d5d73..86747151ee5b 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -105,9 +105,9 @@ static void request_key_auth_revoke(struct key *key)
105 105
106 kenter("{%d}", key->serial); 106 kenter("{%d}", key->serial);
107 107
108 if (rka->context) { 108 if (rka->cred) {
109 put_task_struct(rka->context); 109 put_cred(rka->cred);
110 rka->context = NULL; 110 rka->cred = NULL;
111 } 111 }
112 112
113} /* end request_key_auth_revoke() */ 113} /* end request_key_auth_revoke() */
@@ -122,9 +122,9 @@ static void request_key_auth_destroy(struct key *key)
122 122
123 kenter("{%d}", key->serial); 123 kenter("{%d}", key->serial);
124 124
125 if (rka->context) { 125 if (rka->cred) {
126 put_task_struct(rka->context); 126 put_cred(rka->cred);
127 rka->context = NULL; 127 rka->cred = NULL;
128 } 128 }
129 129
130 key_put(rka->target_key); 130 key_put(rka->target_key);
@@ -143,6 +143,7 @@ struct key *request_key_auth_new(struct key *target, const void *callout_info,
143 size_t callout_len, struct key *dest_keyring) 143 size_t callout_len, struct key *dest_keyring)
144{ 144{
145 struct request_key_auth *rka, *irka; 145 struct request_key_auth *rka, *irka;
146 const struct cred *cred = current->cred;
146 struct key *authkey = NULL; 147 struct key *authkey = NULL;
147 char desc[20]; 148 char desc[20];
148 int ret; 149 int ret;
@@ -164,28 +165,25 @@ struct key *request_key_auth_new(struct key *target, const void *callout_info,
164 165
165 /* see if the calling process is already servicing the key request of 166 /* see if the calling process is already servicing the key request of
166 * another process */ 167 * another process */
167 if (current->cred->request_key_auth) { 168 if (cred->request_key_auth) {
168 /* it is - use that instantiation context here too */ 169 /* it is - use that instantiation context here too */
169 down_read(&current->cred->request_key_auth->sem); 170 down_read(&cred->request_key_auth->sem);
170 171
171 /* if the auth key has been revoked, then the key we're 172 /* if the auth key has been revoked, then the key we're
172 * servicing is already instantiated */ 173 * servicing is already instantiated */
173 if (test_bit(KEY_FLAG_REVOKED, 174 if (test_bit(KEY_FLAG_REVOKED, &cred->request_key_auth->flags))
174 &current->cred->request_key_auth->flags))
175 goto auth_key_revoked; 175 goto auth_key_revoked;
176 176
177 irka = current->cred->request_key_auth->payload.data; 177 irka = cred->request_key_auth->payload.data;
178 rka->context = irka->context; 178 rka->cred = get_cred(irka->cred);
179 rka->pid = irka->pid; 179 rka->pid = irka->pid;
180 get_task_struct(rka->context);
181 180
182 up_read(&current->cred->request_key_auth->sem); 181 up_read(&cred->request_key_auth->sem);
183 } 182 }
184 else { 183 else {
185 /* it isn't - use this process as the context */ 184 /* it isn't - use this process as the context */
186 rka->context = current; 185 rka->cred = get_cred(cred);
187 rka->pid = current->pid; 186 rka->pid = current->pid;
188 get_task_struct(rka->context);
189 } 187 }
190 188
191 rka->target_key = key_get(target); 189 rka->target_key = key_get(target);
@@ -197,7 +195,7 @@ struct key *request_key_auth_new(struct key *target, const void *callout_info,
197 sprintf(desc, "%x", target->serial); 195 sprintf(desc, "%x", target->serial);
198 196
199 authkey = key_alloc(&key_type_request_key_auth, desc, 197 authkey = key_alloc(&key_type_request_key_auth, desc,
200 current_fsuid(), current_fsgid(), current, 198 cred->fsuid, cred->fsgid, cred,
201 KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH | 199 KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH |
202 KEY_USR_VIEW, KEY_ALLOC_NOT_IN_QUOTA); 200 KEY_USR_VIEW, KEY_ALLOC_NOT_IN_QUOTA);
203 if (IS_ERR(authkey)) { 201 if (IS_ERR(authkey)) {
@@ -205,16 +203,16 @@ struct key *request_key_auth_new(struct key *target, const void *callout_info,
205 goto error_alloc; 203 goto error_alloc;
206 } 204 }
207 205
208 /* construct and attach to the keyring */ 206 /* construct the auth key */
209 ret = key_instantiate_and_link(authkey, rka, 0, NULL, NULL); 207 ret = key_instantiate_and_link(authkey, rka, 0, NULL, NULL);
210 if (ret < 0) 208 if (ret < 0)
211 goto error_inst; 209 goto error_inst;
212 210
213 kleave(" = {%d}", authkey->serial); 211 kleave(" = {%d,%d}", authkey->serial, atomic_read(&authkey->usage));
214 return authkey; 212 return authkey;
215 213
216auth_key_revoked: 214auth_key_revoked:
217 up_read(&current->cred->request_key_auth->sem); 215 up_read(&cred->request_key_auth->sem);
218 kfree(rka->callout_info); 216 kfree(rka->callout_info);
219 kfree(rka); 217 kfree(rka);
220 kleave("= -EKEYREVOKED"); 218 kleave("= -EKEYREVOKED");
@@ -257,6 +255,7 @@ static int key_get_instantiation_authkey_match(const struct key *key,
257 */ 255 */
258struct key *key_get_instantiation_authkey(key_serial_t target_id) 256struct key *key_get_instantiation_authkey(key_serial_t target_id)
259{ 257{
258 const struct cred *cred = current_cred();
260 struct key *authkey; 259 struct key *authkey;
261 key_ref_t authkey_ref; 260 key_ref_t authkey_ref;
262 261
@@ -264,7 +263,7 @@ struct key *key_get_instantiation_authkey(key_serial_t target_id)
264 &key_type_request_key_auth, 263 &key_type_request_key_auth,
265 (void *) (unsigned long) target_id, 264 (void *) (unsigned long) target_id,
266 key_get_instantiation_authkey_match, 265 key_get_instantiation_authkey_match,
267 current); 266 cred);
268 267
269 if (IS_ERR(authkey_ref)) { 268 if (IS_ERR(authkey_ref)) {
270 authkey = ERR_CAST(authkey_ref); 269 authkey = ERR_CAST(authkey_ref);
diff --git a/security/security.c b/security/security.c
index f40a0a04c3c2..a55d739c6864 100644
--- a/security/security.c
+++ b/security/security.c
@@ -145,18 +145,13 @@ int security_capget(struct task_struct *target,
145 return security_ops->capget(target, effective, inheritable, permitted); 145 return security_ops->capget(target, effective, inheritable, permitted);
146} 146}
147 147
148int security_capset_check(const kernel_cap_t *effective, 148int security_capset(struct cred *new, const struct cred *old,
149 const kernel_cap_t *inheritable, 149 const kernel_cap_t *effective,
150 const kernel_cap_t *permitted) 150 const kernel_cap_t *inheritable,
151 const kernel_cap_t *permitted)
151{ 152{
152 return security_ops->capset_check(effective, inheritable, permitted); 153 return security_ops->capset(new, old,
153} 154 effective, inheritable, permitted);
154
155void security_capset_set(const kernel_cap_t *effective,
156 const kernel_cap_t *inheritable,
157 const kernel_cap_t *permitted)
158{
159 security_ops->capset_set(effective, inheritable, permitted);
160} 155}
161 156
162int security_capable(struct task_struct *tsk, int cap) 157int security_capable(struct task_struct *tsk, int cap)
@@ -228,9 +223,9 @@ void security_bprm_free(struct linux_binprm *bprm)
228 security_ops->bprm_free_security(bprm); 223 security_ops->bprm_free_security(bprm);
229} 224}
230 225
231void security_bprm_apply_creds(struct linux_binprm *bprm, int unsafe) 226int security_bprm_apply_creds(struct linux_binprm *bprm, int unsafe)
232{ 227{
233 security_ops->bprm_apply_creds(bprm, unsafe); 228 return security_ops->bprm_apply_creds(bprm, unsafe);
234} 229}
235 230
236void security_bprm_post_apply_creds(struct linux_binprm *bprm) 231void security_bprm_post_apply_creds(struct linux_binprm *bprm)
@@ -616,14 +611,19 @@ int security_task_create(unsigned long clone_flags)
616 return security_ops->task_create(clone_flags); 611 return security_ops->task_create(clone_flags);
617} 612}
618 613
619int security_cred_alloc(struct cred *cred) 614void security_cred_free(struct cred *cred)
620{ 615{
621 return security_ops->cred_alloc_security(cred); 616 security_ops->cred_free(cred);
622} 617}
623 618
624void security_cred_free(struct cred *cred) 619int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp)
625{ 620{
626 security_ops->cred_free(cred); 621 return security_ops->cred_prepare(new, old, gfp);
622}
623
624void security_commit_creds(struct cred *new, const struct cred *old)
625{
626 return security_ops->cred_commit(new, old);
627} 627}
628 628
629int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags) 629int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags)
@@ -631,10 +631,10 @@ int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags)
631 return security_ops->task_setuid(id0, id1, id2, flags); 631 return security_ops->task_setuid(id0, id1, id2, flags);
632} 632}
633 633
634int security_task_post_setuid(uid_t old_ruid, uid_t old_euid, 634int security_task_fix_setuid(struct cred *new, const struct cred *old,
635 uid_t old_suid, int flags) 635 int flags)
636{ 636{
637 return security_ops->task_post_setuid(old_ruid, old_euid, old_suid, flags); 637 return security_ops->task_fix_setuid(new, old, flags);
638} 638}
639 639
640int security_task_setgid(gid_t id0, gid_t id1, gid_t id2, int flags) 640int security_task_setgid(gid_t id0, gid_t id1, gid_t id2, int flags)
@@ -716,14 +716,9 @@ int security_task_wait(struct task_struct *p)
716} 716}
717 717
718int security_task_prctl(int option, unsigned long arg2, unsigned long arg3, 718int security_task_prctl(int option, unsigned long arg2, unsigned long arg3,
719 unsigned long arg4, unsigned long arg5, long *rc_p) 719 unsigned long arg4, unsigned long arg5)
720{
721 return security_ops->task_prctl(option, arg2, arg3, arg4, arg5, rc_p);
722}
723
724void security_task_reparent_to_init(struct task_struct *p)
725{ 720{
726 security_ops->task_reparent_to_init(p); 721 return security_ops->task_prctl(option, arg2, arg3, arg4, arg5);
727} 722}
728 723
729void security_task_to_inode(struct task_struct *p, struct inode *inode) 724void security_task_to_inode(struct task_struct *p, struct inode *inode)
@@ -1123,9 +1118,10 @@ EXPORT_SYMBOL(security_skb_classify_flow);
1123 1118
1124#ifdef CONFIG_KEYS 1119#ifdef CONFIG_KEYS
1125 1120
1126int security_key_alloc(struct key *key, struct task_struct *tsk, unsigned long flags) 1121int security_key_alloc(struct key *key, const struct cred *cred,
1122 unsigned long flags)
1127{ 1123{
1128 return security_ops->key_alloc(key, tsk, flags); 1124 return security_ops->key_alloc(key, cred, flags);
1129} 1125}
1130 1126
1131void security_key_free(struct key *key) 1127void security_key_free(struct key *key)
@@ -1134,9 +1130,9 @@ void security_key_free(struct key *key)
1134} 1130}
1135 1131
1136int security_key_permission(key_ref_t key_ref, 1132int security_key_permission(key_ref_t key_ref,
1137 struct task_struct *context, key_perm_t perm) 1133 const struct cred *cred, key_perm_t perm)
1138{ 1134{
1139 return security_ops->key_permission(key_ref, context, perm); 1135 return security_ops->key_permission(key_ref, cred, perm);
1140} 1136}
1141 1137
1142int security_key_getsecurity(struct key *key, char **_buffer) 1138int security_key_getsecurity(struct key *key, char **_buffer)
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index f20cbd681ba6..c71bba78872f 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -156,20 +156,20 @@ static int selinux_secmark_enabled(void)
156 return (atomic_read(&selinux_secmark_refcount) > 0); 156 return (atomic_read(&selinux_secmark_refcount) > 0);
157} 157}
158 158
159/* Allocate and free functions for each kind of security blob. */ 159/*
160 160 * initialise the security for the init task
161static int cred_alloc_security(struct cred *cred) 161 */
162static void cred_init_security(void)
162{ 163{
164 struct cred *cred = (struct cred *) current->cred;
163 struct task_security_struct *tsec; 165 struct task_security_struct *tsec;
164 166
165 tsec = kzalloc(sizeof(struct task_security_struct), GFP_KERNEL); 167 tsec = kzalloc(sizeof(struct task_security_struct), GFP_KERNEL);
166 if (!tsec) 168 if (!tsec)
167 return -ENOMEM; 169 panic("SELinux: Failed to initialize initial task.\n");
168 170
169 tsec->osid = tsec->sid = SECINITSID_UNLABELED; 171 tsec->osid = tsec->sid = SECINITSID_KERNEL;
170 cred->security = tsec; 172 cred->security = tsec;
171
172 return 0;
173} 173}
174 174
175/* 175/*
@@ -1379,6 +1379,19 @@ static inline u32 signal_to_av(int sig)
1379} 1379}
1380 1380
1381/* 1381/*
1382 * Check permission between a pair of credentials
1383 * fork check, ptrace check, etc.
1384 */
1385static int cred_has_perm(const struct cred *actor,
1386 const struct cred *target,
1387 u32 perms)
1388{
1389 u32 asid = cred_sid(actor), tsid = cred_sid(target);
1390
1391 return avc_has_perm(asid, tsid, SECCLASS_PROCESS, perms, NULL);
1392}
1393
1394/*
1382 * Check permission between a pair of tasks, e.g. signal checks, 1395 * Check permission between a pair of tasks, e.g. signal checks,
1383 * fork check, ptrace check, etc. 1396 * fork check, ptrace check, etc.
1384 * tsk1 is the actor and tsk2 is the target 1397 * tsk1 is the actor and tsk2 is the target
@@ -1820,24 +1833,19 @@ static int selinux_capget(struct task_struct *target, kernel_cap_t *effective,
1820 return secondary_ops->capget(target, effective, inheritable, permitted); 1833 return secondary_ops->capget(target, effective, inheritable, permitted);
1821} 1834}
1822 1835
1823static int selinux_capset_check(const kernel_cap_t *effective, 1836static int selinux_capset(struct cred *new, const struct cred *old,
1824 const kernel_cap_t *inheritable, 1837 const kernel_cap_t *effective,
1825 const kernel_cap_t *permitted) 1838 const kernel_cap_t *inheritable,
1839 const kernel_cap_t *permitted)
1826{ 1840{
1827 int error; 1841 int error;
1828 1842
1829 error = secondary_ops->capset_check(effective, inheritable, permitted); 1843 error = secondary_ops->capset(new, old,
1844 effective, inheritable, permitted);
1830 if (error) 1845 if (error)
1831 return error; 1846 return error;
1832 1847
1833 return task_has_perm(current, current, PROCESS__SETCAP); 1848 return cred_has_perm(old, new, PROCESS__SETCAP);
1834}
1835
1836static void selinux_capset_set(const kernel_cap_t *effective,
1837 const kernel_cap_t *inheritable,
1838 const kernel_cap_t *permitted)
1839{
1840 secondary_ops->capset_set(effective, inheritable, permitted);
1841} 1849}
1842 1850
1843static int selinux_capable(struct task_struct *tsk, int cap, int audit) 1851static int selinux_capable(struct task_struct *tsk, int cap, int audit)
@@ -2244,16 +2252,23 @@ static inline void flush_unauthorized_files(const struct cred *cred,
2244 spin_unlock(&files->file_lock); 2252 spin_unlock(&files->file_lock);
2245} 2253}
2246 2254
2247static void selinux_bprm_apply_creds(struct linux_binprm *bprm, int unsafe) 2255static int selinux_bprm_apply_creds(struct linux_binprm *bprm, int unsafe)
2248{ 2256{
2249 struct task_security_struct *tsec; 2257 struct task_security_struct *tsec;
2250 struct bprm_security_struct *bsec; 2258 struct bprm_security_struct *bsec;
2259 struct cred *new;
2251 u32 sid; 2260 u32 sid;
2252 int rc; 2261 int rc;
2253 2262
2254 secondary_ops->bprm_apply_creds(bprm, unsafe); 2263 rc = secondary_ops->bprm_apply_creds(bprm, unsafe);
2264 if (rc < 0)
2265 return rc;
2255 2266
2256 tsec = current_security(); 2267 new = prepare_creds();
2268 if (!new)
2269 return -ENOMEM;
2270
2271 tsec = new->security;
2257 2272
2258 bsec = bprm->security; 2273 bsec = bprm->security;
2259 sid = bsec->sid; 2274 sid = bsec->sid;
@@ -2268,7 +2283,7 @@ static void selinux_bprm_apply_creds(struct linux_binprm *bprm, int unsafe)
2268 PROCESS__SHARE, NULL); 2283 PROCESS__SHARE, NULL);
2269 if (rc) { 2284 if (rc) {
2270 bsec->unsafe = 1; 2285 bsec->unsafe = 1;
2271 return; 2286 goto out;
2272 } 2287 }
2273 } 2288 }
2274 2289
@@ -2292,12 +2307,16 @@ static void selinux_bprm_apply_creds(struct linux_binprm *bprm, int unsafe)
2292 PROCESS__PTRACE, NULL); 2307 PROCESS__PTRACE, NULL);
2293 if (rc) { 2308 if (rc) {
2294 bsec->unsafe = 1; 2309 bsec->unsafe = 1;
2295 return; 2310 goto out;
2296 } 2311 }
2297 } 2312 }
2298 } 2313 }
2299 tsec->sid = sid; 2314 tsec->sid = sid;
2300 } 2315 }
2316
2317out:
2318 commit_creds(new);
2319 return 0;
2301} 2320}
2302 2321
2303/* 2322/*
@@ -3021,6 +3040,7 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd,
3021static int file_map_prot_check(struct file *file, unsigned long prot, int shared) 3040static int file_map_prot_check(struct file *file, unsigned long prot, int shared)
3022{ 3041{
3023 const struct cred *cred = current_cred(); 3042 const struct cred *cred = current_cred();
3043 int rc = 0;
3024 3044
3025#ifndef CONFIG_PPC32 3045#ifndef CONFIG_PPC32
3026 if ((prot & PROT_EXEC) && (!file || (!shared && (prot & PROT_WRITE)))) { 3046 if ((prot & PROT_EXEC) && (!file || (!shared && (prot & PROT_WRITE)))) {
@@ -3029,9 +3049,9 @@ static int file_map_prot_check(struct file *file, unsigned long prot, int shared
3029 * private file mapping that will also be writable. 3049 * private file mapping that will also be writable.
3030 * This has an additional check. 3050 * This has an additional check.
3031 */ 3051 */
3032 int rc = task_has_perm(current, current, PROCESS__EXECMEM); 3052 rc = cred_has_perm(cred, cred, PROCESS__EXECMEM);
3033 if (rc) 3053 if (rc)
3034 return rc; 3054 goto error;
3035 } 3055 }
3036#endif 3056#endif
3037 3057
@@ -3048,7 +3068,9 @@ static int file_map_prot_check(struct file *file, unsigned long prot, int shared
3048 3068
3049 return file_has_perm(cred, file, av); 3069 return file_has_perm(cred, file, av);
3050 } 3070 }
3051 return 0; 3071
3072error:
3073 return rc;
3052} 3074}
3053 3075
3054static int selinux_file_mmap(struct file *file, unsigned long reqprot, 3076static int selinux_file_mmap(struct file *file, unsigned long reqprot,
@@ -3090,8 +3112,7 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
3090 rc = 0; 3112 rc = 0;
3091 if (vma->vm_start >= vma->vm_mm->start_brk && 3113 if (vma->vm_start >= vma->vm_mm->start_brk &&
3092 vma->vm_end <= vma->vm_mm->brk) { 3114 vma->vm_end <= vma->vm_mm->brk) {
3093 rc = task_has_perm(current, current, 3115 rc = cred_has_perm(cred, cred, PROCESS__EXECHEAP);
3094 PROCESS__EXECHEAP);
3095 } else if (!vma->vm_file && 3116 } else if (!vma->vm_file &&
3096 vma->vm_start <= vma->vm_mm->start_stack && 3117 vma->vm_start <= vma->vm_mm->start_stack &&
3097 vma->vm_end >= vma->vm_mm->start_stack) { 3118 vma->vm_end >= vma->vm_mm->start_stack) {
@@ -3104,8 +3125,7 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
3104 * modified content. This typically should only 3125 * modified content. This typically should only
3105 * occur for text relocations. 3126 * occur for text relocations.
3106 */ 3127 */
3107 rc = file_has_perm(cred, vma->vm_file, 3128 rc = file_has_perm(cred, vma->vm_file, FILE__EXECMOD);
3108 FILE__EXECMOD);
3109 } 3129 }
3110 if (rc) 3130 if (rc)
3111 return rc; 3131 return rc;
@@ -3211,6 +3231,7 @@ static int selinux_dentry_open(struct file *file, const struct cred *cred)
3211 struct file_security_struct *fsec; 3231 struct file_security_struct *fsec;
3212 struct inode *inode; 3232 struct inode *inode;
3213 struct inode_security_struct *isec; 3233 struct inode_security_struct *isec;
3234
3214 inode = file->f_path.dentry->d_inode; 3235 inode = file->f_path.dentry->d_inode;
3215 fsec = file->f_security; 3236 fsec = file->f_security;
3216 isec = inode->i_security; 3237 isec = inode->i_security;
@@ -3247,38 +3268,41 @@ static int selinux_task_create(unsigned long clone_flags)
3247 return task_has_perm(current, current, PROCESS__FORK); 3268 return task_has_perm(current, current, PROCESS__FORK);
3248} 3269}
3249 3270
3250static int selinux_cred_alloc_security(struct cred *cred) 3271/*
3272 * detach and free the LSM part of a set of credentials
3273 */
3274static void selinux_cred_free(struct cred *cred)
3251{ 3275{
3252 struct task_security_struct *tsec1, *tsec2; 3276 struct task_security_struct *tsec = cred->security;
3253 int rc; 3277 cred->security = NULL;
3254 3278 kfree(tsec);
3255 tsec1 = current_security(); 3279}
3256 3280
3257 rc = cred_alloc_security(cred); 3281/*
3258 if (rc) 3282 * prepare a new set of credentials for modification
3259 return rc; 3283 */
3260 tsec2 = cred->security; 3284static int selinux_cred_prepare(struct cred *new, const struct cred *old,
3285 gfp_t gfp)
3286{
3287 const struct task_security_struct *old_tsec;
3288 struct task_security_struct *tsec;
3261 3289
3262 tsec2->osid = tsec1->osid; 3290 old_tsec = old->security;
3263 tsec2->sid = tsec1->sid;
3264 3291
3265 /* Retain the exec, fs, key, and sock SIDs across fork */ 3292 tsec = kmemdup(old_tsec, sizeof(struct task_security_struct), gfp);
3266 tsec2->exec_sid = tsec1->exec_sid; 3293 if (!tsec)
3267 tsec2->create_sid = tsec1->create_sid; 3294 return -ENOMEM;
3268 tsec2->keycreate_sid = tsec1->keycreate_sid;
3269 tsec2->sockcreate_sid = tsec1->sockcreate_sid;
3270 3295
3296 new->security = tsec;
3271 return 0; 3297 return 0;
3272} 3298}
3273 3299
3274/* 3300/*
3275 * detach and free the LSM part of a set of credentials 3301 * commit new credentials
3276 */ 3302 */
3277static void selinux_cred_free(struct cred *cred) 3303static void selinux_cred_commit(struct cred *new, const struct cred *old)
3278{ 3304{
3279 struct task_security_struct *tsec = cred->security; 3305 secondary_ops->cred_commit(new, old);
3280 cred->security = NULL;
3281 kfree(tsec);
3282} 3306}
3283 3307
3284static int selinux_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags) 3308static int selinux_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags)
@@ -3292,9 +3316,10 @@ static int selinux_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags)
3292 return 0; 3316 return 0;
3293} 3317}
3294 3318
3295static int selinux_task_post_setuid(uid_t id0, uid_t id1, uid_t id2, int flags) 3319static int selinux_task_fix_setuid(struct cred *new, const struct cred *old,
3320 int flags)
3296{ 3321{
3297 return secondary_ops->task_post_setuid(id0, id1, id2, flags); 3322 return secondary_ops->task_fix_setuid(new, old, flags);
3298} 3323}
3299 3324
3300static int selinux_task_setgid(gid_t id0, gid_t id1, gid_t id2, int flags) 3325static int selinux_task_setgid(gid_t id0, gid_t id1, gid_t id2, int flags)
@@ -3368,7 +3393,7 @@ static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim
3368 /* Control the ability to change the hard limit (whether 3393 /* Control the ability to change the hard limit (whether
3369 lowering or raising it), so that the hard limit can 3394 lowering or raising it), so that the hard limit can
3370 later be used as a safe reset point for the soft limit 3395 later be used as a safe reset point for the soft limit
3371 upon context transitions. See selinux_bprm_apply_creds. */ 3396 upon context transitions. See selinux_bprm_committing_creds. */
3372 if (old_rlim->rlim_max != new_rlim->rlim_max) 3397 if (old_rlim->rlim_max != new_rlim->rlim_max)
3373 return task_has_perm(current, current, PROCESS__SETRLIMIT); 3398 return task_has_perm(current, current, PROCESS__SETRLIMIT);
3374 3399
@@ -3422,13 +3447,12 @@ static int selinux_task_prctl(int option,
3422 unsigned long arg2, 3447 unsigned long arg2,
3423 unsigned long arg3, 3448 unsigned long arg3,
3424 unsigned long arg4, 3449 unsigned long arg4,
3425 unsigned long arg5, 3450 unsigned long arg5)
3426 long *rc_p)
3427{ 3451{
3428 /* The current prctl operations do not appear to require 3452 /* The current prctl operations do not appear to require
3429 any SELinux controls since they merely observe or modify 3453 any SELinux controls since they merely observe or modify
3430 the state of the current process. */ 3454 the state of the current process. */
3431 return secondary_ops->task_prctl(option, arg2, arg3, arg4, arg5, rc_p); 3455 return secondary_ops->task_prctl(option, arg2, arg3, arg4, arg5);
3432} 3456}
3433 3457
3434static int selinux_task_wait(struct task_struct *p) 3458static int selinux_task_wait(struct task_struct *p)
@@ -3436,18 +3460,6 @@ static int selinux_task_wait(struct task_struct *p)
3436 return task_has_perm(p, current, PROCESS__SIGCHLD); 3460 return task_has_perm(p, current, PROCESS__SIGCHLD);
3437} 3461}
3438 3462
3439static void selinux_task_reparent_to_init(struct task_struct *p)
3440{
3441 struct task_security_struct *tsec;
3442
3443 secondary_ops->task_reparent_to_init(p);
3444
3445 tsec = p->cred->security;
3446 tsec->osid = tsec->sid;
3447 tsec->sid = SECINITSID_KERNEL;
3448 return;
3449}
3450
3451static void selinux_task_to_inode(struct task_struct *p, 3463static void selinux_task_to_inode(struct task_struct *p,
3452 struct inode *inode) 3464 struct inode *inode)
3453{ 3465{
@@ -5325,7 +5337,8 @@ static int selinux_setprocattr(struct task_struct *p,
5325{ 5337{
5326 struct task_security_struct *tsec; 5338 struct task_security_struct *tsec;
5327 struct task_struct *tracer; 5339 struct task_struct *tracer;
5328 u32 sid = 0; 5340 struct cred *new;
5341 u32 sid = 0, ptsid;
5329 int error; 5342 int error;
5330 char *str = value; 5343 char *str = value;
5331 5344
@@ -5372,86 +5385,75 @@ static int selinux_setprocattr(struct task_struct *p,
5372 return error; 5385 return error;
5373 } 5386 }
5374 5387
5388 new = prepare_creds();
5389 if (!new)
5390 return -ENOMEM;
5391
5375 /* Permission checking based on the specified context is 5392 /* Permission checking based on the specified context is
5376 performed during the actual operation (execve, 5393 performed during the actual operation (execve,
5377 open/mkdir/...), when we know the full context of the 5394 open/mkdir/...), when we know the full context of the
5378 operation. See selinux_bprm_set_security for the execve 5395 operation. See selinux_bprm_set_creds for the execve
5379 checks and may_create for the file creation checks. The 5396 checks and may_create for the file creation checks. The
5380 operation will then fail if the context is not permitted. */ 5397 operation will then fail if the context is not permitted. */
5381 tsec = p->cred->security; 5398 tsec = new->security;
5382 if (!strcmp(name, "exec")) 5399 if (!strcmp(name, "exec")) {
5383 tsec->exec_sid = sid; 5400 tsec->exec_sid = sid;
5384 else if (!strcmp(name, "fscreate")) 5401 } else if (!strcmp(name, "fscreate")) {
5385 tsec->create_sid = sid; 5402 tsec->create_sid = sid;
5386 else if (!strcmp(name, "keycreate")) { 5403 } else if (!strcmp(name, "keycreate")) {
5387 error = may_create_key(sid, p); 5404 error = may_create_key(sid, p);
5388 if (error) 5405 if (error)
5389 return error; 5406 goto abort_change;
5390 tsec->keycreate_sid = sid; 5407 tsec->keycreate_sid = sid;
5391 } else if (!strcmp(name, "sockcreate")) 5408 } else if (!strcmp(name, "sockcreate")) {
5392 tsec->sockcreate_sid = sid; 5409 tsec->sockcreate_sid = sid;
5393 else if (!strcmp(name, "current")) { 5410 } else if (!strcmp(name, "current")) {
5394 struct av_decision avd; 5411 error = -EINVAL;
5395
5396 if (sid == 0) 5412 if (sid == 0)
5397 return -EINVAL; 5413 goto abort_change;
5398 /* 5414
5399 * SELinux allows to change context in the following case only. 5415 /* Only allow single threaded processes to change context */
5400 * - Single threaded processes. 5416 error = -EPERM;
5401 * - Multi threaded processes intend to change its context into 5417 if (!is_single_threaded(p)) {
5402 * more restricted domain (defined by TYPEBOUNDS statement). 5418 error = security_bounded_transition(tsec->sid, sid);
5403 */ 5419 if (error)
5404 if (atomic_read(&p->mm->mm_users) != 1) { 5420 goto abort_change;
5405 struct task_struct *g, *t;
5406 struct mm_struct *mm = p->mm;
5407 read_lock(&tasklist_lock);
5408 do_each_thread(g, t) {
5409 if (t->mm == mm && t != p) {
5410 read_unlock(&tasklist_lock);
5411 error = security_bounded_transition(tsec->sid, sid);
5412 if (!error)
5413 goto boundary_ok;
5414
5415 return error;
5416 }
5417 } while_each_thread(g, t);
5418 read_unlock(&tasklist_lock);
5419 } 5421 }
5420boundary_ok:
5421 5422
5422 /* Check permissions for the transition. */ 5423 /* Check permissions for the transition. */
5423 error = avc_has_perm(tsec->sid, sid, SECCLASS_PROCESS, 5424 error = avc_has_perm(tsec->sid, sid, SECCLASS_PROCESS,
5424 PROCESS__DYNTRANSITION, NULL); 5425 PROCESS__DYNTRANSITION, NULL);
5425 if (error) 5426 if (error)
5426 return error; 5427 goto abort_change;
5427 5428
5428 /* Check for ptracing, and update the task SID if ok. 5429 /* Check for ptracing, and update the task SID if ok.
5429 Otherwise, leave SID unchanged and fail. */ 5430 Otherwise, leave SID unchanged and fail. */
5431 ptsid = 0;
5430 task_lock(p); 5432 task_lock(p);
5431 rcu_read_lock();
5432 tracer = tracehook_tracer_task(p); 5433 tracer = tracehook_tracer_task(p);
5433 if (tracer != NULL) { 5434 if (tracer)
5434 u32 ptsid = task_sid(tracer); 5435 ptsid = task_sid(tracer);
5435 rcu_read_unlock(); 5436 task_unlock(p);
5436 error = avc_has_perm_noaudit(ptsid, sid, 5437
5437 SECCLASS_PROCESS, 5438 if (tracer) {
5438 PROCESS__PTRACE, 0, &avd); 5439 error = avc_has_perm(ptsid, sid, SECCLASS_PROCESS,
5439 if (!error) 5440 PROCESS__PTRACE, NULL);
5440 tsec->sid = sid;
5441 task_unlock(p);
5442 avc_audit(ptsid, sid, SECCLASS_PROCESS,
5443 PROCESS__PTRACE, &avd, error, NULL);
5444 if (error) 5441 if (error)
5445 return error; 5442 goto abort_change;
5446 } else {
5447 rcu_read_unlock();
5448 tsec->sid = sid;
5449 task_unlock(p);
5450 } 5443 }
5451 } else
5452 return -EINVAL;
5453 5444
5445 tsec->sid = sid;
5446 } else {
5447 error = -EINVAL;
5448 goto abort_change;
5449 }
5450
5451 commit_creds(new);
5454 return size; 5452 return size;
5453
5454abort_change:
5455 abort_creds(new);
5456 return error;
5455} 5457}
5456 5458
5457static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) 5459static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
@@ -5471,23 +5473,21 @@ static void selinux_release_secctx(char *secdata, u32 seclen)
5471 5473
5472#ifdef CONFIG_KEYS 5474#ifdef CONFIG_KEYS
5473 5475
5474static int selinux_key_alloc(struct key *k, struct task_struct *tsk, 5476static int selinux_key_alloc(struct key *k, const struct cred *cred,
5475 unsigned long flags) 5477 unsigned long flags)
5476{ 5478{
5477 const struct task_security_struct *__tsec; 5479 const struct task_security_struct *tsec;
5478 struct key_security_struct *ksec; 5480 struct key_security_struct *ksec;
5479 5481
5480 ksec = kzalloc(sizeof(struct key_security_struct), GFP_KERNEL); 5482 ksec = kzalloc(sizeof(struct key_security_struct), GFP_KERNEL);
5481 if (!ksec) 5483 if (!ksec)
5482 return -ENOMEM; 5484 return -ENOMEM;
5483 5485
5484 rcu_read_lock(); 5486 tsec = cred->security;
5485 __tsec = __task_cred(tsk)->security; 5487 if (tsec->keycreate_sid)
5486 if (__tsec->keycreate_sid) 5488 ksec->sid = tsec->keycreate_sid;
5487 ksec->sid = __tsec->keycreate_sid;
5488 else 5489 else
5489 ksec->sid = __tsec->sid; 5490 ksec->sid = tsec->sid;
5490 rcu_read_unlock();
5491 5491
5492 k->security = ksec; 5492 k->security = ksec;
5493 return 0; 5493 return 0;
@@ -5502,8 +5502,8 @@ static void selinux_key_free(struct key *k)
5502} 5502}
5503 5503
5504static int selinux_key_permission(key_ref_t key_ref, 5504static int selinux_key_permission(key_ref_t key_ref,
5505 struct task_struct *ctx, 5505 const struct cred *cred,
5506 key_perm_t perm) 5506 key_perm_t perm)
5507{ 5507{
5508 struct key *key; 5508 struct key *key;
5509 struct key_security_struct *ksec; 5509 struct key_security_struct *ksec;
@@ -5515,7 +5515,7 @@ static int selinux_key_permission(key_ref_t key_ref,
5515 if (perm == 0) 5515 if (perm == 0)
5516 return 0; 5516 return 0;
5517 5517
5518 sid = task_sid(ctx); 5518 sid = cred_sid(cred);
5519 5519
5520 key = key_ref_to_ptr(key_ref); 5520 key = key_ref_to_ptr(key_ref);
5521 ksec = key->security; 5521 ksec = key->security;
@@ -5545,8 +5545,7 @@ static struct security_operations selinux_ops = {
5545 .ptrace_may_access = selinux_ptrace_may_access, 5545 .ptrace_may_access = selinux_ptrace_may_access,
5546 .ptrace_traceme = selinux_ptrace_traceme, 5546 .ptrace_traceme = selinux_ptrace_traceme,
5547 .capget = selinux_capget, 5547 .capget = selinux_capget,
5548 .capset_check = selinux_capset_check, 5548 .capset = selinux_capset,
5549 .capset_set = selinux_capset_set,
5550 .sysctl = selinux_sysctl, 5549 .sysctl = selinux_sysctl,
5551 .capable = selinux_capable, 5550 .capable = selinux_capable,
5552 .quotactl = selinux_quotactl, 5551 .quotactl = selinux_quotactl,
@@ -5621,10 +5620,11 @@ static struct security_operations selinux_ops = {
5621 .dentry_open = selinux_dentry_open, 5620 .dentry_open = selinux_dentry_open,
5622 5621
5623 .task_create = selinux_task_create, 5622 .task_create = selinux_task_create,
5624 .cred_alloc_security = selinux_cred_alloc_security,
5625 .cred_free = selinux_cred_free, 5623 .cred_free = selinux_cred_free,
5624 .cred_prepare = selinux_cred_prepare,
5625 .cred_commit = selinux_cred_commit,
5626 .task_setuid = selinux_task_setuid, 5626 .task_setuid = selinux_task_setuid,
5627 .task_post_setuid = selinux_task_post_setuid, 5627 .task_fix_setuid = selinux_task_fix_setuid,
5628 .task_setgid = selinux_task_setgid, 5628 .task_setgid = selinux_task_setgid,
5629 .task_setpgid = selinux_task_setpgid, 5629 .task_setpgid = selinux_task_setpgid,
5630 .task_getpgid = selinux_task_getpgid, 5630 .task_getpgid = selinux_task_getpgid,
@@ -5641,7 +5641,6 @@ static struct security_operations selinux_ops = {
5641 .task_kill = selinux_task_kill, 5641 .task_kill = selinux_task_kill,
5642 .task_wait = selinux_task_wait, 5642 .task_wait = selinux_task_wait,
5643 .task_prctl = selinux_task_prctl, 5643 .task_prctl = selinux_task_prctl,
5644 .task_reparent_to_init = selinux_task_reparent_to_init,
5645 .task_to_inode = selinux_task_to_inode, 5644 .task_to_inode = selinux_task_to_inode,
5646 5645
5647 .ipc_permission = selinux_ipc_permission, 5646 .ipc_permission = selinux_ipc_permission,
@@ -5737,8 +5736,6 @@ static struct security_operations selinux_ops = {
5737 5736
5738static __init int selinux_init(void) 5737static __init int selinux_init(void)
5739{ 5738{
5740 struct task_security_struct *tsec;
5741
5742 if (!security_module_enable(&selinux_ops)) { 5739 if (!security_module_enable(&selinux_ops)) {
5743 selinux_enabled = 0; 5740 selinux_enabled = 0;
5744 return 0; 5741 return 0;
@@ -5752,10 +5749,7 @@ static __init int selinux_init(void)
5752 printk(KERN_INFO "SELinux: Initializing.\n"); 5749 printk(KERN_INFO "SELinux: Initializing.\n");
5753 5750
5754 /* Set the security state for the initial task. */ 5751 /* Set the security state for the initial task. */
5755 if (cred_alloc_security(current->cred)) 5752 cred_init_security();
5756 panic("SELinux: Failed to initialize initial task.\n");
5757 tsec = current->cred->security;
5758 tsec->osid = tsec->sid = SECINITSID_KERNEL;
5759 5753
5760 sel_inode_cache = kmem_cache_create("selinux_inode_security", 5754 sel_inode_cache = kmem_cache_create("selinux_inode_security",
5761 sizeof(struct inode_security_struct), 5755 sizeof(struct inode_security_struct),
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 11167fd567b9..e952b397153d 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -104,8 +104,7 @@ static int smack_ptrace_may_access(struct task_struct *ctp, unsigned int mode)
104 if (rc != 0) 104 if (rc != 0)
105 return rc; 105 return rc;
106 106
107 rc = smk_access(current->cred->security, ctp->cred->security, 107 rc = smk_access(current_security(), task_security(ctp), MAY_READWRITE);
108 MAY_READWRITE);
109 if (rc != 0 && capable(CAP_MAC_OVERRIDE)) 108 if (rc != 0 && capable(CAP_MAC_OVERRIDE))
110 return 0; 109 return 0;
111 return rc; 110 return rc;
@@ -127,8 +126,7 @@ static int smack_ptrace_traceme(struct task_struct *ptp)
127 if (rc != 0) 126 if (rc != 0)
128 return rc; 127 return rc;
129 128
130 rc = smk_access(ptp->cred->security, current->cred->security, 129 rc = smk_access(task_security(ptp), current_security(), MAY_READWRITE);
131 MAY_READWRITE);
132 if (rc != 0 && has_capability(ptp, CAP_MAC_OVERRIDE)) 130 if (rc != 0 && has_capability(ptp, CAP_MAC_OVERRIDE))
133 return 0; 131 return 0;
134 return rc; 132 return rc;
@@ -977,22 +975,6 @@ static int smack_file_receive(struct file *file)
977 */ 975 */
978 976
979/** 977/**
980 * smack_cred_alloc_security - "allocate" a task cred blob
981 * @cred: the task creds in need of a blob
982 *
983 * Smack isn't using copies of blobs. Everyone
984 * points to an immutable list. No alloc required.
985 * No data copy required.
986 *
987 * Always returns 0
988 */
989static int smack_cred_alloc_security(struct cred *cred)
990{
991 cred->security = current_security();
992 return 0;
993}
994
995/**
996 * smack_cred_free - "free" task-level security credentials 978 * smack_cred_free - "free" task-level security credentials
997 * @cred: the credentials in question 979 * @cred: the credentials in question
998 * 980 *
@@ -1006,6 +988,30 @@ static void smack_cred_free(struct cred *cred)
1006} 988}
1007 989
1008/** 990/**
991 * smack_cred_prepare - prepare new set of credentials for modification
992 * @new: the new credentials
993 * @old: the original credentials
994 * @gfp: the atomicity of any memory allocations
995 *
996 * Prepare a new set of credentials for modification.
997 */
998static int smack_cred_prepare(struct cred *new, const struct cred *old,
999 gfp_t gfp)
1000{
1001 new->security = old->security;
1002 return 0;
1003}
1004
1005/*
1006 * commit new credentials
1007 * @new: the new credentials
1008 * @old: the original credentials
1009 */
1010static void smack_cred_commit(struct cred *new, const struct cred *old)
1011{
1012}
1013
1014/**
1009 * smack_task_setpgid - Smack check on setting pgid 1015 * smack_task_setpgid - Smack check on setting pgid
1010 * @p: the task object 1016 * @p: the task object
1011 * @pgid: unused 1017 * @pgid: unused
@@ -2036,6 +2042,7 @@ static int smack_getprocattr(struct task_struct *p, char *name, char **value)
2036static int smack_setprocattr(struct task_struct *p, char *name, 2042static int smack_setprocattr(struct task_struct *p, char *name,
2037 void *value, size_t size) 2043 void *value, size_t size)
2038{ 2044{
2045 struct cred *new;
2039 char *newsmack; 2046 char *newsmack;
2040 2047
2041 /* 2048 /*
@@ -2058,7 +2065,11 @@ static int smack_setprocattr(struct task_struct *p, char *name,
2058 if (newsmack == NULL) 2065 if (newsmack == NULL)
2059 return -EINVAL; 2066 return -EINVAL;
2060 2067
2061 p->cred->security = newsmack; 2068 new = prepare_creds();
2069 if (!new)
2070 return -ENOMEM;
2071 new->security = newsmack;
2072 commit_creds(new);
2062 return size; 2073 return size;
2063} 2074}
2064 2075
@@ -2354,17 +2365,17 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
2354/** 2365/**
2355 * smack_key_alloc - Set the key security blob 2366 * smack_key_alloc - Set the key security blob
2356 * @key: object 2367 * @key: object
2357 * @tsk: the task associated with the key 2368 * @cred: the credentials to use
2358 * @flags: unused 2369 * @flags: unused
2359 * 2370 *
2360 * No allocation required 2371 * No allocation required
2361 * 2372 *
2362 * Returns 0 2373 * Returns 0
2363 */ 2374 */
2364static int smack_key_alloc(struct key *key, struct task_struct *tsk, 2375static int smack_key_alloc(struct key *key, const struct cred *cred,
2365 unsigned long flags) 2376 unsigned long flags)
2366{ 2377{
2367 key->security = tsk->cred->security; 2378 key->security = cred->security;
2368 return 0; 2379 return 0;
2369} 2380}
2370 2381
@@ -2382,14 +2393,14 @@ static void smack_key_free(struct key *key)
2382/* 2393/*
2383 * smack_key_permission - Smack access on a key 2394 * smack_key_permission - Smack access on a key
2384 * @key_ref: gets to the object 2395 * @key_ref: gets to the object
2385 * @context: task involved 2396 * @cred: the credentials to use
2386 * @perm: unused 2397 * @perm: unused
2387 * 2398 *
2388 * Return 0 if the task has read and write to the object, 2399 * Return 0 if the task has read and write to the object,
2389 * an error code otherwise 2400 * an error code otherwise
2390 */ 2401 */
2391static int smack_key_permission(key_ref_t key_ref, 2402static int smack_key_permission(key_ref_t key_ref,
2392 struct task_struct *context, key_perm_t perm) 2403 const struct cred *cred, key_perm_t perm)
2393{ 2404{
2394 struct key *keyp; 2405 struct key *keyp;
2395 2406
@@ -2405,11 +2416,10 @@ static int smack_key_permission(key_ref_t key_ref,
2405 /* 2416 /*
2406 * This should not occur 2417 * This should not occur
2407 */ 2418 */
2408 if (context->cred->security == NULL) 2419 if (cred->security == NULL)
2409 return -EACCES; 2420 return -EACCES;
2410 2421
2411 return smk_access(context->cred->security, keyp->security, 2422 return smk_access(cred->security, keyp->security, MAY_READWRITE);
2412 MAY_READWRITE);
2413} 2423}
2414#endif /* CONFIG_KEYS */ 2424#endif /* CONFIG_KEYS */
2415 2425
@@ -2580,8 +2590,7 @@ struct security_operations smack_ops = {
2580 .ptrace_may_access = smack_ptrace_may_access, 2590 .ptrace_may_access = smack_ptrace_may_access,
2581 .ptrace_traceme = smack_ptrace_traceme, 2591 .ptrace_traceme = smack_ptrace_traceme,
2582 .capget = cap_capget, 2592 .capget = cap_capget,
2583 .capset_check = cap_capset_check, 2593 .capset = cap_capset,
2584 .capset_set = cap_capset_set,
2585 .capable = cap_capable, 2594 .capable = cap_capable,
2586 .syslog = smack_syslog, 2595 .syslog = smack_syslog,
2587 .settime = cap_settime, 2596 .settime = cap_settime,
@@ -2630,9 +2639,10 @@ struct security_operations smack_ops = {
2630 .file_send_sigiotask = smack_file_send_sigiotask, 2639 .file_send_sigiotask = smack_file_send_sigiotask,
2631 .file_receive = smack_file_receive, 2640 .file_receive = smack_file_receive,
2632 2641
2633 .cred_alloc_security = smack_cred_alloc_security,
2634 .cred_free = smack_cred_free, 2642 .cred_free = smack_cred_free,
2635 .task_post_setuid = cap_task_post_setuid, 2643 .cred_prepare = smack_cred_prepare,
2644 .cred_commit = smack_cred_commit,
2645 .task_fix_setuid = cap_task_fix_setuid,
2636 .task_setpgid = smack_task_setpgid, 2646 .task_setpgid = smack_task_setpgid,
2637 .task_getpgid = smack_task_getpgid, 2647 .task_getpgid = smack_task_getpgid,
2638 .task_getsid = smack_task_getsid, 2648 .task_getsid = smack_task_getsid,
@@ -2645,7 +2655,6 @@ struct security_operations smack_ops = {
2645 .task_movememory = smack_task_movememory, 2655 .task_movememory = smack_task_movememory,
2646 .task_kill = smack_task_kill, 2656 .task_kill = smack_task_kill,
2647 .task_wait = smack_task_wait, 2657 .task_wait = smack_task_wait,
2648 .task_reparent_to_init = cap_task_reparent_to_init,
2649 .task_to_inode = smack_task_to_inode, 2658 .task_to_inode = smack_task_to_inode,
2650 .task_prctl = cap_task_prctl, 2659 .task_prctl = cap_task_prctl,
2651 2660
@@ -2721,6 +2730,8 @@ struct security_operations smack_ops = {
2721 */ 2730 */
2722static __init int smack_init(void) 2731static __init int smack_init(void)
2723{ 2732{
2733 struct cred *cred;
2734
2724 if (!security_module_enable(&smack_ops)) 2735 if (!security_module_enable(&smack_ops))
2725 return 0; 2736 return 0;
2726 2737
@@ -2729,7 +2740,8 @@ static __init int smack_init(void)
2729 /* 2740 /*
2730 * Set the security state for the initial task. 2741 * Set the security state for the initial task.
2731 */ 2742 */
2732 current->cred->security = &smack_known_floor.smk_known; 2743 cred = (struct cred *) current->cred;
2744 cred->security = &smack_known_floor.smk_known;
2733 2745
2734 /* 2746 /*
2735 * Initialize locks 2747 * Initialize locks