diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-14 21:36:33 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-14 21:36:33 -0500 |
commit | c49c41a4134679cecb77362e7f6b59acb6320aa7 (patch) | |
tree | 45e690c036ca5846a48c8be67945d1d841b2d96d /kernel/capability.c | |
parent | 892d208bcf79e4e1058707786a7b6d486697cd78 (diff) | |
parent | f423e5ba76e7e4a6fcb4836b4f072d1fdebba8b5 (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/capability.c')
-rw-r--r-- | kernel/capability.c | 80 |
1 files changed, 46 insertions, 34 deletions
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 | */ |
299 | bool has_capability(struct task_struct *t, int cap) | 300 | bool 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 | */ |
317 | bool has_ns_capability(struct task_struct *t, | 322 | bool 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 | */ |
336 | bool has_capability_noaudit(struct task_struct *t, int cap) | 340 | bool 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 | */ |
353 | bool capable(int cap) | 364 | bool 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 | } |
357 | EXPORT_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) | |||
383 | EXPORT_SYMBOL(ns_capable); | 393 | EXPORT_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 | */ |
393 | bool task_ns_capable(struct task_struct *t, int cap) | 405 | bool 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 | } |
397 | EXPORT_SYMBOL(task_ns_capable); | 409 | EXPORT_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 |