aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-16 18:40:50 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-16 18:40:50 -0500
commit2a74dbb9a86e8102dcd07d284135b4530a84826e (patch)
treea54403e312b6062dfb57bd904ba8b8ce3b11e720
parent770b6cb4d21fb3e3df2a7a51e186a3c14db1ec30 (diff)
parente93072374112db9dc86635934ee761249be28370 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull security subsystem updates from James Morris: "A quiet cycle for the security subsystem with just a few maintenance updates." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: Smack: create a sysfs mount point for smackfs Smack: use select not depends in Kconfig Yama: remove locking from delete path Yama: add RCU to drop read locking drivers/char/tpm: remove tasklet and cleanup KEYS: Use keyring_alloc() to create special keyrings KEYS: Reduce initial permissions on keys KEYS: Make the session and process keyrings per-thread seccomp: Make syscall skipping and nr changes more consistent key: Fix resource leak keys: Fix unreachable code KEYS: Add payload preparsing opportunity prior to key instantiate or update
-rw-r--r--Documentation/prctl/seccomp_filter.txt74
-rw-r--r--Documentation/security/keys.txt17
-rw-r--r--arch/x86/kernel/vsyscall_64.c110
-rw-r--r--drivers/char/tpm/tpm_ibmvtpm.c81
-rw-r--r--drivers/char/tpm/tpm_ibmvtpm.h5
-rw-r--r--fs/cifs/cifsacl.c12
-rw-r--r--fs/nfs/idmap.c12
-rw-r--r--include/linux/cred.h17
-rw-r--r--include/linux/key.h1
-rw-r--r--kernel/cred.c127
-rw-r--r--kernel/seccomp.c13
-rw-r--r--net/dns_resolver/dns_key.c15
-rw-r--r--security/keys/key.c6
-rw-r--r--security/keys/keyctl.c15
-rw-r--r--security/keys/keyring.c10
-rw-r--r--security/keys/process_keys.c92
-rw-r--r--security/keys/request_key.c21
-rw-r--r--security/smack/Kconfig6
-rw-r--r--security/smack/smackfs.c17
-rw-r--r--security/yama/yama_lsm.c88
20 files changed, 369 insertions, 370 deletions
diff --git a/Documentation/prctl/seccomp_filter.txt b/Documentation/prctl/seccomp_filter.txt
index 597c3c581375..1e469ef75778 100644
--- a/Documentation/prctl/seccomp_filter.txt
+++ b/Documentation/prctl/seccomp_filter.txt
@@ -95,12 +95,15 @@ SECCOMP_RET_KILL:
95 95
96SECCOMP_RET_TRAP: 96SECCOMP_RET_TRAP:
97 Results in the kernel sending a SIGSYS signal to the triggering 97 Results in the kernel sending a SIGSYS signal to the triggering
98 task without executing the system call. The kernel will 98 task without executing the system call. siginfo->si_call_addr
99 rollback the register state to just before the system call 99 will show the address of the system call instruction, and
100 entry such that a signal handler in the task will be able to 100 siginfo->si_syscall and siginfo->si_arch will indicate which
101 inspect the ucontext_t->uc_mcontext registers and emulate 101 syscall was attempted. The program counter will be as though
102 system call success or failure upon return from the signal 102 the syscall happened (i.e. it will not point to the syscall
103 handler. 103 instruction). The return value register will contain an arch-
104 dependent value -- if resuming execution, set it to something
105 sensible. (The architecture dependency is because replacing
106 it with -ENOSYS could overwrite some useful information.)
104 107
105 The SECCOMP_RET_DATA portion of the return value will be passed 108 The SECCOMP_RET_DATA portion of the return value will be passed
106 as si_errno. 109 as si_errno.
@@ -123,6 +126,18 @@ SECCOMP_RET_TRACE:
123 the BPF program return value will be available to the tracer 126 the BPF program return value will be available to the tracer
124 via PTRACE_GETEVENTMSG. 127 via PTRACE_GETEVENTMSG.
125 128
129 The tracer can skip the system call by changing the syscall number
130 to -1. Alternatively, the tracer can change the system call
131 requested by changing the system call to a valid syscall number. If
132 the tracer asks to skip the system call, then the system call will
133 appear to return the value that the tracer puts in the return value
134 register.
135
136 The seccomp check will not be run again after the tracer is
137 notified. (This means that seccomp-based sandboxes MUST NOT
138 allow use of ptrace, even of other sandboxed processes, without
139 extreme care; ptracers can use this mechanism to escape.)
140
126SECCOMP_RET_ALLOW: 141SECCOMP_RET_ALLOW:
127 Results in the system call being executed. 142 Results in the system call being executed.
128 143
@@ -161,3 +176,50 @@ architecture supports both ptrace_event and seccomp, it will be able to
161support seccomp filter with minor fixup: SIGSYS support and seccomp return 176support seccomp filter with minor fixup: SIGSYS support and seccomp return
162value checking. Then it must just add CONFIG_HAVE_ARCH_SECCOMP_FILTER 177value checking. Then it must just add CONFIG_HAVE_ARCH_SECCOMP_FILTER
163to its arch-specific Kconfig. 178to its arch-specific Kconfig.
179
180
181
182Caveats
183-------
184
185The vDSO can cause some system calls to run entirely in userspace,
186leading to surprises when you run programs on different machines that
187fall back to real syscalls. To minimize these surprises on x86, make
188sure you test with
189/sys/devices/system/clocksource/clocksource0/current_clocksource set to
190something like acpi_pm.
191
192On x86-64, vsyscall emulation is enabled by default. (vsyscalls are
193legacy variants on vDSO calls.) Currently, emulated vsyscalls will honor seccomp, with a few oddities:
194
195- A return value of SECCOMP_RET_TRAP will set a si_call_addr pointing to
196 the vsyscall entry for the given call and not the address after the
197 'syscall' instruction. Any code which wants to restart the call
198 should be aware that (a) a ret instruction has been emulated and (b)
199 trying to resume the syscall will again trigger the standard vsyscall
200 emulation security checks, making resuming the syscall mostly
201 pointless.
202
203- A return value of SECCOMP_RET_TRACE will signal the tracer as usual,
204 but the syscall may not be changed to another system call using the
205 orig_rax register. It may only be changed to -1 order to skip the
206 currently emulated call. Any other change MAY terminate the process.
207 The rip value seen by the tracer will be the syscall entry address;
208 this is different from normal behavior. The tracer MUST NOT modify
209 rip or rsp. (Do not rely on other changes terminating the process.
210 They might work. For example, on some kernels, choosing a syscall
211 that only exists in future kernels will be correctly emulated (by
212 returning -ENOSYS).
213
214To detect this quirky behavior, check for addr & ~0x0C00 ==
2150xFFFFFFFFFF600000. (For SECCOMP_RET_TRACE, use rip. For
216SECCOMP_RET_TRAP, use siginfo->si_call_addr.) Do not check any other
217condition: future kernels may improve vsyscall emulation and current
218kernels in vsyscall=native mode will behave differently, but the
219instructions at 0xF...F600{0,4,8,C}00 will not be system calls in these
220cases.
221
222Note that modern systems are unlikely to use vsyscalls at all -- they
223are a legacy feature and they are considerably slower than standard
224syscalls. New code will use the vDSO, and vDSO-issued system calls
225are indistinguishable from normal system calls.
diff --git a/Documentation/security/keys.txt b/Documentation/security/keys.txt
index 7d9ca92022d8..7b4145d00452 100644
--- a/Documentation/security/keys.txt
+++ b/Documentation/security/keys.txt
@@ -994,6 +994,23 @@ payload contents" for more information.
994 reference pointer if successful. 994 reference pointer if successful.
995 995
996 996
997(*) A keyring can be created by:
998
999 struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
1000 const struct cred *cred,
1001 key_perm_t perm,
1002 unsigned long flags,
1003 struct key *dest);
1004
1005 This creates a keyring with the given attributes and returns it. If dest
1006 is not NULL, the new keyring will be linked into the keyring to which it
1007 points. No permission checks are made upon the destination keyring.
1008
1009 Error EDQUOT can be returned if the keyring would overload the quota (pass
1010 KEY_ALLOC_NOT_IN_QUOTA in flags if the keyring shouldn't be accounted
1011 towards the user's quota). Error ENOMEM can also be returned.
1012
1013
997(*) To check the validity of a key, this function can be called: 1014(*) To check the validity of a key, this function can be called:
998 1015
999 int validate_key(struct key *key); 1016 int validate_key(struct key *key);
diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c
index 3a3e8c9e280d..9a907a67be8f 100644
--- a/arch/x86/kernel/vsyscall_64.c
+++ b/arch/x86/kernel/vsyscall_64.c
@@ -145,19 +145,6 @@ static int addr_to_vsyscall_nr(unsigned long addr)
145 return nr; 145 return nr;
146} 146}
147 147
148#ifdef CONFIG_SECCOMP
149static int vsyscall_seccomp(struct task_struct *tsk, int syscall_nr)
150{
151 if (!seccomp_mode(&tsk->seccomp))
152 return 0;
153 task_pt_regs(tsk)->orig_ax = syscall_nr;
154 task_pt_regs(tsk)->ax = syscall_nr;
155 return __secure_computing(syscall_nr);
156}
157#else
158#define vsyscall_seccomp(_tsk, _nr) 0
159#endif
160
161static bool write_ok_or_segv(unsigned long ptr, size_t size) 148static bool write_ok_or_segv(unsigned long ptr, size_t size)
162{ 149{
163 /* 150 /*
@@ -190,10 +177,9 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address)
190{ 177{
191 struct task_struct *tsk; 178 struct task_struct *tsk;
192 unsigned long caller; 179 unsigned long caller;
193 int vsyscall_nr; 180 int vsyscall_nr, syscall_nr, tmp;
194 int prev_sig_on_uaccess_error; 181 int prev_sig_on_uaccess_error;
195 long ret; 182 long ret;
196 int skip;
197 183
198 /* 184 /*
199 * No point in checking CS -- the only way to get here is a user mode 185 * No point in checking CS -- the only way to get here is a user mode
@@ -225,56 +211,84 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address)
225 } 211 }
226 212
227 tsk = current; 213 tsk = current;
228 /*
229 * With a real vsyscall, page faults cause SIGSEGV. We want to
230 * preserve that behavior to make writing exploits harder.
231 */
232 prev_sig_on_uaccess_error = current_thread_info()->sig_on_uaccess_error;
233 current_thread_info()->sig_on_uaccess_error = 1;
234 214
235 /* 215 /*
216 * Check for access_ok violations and find the syscall nr.
217 *
236 * NULL is a valid user pointer (in the access_ok sense) on 32-bit and 218 * NULL is a valid user pointer (in the access_ok sense) on 32-bit and
237 * 64-bit, so we don't need to special-case it here. For all the 219 * 64-bit, so we don't need to special-case it here. For all the
238 * vsyscalls, NULL means "don't write anything" not "write it at 220 * vsyscalls, NULL means "don't write anything" not "write it at
239 * address 0". 221 * address 0".
240 */ 222 */
241 ret = -EFAULT;
242 skip = 0;
243 switch (vsyscall_nr) { 223 switch (vsyscall_nr) {
244 case 0: 224 case 0:
245 skip = vsyscall_seccomp(tsk, __NR_gettimeofday);
246 if (skip)
247 break;
248
249 if (!write_ok_or_segv(regs->di, sizeof(struct timeval)) || 225 if (!write_ok_or_segv(regs->di, sizeof(struct timeval)) ||
250 !write_ok_or_segv(regs->si, sizeof(struct timezone))) 226 !write_ok_or_segv(regs->si, sizeof(struct timezone))) {
251 break; 227 ret = -EFAULT;
228 goto check_fault;
229 }
230
231 syscall_nr = __NR_gettimeofday;
232 break;
233
234 case 1:
235 if (!write_ok_or_segv(regs->di, sizeof(time_t))) {
236 ret = -EFAULT;
237 goto check_fault;
238 }
239
240 syscall_nr = __NR_time;
241 break;
242
243 case 2:
244 if (!write_ok_or_segv(regs->di, sizeof(unsigned)) ||
245 !write_ok_or_segv(regs->si, sizeof(unsigned))) {
246 ret = -EFAULT;
247 goto check_fault;
248 }
249
250 syscall_nr = __NR_getcpu;
251 break;
252 }
253
254 /*
255 * Handle seccomp. regs->ip must be the original value.
256 * See seccomp_send_sigsys and Documentation/prctl/seccomp_filter.txt.
257 *
258 * We could optimize the seccomp disabled case, but performance
259 * here doesn't matter.
260 */
261 regs->orig_ax = syscall_nr;
262 regs->ax = -ENOSYS;
263 tmp = secure_computing(syscall_nr);
264 if ((!tmp && regs->orig_ax != syscall_nr) || regs->ip != address) {
265 warn_bad_vsyscall(KERN_DEBUG, regs,
266 "seccomp tried to change syscall nr or ip");
267 do_exit(SIGSYS);
268 }
269 if (tmp)
270 goto do_ret; /* skip requested */
252 271
272 /*
273 * With a real vsyscall, page faults cause SIGSEGV. We want to
274 * preserve that behavior to make writing exploits harder.
275 */
276 prev_sig_on_uaccess_error = current_thread_info()->sig_on_uaccess_error;
277 current_thread_info()->sig_on_uaccess_error = 1;
278
279 ret = -EFAULT;
280 switch (vsyscall_nr) {
281 case 0:
253 ret = sys_gettimeofday( 282 ret = sys_gettimeofday(
254 (struct timeval __user *)regs->di, 283 (struct timeval __user *)regs->di,
255 (struct timezone __user *)regs->si); 284 (struct timezone __user *)regs->si);
256 break; 285 break;
257 286
258 case 1: 287 case 1:
259 skip = vsyscall_seccomp(tsk, __NR_time);
260 if (skip)
261 break;
262
263 if (!write_ok_or_segv(regs->di, sizeof(time_t)))
264 break;
265
266 ret = sys_time((time_t __user *)regs->di); 288 ret = sys_time((time_t __user *)regs->di);
267 break; 289 break;
268 290
269 case 2: 291 case 2:
270 skip = vsyscall_seccomp(tsk, __NR_getcpu);
271 if (skip)
272 break;
273
274 if (!write_ok_or_segv(regs->di, sizeof(unsigned)) ||
275 !write_ok_or_segv(regs->si, sizeof(unsigned)))
276 break;
277
278 ret = sys_getcpu((unsigned __user *)regs->di, 292 ret = sys_getcpu((unsigned __user *)regs->di,
279 (unsigned __user *)regs->si, 293 (unsigned __user *)regs->si,
280 NULL); 294 NULL);
@@ -283,12 +297,7 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address)
283 297
284 current_thread_info()->sig_on_uaccess_error = prev_sig_on_uaccess_error; 298 current_thread_info()->sig_on_uaccess_error = prev_sig_on_uaccess_error;
285 299
286 if (skip) { 300check_fault:
287 if ((long)regs->ax <= 0L) /* seccomp errno emulation */
288 goto do_ret;
289 goto done; /* seccomp trace/trap */
290 }
291
292 if (ret == -EFAULT) { 301 if (ret == -EFAULT) {
293 /* Bad news -- userspace fed a bad pointer to a vsyscall. */ 302 /* Bad news -- userspace fed a bad pointer to a vsyscall. */
294 warn_bad_vsyscall(KERN_INFO, regs, 303 warn_bad_vsyscall(KERN_INFO, regs,
@@ -311,7 +320,6 @@ do_ret:
311 /* Emulate a ret instruction. */ 320 /* Emulate a ret instruction. */
312 regs->ip = caller; 321 regs->ip = caller;
313 regs->sp += 8; 322 regs->sp += 8;
314done:
315 return true; 323 return true;
316 324
317sigsegv: 325sigsegv:
diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c
index 7da840d487d2..9978609d93b2 100644
--- a/drivers/char/tpm/tpm_ibmvtpm.c
+++ b/drivers/char/tpm/tpm_ibmvtpm.c
@@ -38,8 +38,6 @@ static struct vio_device_id tpm_ibmvtpm_device_table[] = {
38}; 38};
39MODULE_DEVICE_TABLE(vio, tpm_ibmvtpm_device_table); 39MODULE_DEVICE_TABLE(vio, tpm_ibmvtpm_device_table);
40 40
41DECLARE_WAIT_QUEUE_HEAD(wq);
42
43/** 41/**
44 * ibmvtpm_send_crq - Send a CRQ request 42 * ibmvtpm_send_crq - Send a CRQ request
45 * @vdev: vio device struct 43 * @vdev: vio device struct
@@ -83,6 +81,7 @@ static int tpm_ibmvtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count)
83{ 81{
84 struct ibmvtpm_dev *ibmvtpm; 82 struct ibmvtpm_dev *ibmvtpm;
85 u16 len; 83 u16 len;
84 int sig;
86 85
87 ibmvtpm = (struct ibmvtpm_dev *)chip->vendor.data; 86 ibmvtpm = (struct ibmvtpm_dev *)chip->vendor.data;
88 87
@@ -91,22 +90,23 @@ static int tpm_ibmvtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count)
91 return 0; 90 return 0;
92 } 91 }
93 92
94 wait_event_interruptible(wq, ibmvtpm->crq_res.len != 0); 93 sig = wait_event_interruptible(ibmvtpm->wq, ibmvtpm->res_len != 0);
94 if (sig)
95 return -EINTR;
96
97 len = ibmvtpm->res_len;
95 98
96 if (count < ibmvtpm->crq_res.len) { 99 if (count < len) {
97 dev_err(ibmvtpm->dev, 100 dev_err(ibmvtpm->dev,
98 "Invalid size in recv: count=%ld, crq_size=%d\n", 101 "Invalid size in recv: count=%ld, crq_size=%d\n",
99 count, ibmvtpm->crq_res.len); 102 count, len);
100 return -EIO; 103 return -EIO;
101 } 104 }
102 105
103 spin_lock(&ibmvtpm->rtce_lock); 106 spin_lock(&ibmvtpm->rtce_lock);
104 memcpy((void *)buf, (void *)ibmvtpm->rtce_buf, ibmvtpm->crq_res.len); 107 memcpy((void *)buf, (void *)ibmvtpm->rtce_buf, len);
105 memset(ibmvtpm->rtce_buf, 0, ibmvtpm->crq_res.len); 108 memset(ibmvtpm->rtce_buf, 0, len);
106 ibmvtpm->crq_res.valid = 0; 109 ibmvtpm->res_len = 0;
107 ibmvtpm->crq_res.msg = 0;
108 len = ibmvtpm->crq_res.len;
109 ibmvtpm->crq_res.len = 0;
110 spin_unlock(&ibmvtpm->rtce_lock); 110 spin_unlock(&ibmvtpm->rtce_lock);
111 return len; 111 return len;
112} 112}
@@ -273,7 +273,6 @@ static int tpm_ibmvtpm_remove(struct vio_dev *vdev)
273 int rc = 0; 273 int rc = 0;
274 274
275 free_irq(vdev->irq, ibmvtpm); 275 free_irq(vdev->irq, ibmvtpm);
276 tasklet_kill(&ibmvtpm->tasklet);
277 276
278 do { 277 do {
279 if (rc) 278 if (rc)
@@ -372,7 +371,6 @@ static int ibmvtpm_reset_crq(struct ibmvtpm_dev *ibmvtpm)
372static int tpm_ibmvtpm_resume(struct device *dev) 371static int tpm_ibmvtpm_resume(struct device *dev)
373{ 372{
374 struct ibmvtpm_dev *ibmvtpm = ibmvtpm_get_data(dev); 373 struct ibmvtpm_dev *ibmvtpm = ibmvtpm_get_data(dev);
375 unsigned long flags;
376 int rc = 0; 374 int rc = 0;
377 375
378 do { 376 do {
@@ -387,10 +385,11 @@ static int tpm_ibmvtpm_resume(struct device *dev)
387 return rc; 385 return rc;
388 } 386 }
389 387
390 spin_lock_irqsave(&ibmvtpm->lock, flags); 388 rc = vio_enable_interrupts(ibmvtpm->vdev);
391 vio_disable_interrupts(ibmvtpm->vdev); 389 if (rc) {
392 tasklet_schedule(&ibmvtpm->tasklet); 390 dev_err(dev, "Error vio_enable_interrupts rc=%d\n", rc);
393 spin_unlock_irqrestore(&ibmvtpm->lock, flags); 391 return rc;
392 }
394 393
395 rc = ibmvtpm_crq_send_init(ibmvtpm); 394 rc = ibmvtpm_crq_send_init(ibmvtpm);
396 if (rc) 395 if (rc)
@@ -467,7 +466,7 @@ static struct ibmvtpm_crq *ibmvtpm_crq_get_next(struct ibmvtpm_dev *ibmvtpm)
467 if (crq->valid & VTPM_MSG_RES) { 466 if (crq->valid & VTPM_MSG_RES) {
468 if (++crq_q->index == crq_q->num_entry) 467 if (++crq_q->index == crq_q->num_entry)
469 crq_q->index = 0; 468 crq_q->index = 0;
470 rmb(); 469 smp_rmb();
471 } else 470 } else
472 crq = NULL; 471 crq = NULL;
473 return crq; 472 return crq;
@@ -535,11 +534,9 @@ static void ibmvtpm_crq_process(struct ibmvtpm_crq *crq,
535 ibmvtpm->vtpm_version = crq->data; 534 ibmvtpm->vtpm_version = crq->data;
536 return; 535 return;
537 case VTPM_TPM_COMMAND_RES: 536 case VTPM_TPM_COMMAND_RES:
538 ibmvtpm->crq_res.valid = crq->valid; 537 /* len of the data in rtce buffer */
539 ibmvtpm->crq_res.msg = crq->msg; 538 ibmvtpm->res_len = crq->len;
540 ibmvtpm->crq_res.len = crq->len; 539 wake_up_interruptible(&ibmvtpm->wq);
541 ibmvtpm->crq_res.data = crq->data;
542 wake_up_interruptible(&wq);
543 return; 540 return;
544 default: 541 default:
545 return; 542 return;
@@ -559,38 +556,19 @@ static void ibmvtpm_crq_process(struct ibmvtpm_crq *crq,
559static irqreturn_t ibmvtpm_interrupt(int irq, void *vtpm_instance) 556static irqreturn_t ibmvtpm_interrupt(int irq, void *vtpm_instance)
560{ 557{
561 struct ibmvtpm_dev *ibmvtpm = (struct ibmvtpm_dev *) vtpm_instance; 558 struct ibmvtpm_dev *ibmvtpm = (struct ibmvtpm_dev *) vtpm_instance;
562 unsigned long flags;
563
564 spin_lock_irqsave(&ibmvtpm->lock, flags);
565 vio_disable_interrupts(ibmvtpm->vdev);
566 tasklet_schedule(&ibmvtpm->tasklet);
567 spin_unlock_irqrestore(&ibmvtpm->lock, flags);
568
569 return IRQ_HANDLED;
570}
571
572/**
573 * ibmvtpm_tasklet - Interrupt handler tasklet
574 * @data: ibm vtpm device struct
575 *
576 * Returns:
577 * Nothing
578 **/
579static void ibmvtpm_tasklet(void *data)
580{
581 struct ibmvtpm_dev *ibmvtpm = data;
582 struct ibmvtpm_crq *crq; 559 struct ibmvtpm_crq *crq;
583 unsigned long flags;
584 560
585 spin_lock_irqsave(&ibmvtpm->lock, flags); 561 /* while loop is needed for initial setup (get version and
562 * get rtce_size). There should be only one tpm request at any
563 * given time.
564 */
586 while ((crq = ibmvtpm_crq_get_next(ibmvtpm)) != NULL) { 565 while ((crq = ibmvtpm_crq_get_next(ibmvtpm)) != NULL) {
587 ibmvtpm_crq_process(crq, ibmvtpm); 566 ibmvtpm_crq_process(crq, ibmvtpm);
588 crq->valid = 0; 567 crq->valid = 0;
589 wmb(); 568 smp_wmb();
590 } 569 }
591 570
592 vio_enable_interrupts(ibmvtpm->vdev); 571 return IRQ_HANDLED;
593 spin_unlock_irqrestore(&ibmvtpm->lock, flags);
594} 572}
595 573
596/** 574/**
@@ -650,9 +628,6 @@ static int tpm_ibmvtpm_probe(struct vio_dev *vio_dev,
650 goto reg_crq_cleanup; 628 goto reg_crq_cleanup;
651 } 629 }
652 630
653 tasklet_init(&ibmvtpm->tasklet, (void *)ibmvtpm_tasklet,
654 (unsigned long)ibmvtpm);
655
656 rc = request_irq(vio_dev->irq, ibmvtpm_interrupt, 0, 631 rc = request_irq(vio_dev->irq, ibmvtpm_interrupt, 0,
657 tpm_ibmvtpm_driver_name, ibmvtpm); 632 tpm_ibmvtpm_driver_name, ibmvtpm);
658 if (rc) { 633 if (rc) {
@@ -666,13 +641,14 @@ static int tpm_ibmvtpm_probe(struct vio_dev *vio_dev,
666 goto init_irq_cleanup; 641 goto init_irq_cleanup;
667 } 642 }
668 643
644 init_waitqueue_head(&ibmvtpm->wq);
645
669 crq_q->index = 0; 646 crq_q->index = 0;
670 647
671 ibmvtpm->dev = dev; 648 ibmvtpm->dev = dev;
672 ibmvtpm->vdev = vio_dev; 649 ibmvtpm->vdev = vio_dev;
673 chip->vendor.data = (void *)ibmvtpm; 650 chip->vendor.data = (void *)ibmvtpm;
674 651
675 spin_lock_init(&ibmvtpm->lock);
676 spin_lock_init(&ibmvtpm->rtce_lock); 652 spin_lock_init(&ibmvtpm->rtce_lock);
677 653
678 rc = ibmvtpm_crq_send_init(ibmvtpm); 654 rc = ibmvtpm_crq_send_init(ibmvtpm);
@@ -689,7 +665,6 @@ static int tpm_ibmvtpm_probe(struct vio_dev *vio_dev,
689 665
690 return rc; 666 return rc;
691init_irq_cleanup: 667init_irq_cleanup:
692 tasklet_kill(&ibmvtpm->tasklet);
693 do { 668 do {
694 rc1 = plpar_hcall_norets(H_FREE_CRQ, vio_dev->unit_address); 669 rc1 = plpar_hcall_norets(H_FREE_CRQ, vio_dev->unit_address);
695 } while (rc1 == H_BUSY || H_IS_LONG_BUSY(rc1)); 670 } while (rc1 == H_BUSY || H_IS_LONG_BUSY(rc1));
diff --git a/drivers/char/tpm/tpm_ibmvtpm.h b/drivers/char/tpm/tpm_ibmvtpm.h
index 4296eb4b4d82..bd82a791f995 100644
--- a/drivers/char/tpm/tpm_ibmvtpm.h
+++ b/drivers/char/tpm/tpm_ibmvtpm.h
@@ -38,13 +38,12 @@ struct ibmvtpm_dev {
38 struct vio_dev *vdev; 38 struct vio_dev *vdev;
39 struct ibmvtpm_crq_queue crq_queue; 39 struct ibmvtpm_crq_queue crq_queue;
40 dma_addr_t crq_dma_handle; 40 dma_addr_t crq_dma_handle;
41 spinlock_t lock;
42 struct tasklet_struct tasklet;
43 u32 rtce_size; 41 u32 rtce_size;
44 void __iomem *rtce_buf; 42 void __iomem *rtce_buf;
45 dma_addr_t rtce_dma_handle; 43 dma_addr_t rtce_dma_handle;
46 spinlock_t rtce_lock; 44 spinlock_t rtce_lock;
47 struct ibmvtpm_crq crq_res; 45 wait_queue_head_t wq;
46 u16 res_len;
48 u32 vtpm_version; 47 u32 vtpm_version;
49}; 48};
50 49
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index 75c1ee699143..5cbd00e74067 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -346,19 +346,15 @@ init_cifs_idmap(void)
346 if (!cred) 346 if (!cred)
347 return -ENOMEM; 347 return -ENOMEM;
348 348
349 keyring = key_alloc(&key_type_keyring, ".cifs_idmap", 0, 0, cred, 349 keyring = keyring_alloc(".cifs_idmap", 0, 0, cred,
350 (KEY_POS_ALL & ~KEY_POS_SETATTR) | 350 (KEY_POS_ALL & ~KEY_POS_SETATTR) |
351 KEY_USR_VIEW | KEY_USR_READ, 351 KEY_USR_VIEW | KEY_USR_READ,
352 KEY_ALLOC_NOT_IN_QUOTA); 352 KEY_ALLOC_NOT_IN_QUOTA, NULL);
353 if (IS_ERR(keyring)) { 353 if (IS_ERR(keyring)) {
354 ret = PTR_ERR(keyring); 354 ret = PTR_ERR(keyring);
355 goto failed_put_cred; 355 goto failed_put_cred;
356 } 356 }
357 357
358 ret = key_instantiate_and_link(keyring, NULL, 0, NULL, NULL);
359 if (ret < 0)
360 goto failed_put_key;
361
362 ret = register_key_type(&cifs_idmap_key_type); 358 ret = register_key_type(&cifs_idmap_key_type);
363 if (ret < 0) 359 if (ret < 0)
364 goto failed_put_key; 360 goto failed_put_key;
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c
index 9cc4a3fbf4b0..bc3968fa81e5 100644
--- a/fs/nfs/idmap.c
+++ b/fs/nfs/idmap.c
@@ -193,19 +193,15 @@ static int nfs_idmap_init_keyring(void)
193 if (!cred) 193 if (!cred)
194 return -ENOMEM; 194 return -ENOMEM;
195 195
196 keyring = key_alloc(&key_type_keyring, ".id_resolver", 0, 0, cred, 196 keyring = keyring_alloc(".id_resolver", 0, 0, cred,
197 (KEY_POS_ALL & ~KEY_POS_SETATTR) | 197 (KEY_POS_ALL & ~KEY_POS_SETATTR) |
198 KEY_USR_VIEW | KEY_USR_READ, 198 KEY_USR_VIEW | KEY_USR_READ,
199 KEY_ALLOC_NOT_IN_QUOTA); 199 KEY_ALLOC_NOT_IN_QUOTA, NULL);
200 if (IS_ERR(keyring)) { 200 if (IS_ERR(keyring)) {
201 ret = PTR_ERR(keyring); 201 ret = PTR_ERR(keyring);
202 goto failed_put_cred; 202 goto failed_put_cred;
203 } 203 }
204 204
205 ret = key_instantiate_and_link(keyring, NULL, 0, NULL, NULL);
206 if (ret < 0)
207 goto failed_put_key;
208
209 ret = register_key_type(&key_type_id_resolver); 205 ret = register_key_type(&key_type_id_resolver);
210 if (ret < 0) 206 if (ret < 0)
211 goto failed_put_key; 207 goto failed_put_key;
diff --git a/include/linux/cred.h b/include/linux/cred.h
index ebbed2ce6637..0142aacb70b7 100644
--- a/include/linux/cred.h
+++ b/include/linux/cred.h
@@ -77,21 +77,6 @@ extern int in_group_p(kgid_t);
77extern int in_egroup_p(kgid_t); 77extern int in_egroup_p(kgid_t);
78 78
79/* 79/*
80 * The common credentials for a thread group
81 * - shared by CLONE_THREAD
82 */
83#ifdef CONFIG_KEYS
84struct thread_group_cred {
85 atomic_t usage;
86 pid_t tgid; /* thread group process ID */
87 spinlock_t lock;
88 struct key __rcu *session_keyring; /* keyring inherited over fork */
89 struct key *process_keyring; /* keyring private to this process */
90 struct rcu_head rcu; /* RCU deletion hook */
91};
92#endif
93
94/*
95 * The security context of a task 80 * The security context of a task
96 * 81 *
97 * The parts of the context break down into two categories: 82 * The parts of the context break down into two categories:
@@ -139,6 +124,8 @@ struct cred {
139#ifdef CONFIG_KEYS 124#ifdef CONFIG_KEYS
140 unsigned char jit_keyring; /* default keyring to attach requested 125 unsigned char jit_keyring; /* default keyring to attach requested
141 * keys to */ 126 * keys to */
127 struct key __rcu *session_keyring; /* keyring inherited over fork */
128 struct key *process_keyring; /* keyring private to this process */
142 struct key *thread_keyring; /* keyring private to this thread */ 129 struct key *thread_keyring; /* keyring private to this thread */
143 struct key *request_key_auth; /* assumed request_key authority */ 130 struct key *request_key_auth; /* assumed request_key authority */
144 struct thread_group_cred *tgcred; /* thread-group shared credentials */ 131 struct thread_group_cred *tgcred; /* thread-group shared credentials */
diff --git a/include/linux/key.h b/include/linux/key.h
index 2393b1c040b6..4dfde1161c5e 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -265,6 +265,7 @@ extern int key_unlink(struct key *keyring,
265 265
266extern struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid, 266extern struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid,
267 const struct cred *cred, 267 const struct cred *cred,
268 key_perm_t perm,
268 unsigned long flags, 269 unsigned long flags,
269 struct key *dest); 270 struct key *dest);
270 271
diff --git a/kernel/cred.c b/kernel/cred.c
index 48cea3da6d05..8888afb846e9 100644
--- a/kernel/cred.c
+++ b/kernel/cred.c
@@ -30,17 +30,6 @@
30static struct kmem_cache *cred_jar; 30static struct kmem_cache *cred_jar;
31 31
32/* 32/*
33 * The common credentials for the initial task's thread group
34 */
35#ifdef CONFIG_KEYS
36static struct thread_group_cred init_tgcred = {
37 .usage = ATOMIC_INIT(2),
38 .tgid = 0,
39 .lock = __SPIN_LOCK_UNLOCKED(init_cred.tgcred.lock),
40};
41#endif
42
43/*
44 * The initial credentials for the initial task 33 * The initial credentials for the initial task
45 */ 34 */
46struct cred init_cred = { 35struct cred init_cred = {
@@ -65,9 +54,6 @@ struct cred init_cred = {
65 .user = INIT_USER, 54 .user = INIT_USER,
66 .user_ns = &init_user_ns, 55 .user_ns = &init_user_ns,
67 .group_info = &init_groups, 56 .group_info = &init_groups,
68#ifdef CONFIG_KEYS
69 .tgcred = &init_tgcred,
70#endif
71}; 57};
72 58
73static inline void set_cred_subscribers(struct cred *cred, int n) 59static inline void set_cred_subscribers(struct cred *cred, int n)
@@ -96,36 +82,6 @@ static inline void alter_cred_subscribers(const struct cred *_cred, int n)
96} 82}
97 83
98/* 84/*
99 * Dispose of the shared task group credentials
100 */
101#ifdef CONFIG_KEYS
102static void release_tgcred_rcu(struct rcu_head *rcu)
103{
104 struct thread_group_cred *tgcred =
105 container_of(rcu, struct thread_group_cred, rcu);
106
107 BUG_ON(atomic_read(&tgcred->usage) != 0);
108
109 key_put(tgcred->session_keyring);
110 key_put(tgcred->process_keyring);
111 kfree(tgcred);
112}
113#endif
114
115/*
116 * Release a set of thread group credentials.
117 */
118static void release_tgcred(struct cred *cred)
119{
120#ifdef CONFIG_KEYS
121 struct thread_group_cred *tgcred = cred->tgcred;
122
123 if (atomic_dec_and_test(&tgcred->usage))
124 call_rcu(&tgcred->rcu, release_tgcred_rcu);
125#endif
126}
127
128/*
129 * The RCU callback to actually dispose of a set of credentials 85 * The RCU callback to actually dispose of a set of credentials
130 */ 86 */
131static void put_cred_rcu(struct rcu_head *rcu) 87static void put_cred_rcu(struct rcu_head *rcu)
@@ -150,9 +106,10 @@ static void put_cred_rcu(struct rcu_head *rcu)
150#endif 106#endif
151 107
152 security_cred_free(cred); 108 security_cred_free(cred);
109 key_put(cred->session_keyring);
110 key_put(cred->process_keyring);
153 key_put(cred->thread_keyring); 111 key_put(cred->thread_keyring);
154 key_put(cred->request_key_auth); 112 key_put(cred->request_key_auth);
155 release_tgcred(cred);
156 if (cred->group_info) 113 if (cred->group_info)
157 put_group_info(cred->group_info); 114 put_group_info(cred->group_info);
158 free_uid(cred->user); 115 free_uid(cred->user);
@@ -246,15 +203,6 @@ struct cred *cred_alloc_blank(void)
246 if (!new) 203 if (!new)
247 return NULL; 204 return NULL;
248 205
249#ifdef CONFIG_KEYS
250 new->tgcred = kzalloc(sizeof(*new->tgcred), GFP_KERNEL);
251 if (!new->tgcred) {
252 kmem_cache_free(cred_jar, new);
253 return NULL;
254 }
255 atomic_set(&new->tgcred->usage, 1);
256#endif
257
258 atomic_set(&new->usage, 1); 206 atomic_set(&new->usage, 1);
259#ifdef CONFIG_DEBUG_CREDENTIALS 207#ifdef CONFIG_DEBUG_CREDENTIALS
260 new->magic = CRED_MAGIC; 208 new->magic = CRED_MAGIC;
@@ -308,9 +256,10 @@ struct cred *prepare_creds(void)
308 get_user_ns(new->user_ns); 256 get_user_ns(new->user_ns);
309 257
310#ifdef CONFIG_KEYS 258#ifdef CONFIG_KEYS
259 key_get(new->session_keyring);
260 key_get(new->process_keyring);
311 key_get(new->thread_keyring); 261 key_get(new->thread_keyring);
312 key_get(new->request_key_auth); 262 key_get(new->request_key_auth);
313 atomic_inc(&new->tgcred->usage);
314#endif 263#endif
315 264
316#ifdef CONFIG_SECURITY 265#ifdef CONFIG_SECURITY
@@ -334,39 +283,20 @@ EXPORT_SYMBOL(prepare_creds);
334 */ 283 */
335struct cred *prepare_exec_creds(void) 284struct cred *prepare_exec_creds(void)
336{ 285{
337 struct thread_group_cred *tgcred = NULL;
338 struct cred *new; 286 struct cred *new;
339 287
340#ifdef CONFIG_KEYS
341 tgcred = kmalloc(sizeof(*tgcred), GFP_KERNEL);
342 if (!tgcred)
343 return NULL;
344#endif
345
346 new = prepare_creds(); 288 new = prepare_creds();
347 if (!new) { 289 if (!new)
348 kfree(tgcred);
349 return new; 290 return new;
350 }
351 291
352#ifdef CONFIG_KEYS 292#ifdef CONFIG_KEYS
353 /* newly exec'd tasks don't get a thread keyring */ 293 /* newly exec'd tasks don't get a thread keyring */
354 key_put(new->thread_keyring); 294 key_put(new->thread_keyring);
355 new->thread_keyring = NULL; 295 new->thread_keyring = NULL;
356 296
357 /* create a new per-thread-group creds for all this set of threads to
358 * share */
359 memcpy(tgcred, new->tgcred, sizeof(struct thread_group_cred));
360
361 atomic_set(&tgcred->usage, 1);
362 spin_lock_init(&tgcred->lock);
363
364 /* inherit the session keyring; new process keyring */ 297 /* inherit the session keyring; new process keyring */
365 key_get(tgcred->session_keyring); 298 key_put(new->process_keyring);
366 tgcred->process_keyring = NULL; 299 new->process_keyring = NULL;
367
368 release_tgcred(new);
369 new->tgcred = tgcred;
370#endif 300#endif
371 301
372 return new; 302 return new;
@@ -383,9 +313,6 @@ struct cred *prepare_exec_creds(void)
383 */ 313 */
384int copy_creds(struct task_struct *p, unsigned long clone_flags) 314int copy_creds(struct task_struct *p, unsigned long clone_flags)
385{ 315{
386#ifdef CONFIG_KEYS
387 struct thread_group_cred *tgcred;
388#endif
389 struct cred *new; 316 struct cred *new;
390 int ret; 317 int ret;
391 318
@@ -425,22 +352,12 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags)
425 install_thread_keyring_to_cred(new); 352 install_thread_keyring_to_cred(new);
426 } 353 }
427 354
428 /* we share the process and session keyrings between all the threads in 355 /* The process keyring is only shared between the threads in a process;
429 * a process - this is slightly icky as we violate COW credentials a 356 * anything outside of those threads doesn't inherit.
430 * bit */ 357 */
431 if (!(clone_flags & CLONE_THREAD)) { 358 if (!(clone_flags & CLONE_THREAD)) {
432 tgcred = kmalloc(sizeof(*tgcred), GFP_KERNEL); 359 key_put(new->process_keyring);
433 if (!tgcred) { 360 new->process_keyring = NULL;
434 ret = -ENOMEM;
435 goto error_put;
436 }
437 atomic_set(&tgcred->usage, 1);
438 spin_lock_init(&tgcred->lock);
439 tgcred->process_keyring = NULL;
440 tgcred->session_keyring = key_get(new->tgcred->session_keyring);
441
442 release_tgcred(new);
443 new->tgcred = tgcred;
444 } 361 }
445#endif 362#endif
446 363
@@ -643,9 +560,6 @@ void __init cred_init(void)
643 */ 560 */
644struct cred *prepare_kernel_cred(struct task_struct *daemon) 561struct cred *prepare_kernel_cred(struct task_struct *daemon)
645{ 562{
646#ifdef CONFIG_KEYS
647 struct thread_group_cred *tgcred;
648#endif
649 const struct cred *old; 563 const struct cred *old;
650 struct cred *new; 564 struct cred *new;
651 565
@@ -653,14 +567,6 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon)
653 if (!new) 567 if (!new)
654 return NULL; 568 return NULL;
655 569
656#ifdef CONFIG_KEYS
657 tgcred = kmalloc(sizeof(*tgcred), GFP_KERNEL);
658 if (!tgcred) {
659 kmem_cache_free(cred_jar, new);
660 return NULL;
661 }
662#endif
663
664 kdebug("prepare_kernel_cred() alloc %p", new); 570 kdebug("prepare_kernel_cred() alloc %p", new);
665 571
666 if (daemon) 572 if (daemon)
@@ -678,13 +584,10 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon)
678 get_group_info(new->group_info); 584 get_group_info(new->group_info);
679 585
680#ifdef CONFIG_KEYS 586#ifdef CONFIG_KEYS
681 atomic_set(&tgcred->usage, 1); 587 new->session_keyring = NULL;
682 spin_lock_init(&tgcred->lock); 588 new->process_keyring = NULL;
683 tgcred->process_keyring = NULL;
684 tgcred->session_keyring = NULL;
685 new->tgcred = tgcred;
686 new->request_key_auth = NULL;
687 new->thread_keyring = NULL; 589 new->thread_keyring = NULL;
590 new->request_key_auth = NULL;
688 new->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; 591 new->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
689#endif 592#endif
690 593
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index ee376beedaf9..5af44b593770 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -396,25 +396,29 @@ int __secure_computing(int this_syscall)
396#ifdef CONFIG_SECCOMP_FILTER 396#ifdef CONFIG_SECCOMP_FILTER
397 case SECCOMP_MODE_FILTER: { 397 case SECCOMP_MODE_FILTER: {
398 int data; 398 int data;
399 struct pt_regs *regs = task_pt_regs(current);
399 ret = seccomp_run_filters(this_syscall); 400 ret = seccomp_run_filters(this_syscall);
400 data = ret & SECCOMP_RET_DATA; 401 data = ret & SECCOMP_RET_DATA;
401 ret &= SECCOMP_RET_ACTION; 402 ret &= SECCOMP_RET_ACTION;
402 switch (ret) { 403 switch (ret) {
403 case SECCOMP_RET_ERRNO: 404 case SECCOMP_RET_ERRNO:
404 /* Set the low-order 16-bits as a errno. */ 405 /* Set the low-order 16-bits as a errno. */
405 syscall_set_return_value(current, task_pt_regs(current), 406 syscall_set_return_value(current, regs,
406 -data, 0); 407 -data, 0);
407 goto skip; 408 goto skip;
408 case SECCOMP_RET_TRAP: 409 case SECCOMP_RET_TRAP:
409 /* Show the handler the original registers. */ 410 /* Show the handler the original registers. */
410 syscall_rollback(current, task_pt_regs(current)); 411 syscall_rollback(current, regs);
411 /* Let the filter pass back 16 bits of data. */ 412 /* Let the filter pass back 16 bits of data. */
412 seccomp_send_sigsys(this_syscall, data); 413 seccomp_send_sigsys(this_syscall, data);
413 goto skip; 414 goto skip;
414 case SECCOMP_RET_TRACE: 415 case SECCOMP_RET_TRACE:
415 /* Skip these calls if there is no tracer. */ 416 /* Skip these calls if there is no tracer. */
416 if (!ptrace_event_enabled(current, PTRACE_EVENT_SECCOMP)) 417 if (!ptrace_event_enabled(current, PTRACE_EVENT_SECCOMP)) {
418 syscall_set_return_value(current, regs,
419 -ENOSYS, 0);
417 goto skip; 420 goto skip;
421 }
418 /* Allow the BPF to provide the event message */ 422 /* Allow the BPF to provide the event message */
419 ptrace_event(PTRACE_EVENT_SECCOMP, data); 423 ptrace_event(PTRACE_EVENT_SECCOMP, data);
420 /* 424 /*
@@ -425,6 +429,9 @@ int __secure_computing(int this_syscall)
425 */ 429 */
426 if (fatal_signal_pending(current)) 430 if (fatal_signal_pending(current))
427 break; 431 break;
432 if (syscall_get_nr(current, regs) < 0)
433 goto skip; /* Explicit request to skip. */
434
428 return 0; 435 return 0;
429 case SECCOMP_RET_ALLOW: 436 case SECCOMP_RET_ALLOW:
430 return 0; 437 return 0;
diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c
index 8aa4b1115384..0a69d0757795 100644
--- a/net/dns_resolver/dns_key.c
+++ b/net/dns_resolver/dns_key.c
@@ -259,20 +259,16 @@ static int __init init_dns_resolver(void)
259 if (!cred) 259 if (!cred)
260 return -ENOMEM; 260 return -ENOMEM;
261 261
262 keyring = key_alloc(&key_type_keyring, ".dns_resolver", 262 keyring = keyring_alloc(".dns_resolver",
263 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, 263 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
264 (KEY_POS_ALL & ~KEY_POS_SETATTR) | 264 (KEY_POS_ALL & ~KEY_POS_SETATTR) |
265 KEY_USR_VIEW | KEY_USR_READ, 265 KEY_USR_VIEW | KEY_USR_READ,
266 KEY_ALLOC_NOT_IN_QUOTA); 266 KEY_ALLOC_NOT_IN_QUOTA, NULL);
267 if (IS_ERR(keyring)) { 267 if (IS_ERR(keyring)) {
268 ret = PTR_ERR(keyring); 268 ret = PTR_ERR(keyring);
269 goto failed_put_cred; 269 goto failed_put_cred;
270 } 270 }
271 271
272 ret = key_instantiate_and_link(keyring, NULL, 0, NULL, NULL);
273 if (ret < 0)
274 goto failed_put_key;
275
276 ret = register_key_type(&key_type_dns_resolver); 272 ret = register_key_type(&key_type_dns_resolver);
277 if (ret < 0) 273 if (ret < 0)
278 goto failed_put_key; 274 goto failed_put_key;
@@ -304,3 +300,4 @@ static void __exit exit_dns_resolver(void)
304module_init(init_dns_resolver) 300module_init(init_dns_resolver)
305module_exit(exit_dns_resolver) 301module_exit(exit_dns_resolver)
306MODULE_LICENSE("GPL"); 302MODULE_LICENSE("GPL");
303
diff --git a/security/keys/key.c b/security/keys/key.c
index a15c9da8f971..8fb7c7bd4657 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -854,13 +854,13 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
854 /* if the client doesn't provide, decide on the permissions we want */ 854 /* if the client doesn't provide, decide on the permissions we want */
855 if (perm == KEY_PERM_UNDEF) { 855 if (perm == KEY_PERM_UNDEF) {
856 perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR; 856 perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR;
857 perm |= KEY_USR_VIEW | KEY_USR_SEARCH | KEY_USR_LINK | KEY_USR_SETATTR; 857 perm |= KEY_USR_VIEW;
858 858
859 if (ktype->read) 859 if (ktype->read)
860 perm |= KEY_POS_READ | KEY_USR_READ; 860 perm |= KEY_POS_READ;
861 861
862 if (ktype == &key_type_keyring || ktype->update) 862 if (ktype == &key_type_keyring || ktype->update)
863 perm |= KEY_USR_WRITE; 863 perm |= KEY_POS_WRITE;
864 } 864 }
865 865
866 /* allocate a new key */ 866 /* allocate a new key */
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 5d34b4e827d6..4b5c948eb414 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -1132,12 +1132,12 @@ long keyctl_instantiate_key_iov(key_serial_t id,
1132 ret = rw_copy_check_uvector(WRITE, _payload_iov, ioc, 1132 ret = rw_copy_check_uvector(WRITE, _payload_iov, ioc,
1133 ARRAY_SIZE(iovstack), iovstack, &iov); 1133 ARRAY_SIZE(iovstack), iovstack, &iov);
1134 if (ret < 0) 1134 if (ret < 0)
1135 return ret; 1135 goto err;
1136 if (ret == 0) 1136 if (ret == 0)
1137 goto no_payload_free; 1137 goto no_payload_free;
1138 1138
1139 ret = keyctl_instantiate_key_common(id, iov, ioc, ret, ringid); 1139 ret = keyctl_instantiate_key_common(id, iov, ioc, ret, ringid);
1140 1140err:
1141 if (iov != iovstack) 1141 if (iov != iovstack)
1142 kfree(iov); 1142 kfree(iov);
1143 return ret; 1143 return ret;
@@ -1495,7 +1495,8 @@ long keyctl_session_to_parent(void)
1495 goto error_keyring; 1495 goto error_keyring;
1496 newwork = &cred->rcu; 1496 newwork = &cred->rcu;
1497 1497
1498 cred->tgcred->session_keyring = key_ref_to_ptr(keyring_r); 1498 cred->session_keyring = key_ref_to_ptr(keyring_r);
1499 keyring_r = NULL;
1499 init_task_work(newwork, key_change_session_keyring); 1500 init_task_work(newwork, key_change_session_keyring);
1500 1501
1501 me = current; 1502 me = current;
@@ -1519,7 +1520,7 @@ long keyctl_session_to_parent(void)
1519 mycred = current_cred(); 1520 mycred = current_cred();
1520 pcred = __task_cred(parent); 1521 pcred = __task_cred(parent);
1521 if (mycred == pcred || 1522 if (mycred == pcred ||
1522 mycred->tgcred->session_keyring == pcred->tgcred->session_keyring) { 1523 mycred->session_keyring == pcred->session_keyring) {
1523 ret = 0; 1524 ret = 0;
1524 goto unlock; 1525 goto unlock;
1525 } 1526 }
@@ -1535,9 +1536,9 @@ long keyctl_session_to_parent(void)
1535 goto unlock; 1536 goto unlock;
1536 1537
1537 /* the keyrings must have the same UID */ 1538 /* the keyrings must have the same UID */
1538 if ((pcred->tgcred->session_keyring && 1539 if ((pcred->session_keyring &&
1539 !uid_eq(pcred->tgcred->session_keyring->uid, mycred->euid)) || 1540 !uid_eq(pcred->session_keyring->uid, mycred->euid)) ||
1540 !uid_eq(mycred->tgcred->session_keyring->uid, mycred->euid)) 1541 !uid_eq(mycred->session_keyring->uid, mycred->euid))
1541 goto unlock; 1542 goto unlock;
1542 1543
1543 /* cancel an already pending keyring replacement */ 1544 /* cancel an already pending keyring replacement */
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 6e42df15a24c..6ece7f2e5707 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -257,17 +257,14 @@ error:
257 * Allocate a keyring and link into the destination keyring. 257 * Allocate a keyring and link into the destination keyring.
258 */ 258 */
259struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid, 259struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid,
260 const struct cred *cred, unsigned long flags, 260 const struct cred *cred, key_perm_t perm,
261 struct key *dest) 261 unsigned long flags, struct key *dest)
262{ 262{
263 struct key *keyring; 263 struct key *keyring;
264 int ret; 264 int ret;
265 265
266 keyring = key_alloc(&key_type_keyring, description, 266 keyring = key_alloc(&key_type_keyring, description,
267 uid, gid, cred, 267 uid, gid, cred, perm, flags);
268 (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
269 flags);
270
271 if (!IS_ERR(keyring)) { 268 if (!IS_ERR(keyring)) {
272 ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL); 269 ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL);
273 if (ret < 0) { 270 if (ret < 0) {
@@ -278,6 +275,7 @@ struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid,
278 275
279 return keyring; 276 return keyring;
280} 277}
278EXPORT_SYMBOL(keyring_alloc);
281 279
282/** 280/**
283 * keyring_search_aux - Search a keyring tree for a key matching some criteria 281 * keyring_search_aux - Search a keyring tree for a key matching some criteria
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 86468f385fc8..58dfe0890947 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -45,10 +45,12 @@ int install_user_keyrings(void)
45 struct user_struct *user; 45 struct user_struct *user;
46 const struct cred *cred; 46 const struct cred *cred;
47 struct key *uid_keyring, *session_keyring; 47 struct key *uid_keyring, *session_keyring;
48 key_perm_t user_keyring_perm;
48 char buf[20]; 49 char buf[20];
49 int ret; 50 int ret;
50 uid_t uid; 51 uid_t uid;
51 52
53 user_keyring_perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL;
52 cred = current_cred(); 54 cred = current_cred();
53 user = cred->user; 55 user = cred->user;
54 uid = from_kuid(cred->user_ns, user->uid); 56 uid = from_kuid(cred->user_ns, user->uid);
@@ -73,8 +75,8 @@ int install_user_keyrings(void)
73 uid_keyring = find_keyring_by_name(buf, true); 75 uid_keyring = find_keyring_by_name(buf, true);
74 if (IS_ERR(uid_keyring)) { 76 if (IS_ERR(uid_keyring)) {
75 uid_keyring = keyring_alloc(buf, user->uid, INVALID_GID, 77 uid_keyring = keyring_alloc(buf, user->uid, INVALID_GID,
76 cred, KEY_ALLOC_IN_QUOTA, 78 cred, user_keyring_perm,
77 NULL); 79 KEY_ALLOC_IN_QUOTA, NULL);
78 if (IS_ERR(uid_keyring)) { 80 if (IS_ERR(uid_keyring)) {
79 ret = PTR_ERR(uid_keyring); 81 ret = PTR_ERR(uid_keyring);
80 goto error; 82 goto error;
@@ -89,7 +91,8 @@ int install_user_keyrings(void)
89 if (IS_ERR(session_keyring)) { 91 if (IS_ERR(session_keyring)) {
90 session_keyring = 92 session_keyring =
91 keyring_alloc(buf, user->uid, INVALID_GID, 93 keyring_alloc(buf, user->uid, INVALID_GID,
92 cred, KEY_ALLOC_IN_QUOTA, NULL); 94 cred, user_keyring_perm,
95 KEY_ALLOC_IN_QUOTA, NULL);
93 if (IS_ERR(session_keyring)) { 96 if (IS_ERR(session_keyring)) {
94 ret = PTR_ERR(session_keyring); 97 ret = PTR_ERR(session_keyring);
95 goto error_release; 98 goto error_release;
@@ -130,6 +133,7 @@ int install_thread_keyring_to_cred(struct cred *new)
130 struct key *keyring; 133 struct key *keyring;
131 134
132 keyring = keyring_alloc("_tid", new->uid, new->gid, new, 135 keyring = keyring_alloc("_tid", new->uid, new->gid, new,
136 KEY_POS_ALL | KEY_USR_VIEW,
133 KEY_ALLOC_QUOTA_OVERRUN, NULL); 137 KEY_ALLOC_QUOTA_OVERRUN, NULL);
134 if (IS_ERR(keyring)) 138 if (IS_ERR(keyring))
135 return PTR_ERR(keyring); 139 return PTR_ERR(keyring);
@@ -170,27 +174,18 @@ static int install_thread_keyring(void)
170int install_process_keyring_to_cred(struct cred *new) 174int install_process_keyring_to_cred(struct cred *new)
171{ 175{
172 struct key *keyring; 176 struct key *keyring;
173 int ret;
174 177
175 if (new->tgcred->process_keyring) 178 if (new->process_keyring)
176 return -EEXIST; 179 return -EEXIST;
177 180
178 keyring = keyring_alloc("_pid", new->uid, new->gid, 181 keyring = keyring_alloc("_pid", new->uid, new->gid, new,
179 new, KEY_ALLOC_QUOTA_OVERRUN, NULL); 182 KEY_POS_ALL | KEY_USR_VIEW,
183 KEY_ALLOC_QUOTA_OVERRUN, NULL);
180 if (IS_ERR(keyring)) 184 if (IS_ERR(keyring))
181 return PTR_ERR(keyring); 185 return PTR_ERR(keyring);
182 186
183 spin_lock_irq(&new->tgcred->lock); 187 new->process_keyring = keyring;
184 if (!new->tgcred->process_keyring) { 188 return 0;
185 new->tgcred->process_keyring = keyring;
186 keyring = NULL;
187 ret = 0;
188 } else {
189 ret = -EEXIST;
190 }
191 spin_unlock_irq(&new->tgcred->lock);
192 key_put(keyring);
193 return ret;
194} 189}
195 190
196/* 191/*
@@ -231,11 +226,12 @@ int install_session_keyring_to_cred(struct cred *cred, struct key *keyring)
231 /* create an empty session keyring */ 226 /* create an empty session keyring */
232 if (!keyring) { 227 if (!keyring) {
233 flags = KEY_ALLOC_QUOTA_OVERRUN; 228 flags = KEY_ALLOC_QUOTA_OVERRUN;
234 if (cred->tgcred->session_keyring) 229 if (cred->session_keyring)
235 flags = KEY_ALLOC_IN_QUOTA; 230 flags = KEY_ALLOC_IN_QUOTA;
236 231
237 keyring = keyring_alloc("_ses", cred->uid, cred->gid, 232 keyring = keyring_alloc("_ses", cred->uid, cred->gid, cred,
238 cred, flags, NULL); 233 KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ,
234 flags, NULL);
239 if (IS_ERR(keyring)) 235 if (IS_ERR(keyring))
240 return PTR_ERR(keyring); 236 return PTR_ERR(keyring);
241 } else { 237 } else {
@@ -243,17 +239,11 @@ int install_session_keyring_to_cred(struct cred *cred, struct key *keyring)
243 } 239 }
244 240
245 /* install the keyring */ 241 /* install the keyring */
246 spin_lock_irq(&cred->tgcred->lock); 242 old = cred->session_keyring;
247 old = cred->tgcred->session_keyring; 243 rcu_assign_pointer(cred->session_keyring, keyring);
248 rcu_assign_pointer(cred->tgcred->session_keyring, keyring); 244
249 spin_unlock_irq(&cred->tgcred->lock); 245 if (old)
250
251 /* we're using RCU on the pointer, but there's no point synchronising
252 * on it if it didn't previously point to anything */
253 if (old) {
254 synchronize_rcu();
255 key_put(old); 246 key_put(old);
256 }
257 247
258 return 0; 248 return 0;
259} 249}
@@ -368,9 +358,9 @@ key_ref_t search_my_process_keyrings(struct key_type *type,
368 } 358 }
369 359
370 /* search the process keyring second */ 360 /* search the process keyring second */
371 if (cred->tgcred->process_keyring) { 361 if (cred->process_keyring) {
372 key_ref = keyring_search_aux( 362 key_ref = keyring_search_aux(
373 make_key_ref(cred->tgcred->process_keyring, 1), 363 make_key_ref(cred->process_keyring, 1),
374 cred, type, description, match, no_state_check); 364 cred, type, description, match, no_state_check);
375 if (!IS_ERR(key_ref)) 365 if (!IS_ERR(key_ref))
376 goto found; 366 goto found;
@@ -389,12 +379,10 @@ key_ref_t search_my_process_keyrings(struct key_type *type,
389 } 379 }
390 380
391 /* search the session keyring */ 381 /* search the session keyring */
392 if (cred->tgcred->session_keyring) { 382 if (cred->session_keyring) {
393 rcu_read_lock(); 383 rcu_read_lock();
394 key_ref = keyring_search_aux( 384 key_ref = keyring_search_aux(
395 make_key_ref(rcu_dereference( 385 make_key_ref(rcu_dereference(cred->session_keyring), 1),
396 cred->tgcred->session_keyring),
397 1),
398 cred, type, description, match, no_state_check); 386 cred, type, description, match, no_state_check);
399 rcu_read_unlock(); 387 rcu_read_unlock();
400 388
@@ -564,7 +552,7 @@ try_again:
564 break; 552 break;
565 553
566 case KEY_SPEC_PROCESS_KEYRING: 554 case KEY_SPEC_PROCESS_KEYRING:
567 if (!cred->tgcred->process_keyring) { 555 if (!cred->process_keyring) {
568 if (!(lflags & KEY_LOOKUP_CREATE)) 556 if (!(lflags & KEY_LOOKUP_CREATE))
569 goto error; 557 goto error;
570 558
@@ -576,13 +564,13 @@ try_again:
576 goto reget_creds; 564 goto reget_creds;
577 } 565 }
578 566
579 key = cred->tgcred->process_keyring; 567 key = cred->process_keyring;
580 atomic_inc(&key->usage); 568 atomic_inc(&key->usage);
581 key_ref = make_key_ref(key, 1); 569 key_ref = make_key_ref(key, 1);
582 break; 570 break;
583 571
584 case KEY_SPEC_SESSION_KEYRING: 572 case KEY_SPEC_SESSION_KEYRING:
585 if (!cred->tgcred->session_keyring) { 573 if (!cred->session_keyring) {
586 /* always install a session keyring upon access if one 574 /* always install a session keyring upon access if one
587 * doesn't exist yet */ 575 * doesn't exist yet */
588 ret = install_user_keyrings(); 576 ret = install_user_keyrings();
@@ -597,7 +585,7 @@ try_again:
597 if (ret < 0) 585 if (ret < 0)
598 goto error; 586 goto error;
599 goto reget_creds; 587 goto reget_creds;
600 } else if (cred->tgcred->session_keyring == 588 } else if (cred->session_keyring ==
601 cred->user->session_keyring && 589 cred->user->session_keyring &&
602 lflags & KEY_LOOKUP_CREATE) { 590 lflags & KEY_LOOKUP_CREATE) {
603 ret = join_session_keyring(NULL); 591 ret = join_session_keyring(NULL);
@@ -607,7 +595,7 @@ try_again:
607 } 595 }
608 596
609 rcu_read_lock(); 597 rcu_read_lock();
610 key = rcu_dereference(cred->tgcred->session_keyring); 598 key = rcu_dereference(cred->session_keyring);
611 atomic_inc(&key->usage); 599 atomic_inc(&key->usage);
612 rcu_read_unlock(); 600 rcu_read_unlock();
613 key_ref = make_key_ref(key, 1); 601 key_ref = make_key_ref(key, 1);
@@ -767,12 +755,6 @@ long join_session_keyring(const char *name)
767 struct key *keyring; 755 struct key *keyring;
768 long ret, serial; 756 long ret, serial;
769 757
770 /* only permit this if there's a single thread in the thread group -
771 * this avoids us having to adjust the creds on all threads and risking
772 * ENOMEM */
773 if (!current_is_single_threaded())
774 return -EMLINK;
775
776 new = prepare_creds(); 758 new = prepare_creds();
777 if (!new) 759 if (!new)
778 return -ENOMEM; 760 return -ENOMEM;
@@ -784,7 +766,7 @@ long join_session_keyring(const char *name)
784 if (ret < 0) 766 if (ret < 0)
785 goto error; 767 goto error;
786 768
787 serial = new->tgcred->session_keyring->serial; 769 serial = new->session_keyring->serial;
788 ret = commit_creds(new); 770 ret = commit_creds(new);
789 if (ret == 0) 771 if (ret == 0)
790 ret = serial; 772 ret = serial;
@@ -798,8 +780,10 @@ long join_session_keyring(const char *name)
798 keyring = find_keyring_by_name(name, false); 780 keyring = find_keyring_by_name(name, false);
799 if (PTR_ERR(keyring) == -ENOKEY) { 781 if (PTR_ERR(keyring) == -ENOKEY) {
800 /* not found - try and create a new one */ 782 /* not found - try and create a new one */
801 keyring = keyring_alloc(name, old->uid, old->gid, old, 783 keyring = keyring_alloc(
802 KEY_ALLOC_IN_QUOTA, NULL); 784 name, old->uid, old->gid, old,
785 KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ | KEY_USR_LINK,
786 KEY_ALLOC_IN_QUOTA, NULL);
803 if (IS_ERR(keyring)) { 787 if (IS_ERR(keyring)) {
804 ret = PTR_ERR(keyring); 788 ret = PTR_ERR(keyring);
805 goto error2; 789 goto error2;
@@ -807,6 +791,9 @@ long join_session_keyring(const char *name)
807 } else if (IS_ERR(keyring)) { 791 } else if (IS_ERR(keyring)) {
808 ret = PTR_ERR(keyring); 792 ret = PTR_ERR(keyring);
809 goto error2; 793 goto error2;
794 } else if (keyring == new->session_keyring) {
795 ret = 0;
796 goto error2;
810 } 797 }
811 798
812 /* we've got a keyring - now to install it */ 799 /* we've got a keyring - now to install it */
@@ -863,8 +850,7 @@ void key_change_session_keyring(struct callback_head *twork)
863 850
864 new->jit_keyring = old->jit_keyring; 851 new->jit_keyring = old->jit_keyring;
865 new->thread_keyring = key_get(old->thread_keyring); 852 new->thread_keyring = key_get(old->thread_keyring);
866 new->tgcred->tgid = old->tgcred->tgid; 853 new->process_keyring = key_get(old->process_keyring);
867 new->tgcred->process_keyring = key_get(old->tgcred->process_keyring);
868 854
869 security_transfer_creds(new, old); 855 security_transfer_creds(new, old);
870 856
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 66e21184b559..4bd6bdb74193 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -126,6 +126,7 @@ static int call_sbin_request_key(struct key_construction *cons,
126 126
127 cred = get_current_cred(); 127 cred = get_current_cred();
128 keyring = keyring_alloc(desc, cred->fsuid, cred->fsgid, cred, 128 keyring = keyring_alloc(desc, cred->fsuid, cred->fsgid, cred,
129 KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ,
129 KEY_ALLOC_QUOTA_OVERRUN, NULL); 130 KEY_ALLOC_QUOTA_OVERRUN, NULL);
130 put_cred(cred); 131 put_cred(cred);
131 if (IS_ERR(keyring)) { 132 if (IS_ERR(keyring)) {
@@ -150,12 +151,12 @@ static int call_sbin_request_key(struct key_construction *cons,
150 cred->thread_keyring ? cred->thread_keyring->serial : 0); 151 cred->thread_keyring ? cred->thread_keyring->serial : 0);
151 152
152 prkey = 0; 153 prkey = 0;
153 if (cred->tgcred->process_keyring) 154 if (cred->process_keyring)
154 prkey = cred->tgcred->process_keyring->serial; 155 prkey = cred->process_keyring->serial;
155 sprintf(keyring_str[1], "%d", prkey); 156 sprintf(keyring_str[1], "%d", prkey);
156 157
157 rcu_read_lock(); 158 rcu_read_lock();
158 session = rcu_dereference(cred->tgcred->session_keyring); 159 session = rcu_dereference(cred->session_keyring);
159 if (!session) 160 if (!session)
160 session = cred->user->session_keyring; 161 session = cred->user->session_keyring;
161 sskey = session->serial; 162 sskey = session->serial;
@@ -297,14 +298,14 @@ static void construct_get_dest_keyring(struct key **_dest_keyring)
297 break; 298 break;
298 299
299 case KEY_REQKEY_DEFL_PROCESS_KEYRING: 300 case KEY_REQKEY_DEFL_PROCESS_KEYRING:
300 dest_keyring = key_get(cred->tgcred->process_keyring); 301 dest_keyring = key_get(cred->process_keyring);
301 if (dest_keyring) 302 if (dest_keyring)
302 break; 303 break;
303 304
304 case KEY_REQKEY_DEFL_SESSION_KEYRING: 305 case KEY_REQKEY_DEFL_SESSION_KEYRING:
305 rcu_read_lock(); 306 rcu_read_lock();
306 dest_keyring = key_get( 307 dest_keyring = key_get(
307 rcu_dereference(cred->tgcred->session_keyring)); 308 rcu_dereference(cred->session_keyring));
308 rcu_read_unlock(); 309 rcu_read_unlock();
309 310
310 if (dest_keyring) 311 if (dest_keyring)
@@ -347,6 +348,7 @@ static int construct_alloc_key(struct key_type *type,
347 const struct cred *cred = current_cred(); 348 const struct cred *cred = current_cred();
348 unsigned long prealloc; 349 unsigned long prealloc;
349 struct key *key; 350 struct key *key;
351 key_perm_t perm;
350 key_ref_t key_ref; 352 key_ref_t key_ref;
351 int ret; 353 int ret;
352 354
@@ -355,8 +357,15 @@ static int construct_alloc_key(struct key_type *type,
355 *_key = NULL; 357 *_key = NULL;
356 mutex_lock(&user->cons_lock); 358 mutex_lock(&user->cons_lock);
357 359
360 perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR;
361 perm |= KEY_USR_VIEW;
362 if (type->read)
363 perm |= KEY_POS_READ;
364 if (type == &key_type_keyring || type->update)
365 perm |= KEY_POS_WRITE;
366
358 key = key_alloc(type, description, cred->fsuid, cred->fsgid, cred, 367 key = key_alloc(type, description, cred->fsuid, cred->fsgid, cred,
359 KEY_POS_ALL, flags); 368 perm, flags);
360 if (IS_ERR(key)) 369 if (IS_ERR(key))
361 goto alloc_failed; 370 goto alloc_failed;
362 371
diff --git a/security/smack/Kconfig b/security/smack/Kconfig
index 603b08784341..e69de9c642b7 100644
--- a/security/smack/Kconfig
+++ b/security/smack/Kconfig
@@ -1,6 +1,10 @@
1config SECURITY_SMACK 1config SECURITY_SMACK
2 bool "Simplified Mandatory Access Control Kernel Support" 2 bool "Simplified Mandatory Access Control Kernel Support"
3 depends on NETLABEL && SECURITY_NETWORK 3 depends on NET
4 depends on INET
5 depends on SECURITY
6 select NETLABEL
7 select SECURITY_NETWORK
4 default n 8 default n
5 help 9 help
6 This selects the Simplified Mandatory Access Control Kernel. 10 This selects the Simplified Mandatory Access Control Kernel.
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 99929a50093a..76a5dca46404 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -2063,6 +2063,19 @@ static const struct file_operations smk_revoke_subj_ops = {
2063 .llseek = generic_file_llseek, 2063 .llseek = generic_file_llseek,
2064}; 2064};
2065 2065
2066static struct kset *smackfs_kset;
2067/**
2068 * smk_init_sysfs - initialize /sys/fs/smackfs
2069 *
2070 */
2071static int smk_init_sysfs(void)
2072{
2073 smackfs_kset = kset_create_and_add("smackfs", NULL, fs_kobj);
2074 if (!smackfs_kset)
2075 return -ENOMEM;
2076 return 0;
2077}
2078
2066/** 2079/**
2067 * smk_fill_super - fill the /smackfs superblock 2080 * smk_fill_super - fill the /smackfs superblock
2068 * @sb: the empty superblock 2081 * @sb: the empty superblock
@@ -2183,6 +2196,10 @@ static int __init init_smk_fs(void)
2183 if (!security_module_enable(&smack_ops)) 2196 if (!security_module_enable(&smack_ops))
2184 return 0; 2197 return 0;
2185 2198
2199 err = smk_init_sysfs();
2200 if (err)
2201 printk(KERN_ERR "smackfs: sysfs mountpoint problem.\n");
2202
2186 err = register_filesystem(&smk_fs_type); 2203 err = register_filesystem(&smk_fs_type);
2187 if (!err) { 2204 if (!err) {
2188 smackfs_mount = kern_mount(&smk_fs_type); 2205 smackfs_mount = kern_mount(&smk_fs_type);
diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c
index b4c29848b49d..2663145d1197 100644
--- a/security/yama/yama_lsm.c
+++ b/security/yama/yama_lsm.c
@@ -17,6 +17,7 @@
17#include <linux/ptrace.h> 17#include <linux/ptrace.h>
18#include <linux/prctl.h> 18#include <linux/prctl.h>
19#include <linux/ratelimit.h> 19#include <linux/ratelimit.h>
20#include <linux/workqueue.h>
20 21
21#define YAMA_SCOPE_DISABLED 0 22#define YAMA_SCOPE_DISABLED 0
22#define YAMA_SCOPE_RELATIONAL 1 23#define YAMA_SCOPE_RELATIONAL 1
@@ -29,12 +30,37 @@ static int ptrace_scope = YAMA_SCOPE_RELATIONAL;
29struct ptrace_relation { 30struct ptrace_relation {
30 struct task_struct *tracer; 31 struct task_struct *tracer;
31 struct task_struct *tracee; 32 struct task_struct *tracee;
33 bool invalid;
32 struct list_head node; 34 struct list_head node;
35 struct rcu_head rcu;
33}; 36};
34 37
35static LIST_HEAD(ptracer_relations); 38static LIST_HEAD(ptracer_relations);
36static DEFINE_SPINLOCK(ptracer_relations_lock); 39static DEFINE_SPINLOCK(ptracer_relations_lock);
37 40
41static void yama_relation_cleanup(struct work_struct *work);
42static DECLARE_WORK(yama_relation_work, yama_relation_cleanup);
43
44/**
45 * yama_relation_cleanup - remove invalid entries from the relation list
46 *
47 */
48static void yama_relation_cleanup(struct work_struct *work)
49{
50 struct ptrace_relation *relation;
51
52 spin_lock(&ptracer_relations_lock);
53 rcu_read_lock();
54 list_for_each_entry_rcu(relation, &ptracer_relations, node) {
55 if (relation->invalid) {
56 list_del_rcu(&relation->node);
57 kfree_rcu(relation, rcu);
58 }
59 }
60 rcu_read_unlock();
61 spin_unlock(&ptracer_relations_lock);
62}
63
38/** 64/**
39 * yama_ptracer_add - add/replace an exception for this tracer/tracee pair 65 * yama_ptracer_add - add/replace an exception for this tracer/tracee pair
40 * @tracer: the task_struct of the process doing the ptrace 66 * @tracer: the task_struct of the process doing the ptrace
@@ -48,32 +74,34 @@ static DEFINE_SPINLOCK(ptracer_relations_lock);
48static int yama_ptracer_add(struct task_struct *tracer, 74static int yama_ptracer_add(struct task_struct *tracer,
49 struct task_struct *tracee) 75 struct task_struct *tracee)
50{ 76{
51 int rc = 0; 77 struct ptrace_relation *relation, *added;
52 struct ptrace_relation *added;
53 struct ptrace_relation *entry, *relation = NULL;
54 78
55 added = kmalloc(sizeof(*added), GFP_KERNEL); 79 added = kmalloc(sizeof(*added), GFP_KERNEL);
56 if (!added) 80 if (!added)
57 return -ENOMEM; 81 return -ENOMEM;
58 82
59 spin_lock_bh(&ptracer_relations_lock); 83 added->tracee = tracee;
60 list_for_each_entry(entry, &ptracer_relations, node) 84 added->tracer = tracer;
61 if (entry->tracee == tracee) { 85 added->invalid = false;
62 relation = entry; 86
63 break; 87 spin_lock(&ptracer_relations_lock);
88 rcu_read_lock();
89 list_for_each_entry_rcu(relation, &ptracer_relations, node) {
90 if (relation->invalid)
91 continue;
92 if (relation->tracee == tracee) {
93 list_replace_rcu(&relation->node, &added->node);
94 kfree_rcu(relation, rcu);
95 goto out;
64 } 96 }
65 if (!relation) {
66 relation = added;
67 relation->tracee = tracee;
68 list_add(&relation->node, &ptracer_relations);
69 } 97 }
70 relation->tracer = tracer;
71 98
72 spin_unlock_bh(&ptracer_relations_lock); 99 list_add_rcu(&added->node, &ptracer_relations);
73 if (added != relation)
74 kfree(added);
75 100
76 return rc; 101out:
102 rcu_read_unlock();
103 spin_unlock(&ptracer_relations_lock);
104 return 0;
77} 105}
78 106
79/** 107/**
@@ -84,16 +112,23 @@ static int yama_ptracer_add(struct task_struct *tracer,
84static void yama_ptracer_del(struct task_struct *tracer, 112static void yama_ptracer_del(struct task_struct *tracer,
85 struct task_struct *tracee) 113 struct task_struct *tracee)
86{ 114{
87 struct ptrace_relation *relation, *safe; 115 struct ptrace_relation *relation;
116 bool marked = false;
88 117
89 spin_lock_bh(&ptracer_relations_lock); 118 rcu_read_lock();
90 list_for_each_entry_safe(relation, safe, &ptracer_relations, node) 119 list_for_each_entry_rcu(relation, &ptracer_relations, node) {
120 if (relation->invalid)
121 continue;
91 if (relation->tracee == tracee || 122 if (relation->tracee == tracee ||
92 (tracer && relation->tracer == tracer)) { 123 (tracer && relation->tracer == tracer)) {
93 list_del(&relation->node); 124 relation->invalid = true;
94 kfree(relation); 125 marked = true;
95 } 126 }
96 spin_unlock_bh(&ptracer_relations_lock); 127 }
128 rcu_read_unlock();
129
130 if (marked)
131 schedule_work(&yama_relation_work);
97} 132}
98 133
99/** 134/**
@@ -217,21 +252,22 @@ static int ptracer_exception_found(struct task_struct *tracer,
217 struct task_struct *parent = NULL; 252 struct task_struct *parent = NULL;
218 bool found = false; 253 bool found = false;
219 254
220 spin_lock_bh(&ptracer_relations_lock);
221 rcu_read_lock(); 255 rcu_read_lock();
222 if (!thread_group_leader(tracee)) 256 if (!thread_group_leader(tracee))
223 tracee = rcu_dereference(tracee->group_leader); 257 tracee = rcu_dereference(tracee->group_leader);
224 list_for_each_entry(relation, &ptracer_relations, node) 258 list_for_each_entry_rcu(relation, &ptracer_relations, node) {
259 if (relation->invalid)
260 continue;
225 if (relation->tracee == tracee) { 261 if (relation->tracee == tracee) {
226 parent = relation->tracer; 262 parent = relation->tracer;
227 found = true; 263 found = true;
228 break; 264 break;
229 } 265 }
266 }
230 267
231 if (found && (parent == NULL || task_is_descendant(parent, tracer))) 268 if (found && (parent == NULL || task_is_descendant(parent, tracer)))
232 rc = 1; 269 rc = 1;
233 rcu_read_unlock(); 270 rcu_read_unlock();
234 spin_unlock_bh(&ptracer_relations_lock);
235 271
236 return rc; 272 return rc;
237} 273}