aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-01-14 21:36:33 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-01-14 21:36:33 -0500
commitc49c41a4134679cecb77362e7f6b59acb6320aa7 (patch)
tree45e690c036ca5846a48c8be67945d1d841b2d96d /kernel
parent892d208bcf79e4e1058707786a7b6d486697cd78 (diff)
parentf423e5ba76e7e4a6fcb4836b4f072d1fdebba8b5 (diff)
Merge branch 'for-linus' of git://selinuxproject.org/~jmorris/linux-security
* 'for-linus' of git://selinuxproject.org/~jmorris/linux-security: capabilities: remove __cap_full_set definition security: remove the security_netlink_recv hook as it is equivalent to capable() ptrace: do not audit capability check when outputing /proc/pid/stat capabilities: remove task_ns_* functions capabitlies: ns_capable can use the cap helpers rather than lsm call capabilities: style only - move capable below ns_capable capabilites: introduce new has_ns_capabilities_noaudit capabilities: call has_ns_capability from has_capability capabilities: remove all _real_ interfaces capabilities: introduce security_capable_noaudit capabilities: reverse arguments to security_capable capabilities: remove the task from capable LSM hook entirely selinux: sparse fix: fix several warnings in the security server cod selinux: sparse fix: fix warnings in netlink code selinux: sparse fix: eliminate warnings for selinuxfs selinux: sparse fix: declare selinux_disable() in security.h selinux: sparse fix: move selinux_complete_init selinux: sparse fix: make selinux_secmark_refcount static SELinux: Fix RCU deref check warning in sel_netport_insert() Manually fix up a semantic mis-merge wrt security_netlink_recv(): - the interface was removed in commit fd7784615248 ("security: remove the security_netlink_recv hook as it is equivalent to capable()") - a new user of it appeared in commit a38f7907b926 ("crypto: Add userspace configuration API") causing no automatic merge conflict, but Eric Paris pointed out the issue.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/audit.c4
-rw-r--r--kernel/capability.c80
-rw-r--r--kernel/ptrace.c14
-rw-r--r--kernel/sched/core.c2
4 files changed, 60 insertions, 40 deletions
diff --git a/kernel/audit.c b/kernel/audit.c
index 2c1d6ab7106e..57e3f5107937 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -601,13 +601,13 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)
601 case AUDIT_TTY_SET: 601 case AUDIT_TTY_SET:
602 case AUDIT_TRIM: 602 case AUDIT_TRIM:
603 case AUDIT_MAKE_EQUIV: 603 case AUDIT_MAKE_EQUIV:
604 if (security_netlink_recv(skb, CAP_AUDIT_CONTROL)) 604 if (!capable(CAP_AUDIT_CONTROL))
605 err = -EPERM; 605 err = -EPERM;
606 break; 606 break;
607 case AUDIT_USER: 607 case AUDIT_USER:
608 case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG: 608 case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG:
609 case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2: 609 case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2:
610 if (security_netlink_recv(skb, CAP_AUDIT_WRITE)) 610 if (!capable(CAP_AUDIT_WRITE))
611 err = -EPERM; 611 err = -EPERM;
612 break; 612 break;
613 default: /* bad msg */ 613 default: /* bad msg */
diff --git a/kernel/capability.c b/kernel/capability.c
index b463871a4e69..0fcf1c14a297 100644
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -287,74 +287,84 @@ error:
287} 287}
288 288
289/** 289/**
290 * has_capability - Does a task have a capability in init_user_ns 290 * has_ns_capability - Does a task have a capability in a specific user ns
291 * @t: The task in question 291 * @t: The task in question
292 * @ns: target user namespace
292 * @cap: The capability to be tested for 293 * @cap: The capability to be tested for
293 * 294 *
294 * Return true if the specified task has the given superior capability 295 * Return true if the specified task has the given superior capability
295 * currently in effect to the initial user namespace, false if not. 296 * currently in effect to the specified user namespace, false if not.
296 * 297 *
297 * Note that this does not set PF_SUPERPRIV on the task. 298 * Note that this does not set PF_SUPERPRIV on the task.
298 */ 299 */
299bool has_capability(struct task_struct *t, int cap) 300bool has_ns_capability(struct task_struct *t,
301 struct user_namespace *ns, int cap)
300{ 302{
301 int ret = security_real_capable(t, &init_user_ns, cap); 303 int ret;
304
305 rcu_read_lock();
306 ret = security_capable(__task_cred(t), ns, cap);
307 rcu_read_unlock();
302 308
303 return (ret == 0); 309 return (ret == 0);
304} 310}
305 311
306/** 312/**
307 * has_capability - Does a task have a capability in a specific user ns 313 * has_capability - Does a task have a capability in init_user_ns
308 * @t: The task in question 314 * @t: The task in question
309 * @ns: target user namespace
310 * @cap: The capability to be tested for 315 * @cap: The capability to be tested for
311 * 316 *
312 * Return true if the specified task has the given superior capability 317 * Return true if the specified task has the given superior capability
313 * currently in effect to the specified user namespace, false if not. 318 * currently in effect to the initial user namespace, false if not.
314 * 319 *
315 * Note that this does not set PF_SUPERPRIV on the task. 320 * Note that this does not set PF_SUPERPRIV on the task.
316 */ 321 */
317bool has_ns_capability(struct task_struct *t, 322bool has_capability(struct task_struct *t, int cap)
318 struct user_namespace *ns, int cap)
319{ 323{
320 int ret = security_real_capable(t, ns, cap); 324 return has_ns_capability(t, &init_user_ns, cap);
321
322 return (ret == 0);
323} 325}
324 326
325/** 327/**
326 * has_capability_noaudit - Does a task have a capability (unaudited) 328 * has_ns_capability_noaudit - Does a task have a capability (unaudited)
329 * in a specific user ns.
327 * @t: The task in question 330 * @t: The task in question
331 * @ns: target user namespace
328 * @cap: The capability to be tested for 332 * @cap: The capability to be tested for
329 * 333 *
330 * Return true if the specified task has the given superior capability 334 * Return true if the specified task has the given superior capability
331 * currently in effect to init_user_ns, false if not. Don't write an 335 * currently in effect to the specified user namespace, false if not.
332 * audit message for the check. 336 * Do not write an audit message for the check.
333 * 337 *
334 * Note that this does not set PF_SUPERPRIV on the task. 338 * Note that this does not set PF_SUPERPRIV on the task.
335 */ 339 */
336bool has_capability_noaudit(struct task_struct *t, int cap) 340bool has_ns_capability_noaudit(struct task_struct *t,
341 struct user_namespace *ns, int cap)
337{ 342{
338 int ret = security_real_capable_noaudit(t, &init_user_ns, cap); 343 int ret;
344
345 rcu_read_lock();
346 ret = security_capable_noaudit(__task_cred(t), ns, cap);
347 rcu_read_unlock();
339 348
340 return (ret == 0); 349 return (ret == 0);
341} 350}
342 351
343/** 352/**
344 * capable - Determine if the current task has a superior capability in effect 353 * has_capability_noaudit - Does a task have a capability (unaudited) in the
354 * initial user ns
355 * @t: The task in question
345 * @cap: The capability to be tested for 356 * @cap: The capability to be tested for
346 * 357 *
347 * Return true if the current task has the given superior capability currently 358 * Return true if the specified task has the given superior capability
348 * available for use, false if not. 359 * currently in effect to init_user_ns, false if not. Don't write an
360 * audit message for the check.
349 * 361 *
350 * This sets PF_SUPERPRIV on the task if the capability is available on the 362 * Note that this does not set PF_SUPERPRIV on the task.
351 * assumption that it's about to be used.
352 */ 363 */
353bool capable(int cap) 364bool has_capability_noaudit(struct task_struct *t, int cap)
354{ 365{
355 return ns_capable(&init_user_ns, cap); 366 return has_ns_capability_noaudit(t, &init_user_ns, cap);
356} 367}
357EXPORT_SYMBOL(capable);
358 368
359/** 369/**
360 * ns_capable - Determine if the current task has a superior capability in effect 370 * ns_capable - Determine if the current task has a superior capability in effect
@@ -374,7 +384,7 @@ bool ns_capable(struct user_namespace *ns, int cap)
374 BUG(); 384 BUG();
375 } 385 }
376 386
377 if (security_capable(ns, current_cred(), cap) == 0) { 387 if (has_ns_capability(current, ns, cap)) {
378 current->flags |= PF_SUPERPRIV; 388 current->flags |= PF_SUPERPRIV;
379 return true; 389 return true;
380 } 390 }
@@ -383,18 +393,20 @@ bool ns_capable(struct user_namespace *ns, int cap)
383EXPORT_SYMBOL(ns_capable); 393EXPORT_SYMBOL(ns_capable);
384 394
385/** 395/**
386 * task_ns_capable - Determine whether current task has a superior 396 * capable - Determine if the current task has a superior capability in effect
387 * capability targeted at a specific task's user namespace. 397 * @cap: The capability to be tested for
388 * @t: The task whose user namespace is targeted. 398 *
389 * @cap: The capability in question. 399 * Return true if the current task has the given superior capability currently
400 * available for use, false if not.
390 * 401 *
391 * Return true if it does, false otherwise. 402 * This sets PF_SUPERPRIV on the task if the capability is available on the
403 * assumption that it's about to be used.
392 */ 404 */
393bool task_ns_capable(struct task_struct *t, int cap) 405bool capable(int cap)
394{ 406{
395 return ns_capable(task_cred_xxx(t, user)->user_ns, cap); 407 return ns_capable(&init_user_ns, cap);
396} 408}
397EXPORT_SYMBOL(task_ns_capable); 409EXPORT_SYMBOL(capable);
398 410
399/** 411/**
400 * nsown_capable - Check superior capability to one's own user_ns 412 * nsown_capable - Check superior capability to one's own user_ns
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 78ab24a7b0e4..00ab2ca5ed11 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -172,6 +172,14 @@ int ptrace_check_attach(struct task_struct *child, bool ignore_state)
172 return ret; 172 return ret;
173} 173}
174 174
175static int ptrace_has_cap(struct user_namespace *ns, unsigned int mode)
176{
177 if (mode & PTRACE_MODE_NOAUDIT)
178 return has_ns_capability_noaudit(current, ns, CAP_SYS_PTRACE);
179 else
180 return has_ns_capability(current, ns, CAP_SYS_PTRACE);
181}
182
175int __ptrace_may_access(struct task_struct *task, unsigned int mode) 183int __ptrace_may_access(struct task_struct *task, unsigned int mode)
176{ 184{
177 const struct cred *cred = current_cred(), *tcred; 185 const struct cred *cred = current_cred(), *tcred;
@@ -198,7 +206,7 @@ int __ptrace_may_access(struct task_struct *task, unsigned int mode)
198 cred->gid == tcred->sgid && 206 cred->gid == tcred->sgid &&
199 cred->gid == tcred->gid)) 207 cred->gid == tcred->gid))
200 goto ok; 208 goto ok;
201 if (ns_capable(tcred->user->user_ns, CAP_SYS_PTRACE)) 209 if (ptrace_has_cap(tcred->user->user_ns, mode))
202 goto ok; 210 goto ok;
203 rcu_read_unlock(); 211 rcu_read_unlock();
204 return -EPERM; 212 return -EPERM;
@@ -207,7 +215,7 @@ ok:
207 smp_rmb(); 215 smp_rmb();
208 if (task->mm) 216 if (task->mm)
209 dumpable = get_dumpable(task->mm); 217 dumpable = get_dumpable(task->mm);
210 if (!dumpable && !task_ns_capable(task, CAP_SYS_PTRACE)) 218 if (!dumpable && !ptrace_has_cap(task_user_ns(task), mode))
211 return -EPERM; 219 return -EPERM;
212 220
213 return security_ptrace_access_check(task, mode); 221 return security_ptrace_access_check(task, mode);
@@ -277,7 +285,7 @@ static int ptrace_attach(struct task_struct *task, long request,
277 task->ptrace = PT_PTRACED; 285 task->ptrace = PT_PTRACED;
278 if (seize) 286 if (seize)
279 task->ptrace |= PT_SEIZED; 287 task->ptrace |= PT_SEIZED;
280 if (task_ns_capable(task, CAP_SYS_PTRACE)) 288 if (ns_capable(task_user_ns(task), CAP_SYS_PTRACE))
281 task->ptrace |= PT_PTRACE_CAP; 289 task->ptrace |= PT_PTRACE_CAP;
282 290
283 __ptrace_link(task, current); 291 __ptrace_link(task, current);
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index fd7b25e90079..df00cb09263e 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -4330,7 +4330,7 @@ long sched_setaffinity(pid_t pid, const struct cpumask *in_mask)
4330 goto out_free_cpus_allowed; 4330 goto out_free_cpus_allowed;
4331 } 4331 }
4332 retval = -EPERM; 4332 retval = -EPERM;
4333 if (!check_same_owner(p) && !task_ns_capable(p, CAP_SYS_NICE)) 4333 if (!check_same_owner(p) && !ns_capable(task_user_ns(p), CAP_SYS_NICE))
4334 goto out_unlock; 4334 goto out_unlock;
4335 4335
4336 retval = security_task_setscheduler(p); 4336 retval = security_task_setscheduler(p);