diff options
| author | Al Viro <viro@zeniv.linux.org.uk> | 2018-12-23 16:02:47 -0500 |
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2019-02-28 03:29:27 -0500 |
| commit | 0b52075ee62301dd150c9f2c3ddd0035ed894cde (patch) | |
| tree | bb5b54d2fee0e0e37f73635030dc0e25e93c9aa5 /security | |
| parent | cb50b348c71ffa90d7d1b2a494b553b5099bc090 (diff) | |
introduce cloning of fs_context
new primitive: vfs_dup_fs_context(). Comes with fs_context
method (->dup()) for copying the filesystem-specific parts
of fs_context, along with LSM one (->fs_context_dup()) for
doing the same to LSM parts.
[needs better commit message, and change of Author:, anyway]
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'security')
| -rw-r--r-- | security/security.c | 5 | ||||
| -rw-r--r-- | security/selinux/hooks.c | 39 | ||||
| -rw-r--r-- | security/smack/smack_lsm.c | 49 |
3 files changed, 93 insertions, 0 deletions
diff --git a/security/security.c b/security/security.c index e5519488327d..5759339319dc 100644 --- a/security/security.c +++ b/security/security.c | |||
| @@ -374,6 +374,11 @@ void security_bprm_committed_creds(struct linux_binprm *bprm) | |||
| 374 | call_void_hook(bprm_committed_creds, bprm); | 374 | call_void_hook(bprm_committed_creds, bprm); |
| 375 | } | 375 | } |
| 376 | 376 | ||
| 377 | int security_fs_context_dup(struct fs_context *fc, struct fs_context *src_fc) | ||
| 378 | { | ||
| 379 | return call_int_hook(fs_context_dup, 0, fc, src_fc); | ||
| 380 | } | ||
| 381 | |||
| 377 | int security_fs_context_parse_param(struct fs_context *fc, struct fs_parameter *param) | 382 | int security_fs_context_parse_param(struct fs_context *fc, struct fs_parameter *param) |
| 378 | { | 383 | { |
| 379 | return call_int_hook(fs_context_parse_param, -ENOPARAM, fc, param); | 384 | return call_int_hook(fs_context_parse_param, -ENOPARAM, fc, param); |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index f99381e97d73..4ba83de5fa80 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -2764,6 +2764,44 @@ static int selinux_umount(struct vfsmount *mnt, int flags) | |||
| 2764 | FILESYSTEM__UNMOUNT, NULL); | 2764 | FILESYSTEM__UNMOUNT, NULL); |
| 2765 | } | 2765 | } |
| 2766 | 2766 | ||
| 2767 | static int selinux_fs_context_dup(struct fs_context *fc, | ||
| 2768 | struct fs_context *src_fc) | ||
| 2769 | { | ||
| 2770 | const struct selinux_mnt_opts *src = src_fc->security; | ||
| 2771 | struct selinux_mnt_opts *opts; | ||
| 2772 | |||
| 2773 | if (!src) | ||
| 2774 | return 0; | ||
| 2775 | |||
| 2776 | fc->security = kzalloc(sizeof(struct selinux_mnt_opts), GFP_KERNEL); | ||
| 2777 | if (!fc->security) | ||
| 2778 | return -ENOMEM; | ||
| 2779 | |||
| 2780 | opts = fc->security; | ||
| 2781 | |||
| 2782 | if (src->fscontext) { | ||
| 2783 | opts->fscontext = kstrdup(src->fscontext, GFP_KERNEL); | ||
| 2784 | if (!opts->fscontext) | ||
| 2785 | return -ENOMEM; | ||
| 2786 | } | ||
| 2787 | if (src->context) { | ||
| 2788 | opts->context = kstrdup(src->context, GFP_KERNEL); | ||
| 2789 | if (!opts->context) | ||
| 2790 | return -ENOMEM; | ||
| 2791 | } | ||
| 2792 | if (src->rootcontext) { | ||
| 2793 | opts->rootcontext = kstrdup(src->rootcontext, GFP_KERNEL); | ||
| 2794 | if (!opts->rootcontext) | ||
| 2795 | return -ENOMEM; | ||
| 2796 | } | ||
| 2797 | if (src->defcontext) { | ||
| 2798 | opts->defcontext = kstrdup(src->defcontext, GFP_KERNEL); | ||
| 2799 | if (!opts->defcontext) | ||
| 2800 | return -ENOMEM; | ||
| 2801 | } | ||
| 2802 | return 0; | ||
| 2803 | } | ||
| 2804 | |||
| 2767 | static const struct fs_parameter_spec selinux_param_specs[] = { | 2805 | static const struct fs_parameter_spec selinux_param_specs[] = { |
| 2768 | fsparam_string(CONTEXT_STR, Opt_context), | 2806 | fsparam_string(CONTEXT_STR, Opt_context), |
| 2769 | fsparam_string(DEFCONTEXT_STR, Opt_defcontext), | 2807 | fsparam_string(DEFCONTEXT_STR, Opt_defcontext), |
| @@ -6745,6 +6783,7 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { | |||
| 6745 | LSM_HOOK_INIT(bprm_committing_creds, selinux_bprm_committing_creds), | 6783 | LSM_HOOK_INIT(bprm_committing_creds, selinux_bprm_committing_creds), |
| 6746 | LSM_HOOK_INIT(bprm_committed_creds, selinux_bprm_committed_creds), | 6784 | LSM_HOOK_INIT(bprm_committed_creds, selinux_bprm_committed_creds), |
| 6747 | 6785 | ||
| 6786 | LSM_HOOK_INIT(fs_context_dup, selinux_fs_context_dup), | ||
| 6748 | LSM_HOOK_INIT(fs_context_parse_param, selinux_fs_context_parse_param), | 6787 | LSM_HOOK_INIT(fs_context_parse_param, selinux_fs_context_parse_param), |
| 6749 | 6788 | ||
| 6750 | LSM_HOOK_INIT(sb_alloc_security, selinux_sb_alloc_security), | 6789 | LSM_HOOK_INIT(sb_alloc_security, selinux_sb_alloc_security), |
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 5f93c4f84384..03176f600a87 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
| @@ -647,6 +647,54 @@ out_opt_err: | |||
| 647 | return -EINVAL; | 647 | return -EINVAL; |
| 648 | } | 648 | } |
| 649 | 649 | ||
| 650 | /** | ||
| 651 | * smack_fs_context_dup - Duplicate the security data on fs_context duplication | ||
| 652 | * @fc: The new filesystem context. | ||
| 653 | * @src_fc: The source filesystem context being duplicated. | ||
| 654 | * | ||
| 655 | * Returns 0 on success or -ENOMEM on error. | ||
| 656 | */ | ||
| 657 | static int smack_fs_context_dup(struct fs_context *fc, | ||
| 658 | struct fs_context *src_fc) | ||
| 659 | { | ||
| 660 | struct smack_mnt_opts *dst, *src = src_fc->security; | ||
| 661 | |||
| 662 | if (!src) | ||
| 663 | return 0; | ||
| 664 | |||
| 665 | fc->security = kzalloc(sizeof(struct smack_mnt_opts), GFP_KERNEL); | ||
| 666 | if (!fc->security) | ||
| 667 | return -ENOMEM; | ||
| 668 | dst = fc->security; | ||
| 669 | |||
| 670 | if (src->fsdefault) { | ||
| 671 | dst->fsdefault = kstrdup(src->fsdefault, GFP_KERNEL); | ||
| 672 | if (!dst->fsdefault) | ||
| 673 | return -ENOMEM; | ||
| 674 | } | ||
| 675 | if (src->fsfloor) { | ||
| 676 | dst->fsfloor = kstrdup(src->fsfloor, GFP_KERNEL); | ||
| 677 | if (!dst->fsfloor) | ||
| 678 | return -ENOMEM; | ||
| 679 | } | ||
| 680 | if (src->fshat) { | ||
| 681 | dst->fshat = kstrdup(src->fshat, GFP_KERNEL); | ||
| 682 | if (!dst->fshat) | ||
| 683 | return -ENOMEM; | ||
| 684 | } | ||
| 685 | if (src->fsroot) { | ||
| 686 | dst->fsroot = kstrdup(src->fsroot, GFP_KERNEL); | ||
| 687 | if (!dst->fsroot) | ||
| 688 | return -ENOMEM; | ||
| 689 | } | ||
| 690 | if (src->fstransmute) { | ||
| 691 | dst->fstransmute = kstrdup(src->fstransmute, GFP_KERNEL); | ||
| 692 | if (!dst->fstransmute) | ||
| 693 | return -ENOMEM; | ||
| 694 | } | ||
| 695 | return 0; | ||
| 696 | } | ||
| 697 | |||
| 650 | static const struct fs_parameter_spec smack_param_specs[] = { | 698 | static const struct fs_parameter_spec smack_param_specs[] = { |
| 651 | fsparam_string("fsdefault", Opt_fsdefault), | 699 | fsparam_string("fsdefault", Opt_fsdefault), |
| 652 | fsparam_string("fsfloor", Opt_fsfloor), | 700 | fsparam_string("fsfloor", Opt_fsfloor), |
| @@ -4626,6 +4674,7 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = { | |||
| 4626 | LSM_HOOK_INIT(ptrace_traceme, smack_ptrace_traceme), | 4674 | LSM_HOOK_INIT(ptrace_traceme, smack_ptrace_traceme), |
| 4627 | LSM_HOOK_INIT(syslog, smack_syslog), | 4675 | LSM_HOOK_INIT(syslog, smack_syslog), |
| 4628 | 4676 | ||
| 4677 | LSM_HOOK_INIT(fs_context_dup, smack_fs_context_dup), | ||
| 4629 | LSM_HOOK_INIT(fs_context_parse_param, smack_fs_context_parse_param), | 4678 | LSM_HOOK_INIT(fs_context_parse_param, smack_fs_context_parse_param), |
| 4630 | 4679 | ||
| 4631 | LSM_HOOK_INIT(sb_alloc_security, smack_sb_alloc_security), | 4680 | LSM_HOOK_INIT(sb_alloc_security, smack_sb_alloc_security), |
