Ядро Linux в комментариях

       

Kernel/capability.c


22460 /* 22461 * linux/kernel/capability.c 22462 * 22463 * Copyright (C) 1997 Andrew Main <zefram@fysh.org> 22464 * Integrated into 2.1.97+, Andrew G. Morgan 22465 * <morgan@transmeta.com> 22466 */ 22467 22468 #include <linux/mm.h> 22469 #include <asm/uaccess.h> 22470 22471 /* Note: never hold tasklist_lock while spinning for this 22472 * one */ 22473 spinlock_t task_capability_lock; 22474 22475 /* For sys_getproccap() and sys_setproccap(), any of the 22476 * three capability set pointers may be NULL -- 22477 * indicating that that set is uninteresting and/or not 22478 * to be changed. */ 22479

22480 asmlinkage int sys_capget(cap_user_header_t header, 22481 cap_user_data_t dataptr) 22482 { 22483 int error, pid; 22484 __u32 version; 22485 struct task_struct *target; 22486 struct __user_cap_data_struct data; 22487 22488 if (get_user(version, &header->version)) 22489 return -EFAULT; 22490 22491 error = -EINVAL; 22492 if (version != _LINUX_CAPABILITY_VERSION) { 22493 version = _LINUX_CAPABILITY_VERSION; 22494 if (put_user(version, &header->version)) 22495 error = -EFAULT; 22496 return error; 22497 } 22498 22499 if (get_user(pid, &header->pid)) 22500 return -EFAULT; 22501 22502 if (pid < 0) 22503 return -EINVAL; 22504 22505 error = 0; 22506 22507 spin_lock(&task_capability_lock); 22508 22509 if (pid && pid != current->pid) { 22510 read_lock(&tasklist_lock); 22511 /* identify target of query */ 22512 target = find_task_by_pid(pid); 22513 if (!target) 22514 error = -ESRCH; 22515 } else { 22516 target = current; 22517 } 22518 22519 if (!error) { 22520 data.permitted = cap_t(target->cap_permitted); 22521 data.inheritable = cap_t(target->cap_inheritable); 22522 data.effective = cap_t(target->cap_effective); 22523 } 22524 22525 if (target != current) 22526 read_unlock(&tasklist_lock); 22527 spin_unlock(&task_capability_lock); 22528 22529 if (!error) { 22530 if (copy_to_user(dataptr, &data, sizeof data)) 22531 return -EFAULT; 22532 } 22533 22534 return error; 22535 } 22536 22537 /* set capabilities for all processes in a given process 22538 * group */ 22539 static void cap_set_pg(int pgrp, 22540 kernel_cap_t *effective, 22541 kernel_cap_t *inheritable, 22542 kernel_cap_t *permitted) 22543 { 22544 struct task_struct *target; 22545 22546 /* FIXME: do we need to have a write lock here..? */ 22547 read_lock(&tasklist_lock); 22548 for_each_task(target) { 22549 if (target->pgrp != pgrp) 22550 continue; 22551 target->cap_effective = *effective; 22552 target->cap_inheritable = *inheritable; 22553 target->cap_permitted = *permitted; 22554 } 22555 read_unlock(&tasklist_lock); 22556 } 22557 22558 /* set capabilities for all processes other than 1 and 22559 * self */ 22560 22561 static void cap_set_all(kernel_cap_t *effective, 22562 kernel_cap_t *inheritable, 22563 kernel_cap_t *permitted) 22564 { 22565 struct task_struct *target; 22566 22567 /* FIXME: do we need to have a write lock here..? */ 22568 read_lock(&tasklist_lock); 22569 /* ALL means everyone other than self or 'init' */ 22570 for_each_task(target) { 22571 if (target == current target->pid == 1) 22572 continue; 22573 target->cap_effective = *effective; 22574 target->cap_inheritable = *inheritable; 22575 target->cap_permitted = *permitted; 22576 } 22577 read_unlock(&tasklist_lock); 22578 } 22579 22580 /* The restrictions on setting capabilities are specified 22581 * as: 22582 * 22583 * [pid is for the 'target' task. 'current' is the 22584 * calling task.] 22585 * 22586 * I: any raised capabilities must be a subset of the 22587 * (old current) Permitted 22588 * P: any raised capabilities must be a subset of the 22589 * (old current) permitted 22590 * E: must be set to a subset of (new target) Permitted 22591 */


22592 asmlinkage int sys_capset( cap_user_header_t header, 22593 const cap_user_data_t data) 22594 { 22595 kernel_cap_t inheritable, permitted, effective; 22596 __u32 version; 22597 struct task_struct *target; 22598 int error, pid; 22599 22600 if (get_user(version, &header->version)) 22601 return -EFAULT; 22602 22603 if (version != _LINUX_CAPABILITY_VERSION) { 22604 version = _LINUX_CAPABILITY_VERSION; 22605 if (put_user(version, &header->version)) 22606 return -EFAULT; 22607 return -EINVAL; 22608 } 22609 22610 if (get_user(pid, &header->pid)) 22611 return -EFAULT; 22612 22613 if (pid && !capable(CAP_SETPCAP)) 22614 return -EPERM; 22615 22616 if (copy_from_user(&effective, &data->effective, 22617 sizeof(effective)) 22618 copy_from_user(&inheritable, &data->inheritable, 22619 sizeof(inheritable)) 22620 copy_from_user(&permitted, &data->permitted, 22621 sizeof(permitted))) 22622 return -EFAULT; 22623 22624 error = -EPERM; 22625 spin_lock(&task_capability_lock); 22626 22627 if (pid > 0 && pid != current->pid) { 22628 read_lock(&tasklist_lock); 22629 /* identify target of query */ 22630 target = find_task_by_pid(pid); 22631 if (!target) { 22632 error = -ESRCH; 22633 goto out; 22634 } 22635 } else { 22636 target = current; 22637 } 22638 22639 22640 /* verify restrictions on target's new Inheritable 22641 * set */ 22642 if (!cap_issubset(inheritable, 22643 cap_combine(target->cap_inheritable, 22644 current->cap_permitted))) { 22645 goto out; 22646 } 22647 22648 /* verify restrictions on target's new Permitted 22649 * set */ 22650 if (!cap_issubset(permitted, 22651 cap_combine(target->cap_permitted, 22652 current->cap_permitted))) { 22653 goto out; 22654 } 22655 22656 /* verify the _new_Effective_ is a subset of the 22657 * _new_Permitted_ */ 22658 if (!cap_issubset(effective, permitted)) { 22659 goto out; 22660 } 22661 22662 /* having verified that the proposed changes are 22663 * legal, we now put them into effect. */ 22664 error = 0; 22665 22666 if (pid < 0) { 22667 if (pid == -1) /* all procs but current & init */ 22668 cap_set_all(&effective,&inheritable,&permitted); 22669 22670 else /* all procs in process group */ 22671 cap_set_pg(-pid, &effective, &inheritable, 22672 &permitted); 22673 goto spin_out; 22674 } else { 22675 /* FIXME: do we need a write lock here..? */ 22676 target->cap_effective = effective; 22677 target->cap_inheritable = inheritable; 22678 target->cap_permitted = permitted; 22679 } 22680 22681 out: 22682 if (target != current) { 22683 read_unlock(&tasklist_lock); 22684 } 22685 spin_out: 22686 spin_unlock(&task_capability_lock); 22687 return error; 22688 }


Содержание раздела