diff options
Diffstat (limited to 'security')
59 files changed, 2342 insertions, 2822 deletions
diff --git a/security/Kconfig b/security/Kconfig index beb86b500adf..bf4ec46474b6 100644 --- a/security/Kconfig +++ b/security/Kconfig | |||
| @@ -21,6 +21,7 @@ config SECURITY_DMESG_RESTRICT | |||
| 21 | config SECURITY | 21 | config SECURITY |
| 22 | bool "Enable different security models" | 22 | bool "Enable different security models" |
| 23 | depends on SYSFS | 23 | depends on SYSFS |
| 24 | depends on MULTIUSER | ||
| 24 | help | 25 | help |
| 25 | This allows you to choose different security modules to be | 26 | This allows you to choose different security modules to be |
| 26 | configured into your kernel. | 27 | configured into your kernel. |
diff --git a/security/Makefile b/security/Makefile index 05f1c934d74b..c9bfbc84ff50 100644 --- a/security/Makefile +++ b/security/Makefile | |||
| @@ -14,7 +14,7 @@ obj-y += commoncap.o | |||
| 14 | obj-$(CONFIG_MMU) += min_addr.o | 14 | obj-$(CONFIG_MMU) += min_addr.o |
| 15 | 15 | ||
| 16 | # Object file lists | 16 | # Object file lists |
| 17 | obj-$(CONFIG_SECURITY) += security.o capability.o | 17 | obj-$(CONFIG_SECURITY) += security.o |
| 18 | obj-$(CONFIG_SECURITYFS) += inode.o | 18 | obj-$(CONFIG_SECURITYFS) += inode.o |
| 19 | obj-$(CONFIG_SECURITY_SELINUX) += selinux/ | 19 | obj-$(CONFIG_SECURITY_SELINUX) += selinux/ |
| 20 | obj-$(CONFIG_SECURITY_SMACK) += smack/ | 20 | obj-$(CONFIG_SECURITY_SMACK) += smack/ |
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c index 7db9954f1af2..ad4fa49ad1db 100644 --- a/security/apparmor/apparmorfs.c +++ b/security/apparmor/apparmorfs.c | |||
| @@ -365,7 +365,7 @@ void __aa_fs_profile_rmdir(struct aa_profile *profile) | |||
| 365 | if (!profile->dents[i]) | 365 | if (!profile->dents[i]) |
| 366 | continue; | 366 | continue; |
| 367 | 367 | ||
| 368 | r = profile->dents[i]->d_inode->i_private; | 368 | r = d_inode(profile->dents[i])->i_private; |
| 369 | securityfs_remove(profile->dents[i]); | 369 | securityfs_remove(profile->dents[i]); |
| 370 | aa_put_replacedby(r); | 370 | aa_put_replacedby(r); |
| 371 | profile->dents[i] = NULL; | 371 | profile->dents[i] = NULL; |
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c index d97cba3e3849..dc0027b28b04 100644 --- a/security/apparmor/domain.c +++ b/security/apparmor/domain.c | |||
| @@ -347,9 +347,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm) | |||
| 347 | file_inode(bprm->file)->i_mode | 347 | file_inode(bprm->file)->i_mode |
| 348 | }; | 348 | }; |
| 349 | const char *name = NULL, *target = NULL, *info = NULL; | 349 | const char *name = NULL, *target = NULL, *info = NULL; |
| 350 | int error = cap_bprm_set_creds(bprm); | 350 | int error = 0; |
| 351 | if (error) | ||
| 352 | return error; | ||
| 353 | 351 | ||
| 354 | if (bprm->cred_prepared) | 352 | if (bprm->cred_prepared) |
| 355 | return 0; | 353 | return 0; |
| @@ -531,15 +529,13 @@ cleanup: | |||
| 531 | */ | 529 | */ |
| 532 | int apparmor_bprm_secureexec(struct linux_binprm *bprm) | 530 | int apparmor_bprm_secureexec(struct linux_binprm *bprm) |
| 533 | { | 531 | { |
| 534 | int ret = cap_bprm_secureexec(bprm); | ||
| 535 | |||
| 536 | /* the decision to use secure exec is computed in set_creds | 532 | /* the decision to use secure exec is computed in set_creds |
| 537 | * and stored in bprm->unsafe. | 533 | * and stored in bprm->unsafe. |
| 538 | */ | 534 | */ |
| 539 | if (!ret && (bprm->unsafe & AA_SECURE_X_NEEDED)) | 535 | if (bprm->unsafe & AA_SECURE_X_NEEDED) |
| 540 | ret = 1; | 536 | return 1; |
| 541 | 537 | ||
| 542 | return ret; | 538 | return 0; |
| 543 | } | 539 | } |
| 544 | 540 | ||
| 545 | /** | 541 | /** |
diff --git a/security/apparmor/file.c b/security/apparmor/file.c index fdaa50cb1876..913f377a038a 100644 --- a/security/apparmor/file.c +++ b/security/apparmor/file.c | |||
| @@ -259,7 +259,7 @@ unsigned int aa_str_perms(struct aa_dfa *dfa, unsigned int start, | |||
| 259 | */ | 259 | */ |
| 260 | static inline bool is_deleted(struct dentry *dentry) | 260 | static inline bool is_deleted(struct dentry *dentry) |
| 261 | { | 261 | { |
| 262 | if (d_unlinked(dentry) && dentry->d_inode->i_nlink == 0) | 262 | if (d_unlinked(dentry) && d_backing_inode(dentry)->i_nlink == 0) |
| 263 | return 1; | 263 | return 1; |
| 264 | return 0; | 264 | return 0; |
| 265 | } | 265 | } |
| @@ -351,8 +351,8 @@ int aa_path_link(struct aa_profile *profile, struct dentry *old_dentry, | |||
| 351 | struct path link = { new_dir->mnt, new_dentry }; | 351 | struct path link = { new_dir->mnt, new_dentry }; |
| 352 | struct path target = { new_dir->mnt, old_dentry }; | 352 | struct path target = { new_dir->mnt, old_dentry }; |
| 353 | struct path_cond cond = { | 353 | struct path_cond cond = { |
| 354 | old_dentry->d_inode->i_uid, | 354 | d_backing_inode(old_dentry)->i_uid, |
| 355 | old_dentry->d_inode->i_mode | 355 | d_backing_inode(old_dentry)->i_mode |
| 356 | }; | 356 | }; |
| 357 | char *buffer = NULL, *buffer2 = NULL; | 357 | char *buffer = NULL, *buffer2 = NULL; |
| 358 | const char *lname, *tname = NULL, *info = NULL; | 358 | const char *lname, *tname = NULL, *info = NULL; |
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 107db88b1d5f..dec607c17b64 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | * License. | 12 | * License. |
| 13 | */ | 13 | */ |
| 14 | 14 | ||
| 15 | #include <linux/security.h> | 15 | #include <linux/lsm_hooks.h> |
| 16 | #include <linux/moduleparam.h> | 16 | #include <linux/moduleparam.h> |
| 17 | #include <linux/mm.h> | 17 | #include <linux/mm.h> |
| 18 | #include <linux/mman.h> | 18 | #include <linux/mman.h> |
| @@ -96,19 +96,11 @@ static void apparmor_cred_transfer(struct cred *new, const struct cred *old) | |||
| 96 | static int apparmor_ptrace_access_check(struct task_struct *child, | 96 | static int apparmor_ptrace_access_check(struct task_struct *child, |
| 97 | unsigned int mode) | 97 | unsigned int mode) |
| 98 | { | 98 | { |
| 99 | int error = cap_ptrace_access_check(child, mode); | ||
| 100 | if (error) | ||
| 101 | return error; | ||
| 102 | |||
| 103 | return aa_ptrace(current, child, mode); | 99 | return aa_ptrace(current, child, mode); |
| 104 | } | 100 | } |
| 105 | 101 | ||
| 106 | static int apparmor_ptrace_traceme(struct task_struct *parent) | 102 | static int apparmor_ptrace_traceme(struct task_struct *parent) |
| 107 | { | 103 | { |
| 108 | int error = cap_ptrace_traceme(parent); | ||
| 109 | if (error) | ||
| 110 | return error; | ||
| 111 | |||
| 112 | return aa_ptrace(parent, current, PTRACE_MODE_ATTACH); | 104 | return aa_ptrace(parent, current, PTRACE_MODE_ATTACH); |
| 113 | } | 105 | } |
| 114 | 106 | ||
| @@ -123,10 +115,10 @@ static int apparmor_capget(struct task_struct *target, kernel_cap_t *effective, | |||
| 123 | cred = __task_cred(target); | 115 | cred = __task_cred(target); |
| 124 | profile = aa_cred_profile(cred); | 116 | profile = aa_cred_profile(cred); |
| 125 | 117 | ||
| 126 | *effective = cred->cap_effective; | 118 | /* |
| 127 | *inheritable = cred->cap_inheritable; | 119 | * cap_capget is stacked ahead of this and will |
| 128 | *permitted = cred->cap_permitted; | 120 | * initialize effective and permitted. |
| 129 | 121 | */ | |
| 130 | if (!unconfined(profile) && !COMPLAIN_MODE(profile)) { | 122 | if (!unconfined(profile) && !COMPLAIN_MODE(profile)) { |
| 131 | *effective = cap_intersect(*effective, profile->caps.allow); | 123 | *effective = cap_intersect(*effective, profile->caps.allow); |
| 132 | *permitted = cap_intersect(*permitted, profile->caps.allow); | 124 | *permitted = cap_intersect(*permitted, profile->caps.allow); |
| @@ -140,13 +132,11 @@ static int apparmor_capable(const struct cred *cred, struct user_namespace *ns, | |||
| 140 | int cap, int audit) | 132 | int cap, int audit) |
| 141 | { | 133 | { |
| 142 | struct aa_profile *profile; | 134 | struct aa_profile *profile; |
| 143 | /* cap_capable returns 0 on success, else -EPERM */ | 135 | int error = 0; |
| 144 | int error = cap_capable(cred, ns, cap, audit); | 136 | |
| 145 | if (!error) { | 137 | profile = aa_cred_profile(cred); |
| 146 | profile = aa_cred_profile(cred); | 138 | if (!unconfined(profile)) |
| 147 | if (!unconfined(profile)) | 139 | error = aa_capable(profile, cap, audit); |
| 148 | error = aa_capable(profile, cap, audit); | ||
| 149 | } | ||
| 150 | return error; | 140 | return error; |
| 151 | } | 141 | } |
| 152 | 142 | ||
| @@ -204,8 +194,8 @@ static int common_perm_mnt_dentry(int op, struct vfsmount *mnt, | |||
| 204 | struct dentry *dentry, u32 mask) | 194 | struct dentry *dentry, u32 mask) |
| 205 | { | 195 | { |
| 206 | struct path path = { mnt, dentry }; | 196 | struct path path = { mnt, dentry }; |
| 207 | struct path_cond cond = { dentry->d_inode->i_uid, | 197 | struct path_cond cond = { d_backing_inode(dentry)->i_uid, |
| 208 | dentry->d_inode->i_mode | 198 | d_backing_inode(dentry)->i_mode |
| 209 | }; | 199 | }; |
| 210 | 200 | ||
| 211 | return common_perm(op, &path, mask, &cond); | 201 | return common_perm(op, &path, mask, &cond); |
| @@ -223,7 +213,7 @@ static int common_perm_mnt_dentry(int op, struct vfsmount *mnt, | |||
| 223 | static int common_perm_rm(int op, struct path *dir, | 213 | static int common_perm_rm(int op, struct path *dir, |
| 224 | struct dentry *dentry, u32 mask) | 214 | struct dentry *dentry, u32 mask) |
| 225 | { | 215 | { |
| 226 | struct inode *inode = dentry->d_inode; | 216 | struct inode *inode = d_backing_inode(dentry); |
| 227 | struct path_cond cond = { }; | 217 | struct path_cond cond = { }; |
| 228 | 218 | ||
| 229 | if (!inode || !dir->mnt || !mediated_filesystem(dentry)) | 219 | if (!inode || !dir->mnt || !mediated_filesystem(dentry)) |
| @@ -281,8 +271,8 @@ static int apparmor_path_mknod(struct path *dir, struct dentry *dentry, | |||
| 281 | 271 | ||
| 282 | static int apparmor_path_truncate(struct path *path) | 272 | static int apparmor_path_truncate(struct path *path) |
| 283 | { | 273 | { |
| 284 | struct path_cond cond = { path->dentry->d_inode->i_uid, | 274 | struct path_cond cond = { d_backing_inode(path->dentry)->i_uid, |
| 285 | path->dentry->d_inode->i_mode | 275 | d_backing_inode(path->dentry)->i_mode |
| 286 | }; | 276 | }; |
| 287 | 277 | ||
| 288 | if (!path->mnt || !mediated_filesystem(path->dentry)) | 278 | if (!path->mnt || !mediated_filesystem(path->dentry)) |
| @@ -327,8 +317,8 @@ static int apparmor_path_rename(struct path *old_dir, struct dentry *old_dentry, | |||
| 327 | if (!unconfined(profile)) { | 317 | if (!unconfined(profile)) { |
| 328 | struct path old_path = { old_dir->mnt, old_dentry }; | 318 | struct path old_path = { old_dir->mnt, old_dentry }; |
| 329 | struct path new_path = { new_dir->mnt, new_dentry }; | 319 | struct path new_path = { new_dir->mnt, new_dentry }; |
| 330 | struct path_cond cond = { old_dentry->d_inode->i_uid, | 320 | struct path_cond cond = { d_backing_inode(old_dentry)->i_uid, |
| 331 | old_dentry->d_inode->i_mode | 321 | d_backing_inode(old_dentry)->i_mode |
| 332 | }; | 322 | }; |
| 333 | 323 | ||
| 334 | error = aa_path_perm(OP_RENAME_SRC, profile, &old_path, 0, | 324 | error = aa_path_perm(OP_RENAME_SRC, profile, &old_path, 0, |
| @@ -354,8 +344,8 @@ static int apparmor_path_chmod(struct path *path, umode_t mode) | |||
| 354 | 344 | ||
| 355 | static int apparmor_path_chown(struct path *path, kuid_t uid, kgid_t gid) | 345 | static int apparmor_path_chown(struct path *path, kuid_t uid, kgid_t gid) |
| 356 | { | 346 | { |
| 357 | struct path_cond cond = { path->dentry->d_inode->i_uid, | 347 | struct path_cond cond = { d_backing_inode(path->dentry)->i_uid, |
| 358 | path->dentry->d_inode->i_mode | 348 | d_backing_inode(path->dentry)->i_mode |
| 359 | }; | 349 | }; |
| 360 | 350 | ||
| 361 | if (!mediated_filesystem(path->dentry)) | 351 | if (!mediated_filesystem(path->dentry)) |
| @@ -364,12 +354,12 @@ static int apparmor_path_chown(struct path *path, kuid_t uid, kgid_t gid) | |||
| 364 | return common_perm(OP_CHOWN, path, AA_MAY_CHOWN, &cond); | 354 | return common_perm(OP_CHOWN, path, AA_MAY_CHOWN, &cond); |
| 365 | } | 355 | } |
| 366 | 356 | ||
| 367 | static int apparmor_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) | 357 | static int apparmor_inode_getattr(const struct path *path) |
| 368 | { | 358 | { |
| 369 | if (!mediated_filesystem(dentry)) | 359 | if (!mediated_filesystem(path->dentry)) |
| 370 | return 0; | 360 | return 0; |
| 371 | 361 | ||
| 372 | return common_perm_mnt_dentry(OP_GETATTR, mnt, dentry, | 362 | return common_perm_mnt_dentry(OP_GETATTR, path->mnt, path->dentry, |
| 373 | AA_MAY_META_READ); | 363 | AA_MAY_META_READ); |
| 374 | } | 364 | } |
| 375 | 365 | ||
| @@ -615,49 +605,46 @@ static int apparmor_task_setrlimit(struct task_struct *task, | |||
| 615 | return error; | 605 | return error; |
| 616 | } | 606 | } |
| 617 | 607 | ||
| 618 | static struct security_operations apparmor_ops = { | 608 | static struct security_hook_list apparmor_hooks[] = { |
| 619 | .name = "apparmor", | 609 | LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check), |
| 620 | 610 | LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme), | |
| 621 | .ptrace_access_check = apparmor_ptrace_access_check, | 611 | LSM_HOOK_INIT(capget, apparmor_capget), |
| 622 | .ptrace_traceme = apparmor_ptrace_traceme, | 612 | LSM_HOOK_INIT(capable, apparmor_capable), |
| 623 | .capget = apparmor_capget, | 613 | |
| 624 | .capable = apparmor_capable, | 614 | LSM_HOOK_INIT(path_link, apparmor_path_link), |
| 625 | 615 | LSM_HOOK_INIT(path_unlink, apparmor_path_unlink), | |
| 626 | .path_link = apparmor_path_link, | 616 | LSM_HOOK_INIT(path_symlink, apparmor_path_symlink), |
| 627 | .path_unlink = apparmor_path_unlink, | 617 | LSM_HOOK_INIT(path_mkdir, apparmor_path_mkdir), |
| 628 | .path_symlink = apparmor_path_symlink, | 618 | LSM_HOOK_INIT(path_rmdir, apparmor_path_rmdir), |
| 629 | .path_mkdir = apparmor_path_mkdir, | 619 | LSM_HOOK_INIT(path_mknod, apparmor_path_mknod), |
| 630 | .path_rmdir = apparmor_path_rmdir, | 620 | LSM_HOOK_INIT(path_rename, apparmor_path_rename), |
| 631 | .path_mknod = apparmor_path_mknod, | 621 | LSM_HOOK_INIT(path_chmod, apparmor_path_chmod), |
| 632 | .path_rename = apparmor_path_rename, | 622 | LSM_HOOK_INIT(path_chown, apparmor_path_chown), |
| 633 | .path_chmod = apparmor_path_chmod, | 623 | LSM_HOOK_INIT(path_truncate, apparmor_path_truncate), |
| 634 | .path_chown = apparmor_path_chown, | 624 | LSM_HOOK_INIT(inode_getattr, apparmor_inode_getattr), |
| 635 | .path_truncate = apparmor_path_truncate, | 625 | |
| 636 | .inode_getattr = apparmor_inode_getattr, | 626 | LSM_HOOK_INIT(file_open, apparmor_file_open), |
| 637 | 627 | LSM_HOOK_INIT(file_permission, apparmor_file_permission), | |
| 638 | .file_open = apparmor_file_open, | 628 | LSM_HOOK_INIT(file_alloc_security, apparmor_file_alloc_security), |
| 639 | .file_permission = apparmor_file_permission, | 629 | LSM_HOOK_INIT(file_free_security, apparmor_file_free_security), |
| 640 | .file_alloc_security = apparmor_file_alloc_security, | 630 | LSM_HOOK_INIT(mmap_file, apparmor_mmap_file), |
| 641 | .file_free_security = apparmor_file_free_security, | 631 | LSM_HOOK_INIT(file_mprotect, apparmor_file_mprotect), |
| 642 | .mmap_file = apparmor_mmap_file, | 632 | LSM_HOOK_INIT(file_lock, apparmor_file_lock), |
| 643 | .mmap_addr = cap_mmap_addr, | 633 | |
| 644 | .file_mprotect = apparmor_file_mprotect, | 634 | LSM_HOOK_INIT(getprocattr, apparmor_getprocattr), |
| 645 | .file_lock = apparmor_file_lock, | 635 | LSM_HOOK_INIT(setprocattr, apparmor_setprocattr), |
| 646 | 636 | ||
| 647 | .getprocattr = apparmor_getprocattr, | 637 | LSM_HOOK_INIT(cred_alloc_blank, apparmor_cred_alloc_blank), |
| 648 | .setprocattr = apparmor_setprocattr, | 638 | LSM_HOOK_INIT(cred_free, apparmor_cred_free), |
| 649 | 639 | LSM_HOOK_INIT(cred_prepare, apparmor_cred_prepare), | |
| 650 | .cred_alloc_blank = apparmor_cred_alloc_blank, | 640 | LSM_HOOK_INIT(cred_transfer, apparmor_cred_transfer), |
| 651 | .cred_free = apparmor_cred_free, | 641 | |
| 652 | .cred_prepare = apparmor_cred_prepare, | 642 | LSM_HOOK_INIT(bprm_set_creds, apparmor_bprm_set_creds), |
| 653 | .cred_transfer = apparmor_cred_transfer, | 643 | LSM_HOOK_INIT(bprm_committing_creds, apparmor_bprm_committing_creds), |
| 654 | 644 | LSM_HOOK_INIT(bprm_committed_creds, apparmor_bprm_committed_creds), | |
| 655 | .bprm_set_creds = apparmor_bprm_set_creds, | 645 | LSM_HOOK_INIT(bprm_secureexec, apparmor_bprm_secureexec), |
| 656 | .bprm_committing_creds = apparmor_bprm_committing_creds, | 646 | |
| 657 | .bprm_committed_creds = apparmor_bprm_committed_creds, | 647 | LSM_HOOK_INIT(task_setrlimit, apparmor_task_setrlimit), |
| 658 | .bprm_secureexec = apparmor_bprm_secureexec, | ||
| 659 | |||
| 660 | .task_setrlimit = apparmor_task_setrlimit, | ||
| 661 | }; | 648 | }; |
| 662 | 649 | ||
| 663 | /* | 650 | /* |
| @@ -667,7 +654,7 @@ static struct security_operations apparmor_ops = { | |||
| 667 | static int param_set_aabool(const char *val, const struct kernel_param *kp); | 654 | static int param_set_aabool(const char *val, const struct kernel_param *kp); |
| 668 | static int param_get_aabool(char *buffer, const struct kernel_param *kp); | 655 | static int param_get_aabool(char *buffer, const struct kernel_param *kp); |
| 669 | #define param_check_aabool param_check_bool | 656 | #define param_check_aabool param_check_bool |
| 670 | static struct kernel_param_ops param_ops_aabool = { | 657 | static const struct kernel_param_ops param_ops_aabool = { |
| 671 | .flags = KERNEL_PARAM_OPS_FL_NOARG, | 658 | .flags = KERNEL_PARAM_OPS_FL_NOARG, |
| 672 | .set = param_set_aabool, | 659 | .set = param_set_aabool, |
| 673 | .get = param_get_aabool | 660 | .get = param_get_aabool |
| @@ -676,7 +663,7 @@ static struct kernel_param_ops param_ops_aabool = { | |||
| 676 | static int param_set_aauint(const char *val, const struct kernel_param *kp); | 663 | static int param_set_aauint(const char *val, const struct kernel_param *kp); |
| 677 | static int param_get_aauint(char *buffer, const struct kernel_param *kp); | 664 | static int param_get_aauint(char *buffer, const struct kernel_param *kp); |
| 678 | #define param_check_aauint param_check_uint | 665 | #define param_check_aauint param_check_uint |
| 679 | static struct kernel_param_ops param_ops_aauint = { | 666 | static const struct kernel_param_ops param_ops_aauint = { |
| 680 | .set = param_set_aauint, | 667 | .set = param_set_aauint, |
| 681 | .get = param_get_aauint | 668 | .get = param_get_aauint |
| 682 | }; | 669 | }; |
| @@ -684,7 +671,7 @@ static struct kernel_param_ops param_ops_aauint = { | |||
| 684 | static int param_set_aalockpolicy(const char *val, const struct kernel_param *kp); | 671 | static int param_set_aalockpolicy(const char *val, const struct kernel_param *kp); |
| 685 | static int param_get_aalockpolicy(char *buffer, const struct kernel_param *kp); | 672 | static int param_get_aalockpolicy(char *buffer, const struct kernel_param *kp); |
| 686 | #define param_check_aalockpolicy param_check_bool | 673 | #define param_check_aalockpolicy param_check_bool |
| 687 | static struct kernel_param_ops param_ops_aalockpolicy = { | 674 | static const struct kernel_param_ops param_ops_aalockpolicy = { |
| 688 | .flags = KERNEL_PARAM_OPS_FL_NOARG, | 675 | .flags = KERNEL_PARAM_OPS_FL_NOARG, |
| 689 | .set = param_set_aalockpolicy, | 676 | .set = param_set_aalockpolicy, |
| 690 | .get = param_get_aalockpolicy | 677 | .get = param_get_aalockpolicy |
| @@ -898,7 +885,7 @@ static int __init apparmor_init(void) | |||
| 898 | { | 885 | { |
| 899 | int error; | 886 | int error; |
| 900 | 887 | ||
| 901 | if (!apparmor_enabled || !security_module_enable(&apparmor_ops)) { | 888 | if (!apparmor_enabled || !security_module_enable("apparmor")) { |
| 902 | aa_info_message("AppArmor disabled by boot time parameter"); | 889 | aa_info_message("AppArmor disabled by boot time parameter"); |
| 903 | apparmor_enabled = 0; | 890 | apparmor_enabled = 0; |
| 904 | return 0; | 891 | return 0; |
| @@ -913,17 +900,10 @@ static int __init apparmor_init(void) | |||
| 913 | error = set_init_cxt(); | 900 | error = set_init_cxt(); |
| 914 | if (error) { | 901 | if (error) { |
| 915 | AA_ERROR("Failed to set context on init task\n"); | 902 | AA_ERROR("Failed to set context on init task\n"); |
| 916 | goto register_security_out; | 903 | aa_free_root_ns(); |
| 917 | } | 904 | goto alloc_out; |
| 918 | |||
| 919 | error = register_security(&apparmor_ops); | ||
| 920 | if (error) { | ||
| 921 | struct cred *cred = (struct cred *)current->real_cred; | ||
| 922 | aa_free_task_context(cred_cxt(cred)); | ||
| 923 | cred_cxt(cred) = NULL; | ||
| 924 | AA_ERROR("Unable to register AppArmor\n"); | ||
| 925 | goto register_security_out; | ||
| 926 | } | 905 | } |
| 906 | security_add_hooks(apparmor_hooks, ARRAY_SIZE(apparmor_hooks)); | ||
| 927 | 907 | ||
| 928 | /* Report that AppArmor successfully initialized */ | 908 | /* Report that AppArmor successfully initialized */ |
| 929 | apparmor_initialized = 1; | 909 | apparmor_initialized = 1; |
| @@ -936,9 +916,6 @@ static int __init apparmor_init(void) | |||
| 936 | 916 | ||
| 937 | return error; | 917 | return error; |
| 938 | 918 | ||
| 939 | register_security_out: | ||
| 940 | aa_free_root_ns(); | ||
| 941 | |||
| 942 | alloc_out: | 919 | alloc_out: |
| 943 | aa_destroy_aafs(); | 920 | aa_destroy_aafs(); |
| 944 | 921 | ||
diff --git a/security/capability.c b/security/capability.c deleted file mode 100644 index 070dd46f62f4..000000000000 --- a/security/capability.c +++ /dev/null | |||
| @@ -1,1164 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Capabilities Linux Security Module | ||
| 3 | * | ||
| 4 | * This is the default security module in case no other module is loaded. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/security.h> | ||
| 14 | |||
| 15 | static int cap_binder_set_context_mgr(struct task_struct *mgr) | ||
| 16 | { | ||
| 17 | return 0; | ||
| 18 | } | ||
| 19 | |||
| 20 | static int cap_binder_transaction(struct task_struct *from, | ||
| 21 | struct task_struct *to) | ||
| 22 | { | ||
| 23 | return 0; | ||
| 24 | } | ||
| 25 | |||
| 26 | static int cap_binder_transfer_binder(struct task_struct *from, | ||
| 27 | struct task_struct *to) | ||
| 28 | { | ||
| 29 | return 0; | ||
| 30 | } | ||
| 31 | |||
| 32 | static int cap_binder_transfer_file(struct task_struct *from, | ||
| 33 | struct task_struct *to, struct file *file) | ||
| 34 | { | ||
| 35 | return 0; | ||
| 36 | } | ||
| 37 | |||
| 38 | static int cap_syslog(int type) | ||
| 39 | { | ||
| 40 | return 0; | ||
| 41 | } | ||
| 42 | |||
| 43 | static int cap_quotactl(int cmds, int type, int id, struct super_block *sb) | ||
| 44 | { | ||
| 45 | return 0; | ||
| 46 | } | ||
| 47 | |||
| 48 | static int cap_quota_on(struct dentry *dentry) | ||
| 49 | { | ||
| 50 | return 0; | ||
| 51 | } | ||
| 52 | |||
| 53 | static int cap_bprm_check_security(struct linux_binprm *bprm) | ||
| 54 | { | ||
| 55 | return 0; | ||
| 56 | } | ||
| 57 | |||
| 58 | static void cap_bprm_committing_creds(struct linux_binprm *bprm) | ||
| 59 | { | ||
| 60 | } | ||
| 61 | |||
| 62 | static void cap_bprm_committed_creds(struct linux_binprm *bprm) | ||
| 63 | { | ||
| 64 | } | ||
| 65 | |||
| 66 | static int cap_sb_alloc_security(struct super_block *sb) | ||
| 67 | { | ||
| 68 | return 0; | ||
| 69 | } | ||
| 70 | |||
| 71 | static void cap_sb_free_security(struct super_block *sb) | ||
| 72 | { | ||
| 73 | } | ||
| 74 | |||
| 75 | static int cap_sb_copy_data(char *orig, char *copy) | ||
| 76 | { | ||
| 77 | return 0; | ||
| 78 | } | ||
| 79 | |||
| 80 | static int cap_sb_remount(struct super_block *sb, void *data) | ||
| 81 | { | ||
| 82 | return 0; | ||
| 83 | } | ||
| 84 | |||
| 85 | static int cap_sb_kern_mount(struct super_block *sb, int flags, void *data) | ||
| 86 | { | ||
| 87 | return 0; | ||
| 88 | } | ||
| 89 | |||
| 90 | static int cap_sb_show_options(struct seq_file *m, struct super_block *sb) | ||
| 91 | { | ||
| 92 | return 0; | ||
| 93 | } | ||
| 94 | |||
| 95 | static int cap_sb_statfs(struct dentry *dentry) | ||
| 96 | { | ||
| 97 | return 0; | ||
| 98 | } | ||
| 99 | |||
| 100 | static int cap_sb_mount(const char *dev_name, struct path *path, | ||
| 101 | const char *type, unsigned long flags, void *data) | ||
| 102 | { | ||
| 103 | return 0; | ||
| 104 | } | ||
| 105 | |||
| 106 | static int cap_sb_umount(struct vfsmount *mnt, int flags) | ||
| 107 | { | ||
| 108 | return 0; | ||
| 109 | } | ||
| 110 | |||
| 111 | static int cap_sb_pivotroot(struct path *old_path, struct path *new_path) | ||
| 112 | { | ||
| 113 | return 0; | ||
| 114 | } | ||
| 115 | |||
| 116 | static int cap_sb_set_mnt_opts(struct super_block *sb, | ||
| 117 | struct security_mnt_opts *opts, | ||
| 118 | unsigned long kern_flags, | ||
| 119 | unsigned long *set_kern_flags) | ||
| 120 | |||
| 121 | { | ||
| 122 | if (unlikely(opts->num_mnt_opts)) | ||
| 123 | return -EOPNOTSUPP; | ||
| 124 | return 0; | ||
| 125 | } | ||
| 126 | |||
| 127 | static int cap_sb_clone_mnt_opts(const struct super_block *oldsb, | ||
| 128 | struct super_block *newsb) | ||
| 129 | { | ||
| 130 | return 0; | ||
| 131 | } | ||
| 132 | |||
| 133 | static int cap_sb_parse_opts_str(char *options, struct security_mnt_opts *opts) | ||
| 134 | { | ||
| 135 | return 0; | ||
| 136 | } | ||
| 137 | |||
| 138 | static int cap_dentry_init_security(struct dentry *dentry, int mode, | ||
| 139 | struct qstr *name, void **ctx, | ||
| 140 | u32 *ctxlen) | ||
| 141 | { | ||
| 142 | return -EOPNOTSUPP; | ||
| 143 | } | ||
| 144 | |||
| 145 | static int cap_inode_alloc_security(struct inode *inode) | ||
| 146 | { | ||
| 147 | return 0; | ||
| 148 | } | ||
| 149 | |||
| 150 | static void cap_inode_free_security(struct inode *inode) | ||
| 151 | { | ||
| 152 | } | ||
| 153 | |||
| 154 | static int cap_inode_init_security(struct inode *inode, struct inode *dir, | ||
| 155 | const struct qstr *qstr, const char **name, | ||
| 156 | void **value, size_t *len) | ||
| 157 | { | ||
| 158 | return -EOPNOTSUPP; | ||
| 159 | } | ||
| 160 | |||
| 161 | static int cap_inode_create(struct inode *inode, struct dentry *dentry, | ||
| 162 | umode_t mask) | ||
| 163 | { | ||
| 164 | return 0; | ||
| 165 | } | ||
| 166 | |||
| 167 | static int cap_inode_link(struct dentry *old_dentry, struct inode *inode, | ||
| 168 | struct dentry *new_dentry) | ||
| 169 | { | ||
| 170 | return 0; | ||
| 171 | } | ||
| 172 | |||
| 173 | static int cap_inode_unlink(struct inode *inode, struct dentry *dentry) | ||
| 174 | { | ||
| 175 | return 0; | ||
| 176 | } | ||
| 177 | |||
| 178 | static int cap_inode_symlink(struct inode *inode, struct dentry *dentry, | ||
| 179 | const char *name) | ||
| 180 | { | ||
| 181 | return 0; | ||
| 182 | } | ||
| 183 | |||
| 184 | static int cap_inode_mkdir(struct inode *inode, struct dentry *dentry, | ||
| 185 | umode_t mask) | ||
| 186 | { | ||
| 187 | return 0; | ||
| 188 | } | ||
| 189 | |||
| 190 | static int cap_inode_rmdir(struct inode *inode, struct dentry *dentry) | ||
| 191 | { | ||
| 192 | return 0; | ||
| 193 | } | ||
| 194 | |||
| 195 | static int cap_inode_mknod(struct inode *inode, struct dentry *dentry, | ||
| 196 | umode_t mode, dev_t dev) | ||
| 197 | { | ||
| 198 | return 0; | ||
| 199 | } | ||
| 200 | |||
| 201 | static int cap_inode_rename(struct inode *old_inode, struct dentry *old_dentry, | ||
| 202 | struct inode *new_inode, struct dentry *new_dentry) | ||
| 203 | { | ||
| 204 | return 0; | ||
| 205 | } | ||
| 206 | |||
| 207 | static int cap_inode_readlink(struct dentry *dentry) | ||
| 208 | { | ||
| 209 | return 0; | ||
| 210 | } | ||
| 211 | |||
| 212 | static int cap_inode_follow_link(struct dentry *dentry, | ||
| 213 | struct nameidata *nameidata) | ||
| 214 | { | ||
| 215 | return 0; | ||
| 216 | } | ||
| 217 | |||
| 218 | static int cap_inode_permission(struct inode *inode, int mask) | ||
| 219 | { | ||
| 220 | return 0; | ||
| 221 | } | ||
| 222 | |||
| 223 | static int cap_inode_setattr(struct dentry *dentry, struct iattr *iattr) | ||
| 224 | { | ||
| 225 | return 0; | ||
| 226 | } | ||
| 227 | |||
| 228 | static int cap_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) | ||
| 229 | { | ||
| 230 | return 0; | ||
| 231 | } | ||
| 232 | |||
| 233 | static void cap_inode_post_setxattr(struct dentry *dentry, const char *name, | ||
| 234 | const void *value, size_t size, int flags) | ||
| 235 | { | ||
| 236 | } | ||
| 237 | |||
| 238 | static int cap_inode_getxattr(struct dentry *dentry, const char *name) | ||
| 239 | { | ||
| 240 | return 0; | ||
| 241 | } | ||
| 242 | |||
| 243 | static int cap_inode_listxattr(struct dentry *dentry) | ||
| 244 | { | ||
| 245 | return 0; | ||
| 246 | } | ||
| 247 | |||
| 248 | static int cap_inode_getsecurity(const struct inode *inode, const char *name, | ||
| 249 | void **buffer, bool alloc) | ||
| 250 | { | ||
| 251 | return -EOPNOTSUPP; | ||
| 252 | } | ||
| 253 | |||
| 254 | static int cap_inode_setsecurity(struct inode *inode, const char *name, | ||
| 255 | const void *value, size_t size, int flags) | ||
| 256 | { | ||
| 257 | return -EOPNOTSUPP; | ||
| 258 | } | ||
| 259 | |||
| 260 | static int cap_inode_listsecurity(struct inode *inode, char *buffer, | ||
| 261 | size_t buffer_size) | ||
| 262 | { | ||
| 263 | return 0; | ||
| 264 | } | ||
| 265 | |||
| 266 | static void cap_inode_getsecid(const struct inode *inode, u32 *secid) | ||
| 267 | { | ||
| 268 | *secid = 0; | ||
| 269 | } | ||
| 270 | |||
| 271 | #ifdef CONFIG_SECURITY_PATH | ||
| 272 | static int cap_path_mknod(struct path *dir, struct dentry *dentry, umode_t mode, | ||
| 273 | unsigned int dev) | ||
| 274 | { | ||
| 275 | return 0; | ||
| 276 | } | ||
| 277 | |||
| 278 | static int cap_path_mkdir(struct path *dir, struct dentry *dentry, umode_t mode) | ||
| 279 | { | ||
| 280 | return 0; | ||
| 281 | } | ||
| 282 | |||
| 283 | static int cap_path_rmdir(struct path *dir, struct dentry *dentry) | ||
| 284 | { | ||
| 285 | return 0; | ||
| 286 | } | ||
| 287 | |||
| 288 | static int cap_path_unlink(struct path *dir, struct dentry *dentry) | ||
| 289 | { | ||
| 290 | return 0; | ||
| 291 | } | ||
| 292 | |||
| 293 | static int cap_path_symlink(struct path *dir, struct dentry *dentry, | ||
| 294 | const char *old_name) | ||
| 295 | { | ||
| 296 | return 0; | ||
| 297 | } | ||
| 298 | |||
| 299 | static int cap_path_link(struct dentry *old_dentry, struct path *new_dir, | ||
| 300 | struct dentry *new_dentry) | ||
| 301 | { | ||
| 302 | return 0; | ||
| 303 | } | ||
| 304 | |||
| 305 | static int cap_path_rename(struct path *old_path, struct dentry *old_dentry, | ||
| 306 | struct path *new_path, struct dentry *new_dentry) | ||
| 307 | { | ||
| 308 | return 0; | ||
| 309 | } | ||
| 310 | |||
| 311 | static int cap_path_truncate(struct path *path) | ||
| 312 | { | ||
| 313 | return 0; | ||
| 314 | } | ||
| 315 | |||
| 316 | static int cap_path_chmod(struct path *path, umode_t mode) | ||
| 317 | { | ||
| 318 | return 0; | ||
| 319 | } | ||
| 320 | |||
| 321 | static int cap_path_chown(struct path *path, kuid_t uid, kgid_t gid) | ||
| 322 | { | ||
| 323 | return 0; | ||
| 324 | } | ||
| 325 | |||
| 326 | static int cap_path_chroot(struct path *root) | ||
| 327 | { | ||
| 328 | return 0; | ||
| 329 | } | ||
| 330 | #endif | ||
| 331 | |||
| 332 | static int cap_file_permission(struct file *file, int mask) | ||
| 333 | { | ||
| 334 | return 0; | ||
| 335 | } | ||
| 336 | |||
| 337 | static int cap_file_alloc_security(struct file *file) | ||
| 338 | { | ||
| 339 | return 0; | ||
| 340 | } | ||
| 341 | |||
| 342 | static void cap_file_free_security(struct file *file) | ||
| 343 | { | ||
| 344 | } | ||
| 345 | |||
| 346 | static int cap_file_ioctl(struct file *file, unsigned int command, | ||
| 347 | unsigned long arg) | ||
| 348 | { | ||
| 349 | return 0; | ||
| 350 | } | ||
| 351 | |||
| 352 | static int cap_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot, | ||
| 353 | unsigned long prot) | ||
| 354 | { | ||
| 355 | return 0; | ||
| 356 | } | ||
| 357 | |||
| 358 | static int cap_file_lock(struct file *file, unsigned int cmd) | ||
| 359 | { | ||
| 360 | return 0; | ||
| 361 | } | ||
| 362 | |||
| 363 | static int cap_file_fcntl(struct file *file, unsigned int cmd, | ||
| 364 | unsigned long arg) | ||
| 365 | { | ||
| 366 | return 0; | ||
| 367 | } | ||
| 368 | |||
| 369 | static void cap_file_set_fowner(struct file *file) | ||
| 370 | { | ||
| 371 | return; | ||
| 372 | } | ||
| 373 | |||
| 374 | static int cap_file_send_sigiotask(struct task_struct *tsk, | ||
| 375 | struct fown_struct *fown, int sig) | ||
| 376 | { | ||
| 377 | return 0; | ||
| 378 | } | ||
| 379 | |||
| 380 | static int cap_file_receive(struct file *file) | ||
| 381 | { | ||
| 382 | return 0; | ||
| 383 | } | ||
| 384 | |||
| 385 | static int cap_file_open(struct file *file, const struct cred *cred) | ||
| 386 | { | ||
| 387 | return 0; | ||
| 388 | } | ||
| 389 | |||
| 390 | static int cap_task_create(unsigned long clone_flags) | ||
| 391 | { | ||
| 392 | return 0; | ||
| 393 | } | ||
| 394 | |||
| 395 | static void cap_task_free(struct task_struct *task) | ||
| 396 | { | ||
| 397 | } | ||
| 398 | |||
| 399 | static int cap_cred_alloc_blank(struct cred *cred, gfp_t gfp) | ||
| 400 | { | ||
| 401 | return 0; | ||
| 402 | } | ||
| 403 | |||
| 404 | static void cap_cred_free(struct cred *cred) | ||
| 405 | { | ||
| 406 | } | ||
| 407 | |||
| 408 | static int cap_cred_prepare(struct cred *new, const struct cred *old, gfp_t gfp) | ||
| 409 | { | ||
| 410 | return 0; | ||
| 411 | } | ||
| 412 | |||
| 413 | static void cap_cred_transfer(struct cred *new, const struct cred *old) | ||
| 414 | { | ||
| 415 | } | ||
| 416 | |||
| 417 | static int cap_kernel_act_as(struct cred *new, u32 secid) | ||
| 418 | { | ||
| 419 | return 0; | ||
| 420 | } | ||
| 421 | |||
| 422 | static int cap_kernel_create_files_as(struct cred *new, struct inode *inode) | ||
| 423 | { | ||
| 424 | return 0; | ||
| 425 | } | ||
| 426 | |||
| 427 | static int cap_kernel_fw_from_file(struct file *file, char *buf, size_t size) | ||
| 428 | { | ||
| 429 | return 0; | ||
| 430 | } | ||
| 431 | |||
| 432 | static int cap_kernel_module_request(char *kmod_name) | ||
| 433 | { | ||
| 434 | return 0; | ||
| 435 | } | ||
| 436 | |||
| 437 | static int cap_kernel_module_from_file(struct file *file) | ||
| 438 | { | ||
| 439 | return 0; | ||
| 440 | } | ||
| 441 | |||
| 442 | static int cap_task_setpgid(struct task_struct *p, pid_t pgid) | ||
| 443 | { | ||
| 444 | return 0; | ||
| 445 | } | ||
| 446 | |||
| 447 | static int cap_task_getpgid(struct task_struct *p) | ||
| 448 | { | ||
| 449 | return 0; | ||
| 450 | } | ||
| 451 | |||
| 452 | static int cap_task_getsid(struct task_struct *p) | ||
| 453 | { | ||
| 454 | return 0; | ||
| 455 | } | ||
| 456 | |||
| 457 | static void cap_task_getsecid(struct task_struct *p, u32 *secid) | ||
| 458 | { | ||
| 459 | *secid = 0; | ||
| 460 | } | ||
| 461 | |||
| 462 | static int cap_task_getioprio(struct task_struct *p) | ||
| 463 | { | ||
| 464 | return 0; | ||
| 465 | } | ||
| 466 | |||
| 467 | static int cap_task_setrlimit(struct task_struct *p, unsigned int resource, | ||
| 468 | struct rlimit *new_rlim) | ||
| 469 | { | ||
| 470 | return 0; | ||
| 471 | } | ||
| 472 | |||
| 473 | static int cap_task_getscheduler(struct task_struct *p) | ||
| 474 | { | ||
| 475 | return 0; | ||
| 476 | } | ||
| 477 | |||
| 478 | static int cap_task_movememory(struct task_struct *p) | ||
| 479 | { | ||
| 480 | return 0; | ||
| 481 | } | ||
| 482 | |||
| 483 | static int cap_task_wait(struct task_struct *p) | ||
| 484 | { | ||
| 485 | return 0; | ||
| 486 | } | ||
| 487 | |||
| 488 | static int cap_task_kill(struct task_struct *p, struct siginfo *info, | ||
| 489 | int sig, u32 secid) | ||
| 490 | { | ||
| 491 | return 0; | ||
| 492 | } | ||
| 493 | |||
| 494 | static void cap_task_to_inode(struct task_struct *p, struct inode *inode) | ||
| 495 | { | ||
| 496 | } | ||
| 497 | |||
| 498 | static int cap_ipc_permission(struct kern_ipc_perm *ipcp, short flag) | ||
| 499 | { | ||
| 500 | return 0; | ||
| 501 | } | ||
| 502 | |||
| 503 | static void cap_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid) | ||
| 504 | { | ||
| 505 | *secid = 0; | ||
| 506 | } | ||
| 507 | |||
| 508 | static int cap_msg_msg_alloc_security(struct msg_msg *msg) | ||
| 509 | { | ||
| 510 | return 0; | ||
| 511 | } | ||
| 512 | |||
| 513 | static void cap_msg_msg_free_security(struct msg_msg *msg) | ||
| 514 | { | ||
| 515 | } | ||
| 516 | |||
| 517 | static int cap_msg_queue_alloc_security(struct msg_queue *msq) | ||
| 518 | { | ||
| 519 | return 0; | ||
| 520 | } | ||
| 521 | |||
| 522 | static void cap_msg_queue_free_security(struct msg_queue *msq) | ||
| 523 | { | ||
| 524 | } | ||
| 525 | |||
| 526 | static int cap_msg_queue_associate(struct msg_queue *msq, int msqflg) | ||
| 527 | { | ||
| 528 | return 0; | ||
| 529 | } | ||
| 530 | |||
| 531 | static int cap_msg_queue_msgctl(struct msg_queue *msq, int cmd) | ||
| 532 | { | ||
| 533 | return 0; | ||
| 534 | } | ||
| 535 | |||
| 536 | static int cap_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, | ||
| 537 | int msgflg) | ||
| 538 | { | ||
| 539 | return 0; | ||
| 540 | } | ||
| 541 | |||
| 542 | static int cap_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, | ||
| 543 | struct task_struct *target, long type, int mode) | ||
| 544 | { | ||
| 545 | return 0; | ||
| 546 | } | ||
| 547 | |||
| 548 | static int cap_shm_alloc_security(struct shmid_kernel *shp) | ||
| 549 | { | ||
| 550 | return 0; | ||
| 551 | } | ||
| 552 | |||
| 553 | static void cap_shm_free_security(struct shmid_kernel *shp) | ||
| 554 | { | ||
| 555 | } | ||
| 556 | |||
| 557 | static int cap_shm_associate(struct shmid_kernel *shp, int shmflg) | ||
| 558 | { | ||
| 559 | return 0; | ||
| 560 | } | ||
| 561 | |||
| 562 | static int cap_shm_shmctl(struct shmid_kernel *shp, int cmd) | ||
| 563 | { | ||
| 564 | return 0; | ||
| 565 | } | ||
| 566 | |||
| 567 | static int cap_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, | ||
| 568 | int shmflg) | ||
| 569 | { | ||
| 570 | return 0; | ||
| 571 | } | ||
| 572 | |||
| 573 | static int cap_sem_alloc_security(struct sem_array *sma) | ||
| 574 | { | ||
| 575 | return 0; | ||
| 576 | } | ||
| 577 | |||
| 578 | static void cap_sem_free_security(struct sem_array *sma) | ||
| 579 | { | ||
| 580 | } | ||
| 581 | |||
| 582 | static int cap_sem_associate(struct sem_array *sma, int semflg) | ||
| 583 | { | ||
| 584 | return 0; | ||
| 585 | } | ||
| 586 | |||
| 587 | static int cap_sem_semctl(struct sem_array *sma, int cmd) | ||
| 588 | { | ||
| 589 | return 0; | ||
| 590 | } | ||
| 591 | |||
| 592 | static int cap_sem_semop(struct sem_array *sma, struct sembuf *sops, | ||
| 593 | unsigned nsops, int alter) | ||
| 594 | { | ||
| 595 | return 0; | ||
| 596 | } | ||
| 597 | |||
| 598 | #ifdef CONFIG_SECURITY_NETWORK | ||
| 599 | static int cap_unix_stream_connect(struct sock *sock, struct sock *other, | ||
| 600 | struct sock *newsk) | ||
| 601 | { | ||
| 602 | return 0; | ||
| 603 | } | ||
| 604 | |||
| 605 | static int cap_unix_may_send(struct socket *sock, struct socket *other) | ||
| 606 | { | ||
| 607 | return 0; | ||
| 608 | } | ||
| 609 | |||
| 610 | static int cap_socket_create(int family, int type, int protocol, int kern) | ||
| 611 | { | ||
| 612 | return 0; | ||
| 613 | } | ||
| 614 | |||
| 615 | static int cap_socket_post_create(struct socket *sock, int family, int type, | ||
| 616 | int protocol, int kern) | ||
| 617 | { | ||
| 618 | return 0; | ||
| 619 | } | ||
| 620 | |||
| 621 | static int cap_socket_bind(struct socket *sock, struct sockaddr *address, | ||
| 622 | int addrlen) | ||
| 623 | { | ||
| 624 | return 0; | ||
| 625 | } | ||
| 626 | |||
| 627 | static int cap_socket_connect(struct socket *sock, struct sockaddr *address, | ||
| 628 | int addrlen) | ||
| 629 | { | ||
| 630 | return 0; | ||
| 631 | } | ||
| 632 | |||
| 633 | static int cap_socket_listen(struct socket *sock, int backlog) | ||
| 634 | { | ||
| 635 | return 0; | ||
| 636 | } | ||
| 637 | |||
| 638 | static int cap_socket_accept(struct socket *sock, struct socket *newsock) | ||
| 639 | { | ||
| 640 | return 0; | ||
| 641 | } | ||
| 642 | |||
| 643 | static int cap_socket_sendmsg(struct socket *sock, struct msghdr *msg, int size) | ||
| 644 | { | ||
| 645 | return 0; | ||
| 646 | } | ||
| 647 | |||
| 648 | static int cap_socket_recvmsg(struct socket *sock, struct msghdr *msg, | ||
| 649 | int size, int flags) | ||
| 650 | { | ||
| 651 | return 0; | ||
| 652 | } | ||
| 653 | |||
| 654 | static int cap_socket_getsockname(struct socket *sock) | ||
| 655 | { | ||
| 656 | return 0; | ||
| 657 | } | ||
| 658 | |||
| 659 | static int cap_socket_getpeername(struct socket *sock) | ||
| 660 | { | ||
| 661 | return 0; | ||
| 662 | } | ||
| 663 | |||
| 664 | static int cap_socket_setsockopt(struct socket *sock, int level, int optname) | ||
| 665 | { | ||
| 666 | return 0; | ||
| 667 | } | ||
| 668 | |||
| 669 | static int cap_socket_getsockopt(struct socket *sock, int level, int optname) | ||
| 670 | { | ||
| 671 | return 0; | ||
| 672 | } | ||
| 673 | |||
| 674 | static int cap_socket_shutdown(struct socket *sock, int how) | ||
| 675 | { | ||
| 676 | return 0; | ||
| 677 | } | ||
| 678 | |||
| 679 | static int cap_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) | ||
| 680 | { | ||
| 681 | return 0; | ||
| 682 | } | ||
| 683 | |||
| 684 | static int cap_socket_getpeersec_stream(struct socket *sock, | ||
| 685 | char __user *optval, | ||
| 686 | int __user *optlen, unsigned len) | ||
| 687 | { | ||
| 688 | return -ENOPROTOOPT; | ||
| 689 | } | ||
| 690 | |||
| 691 | static int cap_socket_getpeersec_dgram(struct socket *sock, | ||
| 692 | struct sk_buff *skb, u32 *secid) | ||
| 693 | { | ||
| 694 | return -ENOPROTOOPT; | ||
| 695 | } | ||
| 696 | |||
| 697 | static int cap_sk_alloc_security(struct sock *sk, int family, gfp_t priority) | ||
| 698 | { | ||
| 699 | return 0; | ||
| 700 | } | ||
| 701 | |||
| 702 | static void cap_sk_free_security(struct sock *sk) | ||
| 703 | { | ||
| 704 | } | ||
| 705 | |||
| 706 | static void cap_sk_clone_security(const struct sock *sk, struct sock *newsk) | ||
| 707 | { | ||
| 708 | } | ||
| 709 | |||
| 710 | static void cap_sk_getsecid(struct sock *sk, u32 *secid) | ||
| 711 | { | ||
| 712 | } | ||
| 713 | |||
| 714 | static void cap_sock_graft(struct sock *sk, struct socket *parent) | ||
| 715 | { | ||
| 716 | } | ||
| 717 | |||
| 718 | static int cap_inet_conn_request(struct sock *sk, struct sk_buff *skb, | ||
| 719 | struct request_sock *req) | ||
| 720 | { | ||
| 721 | return 0; | ||
| 722 | } | ||
| 723 | |||
| 724 | static void cap_inet_csk_clone(struct sock *newsk, | ||
| 725 | const struct request_sock *req) | ||
| 726 | { | ||
| 727 | } | ||
| 728 | |||
| 729 | static void cap_inet_conn_established(struct sock *sk, struct sk_buff *skb) | ||
| 730 | { | ||
| 731 | } | ||
| 732 | |||
| 733 | static int cap_secmark_relabel_packet(u32 secid) | ||
| 734 | { | ||
| 735 | return 0; | ||
| 736 | } | ||
| 737 | |||
| 738 | static void cap_secmark_refcount_inc(void) | ||
| 739 | { | ||
| 740 | } | ||
| 741 | |||
| 742 | static void cap_secmark_refcount_dec(void) | ||
| 743 | { | ||
| 744 | } | ||
| 745 | |||
| 746 | static void cap_req_classify_flow(const struct request_sock *req, | ||
| 747 | struct flowi *fl) | ||
| 748 | { | ||
| 749 | } | ||
| 750 | |||
| 751 | static int cap_tun_dev_alloc_security(void **security) | ||
| 752 | { | ||
| 753 | return 0; | ||
| 754 | } | ||
| 755 | |||
| 756 | static void cap_tun_dev_free_security(void *security) | ||
| 757 | { | ||
| 758 | } | ||
| 759 | |||
| 760 | static int cap_tun_dev_create(void) | ||
| 761 | { | ||
| 762 | return 0; | ||
| 763 | } | ||
| 764 | |||
| 765 | static int cap_tun_dev_attach_queue(void *security) | ||
| 766 | { | ||
| 767 | return 0; | ||
| 768 | } | ||
| 769 | |||
| 770 | static int cap_tun_dev_attach(struct sock *sk, void *security) | ||
| 771 | { | ||
| 772 | return 0; | ||
| 773 | } | ||
| 774 | |||
| 775 | static int cap_tun_dev_open(void *security) | ||
| 776 | { | ||
| 777 | return 0; | ||
| 778 | } | ||
| 779 | |||
| 780 | static void cap_skb_owned_by(struct sk_buff *skb, struct sock *sk) | ||
| 781 | { | ||
| 782 | } | ||
| 783 | |||
| 784 | #endif /* CONFIG_SECURITY_NETWORK */ | ||
| 785 | |||
| 786 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | ||
| 787 | static int cap_xfrm_policy_alloc_security(struct xfrm_sec_ctx **ctxp, | ||
| 788 | struct xfrm_user_sec_ctx *sec_ctx, | ||
| 789 | gfp_t gfp) | ||
| 790 | { | ||
| 791 | return 0; | ||
| 792 | } | ||
| 793 | |||
| 794 | static int cap_xfrm_policy_clone_security(struct xfrm_sec_ctx *old_ctx, | ||
| 795 | struct xfrm_sec_ctx **new_ctxp) | ||
| 796 | { | ||
| 797 | return 0; | ||
| 798 | } | ||
| 799 | |||
| 800 | static void cap_xfrm_policy_free_security(struct xfrm_sec_ctx *ctx) | ||
| 801 | { | ||
| 802 | } | ||
| 803 | |||
| 804 | static int cap_xfrm_policy_delete_security(struct xfrm_sec_ctx *ctx) | ||
| 805 | { | ||
| 806 | return 0; | ||
| 807 | } | ||
| 808 | |||
| 809 | static int cap_xfrm_state_alloc(struct xfrm_state *x, | ||
| 810 | struct xfrm_user_sec_ctx *sec_ctx) | ||
| 811 | { | ||
| 812 | return 0; | ||
| 813 | } | ||
| 814 | |||
| 815 | static int cap_xfrm_state_alloc_acquire(struct xfrm_state *x, | ||
| 816 | struct xfrm_sec_ctx *polsec, | ||
| 817 | u32 secid) | ||
| 818 | { | ||
| 819 | return 0; | ||
| 820 | } | ||
| 821 | |||
| 822 | static void cap_xfrm_state_free_security(struct xfrm_state *x) | ||
| 823 | { | ||
| 824 | } | ||
| 825 | |||
| 826 | static int cap_xfrm_state_delete_security(struct xfrm_state *x) | ||
| 827 | { | ||
| 828 | return 0; | ||
| 829 | } | ||
| 830 | |||
| 831 | static int cap_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 sk_sid, u8 dir) | ||
| 832 | { | ||
| 833 | return 0; | ||
| 834 | } | ||
| 835 | |||
| 836 | static int cap_xfrm_state_pol_flow_match(struct xfrm_state *x, | ||
| 837 | struct xfrm_policy *xp, | ||
| 838 | const struct flowi *fl) | ||
| 839 | { | ||
| 840 | return 1; | ||
| 841 | } | ||
| 842 | |||
| 843 | static int cap_xfrm_decode_session(struct sk_buff *skb, u32 *fl, int ckall) | ||
| 844 | { | ||
| 845 | return 0; | ||
| 846 | } | ||
| 847 | |||
| 848 | #endif /* CONFIG_SECURITY_NETWORK_XFRM */ | ||
| 849 | static void cap_d_instantiate(struct dentry *dentry, struct inode *inode) | ||
| 850 | { | ||
| 851 | } | ||
| 852 | |||
| 853 | static int cap_getprocattr(struct task_struct *p, char *name, char **value) | ||
| 854 | { | ||
| 855 | return -EINVAL; | ||
| 856 | } | ||
| 857 | |||
| 858 | static int cap_setprocattr(struct task_struct *p, char *name, void *value, | ||
| 859 | size_t size) | ||
| 860 | { | ||
| 861 | return -EINVAL; | ||
| 862 | } | ||
| 863 | |||
| 864 | static int cap_ismaclabel(const char *name) | ||
| 865 | { | ||
| 866 | return 0; | ||
| 867 | } | ||
| 868 | |||
| 869 | static int cap_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) | ||
| 870 | { | ||
| 871 | return -EOPNOTSUPP; | ||
| 872 | } | ||
| 873 | |||
| 874 | static int cap_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) | ||
| 875 | { | ||
| 876 | *secid = 0; | ||
| 877 | return 0; | ||
| 878 | } | ||
| 879 | |||
| 880 | static void cap_release_secctx(char *secdata, u32 seclen) | ||
| 881 | { | ||
| 882 | } | ||
| 883 | |||
| 884 | static int cap_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) | ||
| 885 | { | ||
| 886 | return 0; | ||
| 887 | } | ||
| 888 | |||
| 889 | static int cap_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen) | ||
| 890 | { | ||
| 891 | return 0; | ||
| 892 | } | ||
| 893 | |||
| 894 | static int cap_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen) | ||
| 895 | { | ||
| 896 | return -EOPNOTSUPP; | ||
| 897 | } | ||
| 898 | #ifdef CONFIG_KEYS | ||
| 899 | static int cap_key_alloc(struct key *key, const struct cred *cred, | ||
| 900 | unsigned long flags) | ||
| 901 | { | ||
| 902 | return 0; | ||
| 903 | } | ||
| 904 | |||
| 905 | static void cap_key_free(struct key *key) | ||
| 906 | { | ||
| 907 | } | ||
| 908 | |||
| 909 | static int cap_key_permission(key_ref_t key_ref, const struct cred *cred, | ||
| 910 | unsigned perm) | ||
| 911 | { | ||
| 912 | return 0; | ||
| 913 | } | ||
| 914 | |||
| 915 | static int cap_key_getsecurity(struct key *key, char **_buffer) | ||
| 916 | { | ||
| 917 | *_buffer = NULL; | ||
| 918 | return 0; | ||
| 919 | } | ||
| 920 | |||
| 921 | #endif /* CONFIG_KEYS */ | ||
| 922 | |||
| 923 | #ifdef CONFIG_AUDIT | ||
| 924 | static int cap_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule) | ||
| 925 | { | ||
| 926 | return 0; | ||
| 927 | } | ||
| 928 | |||
| 929 | static int cap_audit_rule_known(struct audit_krule *krule) | ||
| 930 | { | ||
| 931 | return 0; | ||
| 932 | } | ||
| 933 | |||
| 934 | static int cap_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule, | ||
| 935 | struct audit_context *actx) | ||
| 936 | { | ||
| 937 | return 0; | ||
| 938 | } | ||
| 939 | |||
| 940 | static void cap_audit_rule_free(void *lsmrule) | ||
| 941 | { | ||
| 942 | } | ||
| 943 | #endif /* CONFIG_AUDIT */ | ||
| 944 | |||
| 945 | #define set_to_cap_if_null(ops, function) \ | ||
| 946 | do { \ | ||
| 947 | if (!ops->function) { \ | ||
| 948 | ops->function = cap_##function; \ | ||
| 949 | pr_debug("Had to override the " #function \ | ||
| 950 | " security operation with the default.\n");\ | ||
| 951 | } \ | ||
| 952 | } while (0) | ||
| 953 | |||
| 954 | void __init security_fixup_ops(struct security_operations *ops) | ||
| 955 | { | ||
| 956 | set_to_cap_if_null(ops, binder_set_context_mgr); | ||
| 957 | set_to_cap_if_null(ops, binder_transaction); | ||
| 958 | set_to_cap_if_null(ops, binder_transfer_binder); | ||
| 959 | set_to_cap_if_null(ops, binder_transfer_file); | ||
| 960 | set_to_cap_if_null(ops, ptrace_access_check); | ||
| 961 | set_to_cap_if_null(ops, ptrace_traceme); | ||
| 962 | set_to_cap_if_null(ops, capget); | ||
| 963 | set_to_cap_if_null(ops, capset); | ||
| 964 | set_to_cap_if_null(ops, capable); | ||
| 965 | set_to_cap_if_null(ops, quotactl); | ||
| 966 | set_to_cap_if_null(ops, quota_on); | ||
| 967 | set_to_cap_if_null(ops, syslog); | ||
| 968 | set_to_cap_if_null(ops, settime); | ||
| 969 | set_to_cap_if_null(ops, vm_enough_memory); | ||
| 970 | set_to_cap_if_null(ops, bprm_set_creds); | ||
| 971 | set_to_cap_if_null(ops, bprm_committing_creds); | ||
| 972 | set_to_cap_if_null(ops, bprm_committed_creds); | ||
| 973 | set_to_cap_if_null(ops, bprm_check_security); | ||
| 974 | set_to_cap_if_null(ops, bprm_secureexec); | ||
| 975 | set_to_cap_if_null(ops, sb_alloc_security); | ||
| 976 | set_to_cap_if_null(ops, sb_free_security); | ||
| 977 | set_to_cap_if_null(ops, sb_copy_data); | ||
| 978 | set_to_cap_if_null(ops, sb_remount); | ||
| 979 | set_to_cap_if_null(ops, sb_kern_mount); | ||
| 980 | set_to_cap_if_null(ops, sb_show_options); | ||
| 981 | set_to_cap_if_null(ops, sb_statfs); | ||
| 982 | set_to_cap_if_null(ops, sb_mount); | ||
| 983 | set_to_cap_if_null(ops, sb_umount); | ||
| 984 | set_to_cap_if_null(ops, sb_pivotroot); | ||
| 985 | set_to_cap_if_null(ops, sb_set_mnt_opts); | ||
| 986 | set_to_cap_if_null(ops, sb_clone_mnt_opts); | ||
| 987 | set_to_cap_if_null(ops, sb_parse_opts_str); | ||
| 988 | set_to_cap_if_null(ops, dentry_init_security); | ||
| 989 | set_to_cap_if_null(ops, inode_alloc_security); | ||
| 990 | set_to_cap_if_null(ops, inode_free_security); | ||
| 991 | set_to_cap_if_null(ops, inode_init_security); | ||
| 992 | set_to_cap_if_null(ops, inode_create); | ||
| 993 | set_to_cap_if_null(ops, inode_link); | ||
| 994 | set_to_cap_if_null(ops, inode_unlink); | ||
| 995 | set_to_cap_if_null(ops, inode_symlink); | ||
| 996 | set_to_cap_if_null(ops, inode_mkdir); | ||
| 997 | set_to_cap_if_null(ops, inode_rmdir); | ||
| 998 | set_to_cap_if_null(ops, inode_mknod); | ||
| 999 | set_to_cap_if_null(ops, inode_rename); | ||
| 1000 | set_to_cap_if_null(ops, inode_readlink); | ||
| 1001 | set_to_cap_if_null(ops, inode_follow_link); | ||
| 1002 | set_to_cap_if_null(ops, inode_permission); | ||
| 1003 | set_to_cap_if_null(ops, inode_setattr); | ||
| 1004 | set_to_cap_if_null(ops, inode_getattr); | ||
| 1005 | set_to_cap_if_null(ops, inode_setxattr); | ||
| 1006 | set_to_cap_if_null(ops, inode_post_setxattr); | ||
| 1007 | set_to_cap_if_null(ops, inode_getxattr); | ||
| 1008 | set_to_cap_if_null(ops, inode_listxattr); | ||
| 1009 | set_to_cap_if_null(ops, inode_removexattr); | ||
| 1010 | set_to_cap_if_null(ops, inode_need_killpriv); | ||
| 1011 | set_to_cap_if_null(ops, inode_killpriv); | ||
| 1012 | set_to_cap_if_null(ops, inode_getsecurity); | ||
| 1013 | set_to_cap_if_null(ops, inode_setsecurity); | ||
| 1014 | set_to_cap_if_null(ops, inode_listsecurity); | ||
| 1015 | set_to_cap_if_null(ops, inode_getsecid); | ||
| 1016 | #ifdef CONFIG_SECURITY_PATH | ||
| 1017 | set_to_cap_if_null(ops, path_mknod); | ||
| 1018 | set_to_cap_if_null(ops, path_mkdir); | ||
| 1019 | set_to_cap_if_null(ops, path_rmdir); | ||
| 1020 | set_to_cap_if_null(ops, path_unlink); | ||
| 1021 | set_to_cap_if_null(ops, path_symlink); | ||
| 1022 | set_to_cap_if_null(ops, path_link); | ||
| 1023 | set_to_cap_if_null(ops, path_rename); | ||
| 1024 | set_to_cap_if_null(ops, path_truncate); | ||
| 1025 | set_to_cap_if_null(ops, path_chmod); | ||
| 1026 | set_to_cap_if_null(ops, path_chown); | ||
| 1027 | set_to_cap_if_null(ops, path_chroot); | ||
| 1028 | #endif | ||
| 1029 | set_to_cap_if_null(ops, file_permission); | ||
| 1030 | set_to_cap_if_null(ops, file_alloc_security); | ||
| 1031 | set_to_cap_if_null(ops, file_free_security); | ||
| 1032 | set_to_cap_if_null(ops, file_ioctl); | ||
| 1033 | set_to_cap_if_null(ops, mmap_addr); | ||
| 1034 | set_to_cap_if_null(ops, mmap_file); | ||
| 1035 | set_to_cap_if_null(ops, file_mprotect); | ||
| 1036 | set_to_cap_if_null(ops, file_lock); | ||
| 1037 | set_to_cap_if_null(ops, file_fcntl); | ||
| 1038 | set_to_cap_if_null(ops, file_set_fowner); | ||
| 1039 | set_to_cap_if_null(ops, file_send_sigiotask); | ||
| 1040 | set_to_cap_if_null(ops, file_receive); | ||
| 1041 | set_to_cap_if_null(ops, file_open); | ||
| 1042 | set_to_cap_if_null(ops, task_create); | ||
| 1043 | set_to_cap_if_null(ops, task_free); | ||
| 1044 | set_to_cap_if_null(ops, cred_alloc_blank); | ||
| 1045 | set_to_cap_if_null(ops, cred_free); | ||
| 1046 | set_to_cap_if_null(ops, cred_prepare); | ||
| 1047 | set_to_cap_if_null(ops, cred_transfer); | ||
| 1048 | set_to_cap_if_null(ops, kernel_act_as); | ||
| 1049 | set_to_cap_if_null(ops, kernel_create_files_as); | ||
| 1050 | set_to_cap_if_null(ops, kernel_fw_from_file); | ||
| 1051 | set_to_cap_if_null(ops, kernel_module_request); | ||
| 1052 | set_to_cap_if_null(ops, kernel_module_from_file); | ||
| 1053 | set_to_cap_if_null(ops, task_fix_setuid); | ||
| 1054 | set_to_cap_if_null(ops, task_setpgid); | ||
| 1055 | set_to_cap_if_null(ops, task_getpgid); | ||
| 1056 | set_to_cap_if_null(ops, task_getsid); | ||
| 1057 | set_to_cap_if_null(ops, task_getsecid); | ||
| 1058 | set_to_cap_if_null(ops, task_setnice); | ||
| 1059 | set_to_cap_if_null(ops, task_setioprio); | ||
| 1060 | set_to_cap_if_null(ops, task_getioprio); | ||
| 1061 | set_to_cap_if_null(ops, task_setrlimit); | ||
| 1062 | set_to_cap_if_null(ops, task_setscheduler); | ||
| 1063 | set_to_cap_if_null(ops, task_getscheduler); | ||
| 1064 | set_to_cap_if_null(ops, task_movememory); | ||
| 1065 | set_to_cap_if_null(ops, task_wait); | ||
| 1066 | set_to_cap_if_null(ops, task_kill); | ||
| 1067 | set_to_cap_if_null(ops, task_prctl); | ||
| 1068 | set_to_cap_if_null(ops, task_to_inode); | ||
| 1069 | set_to_cap_if_null(ops, ipc_permission); | ||
| 1070 | set_to_cap_if_null(ops, ipc_getsecid); | ||
| 1071 | set_to_cap_if_null(ops, msg_msg_alloc_security); | ||
| 1072 | set_to_cap_if_null(ops, msg_msg_free_security); | ||
| 1073 | set_to_cap_if_null(ops, msg_queue_alloc_security); | ||
| 1074 | set_to_cap_if_null(ops, msg_queue_free_security); | ||
| 1075 | set_to_cap_if_null(ops, msg_queue_associate); | ||
| 1076 | set_to_cap_if_null(ops, msg_queue_msgctl); | ||
| 1077 | set_to_cap_if_null(ops, msg_queue_msgsnd); | ||
| 1078 | set_to_cap_if_null(ops, msg_queue_msgrcv); | ||
| 1079 | set_to_cap_if_null(ops, shm_alloc_security); | ||
| 1080 | set_to_cap_if_null(ops, shm_free_security); | ||
| 1081 | set_to_cap_if_null(ops, shm_associate); | ||
| 1082 | set_to_cap_if_null(ops, shm_shmctl); | ||
| 1083 | set_to_cap_if_null(ops, shm_shmat); | ||
| 1084 | set_to_cap_if_null(ops, sem_alloc_security); | ||
| 1085 | set_to_cap_if_null(ops, sem_free_security); | ||
| 1086 | set_to_cap_if_null(ops, sem_associate); | ||
| 1087 | set_to_cap_if_null(ops, sem_semctl); | ||
| 1088 | set_to_cap_if_null(ops, sem_semop); | ||
| 1089 | set_to_cap_if_null(ops, netlink_send); | ||
| 1090 | set_to_cap_if_null(ops, d_instantiate); | ||
| 1091 | set_to_cap_if_null(ops, getprocattr); | ||
| 1092 | set_to_cap_if_null(ops, setprocattr); | ||
| 1093 | set_to_cap_if_null(ops, ismaclabel); | ||
| 1094 | set_to_cap_if_null(ops, secid_to_secctx); | ||
| 1095 | set_to_cap_if_null(ops, secctx_to_secid); | ||
| 1096 | set_to_cap_if_null(ops, release_secctx); | ||
| 1097 | set_to_cap_if_null(ops, inode_notifysecctx); | ||
| 1098 | set_to_cap_if_null(ops, inode_setsecctx); | ||
| 1099 | set_to_cap_if_null(ops, inode_getsecctx); | ||
| 1100 | #ifdef CONFIG_SECURITY_NETWORK | ||
| 1101 | set_to_cap_if_null(ops, unix_stream_connect); | ||
| 1102 | set_to_cap_if_null(ops, unix_may_send); | ||
| 1103 | set_to_cap_if_null(ops, socket_create); | ||
| 1104 | set_to_cap_if_null(ops, socket_post_create); | ||
| 1105 | set_to_cap_if_null(ops, socket_bind); | ||
| 1106 | set_to_cap_if_null(ops, socket_connect); | ||
| 1107 | set_to_cap_if_null(ops, socket_listen); | ||
| 1108 | set_to_cap_if_null(ops, socket_accept); | ||
| 1109 | set_to_cap_if_null(ops, socket_sendmsg); | ||
| 1110 | set_to_cap_if_null(ops, socket_recvmsg); | ||
| 1111 | set_to_cap_if_null(ops, socket_getsockname); | ||
| 1112 | set_to_cap_if_null(ops, socket_getpeername); | ||
| 1113 | set_to_cap_if_null(ops, socket_setsockopt); | ||
| 1114 | set_to_cap_if_null(ops, socket_getsockopt); | ||
| 1115 | set_to_cap_if_null(ops, socket_shutdown); | ||
| 1116 | set_to_cap_if_null(ops, socket_sock_rcv_skb); | ||
| 1117 | set_to_cap_if_null(ops, socket_getpeersec_stream); | ||
| 1118 | set_to_cap_if_null(ops, socket_getpeersec_dgram); | ||
| 1119 | set_to_cap_if_null(ops, sk_alloc_security); | ||
| 1120 | set_to_cap_if_null(ops, sk_free_security); | ||
| 1121 | set_to_cap_if_null(ops, sk_clone_security); | ||
| 1122 | set_to_cap_if_null(ops, sk_getsecid); | ||
| 1123 | set_to_cap_if_null(ops, sock_graft); | ||
| 1124 | set_to_cap_if_null(ops, inet_conn_request); | ||
| 1125 | set_to_cap_if_null(ops, inet_csk_clone); | ||
| 1126 | set_to_cap_if_null(ops, inet_conn_established); | ||
| 1127 | set_to_cap_if_null(ops, secmark_relabel_packet); | ||
| 1128 | set_to_cap_if_null(ops, secmark_refcount_inc); | ||
| 1129 | set_to_cap_if_null(ops, secmark_refcount_dec); | ||
| 1130 | set_to_cap_if_null(ops, req_classify_flow); | ||
| 1131 | set_to_cap_if_null(ops, tun_dev_alloc_security); | ||
| 1132 | set_to_cap_if_null(ops, tun_dev_free_security); | ||
| 1133 | set_to_cap_if_null(ops, tun_dev_create); | ||
| 1134 | set_to_cap_if_null(ops, tun_dev_open); | ||
| 1135 | set_to_cap_if_null(ops, tun_dev_attach_queue); | ||
| 1136 | set_to_cap_if_null(ops, tun_dev_attach); | ||
| 1137 | set_to_cap_if_null(ops, skb_owned_by); | ||
| 1138 | #endif /* CONFIG_SECURITY_NETWORK */ | ||
| 1139 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | ||
| 1140 | set_to_cap_if_null(ops, xfrm_policy_alloc_security); | ||
| 1141 | set_to_cap_if_null(ops, xfrm_policy_clone_security); | ||
| 1142 | set_to_cap_if_null(ops, xfrm_policy_free_security); | ||
| 1143 | set_to_cap_if_null(ops, xfrm_policy_delete_security); | ||
| 1144 | set_to_cap_if_null(ops, xfrm_state_alloc); | ||
| 1145 | set_to_cap_if_null(ops, xfrm_state_alloc_acquire); | ||
| 1146 | set_to_cap_if_null(ops, xfrm_state_free_security); | ||
| 1147 | set_to_cap_if_null(ops, xfrm_state_delete_security); | ||
| 1148 | set_to_cap_if_null(ops, xfrm_policy_lookup); | ||
| 1149 | set_to_cap_if_null(ops, xfrm_state_pol_flow_match); | ||
| 1150 | set_to_cap_if_null(ops, xfrm_decode_session); | ||
| 1151 | #endif /* CONFIG_SECURITY_NETWORK_XFRM */ | ||
| 1152 | #ifdef CONFIG_KEYS | ||
| 1153 | set_to_cap_if_null(ops, key_alloc); | ||
| 1154 | set_to_cap_if_null(ops, key_free); | ||
| 1155 | set_to_cap_if_null(ops, key_permission); | ||
| 1156 | set_to_cap_if_null(ops, key_getsecurity); | ||
| 1157 | #endif /* CONFIG_KEYS */ | ||
| 1158 | #ifdef CONFIG_AUDIT | ||
| 1159 | set_to_cap_if_null(ops, audit_rule_init); | ||
| 1160 | set_to_cap_if_null(ops, audit_rule_known); | ||
| 1161 | set_to_cap_if_null(ops, audit_rule_match); | ||
| 1162 | set_to_cap_if_null(ops, audit_rule_free); | ||
| 1163 | #endif | ||
| 1164 | } | ||
diff --git a/security/commoncap.c b/security/commoncap.c index f66713bd7450..d103f5a4043d 100644 --- a/security/commoncap.c +++ b/security/commoncap.c | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
| 13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
| 14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
| 15 | #include <linux/security.h> | 15 | #include <linux/lsm_hooks.h> |
| 16 | #include <linux/file.h> | 16 | #include <linux/file.h> |
| 17 | #include <linux/mm.h> | 17 | #include <linux/mm.h> |
| 18 | #include <linux/mman.h> | 18 | #include <linux/mman.h> |
| @@ -53,11 +53,6 @@ static void warn_setuid_and_fcaps_mixed(const char *fname) | |||
| 53 | } | 53 | } |
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | int cap_netlink_send(struct sock *sk, struct sk_buff *skb) | ||
| 57 | { | ||
| 58 | return 0; | ||
| 59 | } | ||
| 60 | |||
| 61 | /** | 56 | /** |
| 62 | * cap_capable - Determine whether a task has a particular effective capability | 57 | * cap_capable - Determine whether a task has a particular effective capability |
| 63 | * @cred: The credentials to use | 58 | * @cred: The credentials to use |
| @@ -297,7 +292,7 @@ static inline void bprm_clear_caps(struct linux_binprm *bprm) | |||
| 297 | */ | 292 | */ |
| 298 | int cap_inode_need_killpriv(struct dentry *dentry) | 293 | int cap_inode_need_killpriv(struct dentry *dentry) |
| 299 | { | 294 | { |
| 300 | struct inode *inode = dentry->d_inode; | 295 | struct inode *inode = d_backing_inode(dentry); |
| 301 | int error; | 296 | int error; |
| 302 | 297 | ||
| 303 | if (!inode->i_op->getxattr) | 298 | if (!inode->i_op->getxattr) |
| @@ -319,7 +314,7 @@ int cap_inode_need_killpriv(struct dentry *dentry) | |||
| 319 | */ | 314 | */ |
| 320 | int cap_inode_killpriv(struct dentry *dentry) | 315 | int cap_inode_killpriv(struct dentry *dentry) |
| 321 | { | 316 | { |
| 322 | struct inode *inode = dentry->d_inode; | 317 | struct inode *inode = d_backing_inode(dentry); |
| 323 | 318 | ||
| 324 | if (!inode->i_op->removexattr) | 319 | if (!inode->i_op->removexattr) |
| 325 | return 0; | 320 | return 0; |
| @@ -375,7 +370,7 @@ static inline int bprm_caps_from_vfs_caps(struct cpu_vfs_cap_data *caps, | |||
| 375 | */ | 370 | */ |
| 376 | int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps) | 371 | int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps) |
| 377 | { | 372 | { |
| 378 | struct inode *inode = dentry->d_inode; | 373 | struct inode *inode = d_backing_inode(dentry); |
| 379 | __u32 magic_etc; | 374 | __u32 magic_etc; |
| 380 | unsigned tocopy, i; | 375 | unsigned tocopy, i; |
| 381 | int size; | 376 | int size; |
| @@ -941,7 +936,7 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, | |||
| 941 | * @pages: The size of the mapping | 936 | * @pages: The size of the mapping |
| 942 | * | 937 | * |
| 943 | * Determine whether the allocation of a new virtual mapping by the current | 938 | * Determine whether the allocation of a new virtual mapping by the current |
| 944 | * task is permitted, returning 0 if permission is granted, -ve if not. | 939 | * task is permitted, returning 1 if permission is granted, 0 if not. |
| 945 | */ | 940 | */ |
| 946 | int cap_vm_enough_memory(struct mm_struct *mm, long pages) | 941 | int cap_vm_enough_memory(struct mm_struct *mm, long pages) |
| 947 | { | 942 | { |
| @@ -950,7 +945,7 @@ int cap_vm_enough_memory(struct mm_struct *mm, long pages) | |||
| 950 | if (cap_capable(current_cred(), &init_user_ns, CAP_SYS_ADMIN, | 945 | if (cap_capable(current_cred(), &init_user_ns, CAP_SYS_ADMIN, |
| 951 | SECURITY_CAP_NOAUDIT) == 0) | 946 | SECURITY_CAP_NOAUDIT) == 0) |
| 952 | cap_sys_admin = 1; | 947 | cap_sys_admin = 1; |
| 953 | return __vm_enough_memory(mm, pages, cap_sys_admin); | 948 | return cap_sys_admin; |
| 954 | } | 949 | } |
| 955 | 950 | ||
| 956 | /* | 951 | /* |
| @@ -981,3 +976,33 @@ int cap_mmap_file(struct file *file, unsigned long reqprot, | |||
| 981 | { | 976 | { |
| 982 | return 0; | 977 | return 0; |
| 983 | } | 978 | } |
| 979 | |||
| 980 | #ifdef CONFIG_SECURITY | ||
| 981 | |||
| 982 | struct security_hook_list capability_hooks[] = { | ||
| 983 | LSM_HOOK_INIT(capable, cap_capable), | ||
| 984 | LSM_HOOK_INIT(settime, cap_settime), | ||
| 985 | LSM_HOOK_INIT(ptrace_access_check, cap_ptrace_access_check), | ||
| 986 | LSM_HOOK_INIT(ptrace_traceme, cap_ptrace_traceme), | ||
| 987 | LSM_HOOK_INIT(capget, cap_capget), | ||
| 988 | LSM_HOOK_INIT(capset, cap_capset), | ||
| 989 | LSM_HOOK_INIT(bprm_set_creds, cap_bprm_set_creds), | ||
| 990 | LSM_HOOK_INIT(bprm_secureexec, cap_bprm_secureexec), | ||
| 991 | LSM_HOOK_INIT(inode_need_killpriv, cap_inode_need_killpriv), | ||
| 992 | LSM_HOOK_INIT(inode_killpriv, cap_inode_killpriv), | ||
| 993 | LSM_HOOK_INIT(mmap_addr, cap_mmap_addr), | ||
| 994 | LSM_HOOK_INIT(mmap_file, cap_mmap_file), | ||
| 995 | LSM_HOOK_INIT(task_fix_setuid, cap_task_fix_setuid), | ||
| 996 | LSM_HOOK_INIT(task_prctl, cap_task_prctl), | ||
| 997 | LSM_HOOK_INIT(task_setscheduler, cap_task_setscheduler), | ||
| 998 | LSM_HOOK_INIT(task_setioprio, cap_task_setioprio), | ||
| 999 | LSM_HOOK_INIT(task_setnice, cap_task_setnice), | ||
| 1000 | LSM_HOOK_INIT(vm_enough_memory, cap_vm_enough_memory), | ||
| 1001 | }; | ||
| 1002 | |||
| 1003 | void __init capability_add_hooks(void) | ||
| 1004 | { | ||
| 1005 | security_add_hooks(capability_hooks, ARRAY_SIZE(capability_hooks)); | ||
| 1006 | } | ||
| 1007 | |||
| 1008 | #endif /* CONFIG_SECURITY */ | ||
diff --git a/security/inode.c b/security/inode.c index 131a3c49f766..16622aef9bde 100644 --- a/security/inode.c +++ b/security/inode.c | |||
| @@ -25,11 +25,6 @@ | |||
| 25 | static struct vfsmount *mount; | 25 | static struct vfsmount *mount; |
| 26 | static int mount_count; | 26 | static int mount_count; |
| 27 | 27 | ||
| 28 | static inline int positive(struct dentry *dentry) | ||
| 29 | { | ||
| 30 | return dentry->d_inode && !d_unhashed(dentry); | ||
| 31 | } | ||
| 32 | |||
| 33 | static int fill_super(struct super_block *sb, void *data, int silent) | 28 | static int fill_super(struct super_block *sb, void *data, int silent) |
| 34 | { | 29 | { |
| 35 | static struct tree_descr files[] = {{""}}; | 30 | static struct tree_descr files[] = {{""}}; |
| @@ -102,14 +97,14 @@ struct dentry *securityfs_create_file(const char *name, umode_t mode, | |||
| 102 | if (!parent) | 97 | if (!parent) |
| 103 | parent = mount->mnt_root; | 98 | parent = mount->mnt_root; |
| 104 | 99 | ||
| 105 | dir = parent->d_inode; | 100 | dir = d_inode(parent); |
| 106 | 101 | ||
| 107 | mutex_lock(&dir->i_mutex); | 102 | mutex_lock(&dir->i_mutex); |
| 108 | dentry = lookup_one_len(name, parent, strlen(name)); | 103 | dentry = lookup_one_len(name, parent, strlen(name)); |
| 109 | if (IS_ERR(dentry)) | 104 | if (IS_ERR(dentry)) |
| 110 | goto out; | 105 | goto out; |
| 111 | 106 | ||
| 112 | if (dentry->d_inode) { | 107 | if (d_really_is_positive(dentry)) { |
| 113 | error = -EEXIST; | 108 | error = -EEXIST; |
| 114 | goto out1; | 109 | goto out1; |
| 115 | } | 110 | } |
| @@ -197,37 +192,33 @@ void securityfs_remove(struct dentry *dentry) | |||
| 197 | return; | 192 | return; |
| 198 | 193 | ||
| 199 | parent = dentry->d_parent; | 194 | parent = dentry->d_parent; |
| 200 | if (!parent || !parent->d_inode) | 195 | if (!parent || d_really_is_negative(parent)) |
| 201 | return; | 196 | return; |
| 202 | 197 | ||
| 203 | mutex_lock(&parent->d_inode->i_mutex); | 198 | mutex_lock(&d_inode(parent)->i_mutex); |
| 204 | if (positive(dentry)) { | 199 | if (simple_positive(dentry)) { |
| 205 | if (dentry->d_inode) { | 200 | if (d_is_dir(dentry)) |
| 206 | if (d_is_dir(dentry)) | 201 | simple_rmdir(d_inode(parent), dentry); |
| 207 | simple_rmdir(parent->d_inode, dentry); | 202 | else |
| 208 | else | 203 | simple_unlink(d_inode(parent), dentry); |
| 209 | simple_unlink(parent->d_inode, dentry); | 204 | dput(dentry); |
| 210 | dput(dentry); | ||
| 211 | } | ||
| 212 | } | 205 | } |
| 213 | mutex_unlock(&parent->d_inode->i_mutex); | 206 | mutex_unlock(&d_inode(parent)->i_mutex); |
| 214 | simple_release_fs(&mount, &mount_count); | 207 | simple_release_fs(&mount, &mount_count); |
| 215 | } | 208 | } |
| 216 | EXPORT_SYMBOL_GPL(securityfs_remove); | 209 | EXPORT_SYMBOL_GPL(securityfs_remove); |
| 217 | 210 | ||
| 218 | static struct kobject *security_kobj; | ||
| 219 | |||
| 220 | static int __init securityfs_init(void) | 211 | static int __init securityfs_init(void) |
| 221 | { | 212 | { |
| 222 | int retval; | 213 | int retval; |
| 223 | 214 | ||
| 224 | security_kobj = kobject_create_and_add("security", kernel_kobj); | 215 | retval = sysfs_create_mount_point(kernel_kobj, "security"); |
| 225 | if (!security_kobj) | 216 | if (retval) |
| 226 | return -EINVAL; | 217 | return retval; |
| 227 | 218 | ||
| 228 | retval = register_filesystem(&fs_type); | 219 | retval = register_filesystem(&fs_type); |
| 229 | if (retval) | 220 | if (retval) |
| 230 | kobject_put(security_kobj); | 221 | sysfs_remove_mount_point(kernel_kobj, "security"); |
| 231 | return retval; | 222 | return retval; |
| 232 | } | 223 | } |
| 233 | 224 | ||
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c index 5e3bd72b299a..36fb6b527829 100644 --- a/security/integrity/digsig.c +++ b/security/integrity/digsig.c | |||
| @@ -85,7 +85,7 @@ int __init integrity_init_keyring(const unsigned int id) | |||
| 85 | return err; | 85 | return err; |
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | int __init integrity_load_x509(const unsigned int id, char *path) | 88 | int __init integrity_load_x509(const unsigned int id, const char *path) |
| 89 | { | 89 | { |
| 90 | key_ref_t key; | 90 | key_ref_t key; |
| 91 | char *data; | 91 | char *data; |
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c index 5e9687f02e1b..159ef3ea4130 100644 --- a/security/integrity/evm/evm_crypto.c +++ b/security/integrity/evm/evm_crypto.c | |||
| @@ -131,7 +131,7 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry, | |||
| 131 | size_t req_xattr_value_len, | 131 | size_t req_xattr_value_len, |
| 132 | char type, char *digest) | 132 | char type, char *digest) |
| 133 | { | 133 | { |
| 134 | struct inode *inode = dentry->d_inode; | 134 | struct inode *inode = d_backing_inode(dentry); |
| 135 | struct shash_desc *desc; | 135 | struct shash_desc *desc; |
| 136 | char **xattrname; | 136 | char **xattrname; |
| 137 | size_t xattr_size = 0; | 137 | size_t xattr_size = 0; |
| @@ -199,7 +199,7 @@ int evm_calc_hash(struct dentry *dentry, const char *req_xattr_name, | |||
| 199 | int evm_update_evmxattr(struct dentry *dentry, const char *xattr_name, | 199 | int evm_update_evmxattr(struct dentry *dentry, const char *xattr_name, |
| 200 | const char *xattr_value, size_t xattr_value_len) | 200 | const char *xattr_value, size_t xattr_value_len) |
| 201 | { | 201 | { |
| 202 | struct inode *inode = dentry->d_inode; | 202 | struct inode *inode = d_backing_inode(dentry); |
| 203 | struct evm_ima_xattr_data xattr_data; | 203 | struct evm_ima_xattr_data xattr_data; |
| 204 | int rc = 0; | 204 | int rc = 0; |
| 205 | 205 | ||
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c index f589c9a05da2..1334e02ae8f4 100644 --- a/security/integrity/evm/evm_main.c +++ b/security/integrity/evm/evm_main.c | |||
| @@ -72,7 +72,7 @@ static void __init evm_init_config(void) | |||
| 72 | 72 | ||
| 73 | static int evm_find_protected_xattrs(struct dentry *dentry) | 73 | static int evm_find_protected_xattrs(struct dentry *dentry) |
| 74 | { | 74 | { |
| 75 | struct inode *inode = dentry->d_inode; | 75 | struct inode *inode = d_backing_inode(dentry); |
| 76 | char **xattr; | 76 | char **xattr; |
| 77 | int error; | 77 | int error; |
| 78 | int count = 0; | 78 | int count = 0; |
| @@ -165,8 +165,8 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry, | |||
| 165 | /* Replace RSA with HMAC if not mounted readonly and | 165 | /* Replace RSA with HMAC if not mounted readonly and |
| 166 | * not immutable | 166 | * not immutable |
| 167 | */ | 167 | */ |
| 168 | if (!IS_RDONLY(dentry->d_inode) && | 168 | if (!IS_RDONLY(d_backing_inode(dentry)) && |
| 169 | !IS_IMMUTABLE(dentry->d_inode)) | 169 | !IS_IMMUTABLE(d_backing_inode(dentry))) |
| 170 | evm_update_evmxattr(dentry, xattr_name, | 170 | evm_update_evmxattr(dentry, xattr_name, |
| 171 | xattr_value, | 171 | xattr_value, |
| 172 | xattr_value_len); | 172 | xattr_value_len); |
| @@ -235,7 +235,7 @@ enum integrity_status evm_verifyxattr(struct dentry *dentry, | |||
| 235 | return INTEGRITY_UNKNOWN; | 235 | return INTEGRITY_UNKNOWN; |
| 236 | 236 | ||
| 237 | if (!iint) { | 237 | if (!iint) { |
| 238 | iint = integrity_iint_find(dentry->d_inode); | 238 | iint = integrity_iint_find(d_backing_inode(dentry)); |
| 239 | if (!iint) | 239 | if (!iint) |
| 240 | return INTEGRITY_UNKNOWN; | 240 | return INTEGRITY_UNKNOWN; |
| 241 | } | 241 | } |
| @@ -253,7 +253,7 @@ EXPORT_SYMBOL_GPL(evm_verifyxattr); | |||
| 253 | */ | 253 | */ |
| 254 | static enum integrity_status evm_verify_current_integrity(struct dentry *dentry) | 254 | static enum integrity_status evm_verify_current_integrity(struct dentry *dentry) |
| 255 | { | 255 | { |
| 256 | struct inode *inode = dentry->d_inode; | 256 | struct inode *inode = d_backing_inode(dentry); |
| 257 | 257 | ||
| 258 | if (!evm_initialized || !S_ISREG(inode->i_mode) || evm_fixmode) | 258 | if (!evm_initialized || !S_ISREG(inode->i_mode) || evm_fixmode) |
| 259 | return 0; | 259 | return 0; |
| @@ -293,13 +293,24 @@ static int evm_protect_xattr(struct dentry *dentry, const char *xattr_name, | |||
| 293 | if (evm_status == INTEGRITY_NOXATTRS) { | 293 | if (evm_status == INTEGRITY_NOXATTRS) { |
| 294 | struct integrity_iint_cache *iint; | 294 | struct integrity_iint_cache *iint; |
| 295 | 295 | ||
| 296 | iint = integrity_iint_find(dentry->d_inode); | 296 | iint = integrity_iint_find(d_backing_inode(dentry)); |
| 297 | if (iint && (iint->flags & IMA_NEW_FILE)) | 297 | if (iint && (iint->flags & IMA_NEW_FILE)) |
| 298 | return 0; | 298 | return 0; |
| 299 | |||
| 300 | /* exception for pseudo filesystems */ | ||
| 301 | if (dentry->d_inode->i_sb->s_magic == TMPFS_MAGIC | ||
| 302 | || dentry->d_inode->i_sb->s_magic == SYSFS_MAGIC) | ||
| 303 | return 0; | ||
| 304 | |||
| 305 | integrity_audit_msg(AUDIT_INTEGRITY_METADATA, | ||
| 306 | dentry->d_inode, dentry->d_name.name, | ||
| 307 | "update_metadata", | ||
| 308 | integrity_status_msg[evm_status], | ||
| 309 | -EPERM, 0); | ||
| 299 | } | 310 | } |
| 300 | out: | 311 | out: |
| 301 | if (evm_status != INTEGRITY_PASS) | 312 | if (evm_status != INTEGRITY_PASS) |
| 302 | integrity_audit_msg(AUDIT_INTEGRITY_METADATA, dentry->d_inode, | 313 | integrity_audit_msg(AUDIT_INTEGRITY_METADATA, d_backing_inode(dentry), |
| 303 | dentry->d_name.name, "appraise_metadata", | 314 | dentry->d_name.name, "appraise_metadata", |
| 304 | integrity_status_msg[evm_status], | 315 | integrity_status_msg[evm_status], |
| 305 | -EPERM, 0); | 316 | -EPERM, 0); |
| @@ -376,17 +387,16 @@ void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name, | |||
| 376 | * @xattr_name: pointer to the affected extended attribute name | 387 | * @xattr_name: pointer to the affected extended attribute name |
| 377 | * | 388 | * |
| 378 | * Update the HMAC stored in 'security.evm' to reflect removal of the xattr. | 389 | * Update the HMAC stored in 'security.evm' to reflect removal of the xattr. |
| 390 | * | ||
| 391 | * No need to take the i_mutex lock here, as this function is called from | ||
| 392 | * vfs_removexattr() which takes the i_mutex. | ||
| 379 | */ | 393 | */ |
| 380 | void evm_inode_post_removexattr(struct dentry *dentry, const char *xattr_name) | 394 | void evm_inode_post_removexattr(struct dentry *dentry, const char *xattr_name) |
| 381 | { | 395 | { |
| 382 | struct inode *inode = dentry->d_inode; | ||
| 383 | |||
| 384 | if (!evm_initialized || !evm_protected_xattr(xattr_name)) | 396 | if (!evm_initialized || !evm_protected_xattr(xattr_name)) |
| 385 | return; | 397 | return; |
| 386 | 398 | ||
| 387 | mutex_lock(&inode->i_mutex); | ||
| 388 | evm_update_evmxattr(dentry, xattr_name, NULL, 0); | 399 | evm_update_evmxattr(dentry, xattr_name, NULL, 0); |
| 389 | mutex_unlock(&inode->i_mutex); | ||
| 390 | } | 400 | } |
| 391 | 401 | ||
| 392 | /** | 402 | /** |
| @@ -404,7 +414,7 @@ int evm_inode_setattr(struct dentry *dentry, struct iattr *attr) | |||
| 404 | if ((evm_status == INTEGRITY_PASS) || | 414 | if ((evm_status == INTEGRITY_PASS) || |
| 405 | (evm_status == INTEGRITY_NOXATTRS)) | 415 | (evm_status == INTEGRITY_NOXATTRS)) |
| 406 | return 0; | 416 | return 0; |
| 407 | integrity_audit_msg(AUDIT_INTEGRITY_METADATA, dentry->d_inode, | 417 | integrity_audit_msg(AUDIT_INTEGRITY_METADATA, d_backing_inode(dentry), |
| 408 | dentry->d_name.name, "appraise_metadata", | 418 | dentry->d_name.name, "appraise_metadata", |
| 409 | integrity_status_msg[evm_status], -EPERM, 0); | 419 | integrity_status_msg[evm_status], -EPERM, 0); |
| 410 | return -EPERM; | 420 | return -EPERM; |
diff --git a/security/integrity/iint.c b/security/integrity/iint.c index dbb6d141c3db..3d2f5b45c8cb 100644 --- a/security/integrity/iint.c +++ b/security/integrity/iint.c | |||
| @@ -213,6 +213,9 @@ int __init integrity_read_file(const char *path, char **data) | |||
| 213 | char *buf; | 213 | char *buf; |
| 214 | int rc = -EINVAL; | 214 | int rc = -EINVAL; |
| 215 | 215 | ||
| 216 | if (!path || !*path) | ||
| 217 | return -EINVAL; | ||
| 218 | |||
| 216 | file = filp_open(path, O_RDONLY, 0); | 219 | file = filp_open(path, O_RDONLY, 0); |
| 217 | if (IS_ERR(file)) { | 220 | if (IS_ERR(file)) { |
| 218 | rc = PTR_ERR(file); | 221 | rc = PTR_ERR(file); |
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 8ee997dff139..e2a60c30df44 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h | |||
| @@ -52,6 +52,16 @@ extern int ima_used_chip; | |||
| 52 | extern int ima_hash_algo; | 52 | extern int ima_hash_algo; |
| 53 | extern int ima_appraise; | 53 | extern int ima_appraise; |
| 54 | 54 | ||
| 55 | /* IMA event related data */ | ||
| 56 | struct ima_event_data { | ||
| 57 | struct integrity_iint_cache *iint; | ||
| 58 | struct file *file; | ||
| 59 | const unsigned char *filename; | ||
| 60 | struct evm_ima_xattr_data *xattr_value; | ||
| 61 | int xattr_len; | ||
| 62 | const char *violation; | ||
| 63 | }; | ||
| 64 | |||
| 55 | /* IMA template field data definition */ | 65 | /* IMA template field data definition */ |
| 56 | struct ima_field_data { | 66 | struct ima_field_data { |
| 57 | u8 *data; | 67 | u8 *data; |
| @@ -61,12 +71,10 @@ struct ima_field_data { | |||
| 61 | /* IMA template field definition */ | 71 | /* IMA template field definition */ |
| 62 | struct ima_template_field { | 72 | struct ima_template_field { |
| 63 | const char field_id[IMA_TEMPLATE_FIELD_ID_MAX_LEN]; | 73 | const char field_id[IMA_TEMPLATE_FIELD_ID_MAX_LEN]; |
| 64 | int (*field_init) (struct integrity_iint_cache *iint, struct file *file, | 74 | int (*field_init)(struct ima_event_data *event_data, |
| 65 | const unsigned char *filename, | 75 | struct ima_field_data *field_data); |
| 66 | struct evm_ima_xattr_data *xattr_value, | 76 | void (*field_show)(struct seq_file *m, enum ima_show_type show, |
| 67 | int xattr_len, struct ima_field_data *field_data); | 77 | struct ima_field_data *field_data); |
| 68 | void (*field_show) (struct seq_file *m, enum ima_show_type show, | ||
| 69 | struct ima_field_data *field_data); | ||
| 70 | }; | 78 | }; |
| 71 | 79 | ||
| 72 | /* IMA template descriptor definition */ | 80 | /* IMA template descriptor definition */ |
| @@ -103,10 +111,11 @@ int ima_calc_field_array_hash(struct ima_field_data *field_data, | |||
| 103 | struct ima_digest_data *hash); | 111 | struct ima_digest_data *hash); |
| 104 | int __init ima_calc_boot_aggregate(struct ima_digest_data *hash); | 112 | int __init ima_calc_boot_aggregate(struct ima_digest_data *hash); |
| 105 | void ima_add_violation(struct file *file, const unsigned char *filename, | 113 | void ima_add_violation(struct file *file, const unsigned char *filename, |
| 114 | struct integrity_iint_cache *iint, | ||
| 106 | const char *op, const char *cause); | 115 | const char *op, const char *cause); |
| 107 | int ima_init_crypto(void); | 116 | int ima_init_crypto(void); |
| 108 | void ima_putc(struct seq_file *m, void *data, int datalen); | 117 | void ima_putc(struct seq_file *m, void *data, int datalen); |
| 109 | void ima_print_digest(struct seq_file *m, u8 *digest, int size); | 118 | void ima_print_digest(struct seq_file *m, u8 *digest, u32 size); |
| 110 | struct ima_template_desc *ima_template_desc_current(void); | 119 | struct ima_template_desc *ima_template_desc_current(void); |
| 111 | int ima_init_template(void); | 120 | int ima_init_template(void); |
| 112 | 121 | ||
| @@ -140,10 +149,8 @@ void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file, | |||
| 140 | int xattr_len); | 149 | int xattr_len); |
| 141 | void ima_audit_measurement(struct integrity_iint_cache *iint, | 150 | void ima_audit_measurement(struct integrity_iint_cache *iint, |
| 142 | const unsigned char *filename); | 151 | const unsigned char *filename); |
| 143 | int ima_alloc_init_template(struct integrity_iint_cache *iint, | 152 | int ima_alloc_init_template(struct ima_event_data *event_data, |
| 144 | struct file *file, const unsigned char *filename, | 153 | struct ima_template_entry **entry); |
| 145 | struct evm_ima_xattr_data *xattr_value, | ||
| 146 | int xattr_len, struct ima_template_entry **entry); | ||
| 147 | int ima_store_template(struct ima_template_entry *entry, int violation, | 154 | int ima_store_template(struct ima_template_entry *entry, int violation, |
| 148 | struct inode *inode, const unsigned char *filename); | 155 | struct inode *inode, const unsigned char *filename); |
| 149 | void ima_free_template_entry(struct ima_template_entry *entry); | 156 | void ima_free_template_entry(struct ima_template_entry *entry); |
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c index b8a27c5052d4..1d950fbb2aec 100644 --- a/security/integrity/ima/ima_api.c +++ b/security/integrity/ima/ima_api.c | |||
| @@ -37,10 +37,8 @@ void ima_free_template_entry(struct ima_template_entry *entry) | |||
| 37 | /* | 37 | /* |
| 38 | * ima_alloc_init_template - create and initialize a new template entry | 38 | * ima_alloc_init_template - create and initialize a new template entry |
| 39 | */ | 39 | */ |
| 40 | int ima_alloc_init_template(struct integrity_iint_cache *iint, | 40 | int ima_alloc_init_template(struct ima_event_data *event_data, |
| 41 | struct file *file, const unsigned char *filename, | 41 | struct ima_template_entry **entry) |
| 42 | struct evm_ima_xattr_data *xattr_value, | ||
| 43 | int xattr_len, struct ima_template_entry **entry) | ||
| 44 | { | 42 | { |
| 45 | struct ima_template_desc *template_desc = ima_template_desc_current(); | 43 | struct ima_template_desc *template_desc = ima_template_desc_current(); |
| 46 | int i, result = 0; | 44 | int i, result = 0; |
| @@ -55,8 +53,7 @@ int ima_alloc_init_template(struct integrity_iint_cache *iint, | |||
| 55 | struct ima_template_field *field = template_desc->fields[i]; | 53 | struct ima_template_field *field = template_desc->fields[i]; |
| 56 | u32 len; | 54 | u32 len; |
| 57 | 55 | ||
| 58 | result = field->field_init(iint, file, filename, | 56 | result = field->field_init(event_data, |
| 59 | xattr_value, xattr_len, | ||
| 60 | &((*entry)->template_data[i])); | 57 | &((*entry)->template_data[i])); |
| 61 | if (result != 0) | 58 | if (result != 0) |
| 62 | goto out; | 59 | goto out; |
| @@ -129,18 +126,20 @@ int ima_store_template(struct ima_template_entry *entry, | |||
| 129 | * value is invalidated. | 126 | * value is invalidated. |
| 130 | */ | 127 | */ |
| 131 | void ima_add_violation(struct file *file, const unsigned char *filename, | 128 | void ima_add_violation(struct file *file, const unsigned char *filename, |
| 129 | struct integrity_iint_cache *iint, | ||
| 132 | const char *op, const char *cause) | 130 | const char *op, const char *cause) |
| 133 | { | 131 | { |
| 134 | struct ima_template_entry *entry; | 132 | struct ima_template_entry *entry; |
| 135 | struct inode *inode = file_inode(file); | 133 | struct inode *inode = file_inode(file); |
| 134 | struct ima_event_data event_data = {iint, file, filename, NULL, 0, | ||
| 135 | cause}; | ||
| 136 | int violation = 1; | 136 | int violation = 1; |
| 137 | int result; | 137 | int result; |
| 138 | 138 | ||
| 139 | /* can overflow, only indicator */ | 139 | /* can overflow, only indicator */ |
| 140 | atomic_long_inc(&ima_htable.violations); | 140 | atomic_long_inc(&ima_htable.violations); |
| 141 | 141 | ||
| 142 | result = ima_alloc_init_template(NULL, file, filename, | 142 | result = ima_alloc_init_template(&event_data, &entry); |
| 143 | NULL, 0, &entry); | ||
| 144 | if (result < 0) { | 143 | if (result < 0) { |
| 145 | result = -ENOMEM; | 144 | result = -ENOMEM; |
| 146 | goto err_out; | 145 | goto err_out; |
| @@ -267,13 +266,14 @@ void ima_store_measurement(struct integrity_iint_cache *iint, | |||
| 267 | int result = -ENOMEM; | 266 | int result = -ENOMEM; |
| 268 | struct inode *inode = file_inode(file); | 267 | struct inode *inode = file_inode(file); |
| 269 | struct ima_template_entry *entry; | 268 | struct ima_template_entry *entry; |
| 269 | struct ima_event_data event_data = {iint, file, filename, xattr_value, | ||
| 270 | xattr_len, NULL}; | ||
| 270 | int violation = 0; | 271 | int violation = 0; |
| 271 | 272 | ||
| 272 | if (iint->flags & IMA_MEASURED) | 273 | if (iint->flags & IMA_MEASURED) |
| 273 | return; | 274 | return; |
| 274 | 275 | ||
| 275 | result = ima_alloc_init_template(iint, file, filename, | 276 | result = ima_alloc_init_template(&event_data, &entry); |
| 276 | xattr_value, xattr_len, &entry); | ||
| 277 | if (result < 0) { | 277 | if (result < 0) { |
| 278 | integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename, | 278 | integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename, |
| 279 | op, audit_cause, result, 0); | 279 | op, audit_cause, result, 0); |
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index fffcdb0b31f0..1873b5536f80 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c | |||
| @@ -165,7 +165,7 @@ void ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, int xattr_len, | |||
| 165 | int ima_read_xattr(struct dentry *dentry, | 165 | int ima_read_xattr(struct dentry *dentry, |
| 166 | struct evm_ima_xattr_data **xattr_value) | 166 | struct evm_ima_xattr_data **xattr_value) |
| 167 | { | 167 | { |
| 168 | struct inode *inode = dentry->d_inode; | 168 | struct inode *inode = d_backing_inode(dentry); |
| 169 | 169 | ||
| 170 | if (!inode->i_op->getxattr) | 170 | if (!inode->i_op->getxattr) |
| 171 | return 0; | 171 | return 0; |
| @@ -190,7 +190,7 @@ int ima_appraise_measurement(int func, struct integrity_iint_cache *iint, | |||
| 190 | static const char op[] = "appraise_data"; | 190 | static const char op[] = "appraise_data"; |
| 191 | char *cause = "unknown"; | 191 | char *cause = "unknown"; |
| 192 | struct dentry *dentry = file->f_path.dentry; | 192 | struct dentry *dentry = file->f_path.dentry; |
| 193 | struct inode *inode = dentry->d_inode; | 193 | struct inode *inode = d_backing_inode(dentry); |
| 194 | enum integrity_status status = INTEGRITY_UNKNOWN; | 194 | enum integrity_status status = INTEGRITY_UNKNOWN; |
| 195 | int rc = xattr_len, hash_start = 0; | 195 | int rc = xattr_len, hash_start = 0; |
| 196 | 196 | ||
| @@ -314,7 +314,7 @@ void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file) | |||
| 314 | */ | 314 | */ |
| 315 | void ima_inode_post_setattr(struct dentry *dentry) | 315 | void ima_inode_post_setattr(struct dentry *dentry) |
| 316 | { | 316 | { |
| 317 | struct inode *inode = dentry->d_inode; | 317 | struct inode *inode = d_backing_inode(dentry); |
| 318 | struct integrity_iint_cache *iint; | 318 | struct integrity_iint_cache *iint; |
| 319 | int must_appraise, rc; | 319 | int must_appraise, rc; |
| 320 | 320 | ||
| @@ -378,10 +378,14 @@ int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name, | |||
| 378 | result = ima_protect_xattr(dentry, xattr_name, xattr_value, | 378 | result = ima_protect_xattr(dentry, xattr_name, xattr_value, |
| 379 | xattr_value_len); | 379 | xattr_value_len); |
| 380 | if (result == 1) { | 380 | if (result == 1) { |
| 381 | bool digsig; | ||
| 382 | |||
| 381 | if (!xattr_value_len || (xvalue->type >= IMA_XATTR_LAST)) | 383 | if (!xattr_value_len || (xvalue->type >= IMA_XATTR_LAST)) |
| 382 | return -EINVAL; | 384 | return -EINVAL; |
| 383 | ima_reset_appraise_flags(dentry->d_inode, | 385 | digsig = (xvalue->type == EVM_IMA_XATTR_DIGSIG); |
| 384 | (xvalue->type == EVM_IMA_XATTR_DIGSIG) ? 1 : 0); | 386 | if (!digsig && (ima_appraise & IMA_APPRAISE_ENFORCE)) |
| 387 | return -EPERM; | ||
| 388 | ima_reset_appraise_flags(d_backing_inode(dentry), digsig); | ||
| 385 | result = 0; | 389 | result = 0; |
| 386 | } | 390 | } |
| 387 | return result; | 391 | return result; |
| @@ -393,7 +397,7 @@ int ima_inode_removexattr(struct dentry *dentry, const char *xattr_name) | |||
| 393 | 397 | ||
| 394 | result = ima_protect_xattr(dentry, xattr_name, NULL, 0); | 398 | result = ima_protect_xattr(dentry, xattr_name, NULL, 0); |
| 395 | if (result == 1) { | 399 | if (result == 1) { |
| 396 | ima_reset_appraise_flags(dentry->d_inode, 0); | 400 | ima_reset_appraise_flags(d_backing_inode(dentry), 0); |
| 397 | result = 0; | 401 | result = 0; |
| 398 | } | 402 | } |
| 399 | return result; | 403 | return result; |
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c index 686355fea7fd..e24121afb2f2 100644 --- a/security/integrity/ima/ima_crypto.c +++ b/security/integrity/ima/ima_crypto.c | |||
| @@ -55,7 +55,7 @@ static int param_set_bufsize(const char *val, const struct kernel_param *kp) | |||
| 55 | return 0; | 55 | return 0; |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | static struct kernel_param_ops param_ops_bufsize = { | 58 | static const struct kernel_param_ops param_ops_bufsize = { |
| 59 | .set = param_set_bufsize, | 59 | .set = param_set_bufsize, |
| 60 | .get = param_get_uint, | 60 | .get = param_get_uint, |
| 61 | }; | 61 | }; |
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c index 461215e5fd31..816d175da79a 100644 --- a/security/integrity/ima/ima_fs.c +++ b/security/integrity/ima/ima_fs.c | |||
| @@ -190,9 +190,9 @@ static const struct file_operations ima_measurements_ops = { | |||
| 190 | .release = seq_release, | 190 | .release = seq_release, |
| 191 | }; | 191 | }; |
| 192 | 192 | ||
| 193 | void ima_print_digest(struct seq_file *m, u8 *digest, int size) | 193 | void ima_print_digest(struct seq_file *m, u8 *digest, u32 size) |
| 194 | { | 194 | { |
| 195 | int i; | 195 | u32 i; |
| 196 | 196 | ||
| 197 | for (i = 0; i < size; i++) | 197 | for (i = 0; i < size; i++) |
| 198 | seq_printf(m, "%02x", *(digest + i)); | 198 | seq_printf(m, "%02x", *(digest + i)); |
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c index 5e4c29d174ee..e600cadd231c 100644 --- a/security/integrity/ima/ima_init.c +++ b/security/integrity/ima/ima_init.c | |||
| @@ -24,12 +24,6 @@ | |||
| 24 | #include <crypto/hash_info.h> | 24 | #include <crypto/hash_info.h> |
| 25 | #include "ima.h" | 25 | #include "ima.h" |
| 26 | 26 | ||
| 27 | #ifdef CONFIG_IMA_X509_PATH | ||
| 28 | #define IMA_X509_PATH CONFIG_IMA_X509_PATH | ||
| 29 | #else | ||
| 30 | #define IMA_X509_PATH "/etc/keys/x509_ima.der" | ||
| 31 | #endif | ||
| 32 | |||
| 33 | /* name for boot aggregate entry */ | 27 | /* name for boot aggregate entry */ |
| 34 | static const char *boot_aggregate_name = "boot_aggregate"; | 28 | static const char *boot_aggregate_name = "boot_aggregate"; |
| 35 | int ima_used_chip; | 29 | int ima_used_chip; |
| @@ -55,6 +49,8 @@ static int __init ima_add_boot_aggregate(void) | |||
| 55 | const char *audit_cause = "ENOMEM"; | 49 | const char *audit_cause = "ENOMEM"; |
| 56 | struct ima_template_entry *entry; | 50 | struct ima_template_entry *entry; |
| 57 | struct integrity_iint_cache tmp_iint, *iint = &tmp_iint; | 51 | struct integrity_iint_cache tmp_iint, *iint = &tmp_iint; |
| 52 | struct ima_event_data event_data = {iint, NULL, boot_aggregate_name, | ||
| 53 | NULL, 0, NULL}; | ||
| 58 | int result = -ENOMEM; | 54 | int result = -ENOMEM; |
| 59 | int violation = 0; | 55 | int violation = 0; |
| 60 | struct { | 56 | struct { |
| @@ -76,8 +72,7 @@ static int __init ima_add_boot_aggregate(void) | |||
| 76 | } | 72 | } |
| 77 | } | 73 | } |
| 78 | 74 | ||
| 79 | result = ima_alloc_init_template(iint, NULL, boot_aggregate_name, | 75 | result = ima_alloc_init_template(&event_data, &entry); |
| 80 | NULL, 0, &entry); | ||
| 81 | if (result < 0) { | 76 | if (result < 0) { |
| 82 | audit_cause = "alloc_entry"; | 77 | audit_cause = "alloc_entry"; |
| 83 | goto err_out; | 78 | goto err_out; |
| @@ -103,7 +98,7 @@ void __init ima_load_x509(void) | |||
| 103 | int unset_flags = ima_policy_flag & IMA_APPRAISE; | 98 | int unset_flags = ima_policy_flag & IMA_APPRAISE; |
| 104 | 99 | ||
| 105 | ima_policy_flag &= ~unset_flags; | 100 | ima_policy_flag &= ~unset_flags; |
| 106 | integrity_load_x509(INTEGRITY_KEYRING_IMA, IMA_X509_PATH); | 101 | integrity_load_x509(INTEGRITY_KEYRING_IMA, CONFIG_IMA_X509_PATH); |
| 107 | ima_policy_flag |= unset_flags; | 102 | ima_policy_flag |= unset_flags; |
| 108 | } | 103 | } |
| 109 | #endif | 104 | #endif |
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index eeee00dce729..c21f09bf8b99 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c | |||
| @@ -106,9 +106,10 @@ static void ima_rdwr_violation_check(struct file *file, | |||
| 106 | *pathname = ima_d_path(&file->f_path, pathbuf); | 106 | *pathname = ima_d_path(&file->f_path, pathbuf); |
| 107 | 107 | ||
| 108 | if (send_tomtou) | 108 | if (send_tomtou) |
| 109 | ima_add_violation(file, *pathname, "invalid_pcr", "ToMToU"); | 109 | ima_add_violation(file, *pathname, iint, |
| 110 | "invalid_pcr", "ToMToU"); | ||
| 110 | if (send_writers) | 111 | if (send_writers) |
| 111 | ima_add_violation(file, *pathname, | 112 | ima_add_violation(file, *pathname, iint, |
| 112 | "invalid_pcr", "open_writers"); | 113 | "invalid_pcr", "open_writers"); |
| 113 | } | 114 | } |
| 114 | 115 | ||
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index d1eefb9d65fb..3997e206f82d 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c | |||
| @@ -27,6 +27,8 @@ | |||
| 27 | #define IMA_UID 0x0008 | 27 | #define IMA_UID 0x0008 |
| 28 | #define IMA_FOWNER 0x0010 | 28 | #define IMA_FOWNER 0x0010 |
| 29 | #define IMA_FSUUID 0x0020 | 29 | #define IMA_FSUUID 0x0020 |
| 30 | #define IMA_INMASK 0x0040 | ||
| 31 | #define IMA_EUID 0x0080 | ||
| 30 | 32 | ||
| 31 | #define UNKNOWN 0 | 33 | #define UNKNOWN 0 |
| 32 | #define MEASURE 0x0001 /* same as IMA_MEASURE */ | 34 | #define MEASURE 0x0001 /* same as IMA_MEASURE */ |
| @@ -42,6 +44,8 @@ enum lsm_rule_types { LSM_OBJ_USER, LSM_OBJ_ROLE, LSM_OBJ_TYPE, | |||
| 42 | LSM_SUBJ_USER, LSM_SUBJ_ROLE, LSM_SUBJ_TYPE | 44 | LSM_SUBJ_USER, LSM_SUBJ_ROLE, LSM_SUBJ_TYPE |
| 43 | }; | 45 | }; |
| 44 | 46 | ||
| 47 | enum policy_types { ORIGINAL_TCB = 1, DEFAULT_TCB }; | ||
| 48 | |||
| 45 | struct ima_rule_entry { | 49 | struct ima_rule_entry { |
| 46 | struct list_head list; | 50 | struct list_head list; |
| 47 | int action; | 51 | int action; |
| @@ -70,7 +74,7 @@ struct ima_rule_entry { | |||
| 70 | * normal users can easily run the machine out of memory simply building | 74 | * normal users can easily run the machine out of memory simply building |
| 71 | * and running executables. | 75 | * and running executables. |
| 72 | */ | 76 | */ |
| 73 | static struct ima_rule_entry default_rules[] = { | 77 | static struct ima_rule_entry dont_measure_rules[] = { |
| 74 | {.action = DONT_MEASURE, .fsmagic = PROC_SUPER_MAGIC, .flags = IMA_FSMAGIC}, | 78 | {.action = DONT_MEASURE, .fsmagic = PROC_SUPER_MAGIC, .flags = IMA_FSMAGIC}, |
| 75 | {.action = DONT_MEASURE, .fsmagic = SYSFS_MAGIC, .flags = IMA_FSMAGIC}, | 79 | {.action = DONT_MEASURE, .fsmagic = SYSFS_MAGIC, .flags = IMA_FSMAGIC}, |
| 76 | {.action = DONT_MEASURE, .fsmagic = DEBUGFS_MAGIC, .flags = IMA_FSMAGIC}, | 80 | {.action = DONT_MEASURE, .fsmagic = DEBUGFS_MAGIC, .flags = IMA_FSMAGIC}, |
| @@ -79,12 +83,31 @@ static struct ima_rule_entry default_rules[] = { | |||
| 79 | {.action = DONT_MEASURE, .fsmagic = BINFMTFS_MAGIC, .flags = IMA_FSMAGIC}, | 83 | {.action = DONT_MEASURE, .fsmagic = BINFMTFS_MAGIC, .flags = IMA_FSMAGIC}, |
| 80 | {.action = DONT_MEASURE, .fsmagic = SECURITYFS_MAGIC, .flags = IMA_FSMAGIC}, | 84 | {.action = DONT_MEASURE, .fsmagic = SECURITYFS_MAGIC, .flags = IMA_FSMAGIC}, |
| 81 | {.action = DONT_MEASURE, .fsmagic = SELINUX_MAGIC, .flags = IMA_FSMAGIC}, | 85 | {.action = DONT_MEASURE, .fsmagic = SELINUX_MAGIC, .flags = IMA_FSMAGIC}, |
| 86 | {.action = DONT_MEASURE, .fsmagic = CGROUP_SUPER_MAGIC, | ||
| 87 | .flags = IMA_FSMAGIC}, | ||
| 88 | {.action = DONT_MEASURE, .fsmagic = NSFS_MAGIC, .flags = IMA_FSMAGIC} | ||
| 89 | }; | ||
| 90 | |||
| 91 | static struct ima_rule_entry original_measurement_rules[] = { | ||
| 82 | {.action = MEASURE, .func = MMAP_CHECK, .mask = MAY_EXEC, | 92 | {.action = MEASURE, .func = MMAP_CHECK, .mask = MAY_EXEC, |
| 83 | .flags = IMA_FUNC | IMA_MASK}, | 93 | .flags = IMA_FUNC | IMA_MASK}, |
| 84 | {.action = MEASURE, .func = BPRM_CHECK, .mask = MAY_EXEC, | 94 | {.action = MEASURE, .func = BPRM_CHECK, .mask = MAY_EXEC, |
| 85 | .flags = IMA_FUNC | IMA_MASK}, | 95 | .flags = IMA_FUNC | IMA_MASK}, |
| 86 | {.action = MEASURE, .func = FILE_CHECK, .mask = MAY_READ, .uid = GLOBAL_ROOT_UID, | 96 | {.action = MEASURE, .func = FILE_CHECK, .mask = MAY_READ, |
| 87 | .flags = IMA_FUNC | IMA_MASK | IMA_UID}, | 97 | .uid = GLOBAL_ROOT_UID, .flags = IMA_FUNC | IMA_MASK | IMA_UID}, |
| 98 | {.action = MEASURE, .func = MODULE_CHECK, .flags = IMA_FUNC}, | ||
| 99 | {.action = MEASURE, .func = FIRMWARE_CHECK, .flags = IMA_FUNC}, | ||
| 100 | }; | ||
| 101 | |||
| 102 | static struct ima_rule_entry default_measurement_rules[] = { | ||
| 103 | {.action = MEASURE, .func = MMAP_CHECK, .mask = MAY_EXEC, | ||
| 104 | .flags = IMA_FUNC | IMA_MASK}, | ||
| 105 | {.action = MEASURE, .func = BPRM_CHECK, .mask = MAY_EXEC, | ||
| 106 | .flags = IMA_FUNC | IMA_MASK}, | ||
| 107 | {.action = MEASURE, .func = FILE_CHECK, .mask = MAY_READ, | ||
| 108 | .uid = GLOBAL_ROOT_UID, .flags = IMA_FUNC | IMA_INMASK | IMA_EUID}, | ||
| 109 | {.action = MEASURE, .func = FILE_CHECK, .mask = MAY_READ, | ||
| 110 | .uid = GLOBAL_ROOT_UID, .flags = IMA_FUNC | IMA_INMASK | IMA_UID}, | ||
| 88 | {.action = MEASURE, .func = MODULE_CHECK, .flags = IMA_FUNC}, | 111 | {.action = MEASURE, .func = MODULE_CHECK, .flags = IMA_FUNC}, |
| 89 | {.action = MEASURE, .func = FIRMWARE_CHECK, .flags = IMA_FUNC}, | 112 | {.action = MEASURE, .func = FIRMWARE_CHECK, .flags = IMA_FUNC}, |
| 90 | }; | 113 | }; |
| @@ -99,6 +122,7 @@ static struct ima_rule_entry default_appraise_rules[] = { | |||
| 99 | {.action = DONT_APPRAISE, .fsmagic = BINFMTFS_MAGIC, .flags = IMA_FSMAGIC}, | 122 | {.action = DONT_APPRAISE, .fsmagic = BINFMTFS_MAGIC, .flags = IMA_FSMAGIC}, |
| 100 | {.action = DONT_APPRAISE, .fsmagic = SECURITYFS_MAGIC, .flags = IMA_FSMAGIC}, | 123 | {.action = DONT_APPRAISE, .fsmagic = SECURITYFS_MAGIC, .flags = IMA_FSMAGIC}, |
| 101 | {.action = DONT_APPRAISE, .fsmagic = SELINUX_MAGIC, .flags = IMA_FSMAGIC}, | 124 | {.action = DONT_APPRAISE, .fsmagic = SELINUX_MAGIC, .flags = IMA_FSMAGIC}, |
| 125 | {.action = DONT_APPRAISE, .fsmagic = NSFS_MAGIC, .flags = IMA_FSMAGIC}, | ||
| 102 | {.action = DONT_APPRAISE, .fsmagic = CGROUP_SUPER_MAGIC, .flags = IMA_FSMAGIC}, | 126 | {.action = DONT_APPRAISE, .fsmagic = CGROUP_SUPER_MAGIC, .flags = IMA_FSMAGIC}, |
| 103 | #ifndef CONFIG_IMA_APPRAISE_SIGNED_INIT | 127 | #ifndef CONFIG_IMA_APPRAISE_SIGNED_INIT |
| 104 | {.action = APPRAISE, .fowner = GLOBAL_ROOT_UID, .flags = IMA_FOWNER}, | 128 | {.action = APPRAISE, .fowner = GLOBAL_ROOT_UID, .flags = IMA_FOWNER}, |
| @@ -115,14 +139,29 @@ static struct list_head *ima_rules; | |||
| 115 | 139 | ||
| 116 | static DEFINE_MUTEX(ima_rules_mutex); | 140 | static DEFINE_MUTEX(ima_rules_mutex); |
| 117 | 141 | ||
| 118 | static bool ima_use_tcb __initdata; | 142 | static int ima_policy __initdata; |
| 119 | static int __init default_measure_policy_setup(char *str) | 143 | static int __init default_measure_policy_setup(char *str) |
| 120 | { | 144 | { |
| 121 | ima_use_tcb = 1; | 145 | if (ima_policy) |
| 146 | return 1; | ||
| 147 | |||
| 148 | ima_policy = ORIGINAL_TCB; | ||
| 122 | return 1; | 149 | return 1; |
| 123 | } | 150 | } |
| 124 | __setup("ima_tcb", default_measure_policy_setup); | 151 | __setup("ima_tcb", default_measure_policy_setup); |
| 125 | 152 | ||
| 153 | static int __init policy_setup(char *str) | ||
| 154 | { | ||
| 155 | if (ima_policy) | ||
| 156 | return 1; | ||
| 157 | |||
| 158 | if (strcmp(str, "tcb") == 0) | ||
| 159 | ima_policy = DEFAULT_TCB; | ||
| 160 | |||
| 161 | return 1; | ||
| 162 | } | ||
| 163 | __setup("ima_policy=", policy_setup); | ||
| 164 | |||
| 126 | static bool ima_use_appraise_tcb __initdata; | 165 | static bool ima_use_appraise_tcb __initdata; |
| 127 | static int __init default_appraise_policy_setup(char *str) | 166 | static int __init default_appraise_policy_setup(char *str) |
| 128 | { | 167 | { |
| @@ -182,6 +221,9 @@ static bool ima_match_rules(struct ima_rule_entry *rule, | |||
| 182 | if ((rule->flags & IMA_MASK) && | 221 | if ((rule->flags & IMA_MASK) && |
| 183 | (rule->mask != mask && func != POST_SETATTR)) | 222 | (rule->mask != mask && func != POST_SETATTR)) |
| 184 | return false; | 223 | return false; |
| 224 | if ((rule->flags & IMA_INMASK) && | ||
| 225 | (!(rule->mask & mask) && func != POST_SETATTR)) | ||
| 226 | return false; | ||
| 185 | if ((rule->flags & IMA_FSMAGIC) | 227 | if ((rule->flags & IMA_FSMAGIC) |
| 186 | && rule->fsmagic != inode->i_sb->s_magic) | 228 | && rule->fsmagic != inode->i_sb->s_magic) |
| 187 | return false; | 229 | return false; |
| @@ -190,6 +232,16 @@ static bool ima_match_rules(struct ima_rule_entry *rule, | |||
| 190 | return false; | 232 | return false; |
| 191 | if ((rule->flags & IMA_UID) && !uid_eq(rule->uid, cred->uid)) | 233 | if ((rule->flags & IMA_UID) && !uid_eq(rule->uid, cred->uid)) |
| 192 | return false; | 234 | return false; |
| 235 | if (rule->flags & IMA_EUID) { | ||
| 236 | if (has_capability_noaudit(current, CAP_SETUID)) { | ||
| 237 | if (!uid_eq(rule->uid, cred->euid) | ||
| 238 | && !uid_eq(rule->uid, cred->suid) | ||
| 239 | && !uid_eq(rule->uid, cred->uid)) | ||
| 240 | return false; | ||
| 241 | } else if (!uid_eq(rule->uid, cred->euid)) | ||
| 242 | return false; | ||
| 243 | } | ||
| 244 | |||
| 193 | if ((rule->flags & IMA_FOWNER) && !uid_eq(rule->fowner, inode->i_uid)) | 245 | if ((rule->flags & IMA_FOWNER) && !uid_eq(rule->fowner, inode->i_uid)) |
| 194 | return false; | 246 | return false; |
| 195 | for (i = 0; i < MAX_LSM_RULES; i++) { | 247 | for (i = 0; i < MAX_LSM_RULES; i++) { |
| @@ -333,21 +385,31 @@ void __init ima_init_policy(void) | |||
| 333 | { | 385 | { |
| 334 | int i, measure_entries, appraise_entries; | 386 | int i, measure_entries, appraise_entries; |
| 335 | 387 | ||
| 336 | /* if !ima_use_tcb set entries = 0 so we load NO default rules */ | 388 | /* if !ima_policy set entries = 0 so we load NO default rules */ |
| 337 | measure_entries = ima_use_tcb ? ARRAY_SIZE(default_rules) : 0; | 389 | measure_entries = ima_policy ? ARRAY_SIZE(dont_measure_rules) : 0; |
| 338 | appraise_entries = ima_use_appraise_tcb ? | 390 | appraise_entries = ima_use_appraise_tcb ? |
| 339 | ARRAY_SIZE(default_appraise_rules) : 0; | 391 | ARRAY_SIZE(default_appraise_rules) : 0; |
| 340 | 392 | ||
| 341 | for (i = 0; i < measure_entries + appraise_entries; i++) { | 393 | for (i = 0; i < measure_entries; i++) |
| 342 | if (i < measure_entries) | 394 | list_add_tail(&dont_measure_rules[i].list, &ima_default_rules); |
| 343 | list_add_tail(&default_rules[i].list, | ||
| 344 | &ima_default_rules); | ||
| 345 | else { | ||
| 346 | int j = i - measure_entries; | ||
| 347 | 395 | ||
| 348 | list_add_tail(&default_appraise_rules[j].list, | 396 | switch (ima_policy) { |
| 397 | case ORIGINAL_TCB: | ||
| 398 | for (i = 0; i < ARRAY_SIZE(original_measurement_rules); i++) | ||
| 399 | list_add_tail(&original_measurement_rules[i].list, | ||
| 349 | &ima_default_rules); | 400 | &ima_default_rules); |
| 350 | } | 401 | break; |
| 402 | case DEFAULT_TCB: | ||
| 403 | for (i = 0; i < ARRAY_SIZE(default_measurement_rules); i++) | ||
| 404 | list_add_tail(&default_measurement_rules[i].list, | ||
| 405 | &ima_default_rules); | ||
| 406 | default: | ||
| 407 | break; | ||
| 408 | } | ||
| 409 | |||
| 410 | for (i = 0; i < appraise_entries; i++) { | ||
| 411 | list_add_tail(&default_appraise_rules[i].list, | ||
| 412 | &ima_default_rules); | ||
| 351 | } | 413 | } |
| 352 | 414 | ||
| 353 | ima_rules = &ima_default_rules; | 415 | ima_rules = &ima_default_rules; |
| @@ -373,7 +435,8 @@ enum { | |||
| 373 | Opt_audit, | 435 | Opt_audit, |
| 374 | Opt_obj_user, Opt_obj_role, Opt_obj_type, | 436 | Opt_obj_user, Opt_obj_role, Opt_obj_type, |
| 375 | Opt_subj_user, Opt_subj_role, Opt_subj_type, | 437 | Opt_subj_user, Opt_subj_role, Opt_subj_type, |
| 376 | Opt_func, Opt_mask, Opt_fsmagic, Opt_uid, Opt_fowner, | 438 | Opt_func, Opt_mask, Opt_fsmagic, |
| 439 | Opt_uid, Opt_euid, Opt_fowner, | ||
| 377 | Opt_appraise_type, Opt_fsuuid, Opt_permit_directio | 440 | Opt_appraise_type, Opt_fsuuid, Opt_permit_directio |
| 378 | }; | 441 | }; |
| 379 | 442 | ||
| @@ -394,6 +457,7 @@ static match_table_t policy_tokens = { | |||
| 394 | {Opt_fsmagic, "fsmagic=%s"}, | 457 | {Opt_fsmagic, "fsmagic=%s"}, |
| 395 | {Opt_fsuuid, "fsuuid=%s"}, | 458 | {Opt_fsuuid, "fsuuid=%s"}, |
| 396 | {Opt_uid, "uid=%s"}, | 459 | {Opt_uid, "uid=%s"}, |
| 460 | {Opt_euid, "euid=%s"}, | ||
| 397 | {Opt_fowner, "fowner=%s"}, | 461 | {Opt_fowner, "fowner=%s"}, |
| 398 | {Opt_appraise_type, "appraise_type=%s"}, | 462 | {Opt_appraise_type, "appraise_type=%s"}, |
| 399 | {Opt_permit_directio, "permit_directio"}, | 463 | {Opt_permit_directio, "permit_directio"}, |
| @@ -435,6 +499,7 @@ static void ima_log_string(struct audit_buffer *ab, char *key, char *value) | |||
| 435 | static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) | 499 | static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) |
| 436 | { | 500 | { |
| 437 | struct audit_buffer *ab; | 501 | struct audit_buffer *ab; |
| 502 | char *from; | ||
| 438 | char *p; | 503 | char *p; |
| 439 | int result = 0; | 504 | int result = 0; |
| 440 | 505 | ||
| @@ -525,18 +590,23 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) | |||
| 525 | if (entry->mask) | 590 | if (entry->mask) |
| 526 | result = -EINVAL; | 591 | result = -EINVAL; |
| 527 | 592 | ||
| 528 | if ((strcmp(args[0].from, "MAY_EXEC")) == 0) | 593 | from = args[0].from; |
| 594 | if (*from == '^') | ||
| 595 | from++; | ||
| 596 | |||
| 597 | if ((strcmp(from, "MAY_EXEC")) == 0) | ||
| 529 | entry->mask = MAY_EXEC; | 598 | entry->mask = MAY_EXEC; |
| 530 | else if (strcmp(args[0].from, "MAY_WRITE") == 0) | 599 | else if (strcmp(from, "MAY_WRITE") == 0) |
| 531 | entry->mask = MAY_WRITE; | 600 | entry->mask = MAY_WRITE; |
| 532 | else if (strcmp(args[0].from, "MAY_READ") == 0) | 601 | else if (strcmp(from, "MAY_READ") == 0) |
| 533 | entry->mask = MAY_READ; | 602 | entry->mask = MAY_READ; |
| 534 | else if (strcmp(args[0].from, "MAY_APPEND") == 0) | 603 | else if (strcmp(from, "MAY_APPEND") == 0) |
| 535 | entry->mask = MAY_APPEND; | 604 | entry->mask = MAY_APPEND; |
| 536 | else | 605 | else |
| 537 | result = -EINVAL; | 606 | result = -EINVAL; |
| 538 | if (!result) | 607 | if (!result) |
| 539 | entry->flags |= IMA_MASK; | 608 | entry->flags |= (*args[0].from == '^') |
| 609 | ? IMA_INMASK : IMA_MASK; | ||
| 540 | break; | 610 | break; |
| 541 | case Opt_fsmagic: | 611 | case Opt_fsmagic: |
| 542 | ima_log_string(ab, "fsmagic", args[0].from); | 612 | ima_log_string(ab, "fsmagic", args[0].from); |
| @@ -566,6 +636,9 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) | |||
| 566 | break; | 636 | break; |
| 567 | case Opt_uid: | 637 | case Opt_uid: |
| 568 | ima_log_string(ab, "uid", args[0].from); | 638 | ima_log_string(ab, "uid", args[0].from); |
| 639 | case Opt_euid: | ||
| 640 | if (token == Opt_euid) | ||
| 641 | ima_log_string(ab, "euid", args[0].from); | ||
| 569 | 642 | ||
| 570 | if (uid_valid(entry->uid)) { | 643 | if (uid_valid(entry->uid)) { |
| 571 | result = -EINVAL; | 644 | result = -EINVAL; |
| @@ -574,11 +647,14 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) | |||
| 574 | 647 | ||
| 575 | result = kstrtoul(args[0].from, 10, &lnum); | 648 | result = kstrtoul(args[0].from, 10, &lnum); |
| 576 | if (!result) { | 649 | if (!result) { |
| 577 | entry->uid = make_kuid(current_user_ns(), (uid_t)lnum); | 650 | entry->uid = make_kuid(current_user_ns(), |
| 578 | if (!uid_valid(entry->uid) || (((uid_t)lnum) != lnum)) | 651 | (uid_t) lnum); |
| 652 | if (!uid_valid(entry->uid) || | ||
| 653 | (uid_t)lnum != lnum) | ||
| 579 | result = -EINVAL; | 654 | result = -EINVAL; |
| 580 | else | 655 | else |
| 581 | entry->flags |= IMA_UID; | 656 | entry->flags |= (token == Opt_uid) |
| 657 | ? IMA_UID : IMA_EUID; | ||
| 582 | } | 658 | } |
| 583 | break; | 659 | break; |
| 584 | case Opt_fowner: | 660 | case Opt_fowner: |
diff --git a/security/integrity/ima/ima_template_lib.c b/security/integrity/ima/ima_template_lib.c index bcfc36cbde6a..2934e3d377f1 100644 --- a/security/integrity/ima/ima_template_lib.c +++ b/security/integrity/ima/ima_template_lib.c | |||
| @@ -70,7 +70,8 @@ static void ima_show_template_data_ascii(struct seq_file *m, | |||
| 70 | enum data_formats datafmt, | 70 | enum data_formats datafmt, |
| 71 | struct ima_field_data *field_data) | 71 | struct ima_field_data *field_data) |
| 72 | { | 72 | { |
| 73 | u8 *buf_ptr = field_data->data, buflen = field_data->len; | 73 | u8 *buf_ptr = field_data->data; |
| 74 | u32 buflen = field_data->len; | ||
| 74 | 75 | ||
| 75 | switch (datafmt) { | 76 | switch (datafmt) { |
| 76 | case DATA_FMT_DIGEST_WITH_ALGO: | 77 | case DATA_FMT_DIGEST_WITH_ALGO: |
| @@ -195,9 +196,7 @@ static int ima_eventdigest_init_common(u8 *digest, u32 digestsize, u8 hash_algo, | |||
| 195 | /* | 196 | /* |
| 196 | * This function writes the digest of an event (with size limit). | 197 | * This function writes the digest of an event (with size limit). |
| 197 | */ | 198 | */ |
| 198 | int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file, | 199 | int ima_eventdigest_init(struct ima_event_data *event_data, |
| 199 | const unsigned char *filename, | ||
| 200 | struct evm_ima_xattr_data *xattr_value, int xattr_len, | ||
| 201 | struct ima_field_data *field_data) | 200 | struct ima_field_data *field_data) |
| 202 | { | 201 | { |
| 203 | struct { | 202 | struct { |
| @@ -211,25 +210,25 @@ int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file, | |||
| 211 | 210 | ||
| 212 | memset(&hash, 0, sizeof(hash)); | 211 | memset(&hash, 0, sizeof(hash)); |
| 213 | 212 | ||
| 214 | if (!iint) /* recording a violation. */ | 213 | if (event_data->violation) /* recording a violation. */ |
| 215 | goto out; | 214 | goto out; |
| 216 | 215 | ||
| 217 | if (ima_template_hash_algo_allowed(iint->ima_hash->algo)) { | 216 | if (ima_template_hash_algo_allowed(event_data->iint->ima_hash->algo)) { |
| 218 | cur_digest = iint->ima_hash->digest; | 217 | cur_digest = event_data->iint->ima_hash->digest; |
| 219 | cur_digestsize = iint->ima_hash->length; | 218 | cur_digestsize = event_data->iint->ima_hash->length; |
| 220 | goto out; | 219 | goto out; |
| 221 | } | 220 | } |
| 222 | 221 | ||
| 223 | if (!file) /* missing info to re-calculate the digest */ | 222 | if (!event_data->file) /* missing info to re-calculate the digest */ |
| 224 | return -EINVAL; | 223 | return -EINVAL; |
| 225 | 224 | ||
| 226 | inode = file_inode(file); | 225 | inode = file_inode(event_data->file); |
| 227 | hash.hdr.algo = ima_template_hash_algo_allowed(ima_hash_algo) ? | 226 | hash.hdr.algo = ima_template_hash_algo_allowed(ima_hash_algo) ? |
| 228 | ima_hash_algo : HASH_ALGO_SHA1; | 227 | ima_hash_algo : HASH_ALGO_SHA1; |
| 229 | result = ima_calc_file_hash(file, &hash.hdr); | 228 | result = ima_calc_file_hash(event_data->file, &hash.hdr); |
| 230 | if (result) { | 229 | if (result) { |
| 231 | integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, | 230 | integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, |
| 232 | filename, "collect_data", | 231 | event_data->filename, "collect_data", |
| 233 | "failed", result, 0); | 232 | "failed", result, 0); |
| 234 | return result; | 233 | return result; |
| 235 | } | 234 | } |
| @@ -243,48 +242,43 @@ out: | |||
| 243 | /* | 242 | /* |
| 244 | * This function writes the digest of an event (without size limit). | 243 | * This function writes the digest of an event (without size limit). |
| 245 | */ | 244 | */ |
| 246 | int ima_eventdigest_ng_init(struct integrity_iint_cache *iint, | 245 | int ima_eventdigest_ng_init(struct ima_event_data *event_data, |
| 247 | struct file *file, const unsigned char *filename, | 246 | struct ima_field_data *field_data) |
| 248 | struct evm_ima_xattr_data *xattr_value, | ||
| 249 | int xattr_len, struct ima_field_data *field_data) | ||
| 250 | { | 247 | { |
| 251 | u8 *cur_digest = NULL, hash_algo = HASH_ALGO_SHA1; | 248 | u8 *cur_digest = NULL, hash_algo = HASH_ALGO_SHA1; |
| 252 | u32 cur_digestsize = 0; | 249 | u32 cur_digestsize = 0; |
| 253 | 250 | ||
| 254 | /* If iint is NULL, we are recording a violation. */ | 251 | if (event_data->violation) /* recording a violation. */ |
| 255 | if (!iint) | ||
| 256 | goto out; | 252 | goto out; |
| 257 | 253 | ||
| 258 | cur_digest = iint->ima_hash->digest; | 254 | cur_digest = event_data->iint->ima_hash->digest; |
| 259 | cur_digestsize = iint->ima_hash->length; | 255 | cur_digestsize = event_data->iint->ima_hash->length; |
| 260 | 256 | ||
| 261 | hash_algo = iint->ima_hash->algo; | 257 | hash_algo = event_data->iint->ima_hash->algo; |
| 262 | out: | 258 | out: |
| 263 | return ima_eventdigest_init_common(cur_digest, cur_digestsize, | 259 | return ima_eventdigest_init_common(cur_digest, cur_digestsize, |
| 264 | hash_algo, field_data); | 260 | hash_algo, field_data); |
| 265 | } | 261 | } |
| 266 | 262 | ||
| 267 | static int ima_eventname_init_common(struct integrity_iint_cache *iint, | 263 | static int ima_eventname_init_common(struct ima_event_data *event_data, |
| 268 | struct file *file, | ||
| 269 | const unsigned char *filename, | ||
| 270 | struct ima_field_data *field_data, | 264 | struct ima_field_data *field_data, |
| 271 | bool size_limit) | 265 | bool size_limit) |
| 272 | { | 266 | { |
| 273 | const char *cur_filename = NULL; | 267 | const char *cur_filename = NULL; |
| 274 | u32 cur_filename_len = 0; | 268 | u32 cur_filename_len = 0; |
| 275 | 269 | ||
| 276 | BUG_ON(filename == NULL && file == NULL); | 270 | BUG_ON(event_data->filename == NULL && event_data->file == NULL); |
| 277 | 271 | ||
| 278 | if (filename) { | 272 | if (event_data->filename) { |
| 279 | cur_filename = filename; | 273 | cur_filename = event_data->filename; |
| 280 | cur_filename_len = strlen(filename); | 274 | cur_filename_len = strlen(event_data->filename); |
| 281 | 275 | ||
| 282 | if (!size_limit || cur_filename_len <= IMA_EVENT_NAME_LEN_MAX) | 276 | if (!size_limit || cur_filename_len <= IMA_EVENT_NAME_LEN_MAX) |
| 283 | goto out; | 277 | goto out; |
| 284 | } | 278 | } |
| 285 | 279 | ||
| 286 | if (file) { | 280 | if (event_data->file) { |
| 287 | cur_filename = file->f_path.dentry->d_name.name; | 281 | cur_filename = event_data->file->f_path.dentry->d_name.name; |
| 288 | cur_filename_len = strlen(cur_filename); | 282 | cur_filename_len = strlen(cur_filename); |
| 289 | } else | 283 | } else |
| 290 | /* | 284 | /* |
| @@ -300,36 +294,30 @@ out: | |||
| 300 | /* | 294 | /* |
| 301 | * This function writes the name of an event (with size limit). | 295 | * This function writes the name of an event (with size limit). |
| 302 | */ | 296 | */ |
| 303 | int ima_eventname_init(struct integrity_iint_cache *iint, struct file *file, | 297 | int ima_eventname_init(struct ima_event_data *event_data, |
| 304 | const unsigned char *filename, | ||
| 305 | struct evm_ima_xattr_data *xattr_value, int xattr_len, | ||
| 306 | struct ima_field_data *field_data) | 298 | struct ima_field_data *field_data) |
| 307 | { | 299 | { |
| 308 | return ima_eventname_init_common(iint, file, filename, | 300 | return ima_eventname_init_common(event_data, field_data, true); |
| 309 | field_data, true); | ||
| 310 | } | 301 | } |
| 311 | 302 | ||
| 312 | /* | 303 | /* |
| 313 | * This function writes the name of an event (without size limit). | 304 | * This function writes the name of an event (without size limit). |
| 314 | */ | 305 | */ |
| 315 | int ima_eventname_ng_init(struct integrity_iint_cache *iint, struct file *file, | 306 | int ima_eventname_ng_init(struct ima_event_data *event_data, |
| 316 | const unsigned char *filename, | ||
| 317 | struct evm_ima_xattr_data *xattr_value, int xattr_len, | ||
| 318 | struct ima_field_data *field_data) | 307 | struct ima_field_data *field_data) |
| 319 | { | 308 | { |
| 320 | return ima_eventname_init_common(iint, file, filename, | 309 | return ima_eventname_init_common(event_data, field_data, false); |
| 321 | field_data, false); | ||
| 322 | } | 310 | } |
| 323 | 311 | ||
| 324 | /* | 312 | /* |
| 325 | * ima_eventsig_init - include the file signature as part of the template data | 313 | * ima_eventsig_init - include the file signature as part of the template data |
| 326 | */ | 314 | */ |
| 327 | int ima_eventsig_init(struct integrity_iint_cache *iint, struct file *file, | 315 | int ima_eventsig_init(struct ima_event_data *event_data, |
| 328 | const unsigned char *filename, | ||
| 329 | struct evm_ima_xattr_data *xattr_value, int xattr_len, | ||
| 330 | struct ima_field_data *field_data) | 316 | struct ima_field_data *field_data) |
| 331 | { | 317 | { |
| 332 | enum data_formats fmt = DATA_FMT_HEX; | 318 | enum data_formats fmt = DATA_FMT_HEX; |
| 319 | struct evm_ima_xattr_data *xattr_value = event_data->xattr_value; | ||
| 320 | int xattr_len = event_data->xattr_len; | ||
| 333 | int rc = 0; | 321 | int rc = 0; |
| 334 | 322 | ||
| 335 | if ((!xattr_value) || (xattr_value->type != EVM_IMA_XATTR_DIGSIG)) | 323 | if ((!xattr_value) || (xattr_value->type != EVM_IMA_XATTR_DIGSIG)) |
diff --git a/security/integrity/ima/ima_template_lib.h b/security/integrity/ima/ima_template_lib.h index 63f6b52cb1c2..c344530c1d69 100644 --- a/security/integrity/ima/ima_template_lib.h +++ b/security/integrity/ima/ima_template_lib.h | |||
| @@ -26,24 +26,14 @@ void ima_show_template_string(struct seq_file *m, enum ima_show_type show, | |||
| 26 | struct ima_field_data *field_data); | 26 | struct ima_field_data *field_data); |
| 27 | void ima_show_template_sig(struct seq_file *m, enum ima_show_type show, | 27 | void ima_show_template_sig(struct seq_file *m, enum ima_show_type show, |
| 28 | struct ima_field_data *field_data); | 28 | struct ima_field_data *field_data); |
| 29 | int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file, | 29 | int ima_eventdigest_init(struct ima_event_data *event_data, |
| 30 | const unsigned char *filename, | ||
| 31 | struct evm_ima_xattr_data *xattr_value, int xattr_len, | ||
| 32 | struct ima_field_data *field_data); | 30 | struct ima_field_data *field_data); |
| 33 | int ima_eventname_init(struct integrity_iint_cache *iint, struct file *file, | 31 | int ima_eventname_init(struct ima_event_data *event_data, |
| 34 | const unsigned char *filename, | ||
| 35 | struct evm_ima_xattr_data *xattr_value, int xattr_len, | ||
| 36 | struct ima_field_data *field_data); | 32 | struct ima_field_data *field_data); |
| 37 | int ima_eventdigest_ng_init(struct integrity_iint_cache *iint, | 33 | int ima_eventdigest_ng_init(struct ima_event_data *event_data, |
| 38 | struct file *file, const unsigned char *filename, | 34 | struct ima_field_data *field_data); |
| 39 | struct evm_ima_xattr_data *xattr_value, | 35 | int ima_eventname_ng_init(struct ima_event_data *event_data, |
| 40 | int xattr_len, struct ima_field_data *field_data); | ||
| 41 | int ima_eventname_ng_init(struct integrity_iint_cache *iint, struct file *file, | ||
| 42 | const unsigned char *filename, | ||
| 43 | struct evm_ima_xattr_data *xattr_value, int xattr_len, | ||
| 44 | struct ima_field_data *field_data); | 36 | struct ima_field_data *field_data); |
| 45 | int ima_eventsig_init(struct integrity_iint_cache *iint, struct file *file, | 37 | int ima_eventsig_init(struct ima_event_data *event_data, |
| 46 | const unsigned char *filename, | ||
| 47 | struct evm_ima_xattr_data *xattr_value, int xattr_len, | ||
| 48 | struct ima_field_data *field_data); | 38 | struct ima_field_data *field_data); |
| 49 | #endif /* __LINUX_IMA_TEMPLATE_LIB_H */ | 39 | #endif /* __LINUX_IMA_TEMPLATE_LIB_H */ |
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h index 0fc9519fefa9..9c6168709d3b 100644 --- a/security/integrity/integrity.h +++ b/security/integrity/integrity.h | |||
| @@ -135,7 +135,7 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, | |||
| 135 | const char *digest, int digestlen); | 135 | const char *digest, int digestlen); |
| 136 | 136 | ||
| 137 | int __init integrity_init_keyring(const unsigned int id); | 137 | int __init integrity_init_keyring(const unsigned int id); |
| 138 | int __init integrity_load_x509(const unsigned int id, char *path); | 138 | int __init integrity_load_x509(const unsigned int id, const char *path); |
| 139 | #else | 139 | #else |
| 140 | 140 | ||
| 141 | static inline int integrity_digsig_verify(const unsigned int id, | 141 | static inline int integrity_digsig_verify(const unsigned int id, |
diff --git a/security/keys/compat.c b/security/keys/compat.c index 347896548ad3..25430a3aa7f7 100644 --- a/security/keys/compat.c +++ b/security/keys/compat.c | |||
| @@ -31,30 +31,21 @@ static long compat_keyctl_instantiate_key_iov( | |||
| 31 | key_serial_t ringid) | 31 | key_serial_t ringid) |
| 32 | { | 32 | { |
| 33 | struct iovec iovstack[UIO_FASTIOV], *iov = iovstack; | 33 | struct iovec iovstack[UIO_FASTIOV], *iov = iovstack; |
| 34 | struct iov_iter from; | ||
| 34 | long ret; | 35 | long ret; |
| 35 | 36 | ||
| 36 | if (!_payload_iov || !ioc) | 37 | if (!_payload_iov) |
| 37 | goto no_payload; | 38 | ioc = 0; |
| 38 | 39 | ||
| 39 | ret = compat_rw_copy_check_uvector(WRITE, _payload_iov, ioc, | 40 | ret = compat_import_iovec(WRITE, _payload_iov, ioc, |
| 40 | ARRAY_SIZE(iovstack), | 41 | ARRAY_SIZE(iovstack), &iov, |
| 41 | iovstack, &iov); | 42 | &from); |
| 42 | if (ret < 0) | 43 | if (ret < 0) |
| 43 | goto err; | 44 | return ret; |
| 44 | if (ret == 0) | ||
| 45 | goto no_payload_free; | ||
| 46 | |||
| 47 | ret = keyctl_instantiate_key_common(id, iov, ioc, ret, ringid); | ||
| 48 | err: | ||
| 49 | if (iov != iovstack) | ||
| 50 | kfree(iov); | ||
| 51 | return ret; | ||
| 52 | 45 | ||
| 53 | no_payload_free: | 46 | ret = keyctl_instantiate_key_common(id, &from, ringid); |
| 54 | if (iov != iovstack) | 47 | kfree(iov); |
| 55 | kfree(iov); | 48 | return ret; |
| 56 | no_payload: | ||
| 57 | return keyctl_instantiate_key_common(id, NULL, 0, 0, ringid); | ||
| 58 | } | 49 | } |
| 59 | 50 | ||
| 60 | /* | 51 | /* |
diff --git a/security/keys/internal.h b/security/keys/internal.h index 200e37867336..5105c2c2da75 100644 --- a/security/keys/internal.h +++ b/security/keys/internal.h | |||
| @@ -243,9 +243,10 @@ extern long keyctl_instantiate_key_iov(key_serial_t, | |||
| 243 | unsigned, key_serial_t); | 243 | unsigned, key_serial_t); |
| 244 | extern long keyctl_invalidate_key(key_serial_t); | 244 | extern long keyctl_invalidate_key(key_serial_t); |
| 245 | 245 | ||
| 246 | struct iov_iter; | ||
| 246 | extern long keyctl_instantiate_key_common(key_serial_t, | 247 | extern long keyctl_instantiate_key_common(key_serial_t, |
| 247 | const struct iovec *, | 248 | struct iov_iter *, |
| 248 | unsigned, size_t, key_serial_t); | 249 | key_serial_t); |
| 249 | #ifdef CONFIG_PERSISTENT_KEYRINGS | 250 | #ifdef CONFIG_PERSISTENT_KEYRINGS |
| 250 | extern long keyctl_get_persistent(uid_t, key_serial_t); | 251 | extern long keyctl_get_persistent(uid_t, key_serial_t); |
| 251 | extern unsigned persistent_keyring_expiry; | 252 | extern unsigned persistent_keyring_expiry; |
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 4743d71e4aa6..0b9ec78a7a7a 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c | |||
| @@ -998,21 +998,6 @@ static int keyctl_change_reqkey_auth(struct key *key) | |||
| 998 | } | 998 | } |
| 999 | 999 | ||
| 1000 | /* | 1000 | /* |
| 1001 | * Copy the iovec data from userspace | ||
| 1002 | */ | ||
| 1003 | static long copy_from_user_iovec(void *buffer, const struct iovec *iov, | ||
| 1004 | unsigned ioc) | ||
| 1005 | { | ||
| 1006 | for (; ioc > 0; ioc--) { | ||
| 1007 | if (copy_from_user(buffer, iov->iov_base, iov->iov_len) != 0) | ||
| 1008 | return -EFAULT; | ||
| 1009 | buffer += iov->iov_len; | ||
| 1010 | iov++; | ||
| 1011 | } | ||
| 1012 | return 0; | ||
| 1013 | } | ||
| 1014 | |||
| 1015 | /* | ||
| 1016 | * Instantiate a key with the specified payload and link the key into the | 1001 | * Instantiate a key with the specified payload and link the key into the |
| 1017 | * destination keyring if one is given. | 1002 | * destination keyring if one is given. |
| 1018 | * | 1003 | * |
| @@ -1022,20 +1007,21 @@ static long copy_from_user_iovec(void *buffer, const struct iovec *iov, | |||
| 1022 | * If successful, 0 will be returned. | 1007 | * If successful, 0 will be returned. |
| 1023 | */ | 1008 | */ |
| 1024 | long keyctl_instantiate_key_common(key_serial_t id, | 1009 | long keyctl_instantiate_key_common(key_serial_t id, |
| 1025 | const struct iovec *payload_iov, | 1010 | struct iov_iter *from, |
| 1026 | unsigned ioc, | ||
| 1027 | size_t plen, | ||
| 1028 | key_serial_t ringid) | 1011 | key_serial_t ringid) |
| 1029 | { | 1012 | { |
| 1030 | const struct cred *cred = current_cred(); | 1013 | const struct cred *cred = current_cred(); |
| 1031 | struct request_key_auth *rka; | 1014 | struct request_key_auth *rka; |
| 1032 | struct key *instkey, *dest_keyring; | 1015 | struct key *instkey, *dest_keyring; |
| 1016 | size_t plen = from ? iov_iter_count(from) : 0; | ||
| 1033 | void *payload; | 1017 | void *payload; |
| 1034 | long ret; | 1018 | long ret; |
| 1035 | bool vm = false; | ||
| 1036 | 1019 | ||
| 1037 | kenter("%d,,%zu,%d", id, plen, ringid); | 1020 | kenter("%d,,%zu,%d", id, plen, ringid); |
| 1038 | 1021 | ||
| 1022 | if (!plen) | ||
| 1023 | from = NULL; | ||
| 1024 | |||
| 1039 | ret = -EINVAL; | 1025 | ret = -EINVAL; |
| 1040 | if (plen > 1024 * 1024 - 1) | 1026 | if (plen > 1024 * 1024 - 1) |
| 1041 | goto error; | 1027 | goto error; |
| @@ -1054,20 +1040,19 @@ long keyctl_instantiate_key_common(key_serial_t id, | |||
| 1054 | /* pull the payload in if one was supplied */ | 1040 | /* pull the payload in if one was supplied */ |
| 1055 | payload = NULL; | 1041 | payload = NULL; |
| 1056 | 1042 | ||
| 1057 | if (payload_iov) { | 1043 | if (from) { |
| 1058 | ret = -ENOMEM; | 1044 | ret = -ENOMEM; |
| 1059 | payload = kmalloc(plen, GFP_KERNEL); | 1045 | payload = kmalloc(plen, GFP_KERNEL); |
| 1060 | if (!payload) { | 1046 | if (!payload) { |
| 1061 | if (plen <= PAGE_SIZE) | 1047 | if (plen <= PAGE_SIZE) |
| 1062 | goto error; | 1048 | goto error; |
| 1063 | vm = true; | ||
| 1064 | payload = vmalloc(plen); | 1049 | payload = vmalloc(plen); |
| 1065 | if (!payload) | 1050 | if (!payload) |
| 1066 | goto error; | 1051 | goto error; |
| 1067 | } | 1052 | } |
| 1068 | 1053 | ||
| 1069 | ret = copy_from_user_iovec(payload, payload_iov, ioc); | 1054 | ret = -EFAULT; |
| 1070 | if (ret < 0) | 1055 | if (copy_from_iter(payload, plen, from) != plen) |
| 1071 | goto error2; | 1056 | goto error2; |
| 1072 | } | 1057 | } |
| 1073 | 1058 | ||
| @@ -1089,10 +1074,7 @@ long keyctl_instantiate_key_common(key_serial_t id, | |||
| 1089 | keyctl_change_reqkey_auth(NULL); | 1074 | keyctl_change_reqkey_auth(NULL); |
| 1090 | 1075 | ||
| 1091 | error2: | 1076 | error2: |
| 1092 | if (!vm) | 1077 | kvfree(payload); |
| 1093 | kfree(payload); | ||
| 1094 | else | ||
| 1095 | vfree(payload); | ||
| 1096 | error: | 1078 | error: |
| 1097 | return ret; | 1079 | return ret; |
| 1098 | } | 1080 | } |
| @@ -1112,15 +1094,19 @@ long keyctl_instantiate_key(key_serial_t id, | |||
| 1112 | key_serial_t ringid) | 1094 | key_serial_t ringid) |
| 1113 | { | 1095 | { |
| 1114 | if (_payload && plen) { | 1096 | if (_payload && plen) { |
| 1115 | struct iovec iov[1] = { | 1097 | struct iovec iov; |
| 1116 | [0].iov_base = (void __user *)_payload, | 1098 | struct iov_iter from; |
| 1117 | [0].iov_len = plen | 1099 | int ret; |
| 1118 | }; | ||
| 1119 | 1100 | ||
| 1120 | return keyctl_instantiate_key_common(id, iov, 1, plen, ringid); | 1101 | ret = import_single_range(WRITE, (void __user *)_payload, plen, |
| 1102 | &iov, &from); | ||
| 1103 | if (unlikely(ret)) | ||
| 1104 | return ret; | ||
| 1105 | |||
| 1106 | return keyctl_instantiate_key_common(id, &from, ringid); | ||
| 1121 | } | 1107 | } |
| 1122 | 1108 | ||
| 1123 | return keyctl_instantiate_key_common(id, NULL, 0, 0, ringid); | 1109 | return keyctl_instantiate_key_common(id, NULL, ringid); |
| 1124 | } | 1110 | } |
| 1125 | 1111 | ||
| 1126 | /* | 1112 | /* |
| @@ -1138,29 +1124,19 @@ long keyctl_instantiate_key_iov(key_serial_t id, | |||
| 1138 | key_serial_t ringid) | 1124 | key_serial_t ringid) |
| 1139 | { | 1125 | { |
| 1140 | struct iovec iovstack[UIO_FASTIOV], *iov = iovstack; | 1126 | struct iovec iovstack[UIO_FASTIOV], *iov = iovstack; |
| 1127 | struct iov_iter from; | ||
| 1141 | long ret; | 1128 | long ret; |
| 1142 | 1129 | ||
| 1143 | if (!_payload_iov || !ioc) | 1130 | if (!_payload_iov) |
| 1144 | goto no_payload; | 1131 | ioc = 0; |
| 1145 | 1132 | ||
| 1146 | ret = rw_copy_check_uvector(WRITE, _payload_iov, ioc, | 1133 | ret = import_iovec(WRITE, _payload_iov, ioc, |
| 1147 | ARRAY_SIZE(iovstack), iovstack, &iov); | 1134 | ARRAY_SIZE(iovstack), &iov, &from); |
| 1148 | if (ret < 0) | 1135 | if (ret < 0) |
| 1149 | goto err; | 1136 | return ret; |
| 1150 | if (ret == 0) | 1137 | ret = keyctl_instantiate_key_common(id, &from, ringid); |
| 1151 | goto no_payload_free; | 1138 | kfree(iov); |
| 1152 | |||
| 1153 | ret = keyctl_instantiate_key_common(id, iov, ioc, ret, ringid); | ||
| 1154 | err: | ||
| 1155 | if (iov != iovstack) | ||
| 1156 | kfree(iov); | ||
| 1157 | return ret; | 1139 | return ret; |
| 1158 | |||
| 1159 | no_payload_free: | ||
| 1160 | if (iov != iovstack) | ||
| 1161 | kfree(iov); | ||
| 1162 | no_payload: | ||
| 1163 | return keyctl_instantiate_key_common(id, NULL, 0, 0, ringid); | ||
| 1164 | } | 1140 | } |
| 1165 | 1141 | ||
| 1166 | /* | 1142 | /* |
diff --git a/security/lsm_audit.c b/security/lsm_audit.c index 69fdf3bc765b..4ed98107ace3 100644 --- a/security/lsm_audit.c +++ b/security/lsm_audit.c | |||
| @@ -211,7 +211,7 @@ static inline void print_ipv4_addr(struct audit_buffer *ab, __be32 addr, | |||
| 211 | static void dump_common_audit_data(struct audit_buffer *ab, | 211 | static void dump_common_audit_data(struct audit_buffer *ab, |
| 212 | struct common_audit_data *a) | 212 | struct common_audit_data *a) |
| 213 | { | 213 | { |
| 214 | struct task_struct *tsk = current; | 214 | char comm[sizeof(current->comm)]; |
| 215 | 215 | ||
| 216 | /* | 216 | /* |
| 217 | * To keep stack sizes in check force programers to notice if they | 217 | * To keep stack sizes in check force programers to notice if they |
| @@ -220,8 +220,8 @@ static void dump_common_audit_data(struct audit_buffer *ab, | |||
| 220 | */ | 220 | */ |
| 221 | BUILD_BUG_ON(sizeof(a->u) > sizeof(void *)*2); | 221 | BUILD_BUG_ON(sizeof(a->u) > sizeof(void *)*2); |
| 222 | 222 | ||
| 223 | audit_log_format(ab, " pid=%d comm=", task_pid_nr(tsk)); | 223 | audit_log_format(ab, " pid=%d comm=", task_pid_nr(current)); |
| 224 | audit_log_untrustedstring(ab, tsk->comm); | 224 | audit_log_untrustedstring(ab, memcpy(comm, current->comm, sizeof(comm))); |
| 225 | 225 | ||
| 226 | switch (a->type) { | 226 | switch (a->type) { |
| 227 | case LSM_AUDIT_DATA_NONE: | 227 | case LSM_AUDIT_DATA_NONE: |
| @@ -237,7 +237,7 @@ static void dump_common_audit_data(struct audit_buffer *ab, | |||
| 237 | 237 | ||
| 238 | audit_log_d_path(ab, " path=", &a->u.path); | 238 | audit_log_d_path(ab, " path=", &a->u.path); |
| 239 | 239 | ||
| 240 | inode = a->u.path.dentry->d_inode; | 240 | inode = d_backing_inode(a->u.path.dentry); |
| 241 | if (inode) { | 241 | if (inode) { |
| 242 | audit_log_format(ab, " dev="); | 242 | audit_log_format(ab, " dev="); |
| 243 | audit_log_untrustedstring(ab, inode->i_sb->s_id); | 243 | audit_log_untrustedstring(ab, inode->i_sb->s_id); |
| @@ -251,7 +251,7 @@ static void dump_common_audit_data(struct audit_buffer *ab, | |||
| 251 | audit_log_format(ab, " name="); | 251 | audit_log_format(ab, " name="); |
| 252 | audit_log_untrustedstring(ab, a->u.dentry->d_name.name); | 252 | audit_log_untrustedstring(ab, a->u.dentry->d_name.name); |
| 253 | 253 | ||
| 254 | inode = a->u.dentry->d_inode; | 254 | inode = d_backing_inode(a->u.dentry); |
| 255 | if (inode) { | 255 | if (inode) { |
| 256 | audit_log_format(ab, " dev="); | 256 | audit_log_format(ab, " dev="); |
| 257 | audit_log_untrustedstring(ab, inode->i_sb->s_id); | 257 | audit_log_untrustedstring(ab, inode->i_sb->s_id); |
| @@ -276,16 +276,19 @@ static void dump_common_audit_data(struct audit_buffer *ab, | |||
| 276 | audit_log_format(ab, " ino=%lu", inode->i_ino); | 276 | audit_log_format(ab, " ino=%lu", inode->i_ino); |
| 277 | break; | 277 | break; |
| 278 | } | 278 | } |
| 279 | case LSM_AUDIT_DATA_TASK: | 279 | case LSM_AUDIT_DATA_TASK: { |
| 280 | tsk = a->u.tsk; | 280 | struct task_struct *tsk = a->u.tsk; |
| 281 | if (tsk) { | 281 | if (tsk) { |
| 282 | pid_t pid = task_pid_nr(tsk); | 282 | pid_t pid = task_pid_nr(tsk); |
| 283 | if (pid) { | 283 | if (pid) { |
| 284 | audit_log_format(ab, " pid=%d comm=", pid); | 284 | char comm[sizeof(tsk->comm)]; |
| 285 | audit_log_untrustedstring(ab, tsk->comm); | 285 | audit_log_format(ab, " opid=%d ocomm=", pid); |
| 286 | audit_log_untrustedstring(ab, | ||
| 287 | memcpy(comm, tsk->comm, sizeof(comm))); | ||
| 286 | } | 288 | } |
| 287 | } | 289 | } |
| 288 | break; | 290 | break; |
| 291 | } | ||
| 289 | case LSM_AUDIT_DATA_NET: | 292 | case LSM_AUDIT_DATA_NET: |
| 290 | if (a->u.net->sk) { | 293 | if (a->u.net->sk) { |
| 291 | struct sock *sk = a->u.net->sk; | 294 | struct sock *sk = a->u.net->sk; |
diff --git a/security/security.c b/security/security.c index e81d5bbe7363..595fffab48b0 100644 --- a/security/security.c +++ b/security/security.c | |||
| @@ -16,7 +16,7 @@ | |||
| 16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
| 17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
| 18 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
| 19 | #include <linux/security.h> | 19 | #include <linux/lsm_hooks.h> |
| 20 | #include <linux/integrity.h> | 20 | #include <linux/integrity.h> |
| 21 | #include <linux/ima.h> | 21 | #include <linux/ima.h> |
| 22 | #include <linux/evm.h> | 22 | #include <linux/evm.h> |
| @@ -29,24 +29,13 @@ | |||
| 29 | 29 | ||
| 30 | #define MAX_LSM_EVM_XATTR 2 | 30 | #define MAX_LSM_EVM_XATTR 2 |
| 31 | 31 | ||
| 32 | /* Maximum number of letters for an LSM name string */ | ||
| 33 | #define SECURITY_NAME_MAX 10 | ||
| 34 | |||
| 32 | /* Boot-time LSM user choice */ | 35 | /* Boot-time LSM user choice */ |
| 33 | static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] = | 36 | static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] = |
| 34 | CONFIG_DEFAULT_SECURITY; | 37 | CONFIG_DEFAULT_SECURITY; |
| 35 | 38 | ||
| 36 | static struct security_operations *security_ops; | ||
| 37 | static struct security_operations default_security_ops = { | ||
| 38 | .name = "default", | ||
| 39 | }; | ||
| 40 | |||
| 41 | static inline int __init verify(struct security_operations *ops) | ||
| 42 | { | ||
| 43 | /* verify the security_operations structure exists */ | ||
| 44 | if (!ops) | ||
| 45 | return -EINVAL; | ||
| 46 | security_fixup_ops(ops); | ||
| 47 | return 0; | ||
| 48 | } | ||
| 49 | |||
| 50 | static void __init do_security_initcalls(void) | 39 | static void __init do_security_initcalls(void) |
| 51 | { | 40 | { |
| 52 | initcall_t *call; | 41 | initcall_t *call; |
| @@ -64,20 +53,27 @@ static void __init do_security_initcalls(void) | |||
| 64 | */ | 53 | */ |
| 65 | int __init security_init(void) | 54 | int __init security_init(void) |
| 66 | { | 55 | { |
| 67 | printk(KERN_INFO "Security Framework initialized\n"); | 56 | pr_info("Security Framework initialized\n"); |
| 68 | 57 | ||
| 69 | security_fixup_ops(&default_security_ops); | 58 | /* |
| 70 | security_ops = &default_security_ops; | 59 | * Always load the capability module. |
| 60 | */ | ||
| 61 | capability_add_hooks(); | ||
| 62 | #ifdef CONFIG_SECURITY_YAMA_STACKED | ||
| 63 | /* | ||
| 64 | * If Yama is configured for stacking load it next. | ||
| 65 | */ | ||
| 66 | yama_add_hooks(); | ||
| 67 | #endif | ||
| 68 | /* | ||
| 69 | * Load the chosen module if there is one. | ||
| 70 | * This will also find yama if it is stacking | ||
| 71 | */ | ||
| 71 | do_security_initcalls(); | 72 | do_security_initcalls(); |
| 72 | 73 | ||
| 73 | return 0; | 74 | return 0; |
| 74 | } | 75 | } |
| 75 | 76 | ||
| 76 | void reset_security_ops(void) | ||
| 77 | { | ||
| 78 | security_ops = &default_security_ops; | ||
| 79 | } | ||
| 80 | |||
| 81 | /* Save user chosen LSM */ | 77 | /* Save user chosen LSM */ |
| 82 | static int __init choose_lsm(char *str) | 78 | static int __init choose_lsm(char *str) |
| 83 | { | 79 | { |
| @@ -88,7 +84,7 @@ __setup("security=", choose_lsm); | |||
| 88 | 84 | ||
| 89 | /** | 85 | /** |
| 90 | * security_module_enable - Load given security module on boot ? | 86 | * security_module_enable - Load given security module on boot ? |
| 91 | * @ops: a pointer to the struct security_operations that is to be checked. | 87 | * @module: the name of the module |
| 92 | * | 88 | * |
| 93 | * Each LSM must pass this method before registering its own operations | 89 | * Each LSM must pass this method before registering its own operations |
| 94 | * to avoid security registration races. This method may also be used | 90 | * to avoid security registration races. This method may also be used |
| @@ -100,84 +96,76 @@ __setup("security=", choose_lsm); | |||
| 100 | * choose an alternate LSM at boot time. | 96 | * choose an alternate LSM at boot time. |
| 101 | * Otherwise, return false. | 97 | * Otherwise, return false. |
| 102 | */ | 98 | */ |
| 103 | int __init security_module_enable(struct security_operations *ops) | 99 | int __init security_module_enable(const char *module) |
| 104 | { | 100 | { |
| 105 | return !strcmp(ops->name, chosen_lsm); | 101 | return !strcmp(module, chosen_lsm); |
| 106 | } | 102 | } |
| 107 | 103 | ||
| 108 | /** | 104 | /* |
| 109 | * register_security - registers a security framework with the kernel | 105 | * Hook list operation macros. |
| 110 | * @ops: a pointer to the struct security_options that is to be registered | ||
| 111 | * | 106 | * |
| 112 | * This function allows a security module to register itself with the | 107 | * call_void_hook: |
| 113 | * kernel security subsystem. Some rudimentary checking is done on the @ops | 108 | * This is a hook that does not return a value. |
| 114 | * value passed to this function. You'll need to check first if your LSM | ||
| 115 | * is allowed to register its @ops by calling security_module_enable(@ops). | ||
| 116 | * | 109 | * |
| 117 | * If there is already a security module registered with the kernel, | 110 | * call_int_hook: |
| 118 | * an error will be returned. Otherwise %0 is returned on success. | 111 | * This is a hook that returns a value. |
| 119 | */ | 112 | */ |
| 120 | int __init register_security(struct security_operations *ops) | ||
| 121 | { | ||
| 122 | if (verify(ops)) { | ||
| 123 | printk(KERN_DEBUG "%s could not verify " | ||
| 124 | "security_operations structure.\n", __func__); | ||
| 125 | return -EINVAL; | ||
| 126 | } | ||
| 127 | |||
| 128 | if (security_ops != &default_security_ops) | ||
| 129 | return -EAGAIN; | ||
| 130 | 113 | ||
| 131 | security_ops = ops; | 114 | #define call_void_hook(FUNC, ...) \ |
| 132 | 115 | do { \ | |
| 133 | return 0; | 116 | struct security_hook_list *P; \ |
| 134 | } | 117 | \ |
| 118 | list_for_each_entry(P, &security_hook_heads.FUNC, list) \ | ||
| 119 | P->hook.FUNC(__VA_ARGS__); \ | ||
| 120 | } while (0) | ||
| 121 | |||
| 122 | #define call_int_hook(FUNC, IRC, ...) ({ \ | ||
| 123 | int RC = IRC; \ | ||
| 124 | do { \ | ||
| 125 | struct security_hook_list *P; \ | ||
| 126 | \ | ||
| 127 | list_for_each_entry(P, &security_hook_heads.FUNC, list) { \ | ||
| 128 | RC = P->hook.FUNC(__VA_ARGS__); \ | ||
| 129 | if (RC != 0) \ | ||
| 130 | break; \ | ||
| 131 | } \ | ||
| 132 | } while (0); \ | ||
| 133 | RC; \ | ||
| 134 | }) | ||
| 135 | 135 | ||
| 136 | /* Security operations */ | 136 | /* Security operations */ |
| 137 | 137 | ||
| 138 | int security_binder_set_context_mgr(struct task_struct *mgr) | 138 | int security_binder_set_context_mgr(struct task_struct *mgr) |
| 139 | { | 139 | { |
| 140 | return security_ops->binder_set_context_mgr(mgr); | 140 | return call_int_hook(binder_set_context_mgr, 0, mgr); |
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | int security_binder_transaction(struct task_struct *from, | 143 | int security_binder_transaction(struct task_struct *from, |
| 144 | struct task_struct *to) | 144 | struct task_struct *to) |
| 145 | { | 145 | { |
| 146 | return security_ops->binder_transaction(from, to); | 146 | return call_int_hook(binder_transaction, 0, from, to); |
| 147 | } | 147 | } |
| 148 | 148 | ||
| 149 | int security_binder_transfer_binder(struct task_struct *from, | 149 | int security_binder_transfer_binder(struct task_struct *from, |
| 150 | struct task_struct *to) | 150 | struct task_struct *to) |
| 151 | { | 151 | { |
| 152 | return security_ops->binder_transfer_binder(from, to); | 152 | return call_int_hook(binder_transfer_binder, 0, from, to); |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | int security_binder_transfer_file(struct task_struct *from, | 155 | int security_binder_transfer_file(struct task_struct *from, |
| 156 | struct task_struct *to, struct file *file) | 156 | struct task_struct *to, struct file *file) |
| 157 | { | 157 | { |
| 158 | return security_ops->binder_transfer_file(from, to, file); | 158 | return call_int_hook(binder_transfer_file, 0, from, to, file); |
| 159 | } | 159 | } |
| 160 | 160 | ||
| 161 | int security_ptrace_access_check(struct task_struct *child, unsigned int mode) | 161 | int security_ptrace_access_check(struct task_struct *child, unsigned int mode) |
| 162 | { | 162 | { |
| 163 | #ifdef CONFIG_SECURITY_YAMA_STACKED | 163 | return call_int_hook(ptrace_access_check, 0, child, mode); |
| 164 | int rc; | ||
| 165 | rc = yama_ptrace_access_check(child, mode); | ||
| 166 | if (rc) | ||
| 167 | return rc; | ||
| 168 | #endif | ||
| 169 | return security_ops->ptrace_access_check(child, mode); | ||
| 170 | } | 164 | } |
| 171 | 165 | ||
| 172 | int security_ptrace_traceme(struct task_struct *parent) | 166 | int security_ptrace_traceme(struct task_struct *parent) |
| 173 | { | 167 | { |
| 174 | #ifdef CONFIG_SECURITY_YAMA_STACKED | 168 | return call_int_hook(ptrace_traceme, 0, parent); |
| 175 | int rc; | ||
| 176 | rc = yama_ptrace_traceme(parent); | ||
| 177 | if (rc) | ||
| 178 | return rc; | ||
| 179 | #endif | ||
| 180 | return security_ops->ptrace_traceme(parent); | ||
| 181 | } | 169 | } |
| 182 | 170 | ||
| 183 | int security_capget(struct task_struct *target, | 171 | int security_capget(struct task_struct *target, |
| @@ -185,7 +173,8 @@ int security_capget(struct task_struct *target, | |||
| 185 | kernel_cap_t *inheritable, | 173 | kernel_cap_t *inheritable, |
| 186 | kernel_cap_t *permitted) | 174 | kernel_cap_t *permitted) |
| 187 | { | 175 | { |
| 188 | return security_ops->capget(target, effective, inheritable, permitted); | 176 | return call_int_hook(capget, 0, target, |
| 177 | effective, inheritable, permitted); | ||
| 189 | } | 178 | } |
| 190 | 179 | ||
| 191 | int security_capset(struct cred *new, const struct cred *old, | 180 | int security_capset(struct cred *new, const struct cred *old, |
| @@ -193,57 +182,75 @@ int security_capset(struct cred *new, const struct cred *old, | |||
| 193 | const kernel_cap_t *inheritable, | 182 | const kernel_cap_t *inheritable, |
| 194 | const kernel_cap_t *permitted) | 183 | const kernel_cap_t *permitted) |
| 195 | { | 184 | { |
| 196 | return security_ops->capset(new, old, | 185 | return call_int_hook(capset, 0, new, old, |
| 197 | effective, inheritable, permitted); | 186 | effective, inheritable, permitted); |
| 198 | } | 187 | } |
| 199 | 188 | ||
| 200 | int security_capable(const struct cred *cred, struct user_namespace *ns, | 189 | int security_capable(const struct cred *cred, struct user_namespace *ns, |
| 201 | int cap) | 190 | int cap) |
| 202 | { | 191 | { |
| 203 | return security_ops->capable(cred, ns, cap, SECURITY_CAP_AUDIT); | 192 | return call_int_hook(capable, 0, cred, ns, cap, SECURITY_CAP_AUDIT); |
| 204 | } | 193 | } |
| 205 | 194 | ||
| 206 | int security_capable_noaudit(const struct cred *cred, struct user_namespace *ns, | 195 | int security_capable_noaudit(const struct cred *cred, struct user_namespace *ns, |
| 207 | int cap) | 196 | int cap) |
| 208 | { | 197 | { |
| 209 | return security_ops->capable(cred, ns, cap, SECURITY_CAP_NOAUDIT); | 198 | return call_int_hook(capable, 0, cred, ns, cap, SECURITY_CAP_NOAUDIT); |
| 210 | } | 199 | } |
| 211 | 200 | ||
| 212 | int security_quotactl(int cmds, int type, int id, struct super_block *sb) | 201 | int security_quotactl(int cmds, int type, int id, struct super_block *sb) |
| 213 | { | 202 | { |
| 214 | return security_ops->quotactl(cmds, type, id, sb); | 203 | return call_int_hook(quotactl, 0, cmds, type, id, sb); |
| 215 | } | 204 | } |
| 216 | 205 | ||
| 217 | int security_quota_on(struct dentry *dentry) | 206 | int security_quota_on(struct dentry *dentry) |
| 218 | { | 207 | { |
| 219 | return security_ops->quota_on(dentry); | 208 | return call_int_hook(quota_on, 0, dentry); |
| 220 | } | 209 | } |
| 221 | 210 | ||
| 222 | int security_syslog(int type) | 211 | int security_syslog(int type) |
| 223 | { | 212 | { |
| 224 | return security_ops->syslog(type); | 213 | return call_int_hook(syslog, 0, type); |
| 225 | } | 214 | } |
| 226 | 215 | ||
| 227 | int security_settime(const struct timespec *ts, const struct timezone *tz) | 216 | int security_settime(const struct timespec *ts, const struct timezone *tz) |
| 228 | { | 217 | { |
| 229 | return security_ops->settime(ts, tz); | 218 | return call_int_hook(settime, 0, ts, tz); |
| 230 | } | 219 | } |
| 231 | 220 | ||
| 232 | int security_vm_enough_memory_mm(struct mm_struct *mm, long pages) | 221 | int security_vm_enough_memory_mm(struct mm_struct *mm, long pages) |
| 233 | { | 222 | { |
| 234 | return security_ops->vm_enough_memory(mm, pages); | 223 | struct security_hook_list *hp; |
| 224 | int cap_sys_admin = 1; | ||
| 225 | int rc; | ||
| 226 | |||
| 227 | /* | ||
| 228 | * The module will respond with a positive value if | ||
| 229 | * it thinks the __vm_enough_memory() call should be | ||
| 230 | * made with the cap_sys_admin set. If all of the modules | ||
| 231 | * agree that it should be set it will. If any module | ||
| 232 | * thinks it should not be set it won't. | ||
| 233 | */ | ||
| 234 | list_for_each_entry(hp, &security_hook_heads.vm_enough_memory, list) { | ||
| 235 | rc = hp->hook.vm_enough_memory(mm, pages); | ||
| 236 | if (rc <= 0) { | ||
| 237 | cap_sys_admin = 0; | ||
| 238 | break; | ||
| 239 | } | ||
| 240 | } | ||
| 241 | return __vm_enough_memory(mm, pages, cap_sys_admin); | ||
| 235 | } | 242 | } |
| 236 | 243 | ||
| 237 | int security_bprm_set_creds(struct linux_binprm *bprm) | 244 | int security_bprm_set_creds(struct linux_binprm *bprm) |
| 238 | { | 245 | { |
| 239 | return security_ops->bprm_set_creds(bprm); | 246 | return call_int_hook(bprm_set_creds, 0, bprm); |
| 240 | } | 247 | } |
| 241 | 248 | ||
| 242 | int security_bprm_check(struct linux_binprm *bprm) | 249 | int security_bprm_check(struct linux_binprm *bprm) |
| 243 | { | 250 | { |
| 244 | int ret; | 251 | int ret; |
| 245 | 252 | ||
| 246 | ret = security_ops->bprm_check_security(bprm); | 253 | ret = call_int_hook(bprm_check_security, 0, bprm); |
| 247 | if (ret) | 254 | if (ret) |
| 248 | return ret; | 255 | return ret; |
| 249 | return ima_bprm_check(bprm); | 256 | return ima_bprm_check(bprm); |
| @@ -251,69 +258,69 @@ int security_bprm_check(struct linux_binprm *bprm) | |||
| 251 | 258 | ||
| 252 | void security_bprm_committing_creds(struct linux_binprm *bprm) | 259 | void security_bprm_committing_creds(struct linux_binprm *bprm) |
| 253 | { | 260 | { |
| 254 | security_ops->bprm_committing_creds(bprm); | 261 | call_void_hook(bprm_committing_creds, bprm); |
| 255 | } | 262 | } |
| 256 | 263 | ||
| 257 | void security_bprm_committed_creds(struct linux_binprm *bprm) | 264 | void security_bprm_committed_creds(struct linux_binprm *bprm) |
| 258 | { | 265 | { |
| 259 | security_ops->bprm_committed_creds(bprm); | 266 | call_void_hook(bprm_committed_creds, bprm); |
| 260 | } | 267 | } |
| 261 | 268 | ||
| 262 | int security_bprm_secureexec(struct linux_binprm *bprm) | 269 | int security_bprm_secureexec(struct linux_binprm *bprm) |
| 263 | { | 270 | { |
| 264 | return security_ops->bprm_secureexec(bprm); | 271 | return call_int_hook(bprm_secureexec, 0, bprm); |
| 265 | } | 272 | } |
| 266 | 273 | ||
| 267 | int security_sb_alloc(struct super_block *sb) | 274 | int security_sb_alloc(struct super_block *sb) |
| 268 | { | 275 | { |
| 269 | return security_ops->sb_alloc_security(sb); | 276 | return call_int_hook(sb_alloc_security, 0, sb); |
| 270 | } | 277 | } |
| 271 | 278 | ||
| 272 | void security_sb_free(struct super_block *sb) | 279 | void security_sb_free(struct super_block *sb) |
| 273 | { | 280 | { |
| 274 | security_ops->sb_free_security(sb); | 281 | call_void_hook(sb_free_security, sb); |
| 275 | } | 282 | } |
| 276 | 283 | ||
| 277 | int security_sb_copy_data(char *orig, char *copy) | 284 | int security_sb_copy_data(char *orig, char *copy) |
| 278 | { | 285 | { |
| 279 | return security_ops->sb_copy_data(orig, copy); | 286 | return call_int_hook(sb_copy_data, 0, orig, copy); |
| 280 | } | 287 | } |
| 281 | EXPORT_SYMBOL(security_sb_copy_data); | 288 | EXPORT_SYMBOL(security_sb_copy_data); |
| 282 | 289 | ||
| 283 | int security_sb_remount(struct super_block *sb, void *data) | 290 | int security_sb_remount(struct super_block *sb, void *data) |
| 284 | { | 291 | { |
| 285 | return security_ops->sb_remount(sb, data); | 292 | return call_int_hook(sb_remount, 0, sb, data); |
| 286 | } | 293 | } |
| 287 | 294 | ||
| 288 | int security_sb_kern_mount(struct super_block *sb, int flags, void *data) | 295 | int security_sb_kern_mount(struct super_block *sb, int flags, void *data) |
| 289 | { | 296 | { |
| 290 | return security_ops->sb_kern_mount(sb, flags, data); | 297 | return call_int_hook(sb_kern_mount, 0, sb, flags, data); |
| 291 | } | 298 | } |
| 292 | 299 | ||
| 293 | int security_sb_show_options(struct seq_file *m, struct super_block *sb) | 300 | int security_sb_show_options(struct seq_file *m, struct super_block *sb) |
| 294 | { | 301 | { |
| 295 | return security_ops->sb_show_options(m, sb); | 302 | return call_int_hook(sb_show_options, 0, m, sb); |
| 296 | } | 303 | } |
| 297 | 304 | ||
| 298 | int security_sb_statfs(struct dentry *dentry) | 305 | int security_sb_statfs(struct dentry *dentry) |
| 299 | { | 306 | { |
| 300 | return security_ops->sb_statfs(dentry); | 307 | return call_int_hook(sb_statfs, 0, dentry); |
| 301 | } | 308 | } |
| 302 | 309 | ||
| 303 | int security_sb_mount(const char *dev_name, struct path *path, | 310 | int security_sb_mount(const char *dev_name, struct path *path, |
| 304 | const char *type, unsigned long flags, void *data) | 311 | const char *type, unsigned long flags, void *data) |
| 305 | { | 312 | { |
| 306 | return security_ops->sb_mount(dev_name, path, type, flags, data); | 313 | return call_int_hook(sb_mount, 0, dev_name, path, type, flags, data); |
| 307 | } | 314 | } |
| 308 | 315 | ||
| 309 | int security_sb_umount(struct vfsmount *mnt, int flags) | 316 | int security_sb_umount(struct vfsmount *mnt, int flags) |
| 310 | { | 317 | { |
| 311 | return security_ops->sb_umount(mnt, flags); | 318 | return call_int_hook(sb_umount, 0, mnt, flags); |
| 312 | } | 319 | } |
| 313 | 320 | ||
| 314 | int security_sb_pivotroot(struct path *old_path, struct path *new_path) | 321 | int security_sb_pivotroot(struct path *old_path, struct path *new_path) |
| 315 | { | 322 | { |
| 316 | return security_ops->sb_pivotroot(old_path, new_path); | 323 | return call_int_hook(sb_pivotroot, 0, old_path, new_path); |
| 317 | } | 324 | } |
| 318 | 325 | ||
| 319 | int security_sb_set_mnt_opts(struct super_block *sb, | 326 | int security_sb_set_mnt_opts(struct super_block *sb, |
| @@ -321,42 +328,43 @@ int security_sb_set_mnt_opts(struct super_block *sb, | |||
| 321 | unsigned long kern_flags, | 328 | unsigned long kern_flags, |
| 322 | unsigned long *set_kern_flags) | 329 | unsigned long *set_kern_flags) |
| 323 | { | 330 | { |
| 324 | return security_ops->sb_set_mnt_opts(sb, opts, kern_flags, | 331 | return call_int_hook(sb_set_mnt_opts, |
| 325 | set_kern_flags); | 332 | opts->num_mnt_opts ? -EOPNOTSUPP : 0, sb, |
| 333 | opts, kern_flags, set_kern_flags); | ||
| 326 | } | 334 | } |
| 327 | EXPORT_SYMBOL(security_sb_set_mnt_opts); | 335 | EXPORT_SYMBOL(security_sb_set_mnt_opts); |
| 328 | 336 | ||
| 329 | int security_sb_clone_mnt_opts(const struct super_block *oldsb, | 337 | int security_sb_clone_mnt_opts(const struct super_block *oldsb, |
| 330 | struct super_block *newsb) | 338 | struct super_block *newsb) |
| 331 | { | 339 | { |
| 332 | return security_ops->sb_clone_mnt_opts(oldsb, newsb); | 340 | return call_int_hook(sb_clone_mnt_opts, 0, oldsb, newsb); |
| 333 | } | 341 | } |
| 334 | EXPORT_SYMBOL(security_sb_clone_mnt_opts); | 342 | EXPORT_SYMBOL(security_sb_clone_mnt_opts); |
| 335 | 343 | ||
| 336 | int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts) | 344 | int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts) |
| 337 | { | 345 | { |
| 338 | return security_ops->sb_parse_opts_str(options, opts); | 346 | return call_int_hook(sb_parse_opts_str, 0, options, opts); |
| 339 | } | 347 | } |
| 340 | EXPORT_SYMBOL(security_sb_parse_opts_str); | 348 | EXPORT_SYMBOL(security_sb_parse_opts_str); |
| 341 | 349 | ||
| 342 | int security_inode_alloc(struct inode *inode) | 350 | int security_inode_alloc(struct inode *inode) |
| 343 | { | 351 | { |
| 344 | inode->i_security = NULL; | 352 | inode->i_security = NULL; |
| 345 | return security_ops->inode_alloc_security(inode); | 353 | return call_int_hook(inode_alloc_security, 0, inode); |
| 346 | } | 354 | } |
| 347 | 355 | ||
| 348 | void security_inode_free(struct inode *inode) | 356 | void security_inode_free(struct inode *inode) |
| 349 | { | 357 | { |
| 350 | integrity_inode_free(inode); | 358 | integrity_inode_free(inode); |
| 351 | security_ops->inode_free_security(inode); | 359 | call_void_hook(inode_free_security, inode); |
| 352 | } | 360 | } |
| 353 | 361 | ||
| 354 | int security_dentry_init_security(struct dentry *dentry, int mode, | 362 | int security_dentry_init_security(struct dentry *dentry, int mode, |
| 355 | struct qstr *name, void **ctx, | 363 | struct qstr *name, void **ctx, |
| 356 | u32 *ctxlen) | 364 | u32 *ctxlen) |
| 357 | { | 365 | { |
| 358 | return security_ops->dentry_init_security(dentry, mode, name, | 366 | return call_int_hook(dentry_init_security, -EOPNOTSUPP, dentry, mode, |
| 359 | ctx, ctxlen); | 367 | name, ctx, ctxlen); |
| 360 | } | 368 | } |
| 361 | EXPORT_SYMBOL(security_dentry_init_security); | 369 | EXPORT_SYMBOL(security_dentry_init_security); |
| 362 | 370 | ||
| @@ -372,11 +380,11 @@ int security_inode_init_security(struct inode *inode, struct inode *dir, | |||
| 372 | return 0; | 380 | return 0; |
| 373 | 381 | ||
| 374 | if (!initxattrs) | 382 | if (!initxattrs) |
| 375 | return security_ops->inode_init_security(inode, dir, qstr, | 383 | return call_int_hook(inode_init_security, 0, inode, dir, qstr, |
| 376 | NULL, NULL, NULL); | 384 | NULL, NULL, NULL); |
| 377 | memset(new_xattrs, 0, sizeof(new_xattrs)); | 385 | memset(new_xattrs, 0, sizeof(new_xattrs)); |
| 378 | lsm_xattr = new_xattrs; | 386 | lsm_xattr = new_xattrs; |
| 379 | ret = security_ops->inode_init_security(inode, dir, qstr, | 387 | ret = call_int_hook(inode_init_security, -EOPNOTSUPP, inode, dir, qstr, |
| 380 | &lsm_xattr->name, | 388 | &lsm_xattr->name, |
| 381 | &lsm_xattr->value, | 389 | &lsm_xattr->value, |
| 382 | &lsm_xattr->value_len); | 390 | &lsm_xattr->value_len); |
| @@ -401,8 +409,8 @@ int security_old_inode_init_security(struct inode *inode, struct inode *dir, | |||
| 401 | { | 409 | { |
| 402 | if (unlikely(IS_PRIVATE(inode))) | 410 | if (unlikely(IS_PRIVATE(inode))) |
| 403 | return -EOPNOTSUPP; | 411 | return -EOPNOTSUPP; |
| 404 | return security_ops->inode_init_security(inode, dir, qstr, name, value, | 412 | return call_int_hook(inode_init_security, 0, inode, dir, qstr, |
| 405 | len); | 413 | name, value, len); |
| 406 | } | 414 | } |
| 407 | EXPORT_SYMBOL(security_old_inode_init_security); | 415 | EXPORT_SYMBOL(security_old_inode_init_security); |
| 408 | 416 | ||
| @@ -410,95 +418,95 @@ EXPORT_SYMBOL(security_old_inode_init_security); | |||
| 410 | int security_path_mknod(struct path *dir, struct dentry *dentry, umode_t mode, | 418 | int security_path_mknod(struct path *dir, struct dentry *dentry, umode_t mode, |
| 411 | unsigned int dev) | 419 | unsigned int dev) |
| 412 | { | 420 | { |
| 413 | if (unlikely(IS_PRIVATE(dir->dentry->d_inode))) | 421 | if (unlikely(IS_PRIVATE(d_backing_inode(dir->dentry)))) |
| 414 | return 0; | 422 | return 0; |
| 415 | return security_ops->path_mknod(dir, dentry, mode, dev); | 423 | return call_int_hook(path_mknod, 0, dir, dentry, mode, dev); |
| 416 | } | 424 | } |
| 417 | EXPORT_SYMBOL(security_path_mknod); | 425 | EXPORT_SYMBOL(security_path_mknod); |
| 418 | 426 | ||
| 419 | int security_path_mkdir(struct path *dir, struct dentry *dentry, umode_t mode) | 427 | int security_path_mkdir(struct path *dir, struct dentry *dentry, umode_t mode) |
| 420 | { | 428 | { |
| 421 | if (unlikely(IS_PRIVATE(dir->dentry->d_inode))) | 429 | if (unlikely(IS_PRIVATE(d_backing_inode(dir->dentry)))) |
| 422 | return 0; | 430 | return 0; |
| 423 | return security_ops->path_mkdir(dir, dentry, mode); | 431 | return call_int_hook(path_mkdir, 0, dir, dentry, mode); |
| 424 | } | 432 | } |
| 425 | EXPORT_SYMBOL(security_path_mkdir); | 433 | EXPORT_SYMBOL(security_path_mkdir); |
| 426 | 434 | ||
| 427 | int security_path_rmdir(struct path *dir, struct dentry *dentry) | 435 | int security_path_rmdir(struct path *dir, struct dentry *dentry) |
| 428 | { | 436 | { |
| 429 | if (unlikely(IS_PRIVATE(dir->dentry->d_inode))) | 437 | if (unlikely(IS_PRIVATE(d_backing_inode(dir->dentry)))) |
| 430 | return 0; | 438 | return 0; |
| 431 | return security_ops->path_rmdir(dir, dentry); | 439 | return call_int_hook(path_rmdir, 0, dir, dentry); |
| 432 | } | 440 | } |
| 433 | 441 | ||
| 434 | int security_path_unlink(struct path *dir, struct dentry *dentry) | 442 | int security_path_unlink(struct path *dir, struct dentry *dentry) |
| 435 | { | 443 | { |
| 436 | if (unlikely(IS_PRIVATE(dir->dentry->d_inode))) | 444 | if (unlikely(IS_PRIVATE(d_backing_inode(dir->dentry)))) |
| 437 | return 0; | 445 | return 0; |
| 438 | return security_ops->path_unlink(dir, dentry); | 446 | return call_int_hook(path_unlink, 0, dir, dentry); |
| 439 | } | 447 | } |
| 440 | EXPORT_SYMBOL(security_path_unlink); | 448 | EXPORT_SYMBOL(security_path_unlink); |
| 441 | 449 | ||
| 442 | int security_path_symlink(struct path *dir, struct dentry *dentry, | 450 | int security_path_symlink(struct path *dir, struct dentry *dentry, |
| 443 | const char *old_name) | 451 | const char *old_name) |
| 444 | { | 452 | { |
| 445 | if (unlikely(IS_PRIVATE(dir->dentry->d_inode))) | 453 | if (unlikely(IS_PRIVATE(d_backing_inode(dir->dentry)))) |
| 446 | return 0; | 454 | return 0; |
| 447 | return security_ops->path_symlink(dir, dentry, old_name); | 455 | return call_int_hook(path_symlink, 0, dir, dentry, old_name); |
| 448 | } | 456 | } |
| 449 | 457 | ||
| 450 | int security_path_link(struct dentry *old_dentry, struct path *new_dir, | 458 | int security_path_link(struct dentry *old_dentry, struct path *new_dir, |
| 451 | struct dentry *new_dentry) | 459 | struct dentry *new_dentry) |
| 452 | { | 460 | { |
| 453 | if (unlikely(IS_PRIVATE(old_dentry->d_inode))) | 461 | if (unlikely(IS_PRIVATE(d_backing_inode(old_dentry)))) |
| 454 | return 0; | 462 | return 0; |
| 455 | return security_ops->path_link(old_dentry, new_dir, new_dentry); | 463 | return call_int_hook(path_link, 0, old_dentry, new_dir, new_dentry); |
| 456 | } | 464 | } |
| 457 | 465 | ||
| 458 | int security_path_rename(struct path *old_dir, struct dentry *old_dentry, | 466 | int security_path_rename(struct path *old_dir, struct dentry *old_dentry, |
| 459 | struct path *new_dir, struct dentry *new_dentry, | 467 | struct path *new_dir, struct dentry *new_dentry, |
| 460 | unsigned int flags) | 468 | unsigned int flags) |
| 461 | { | 469 | { |
| 462 | if (unlikely(IS_PRIVATE(old_dentry->d_inode) || | 470 | if (unlikely(IS_PRIVATE(d_backing_inode(old_dentry)) || |
| 463 | (new_dentry->d_inode && IS_PRIVATE(new_dentry->d_inode)))) | 471 | (d_is_positive(new_dentry) && IS_PRIVATE(d_backing_inode(new_dentry))))) |
| 464 | return 0; | 472 | return 0; |
| 465 | 473 | ||
| 466 | if (flags & RENAME_EXCHANGE) { | 474 | if (flags & RENAME_EXCHANGE) { |
| 467 | int err = security_ops->path_rename(new_dir, new_dentry, | 475 | int err = call_int_hook(path_rename, 0, new_dir, new_dentry, |
| 468 | old_dir, old_dentry); | 476 | old_dir, old_dentry); |
| 469 | if (err) | 477 | if (err) |
| 470 | return err; | 478 | return err; |
| 471 | } | 479 | } |
| 472 | 480 | ||
| 473 | return security_ops->path_rename(old_dir, old_dentry, new_dir, | 481 | return call_int_hook(path_rename, 0, old_dir, old_dentry, new_dir, |
| 474 | new_dentry); | 482 | new_dentry); |
| 475 | } | 483 | } |
| 476 | EXPORT_SYMBOL(security_path_rename); | 484 | EXPORT_SYMBOL(security_path_rename); |
| 477 | 485 | ||
| 478 | int security_path_truncate(struct path *path) | 486 | int security_path_truncate(struct path *path) |
| 479 | { | 487 | { |
| 480 | if (unlikely(IS_PRIVATE(path->dentry->d_inode))) | 488 | if (unlikely(IS_PRIVATE(d_backing_inode(path->dentry)))) |
| 481 | return 0; | 489 | return 0; |
| 482 | return security_ops->path_truncate(path); | 490 | return call_int_hook(path_truncate, 0, path); |
| 483 | } | 491 | } |
| 484 | 492 | ||
| 485 | int security_path_chmod(struct path *path, umode_t mode) | 493 | int security_path_chmod(struct path *path, umode_t mode) |
| 486 | { | 494 | { |
| 487 | if (unlikely(IS_PRIVATE(path->dentry->d_inode))) | 495 | if (unlikely(IS_PRIVATE(d_backing_inode(path->dentry)))) |
| 488 | return 0; | 496 | return 0; |
| 489 | return security_ops->path_chmod(path, mode); | 497 | return call_int_hook(path_chmod, 0, path, mode); |
| 490 | } | 498 | } |
| 491 | 499 | ||
| 492 | int security_path_chown(struct path *path, kuid_t uid, kgid_t gid) | 500 | int security_path_chown(struct path *path, kuid_t uid, kgid_t gid) |
| 493 | { | 501 | { |
| 494 | if (unlikely(IS_PRIVATE(path->dentry->d_inode))) | 502 | if (unlikely(IS_PRIVATE(d_backing_inode(path->dentry)))) |
| 495 | return 0; | 503 | return 0; |
| 496 | return security_ops->path_chown(path, uid, gid); | 504 | return call_int_hook(path_chown, 0, path, uid, gid); |
| 497 | } | 505 | } |
| 498 | 506 | ||
| 499 | int security_path_chroot(struct path *path) | 507 | int security_path_chroot(struct path *path) |
| 500 | { | 508 | { |
| 501 | return security_ops->path_chroot(path); | 509 | return call_int_hook(path_chroot, 0, path); |
| 502 | } | 510 | } |
| 503 | #endif | 511 | #endif |
| 504 | 512 | ||
| @@ -506,23 +514,23 @@ int security_inode_create(struct inode *dir, struct dentry *dentry, umode_t mode | |||
| 506 | { | 514 | { |
| 507 | if (unlikely(IS_PRIVATE(dir))) | 515 | if (unlikely(IS_PRIVATE(dir))) |
| 508 | return 0; | 516 | return 0; |
| 509 | return security_ops->inode_create(dir, dentry, mode); | 517 | return call_int_hook(inode_create, 0, dir, dentry, mode); |
| 510 | } | 518 | } |
| 511 | EXPORT_SYMBOL_GPL(security_inode_create); | 519 | EXPORT_SYMBOL_GPL(security_inode_create); |
| 512 | 520 | ||
| 513 | int security_inode_link(struct dentry *old_dentry, struct inode *dir, | 521 | int security_inode_link(struct dentry *old_dentry, struct inode *dir, |
| 514 | struct dentry *new_dentry) | 522 | struct dentry *new_dentry) |
| 515 | { | 523 | { |
| 516 | if (unlikely(IS_PRIVATE(old_dentry->d_inode))) | 524 | if (unlikely(IS_PRIVATE(d_backing_inode(old_dentry)))) |
| 517 | return 0; | 525 | return 0; |
| 518 | return security_ops->inode_link(old_dentry, dir, new_dentry); | 526 | return call_int_hook(inode_link, 0, old_dentry, dir, new_dentry); |
| 519 | } | 527 | } |
| 520 | 528 | ||
| 521 | int security_inode_unlink(struct inode *dir, struct dentry *dentry) | 529 | int security_inode_unlink(struct inode *dir, struct dentry *dentry) |
| 522 | { | 530 | { |
| 523 | if (unlikely(IS_PRIVATE(dentry->d_inode))) | 531 | if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) |
| 524 | return 0; | 532 | return 0; |
| 525 | return security_ops->inode_unlink(dir, dentry); | 533 | return call_int_hook(inode_unlink, 0, dir, dentry); |
| 526 | } | 534 | } |
| 527 | 535 | ||
| 528 | int security_inode_symlink(struct inode *dir, struct dentry *dentry, | 536 | int security_inode_symlink(struct inode *dir, struct dentry *dentry, |
| @@ -530,89 +538,90 @@ int security_inode_symlink(struct inode *dir, struct dentry *dentry, | |||
| 530 | { | 538 | { |
| 531 | if (unlikely(IS_PRIVATE(dir))) | 539 | if (unlikely(IS_PRIVATE(dir))) |
| 532 | return 0; | 540 | return 0; |
| 533 | return security_ops->inode_symlink(dir, dentry, old_name); | 541 | return call_int_hook(inode_symlink, 0, dir, dentry, old_name); |
| 534 | } | 542 | } |
| 535 | 543 | ||
| 536 | int security_inode_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | 544 | int security_inode_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) |
| 537 | { | 545 | { |
| 538 | if (unlikely(IS_PRIVATE(dir))) | 546 | if (unlikely(IS_PRIVATE(dir))) |
| 539 | return 0; | 547 | return 0; |
| 540 | return security_ops->inode_mkdir(dir, dentry, mode); | 548 | return call_int_hook(inode_mkdir, 0, dir, dentry, mode); |
| 541 | } | 549 | } |
| 542 | EXPORT_SYMBOL_GPL(security_inode_mkdir); | 550 | EXPORT_SYMBOL_GPL(security_inode_mkdir); |
| 543 | 551 | ||
| 544 | int security_inode_rmdir(struct inode *dir, struct dentry *dentry) | 552 | int security_inode_rmdir(struct inode *dir, struct dentry *dentry) |
| 545 | { | 553 | { |
| 546 | if (unlikely(IS_PRIVATE(dentry->d_inode))) | 554 | if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) |
| 547 | return 0; | 555 | return 0; |
| 548 | return security_ops->inode_rmdir(dir, dentry); | 556 | return call_int_hook(inode_rmdir, 0, dir, dentry); |
| 549 | } | 557 | } |
| 550 | 558 | ||
| 551 | int security_inode_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) | 559 | int security_inode_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) |
| 552 | { | 560 | { |
| 553 | if (unlikely(IS_PRIVATE(dir))) | 561 | if (unlikely(IS_PRIVATE(dir))) |
| 554 | return 0; | 562 | return 0; |
| 555 | return security_ops->inode_mknod(dir, dentry, mode, dev); | 563 | return call_int_hook(inode_mknod, 0, dir, dentry, mode, dev); |
| 556 | } | 564 | } |
| 557 | 565 | ||
| 558 | int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry, | 566 | int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry, |
| 559 | struct inode *new_dir, struct dentry *new_dentry, | 567 | struct inode *new_dir, struct dentry *new_dentry, |
| 560 | unsigned int flags) | 568 | unsigned int flags) |
| 561 | { | 569 | { |
| 562 | if (unlikely(IS_PRIVATE(old_dentry->d_inode) || | 570 | if (unlikely(IS_PRIVATE(d_backing_inode(old_dentry)) || |
| 563 | (new_dentry->d_inode && IS_PRIVATE(new_dentry->d_inode)))) | 571 | (d_is_positive(new_dentry) && IS_PRIVATE(d_backing_inode(new_dentry))))) |
| 564 | return 0; | 572 | return 0; |
| 565 | 573 | ||
| 566 | if (flags & RENAME_EXCHANGE) { | 574 | if (flags & RENAME_EXCHANGE) { |
| 567 | int err = security_ops->inode_rename(new_dir, new_dentry, | 575 | int err = call_int_hook(inode_rename, 0, new_dir, new_dentry, |
| 568 | old_dir, old_dentry); | 576 | old_dir, old_dentry); |
| 569 | if (err) | 577 | if (err) |
| 570 | return err; | 578 | return err; |
| 571 | } | 579 | } |
| 572 | 580 | ||
| 573 | return security_ops->inode_rename(old_dir, old_dentry, | 581 | return call_int_hook(inode_rename, 0, old_dir, old_dentry, |
| 574 | new_dir, new_dentry); | 582 | new_dir, new_dentry); |
| 575 | } | 583 | } |
| 576 | 584 | ||
| 577 | int security_inode_readlink(struct dentry *dentry) | 585 | int security_inode_readlink(struct dentry *dentry) |
| 578 | { | 586 | { |
| 579 | if (unlikely(IS_PRIVATE(dentry->d_inode))) | 587 | if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) |
| 580 | return 0; | 588 | return 0; |
| 581 | return security_ops->inode_readlink(dentry); | 589 | return call_int_hook(inode_readlink, 0, dentry); |
| 582 | } | 590 | } |
| 583 | 591 | ||
| 584 | int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd) | 592 | int security_inode_follow_link(struct dentry *dentry, struct inode *inode, |
| 593 | bool rcu) | ||
| 585 | { | 594 | { |
| 586 | if (unlikely(IS_PRIVATE(dentry->d_inode))) | 595 | if (unlikely(IS_PRIVATE(inode))) |
| 587 | return 0; | 596 | return 0; |
| 588 | return security_ops->inode_follow_link(dentry, nd); | 597 | return call_int_hook(inode_follow_link, 0, dentry, inode, rcu); |
| 589 | } | 598 | } |
| 590 | 599 | ||
| 591 | int security_inode_permission(struct inode *inode, int mask) | 600 | int security_inode_permission(struct inode *inode, int mask) |
| 592 | { | 601 | { |
| 593 | if (unlikely(IS_PRIVATE(inode))) | 602 | if (unlikely(IS_PRIVATE(inode))) |
| 594 | return 0; | 603 | return 0; |
| 595 | return security_ops->inode_permission(inode, mask); | 604 | return call_int_hook(inode_permission, 0, inode, mask); |
| 596 | } | 605 | } |
| 597 | 606 | ||
| 598 | int security_inode_setattr(struct dentry *dentry, struct iattr *attr) | 607 | int security_inode_setattr(struct dentry *dentry, struct iattr *attr) |
| 599 | { | 608 | { |
| 600 | int ret; | 609 | int ret; |
| 601 | 610 | ||
| 602 | if (unlikely(IS_PRIVATE(dentry->d_inode))) | 611 | if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) |
| 603 | return 0; | 612 | return 0; |
| 604 | ret = security_ops->inode_setattr(dentry, attr); | 613 | ret = call_int_hook(inode_setattr, 0, dentry, attr); |
| 605 | if (ret) | 614 | if (ret) |
| 606 | return ret; | 615 | return ret; |
| 607 | return evm_inode_setattr(dentry, attr); | 616 | return evm_inode_setattr(dentry, attr); |
| 608 | } | 617 | } |
| 609 | EXPORT_SYMBOL_GPL(security_inode_setattr); | 618 | EXPORT_SYMBOL_GPL(security_inode_setattr); |
| 610 | 619 | ||
| 611 | int security_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) | 620 | int security_inode_getattr(const struct path *path) |
| 612 | { | 621 | { |
| 613 | if (unlikely(IS_PRIVATE(dentry->d_inode))) | 622 | if (unlikely(IS_PRIVATE(d_backing_inode(path->dentry)))) |
| 614 | return 0; | 623 | return 0; |
| 615 | return security_ops->inode_getattr(mnt, dentry); | 624 | return call_int_hook(inode_getattr, 0, path); |
| 616 | } | 625 | } |
| 617 | 626 | ||
| 618 | int security_inode_setxattr(struct dentry *dentry, const char *name, | 627 | int security_inode_setxattr(struct dentry *dentry, const char *name, |
| @@ -620,9 +629,17 @@ int security_inode_setxattr(struct dentry *dentry, const char *name, | |||
| 620 | { | 629 | { |
| 621 | int ret; | 630 | int ret; |
| 622 | 631 | ||
| 623 | if (unlikely(IS_PRIVATE(dentry->d_inode))) | 632 | if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) |
| 624 | return 0; | 633 | return 0; |
| 625 | ret = security_ops->inode_setxattr(dentry, name, value, size, flags); | 634 | /* |
| 635 | * SELinux and Smack integrate the cap call, | ||
| 636 | * so assume that all LSMs supplying this call do so. | ||
| 637 | */ | ||
| 638 | ret = call_int_hook(inode_setxattr, 1, dentry, name, value, size, | ||
| 639 | flags); | ||
| 640 | |||
| 641 | if (ret == 1) | ||
| 642 | ret = cap_inode_setxattr(dentry, name, value, size, flags); | ||
| 626 | if (ret) | 643 | if (ret) |
| 627 | return ret; | 644 | return ret; |
| 628 | ret = ima_inode_setxattr(dentry, name, value, size); | 645 | ret = ima_inode_setxattr(dentry, name, value, size); |
| @@ -634,33 +651,39 @@ int security_inode_setxattr(struct dentry *dentry, const char *name, | |||
| 634 | void security_inode_post_setxattr(struct dentry *dentry, const char *name, | 651 | void security_inode_post_setxattr(struct dentry *dentry, const char *name, |
| 635 | const void *value, size_t size, int flags) | 652 | const void *value, size_t size, int flags) |
| 636 | { | 653 | { |
| 637 | if (unlikely(IS_PRIVATE(dentry->d_inode))) | 654 | if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) |
| 638 | return; | 655 | return; |
| 639 | security_ops->inode_post_setxattr(dentry, name, value, size, flags); | 656 | call_void_hook(inode_post_setxattr, dentry, name, value, size, flags); |
| 640 | evm_inode_post_setxattr(dentry, name, value, size); | 657 | evm_inode_post_setxattr(dentry, name, value, size); |
| 641 | } | 658 | } |
| 642 | 659 | ||
| 643 | int security_inode_getxattr(struct dentry *dentry, const char *name) | 660 | int security_inode_getxattr(struct dentry *dentry, const char *name) |
| 644 | { | 661 | { |
| 645 | if (unlikely(IS_PRIVATE(dentry->d_inode))) | 662 | if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) |
| 646 | return 0; | 663 | return 0; |
| 647 | return security_ops->inode_getxattr(dentry, name); | 664 | return call_int_hook(inode_getxattr, 0, dentry, name); |
| 648 | } | 665 | } |
| 649 | 666 | ||
| 650 | int security_inode_listxattr(struct dentry *dentry) | 667 | int security_inode_listxattr(struct dentry *dentry) |
| 651 | { | 668 | { |
| 652 | if (unlikely(IS_PRIVATE(dentry->d_inode))) | 669 | if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) |
| 653 | return 0; | 670 | return 0; |
| 654 | return security_ops->inode_listxattr(dentry); | 671 | return call_int_hook(inode_listxattr, 0, dentry); |
| 655 | } | 672 | } |
| 656 | 673 | ||
| 657 | int security_inode_removexattr(struct dentry *dentry, const char *name) | 674 | int security_inode_removexattr(struct dentry *dentry, const char *name) |
| 658 | { | 675 | { |
| 659 | int ret; | 676 | int ret; |
| 660 | 677 | ||
| 661 | if (unlikely(IS_PRIVATE(dentry->d_inode))) | 678 | if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) |
| 662 | return 0; | 679 | return 0; |
| 663 | ret = security_ops->inode_removexattr(dentry, name); | 680 | /* |
| 681 | * SELinux and Smack integrate the cap call, | ||
| 682 | * so assume that all LSMs supplying this call do so. | ||
| 683 | */ | ||
| 684 | ret = call_int_hook(inode_removexattr, 1, dentry, name); | ||
| 685 | if (ret == 1) | ||
| 686 | ret = cap_inode_removexattr(dentry, name); | ||
| 664 | if (ret) | 687 | if (ret) |
| 665 | return ret; | 688 | return ret; |
| 666 | ret = ima_inode_removexattr(dentry, name); | 689 | ret = ima_inode_removexattr(dentry, name); |
| @@ -671,46 +694,48 @@ int security_inode_removexattr(struct dentry *dentry, const char *name) | |||
| 671 | 694 | ||
| 672 | int security_inode_need_killpriv(struct dentry *dentry) | 695 | int security_inode_need_killpriv(struct dentry *dentry) |
| 673 | { | 696 | { |
| 674 | return security_ops->inode_need_killpriv(dentry); | 697 | return call_int_hook(inode_need_killpriv, 0, dentry); |
| 675 | } | 698 | } |
| 676 | 699 | ||
| 677 | int security_inode_killpriv(struct dentry *dentry) | 700 | int security_inode_killpriv(struct dentry *dentry) |
| 678 | { | 701 | { |
| 679 | return security_ops->inode_killpriv(dentry); | 702 | return call_int_hook(inode_killpriv, 0, dentry); |
| 680 | } | 703 | } |
| 681 | 704 | ||
| 682 | int security_inode_getsecurity(const struct inode *inode, const char *name, void **buffer, bool alloc) | 705 | int security_inode_getsecurity(const struct inode *inode, const char *name, void **buffer, bool alloc) |
| 683 | { | 706 | { |
| 684 | if (unlikely(IS_PRIVATE(inode))) | 707 | if (unlikely(IS_PRIVATE(inode))) |
| 685 | return -EOPNOTSUPP; | 708 | return -EOPNOTSUPP; |
| 686 | return security_ops->inode_getsecurity(inode, name, buffer, alloc); | 709 | return call_int_hook(inode_getsecurity, -EOPNOTSUPP, inode, name, |
| 710 | buffer, alloc); | ||
| 687 | } | 711 | } |
| 688 | 712 | ||
| 689 | int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags) | 713 | int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags) |
| 690 | { | 714 | { |
| 691 | if (unlikely(IS_PRIVATE(inode))) | 715 | if (unlikely(IS_PRIVATE(inode))) |
| 692 | return -EOPNOTSUPP; | 716 | return -EOPNOTSUPP; |
| 693 | return security_ops->inode_setsecurity(inode, name, value, size, flags); | 717 | return call_int_hook(inode_setsecurity, -EOPNOTSUPP, inode, name, |
| 718 | value, size, flags); | ||
| 694 | } | 719 | } |
| 695 | 720 | ||
| 696 | int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size) | 721 | int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size) |
| 697 | { | 722 | { |
| 698 | if (unlikely(IS_PRIVATE(inode))) | 723 | if (unlikely(IS_PRIVATE(inode))) |
| 699 | return 0; | 724 | return 0; |
| 700 | return security_ops->inode_listsecurity(inode, buffer, buffer_size); | 725 | return call_int_hook(inode_listsecurity, 0, inode, buffer, buffer_size); |
| 701 | } | 726 | } |
| 702 | EXPORT_SYMBOL(security_inode_listsecurity); | 727 | EXPORT_SYMBOL(security_inode_listsecurity); |
| 703 | 728 | ||
| 704 | void security_inode_getsecid(const struct inode *inode, u32 *secid) | 729 | void security_inode_getsecid(const struct inode *inode, u32 *secid) |
| 705 | { | 730 | { |
| 706 | security_ops->inode_getsecid(inode, secid); | 731 | call_void_hook(inode_getsecid, inode, secid); |
| 707 | } | 732 | } |
| 708 | 733 | ||
| 709 | int security_file_permission(struct file *file, int mask) | 734 | int security_file_permission(struct file *file, int mask) |
| 710 | { | 735 | { |
| 711 | int ret; | 736 | int ret; |
| 712 | 737 | ||
| 713 | ret = security_ops->file_permission(file, mask); | 738 | ret = call_int_hook(file_permission, 0, file, mask); |
| 714 | if (ret) | 739 | if (ret) |
| 715 | return ret; | 740 | return ret; |
| 716 | 741 | ||
| @@ -719,17 +744,17 @@ int security_file_permission(struct file *file, int mask) | |||
| 719 | 744 | ||
| 720 | int security_file_alloc(struct file *file) | 745 | int security_file_alloc(struct file *file) |
| 721 | { | 746 | { |
| 722 | return security_ops->file_alloc_security(file); | 747 | return call_int_hook(file_alloc_security, 0, file); |
| 723 | } | 748 | } |
| 724 | 749 | ||
| 725 | void security_file_free(struct file *file) | 750 | void security_file_free(struct file *file) |
| 726 | { | 751 | { |
| 727 | security_ops->file_free_security(file); | 752 | call_void_hook(file_free_security, file); |
| 728 | } | 753 | } |
| 729 | 754 | ||
| 730 | int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 755 | int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
| 731 | { | 756 | { |
| 732 | return security_ops->file_ioctl(file, cmd, arg); | 757 | return call_int_hook(file_ioctl, 0, file, cmd, arg); |
| 733 | } | 758 | } |
| 734 | 759 | ||
| 735 | static inline unsigned long mmap_prot(struct file *file, unsigned long prot) | 760 | static inline unsigned long mmap_prot(struct file *file, unsigned long prot) |
| @@ -769,7 +794,7 @@ int security_mmap_file(struct file *file, unsigned long prot, | |||
| 769 | unsigned long flags) | 794 | unsigned long flags) |
| 770 | { | 795 | { |
| 771 | int ret; | 796 | int ret; |
| 772 | ret = security_ops->mmap_file(file, prot, | 797 | ret = call_int_hook(mmap_file, 0, file, prot, |
| 773 | mmap_prot(file, prot), flags); | 798 | mmap_prot(file, prot), flags); |
| 774 | if (ret) | 799 | if (ret) |
| 775 | return ret; | 800 | return ret; |
| @@ -778,46 +803,46 @@ int security_mmap_file(struct file *file, unsigned long prot, | |||
| 778 | 803 | ||
| 779 | int security_mmap_addr(unsigned long addr) | 804 | int security_mmap_addr(unsigned long addr) |
| 780 | { | 805 | { |
| 781 | return security_ops->mmap_addr(addr); | 806 | return call_int_hook(mmap_addr, 0, addr); |
| 782 | } | 807 | } |
| 783 | 808 | ||
| 784 | int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot, | 809 | int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot, |
| 785 | unsigned long prot) | 810 | unsigned long prot) |
| 786 | { | 811 | { |
| 787 | return security_ops->file_mprotect(vma, reqprot, prot); | 812 | return call_int_hook(file_mprotect, 0, vma, reqprot, prot); |
| 788 | } | 813 | } |
| 789 | 814 | ||
| 790 | int security_file_lock(struct file *file, unsigned int cmd) | 815 | int security_file_lock(struct file *file, unsigned int cmd) |
| 791 | { | 816 | { |
| 792 | return security_ops->file_lock(file, cmd); | 817 | return call_int_hook(file_lock, 0, file, cmd); |
| 793 | } | 818 | } |
| 794 | 819 | ||
| 795 | int security_file_fcntl(struct file *file, unsigned int cmd, unsigned long arg) | 820 | int security_file_fcntl(struct file *file, unsigned int cmd, unsigned long arg) |
| 796 | { | 821 | { |
| 797 | return security_ops->file_fcntl(file, cmd, arg); | 822 | return call_int_hook(file_fcntl, 0, file, cmd, arg); |
| 798 | } | 823 | } |
| 799 | 824 | ||
| 800 | void security_file_set_fowner(struct file *file) | 825 | void security_file_set_fowner(struct file *file) |
| 801 | { | 826 | { |
| 802 | security_ops->file_set_fowner(file); | 827 | call_void_hook(file_set_fowner, file); |
| 803 | } | 828 | } |
| 804 | 829 | ||
| 805 | int security_file_send_sigiotask(struct task_struct *tsk, | 830 | int security_file_send_sigiotask(struct task_struct *tsk, |
| 806 | struct fown_struct *fown, int sig) | 831 | struct fown_struct *fown, int sig) |
| 807 | { | 832 | { |
| 808 | return security_ops->file_send_sigiotask(tsk, fown, sig); | 833 | return call_int_hook(file_send_sigiotask, 0, tsk, fown, sig); |
| 809 | } | 834 | } |
| 810 | 835 | ||
| 811 | int security_file_receive(struct file *file) | 836 | int security_file_receive(struct file *file) |
| 812 | { | 837 | { |
| 813 | return security_ops->file_receive(file); | 838 | return call_int_hook(file_receive, 0, file); |
| 814 | } | 839 | } |
| 815 | 840 | ||
| 816 | int security_file_open(struct file *file, const struct cred *cred) | 841 | int security_file_open(struct file *file, const struct cred *cred) |
| 817 | { | 842 | { |
| 818 | int ret; | 843 | int ret; |
| 819 | 844 | ||
| 820 | ret = security_ops->file_open(file, cred); | 845 | ret = call_int_hook(file_open, 0, file, cred); |
| 821 | if (ret) | 846 | if (ret) |
| 822 | return ret; | 847 | return ret; |
| 823 | 848 | ||
| @@ -826,52 +851,49 @@ int security_file_open(struct file *file, const struct cred *cred) | |||
| 826 | 851 | ||
| 827 | int security_task_create(unsigned long clone_flags) | 852 | int security_task_create(unsigned long clone_flags) |
| 828 | { | 853 | { |
| 829 | return security_ops->task_create(clone_flags); | 854 | return call_int_hook(task_create, 0, clone_flags); |
| 830 | } | 855 | } |
| 831 | 856 | ||
| 832 | void security_task_free(struct task_struct *task) | 857 | void security_task_free(struct task_struct *task) |
| 833 | { | 858 | { |
| 834 | #ifdef CONFIG_SECURITY_YAMA_STACKED | 859 | call_void_hook(task_free, task); |
| 835 | yama_task_free(task); | ||
| 836 | #endif | ||
| 837 | security_ops->task_free(task); | ||
| 838 | } | 860 | } |
| 839 | 861 | ||
| 840 | int security_cred_alloc_blank(struct cred *cred, gfp_t gfp) | 862 | int security_cred_alloc_blank(struct cred *cred, gfp_t gfp) |
| 841 | { | 863 | { |
| 842 | return security_ops->cred_alloc_blank(cred, gfp); | 864 | return call_int_hook(cred_alloc_blank, 0, cred, gfp); |
| 843 | } | 865 | } |
| 844 | 866 | ||
| 845 | void security_cred_free(struct cred *cred) | 867 | void security_cred_free(struct cred *cred) |
| 846 | { | 868 | { |
| 847 | security_ops->cred_free(cred); | 869 | call_void_hook(cred_free, cred); |
| 848 | } | 870 | } |
| 849 | 871 | ||
| 850 | int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp) | 872 | int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp) |
| 851 | { | 873 | { |
| 852 | return security_ops->cred_prepare(new, old, gfp); | 874 | return call_int_hook(cred_prepare, 0, new, old, gfp); |
| 853 | } | 875 | } |
| 854 | 876 | ||
| 855 | void security_transfer_creds(struct cred *new, const struct cred *old) | 877 | void security_transfer_creds(struct cred *new, const struct cred *old) |
| 856 | { | 878 | { |
| 857 | security_ops->cred_transfer(new, old); | 879 | call_void_hook(cred_transfer, new, old); |
| 858 | } | 880 | } |
| 859 | 881 | ||
| 860 | int security_kernel_act_as(struct cred *new, u32 secid) | 882 | int security_kernel_act_as(struct cred *new, u32 secid) |
| 861 | { | 883 | { |
| 862 | return security_ops->kernel_act_as(new, secid); | 884 | return call_int_hook(kernel_act_as, 0, new, secid); |
| 863 | } | 885 | } |
| 864 | 886 | ||
| 865 | int security_kernel_create_files_as(struct cred *new, struct inode *inode) | 887 | int security_kernel_create_files_as(struct cred *new, struct inode *inode) |
| 866 | { | 888 | { |
| 867 | return security_ops->kernel_create_files_as(new, inode); | 889 | return call_int_hook(kernel_create_files_as, 0, new, inode); |
| 868 | } | 890 | } |
| 869 | 891 | ||
| 870 | int security_kernel_fw_from_file(struct file *file, char *buf, size_t size) | 892 | int security_kernel_fw_from_file(struct file *file, char *buf, size_t size) |
| 871 | { | 893 | { |
| 872 | int ret; | 894 | int ret; |
| 873 | 895 | ||
| 874 | ret = security_ops->kernel_fw_from_file(file, buf, size); | 896 | ret = call_int_hook(kernel_fw_from_file, 0, file, buf, size); |
| 875 | if (ret) | 897 | if (ret) |
| 876 | return ret; | 898 | return ret; |
| 877 | return ima_fw_from_file(file, buf, size); | 899 | return ima_fw_from_file(file, buf, size); |
| @@ -880,14 +902,14 @@ EXPORT_SYMBOL_GPL(security_kernel_fw_from_file); | |||
| 880 | 902 | ||
| 881 | int security_kernel_module_request(char *kmod_name) | 903 | int security_kernel_module_request(char *kmod_name) |
| 882 | { | 904 | { |
| 883 | return security_ops->kernel_module_request(kmod_name); | 905 | return call_int_hook(kernel_module_request, 0, kmod_name); |
| 884 | } | 906 | } |
| 885 | 907 | ||
| 886 | int security_kernel_module_from_file(struct file *file) | 908 | int security_kernel_module_from_file(struct file *file) |
| 887 | { | 909 | { |
| 888 | int ret; | 910 | int ret; |
| 889 | 911 | ||
| 890 | ret = security_ops->kernel_module_from_file(file); | 912 | ret = call_int_hook(kernel_module_from_file, 0, file); |
| 891 | if (ret) | 913 | if (ret) |
| 892 | return ret; | 914 | return ret; |
| 893 | return ima_module_check(file); | 915 | return ima_module_check(file); |
| @@ -896,259 +918,269 @@ int security_kernel_module_from_file(struct file *file) | |||
| 896 | int security_task_fix_setuid(struct cred *new, const struct cred *old, | 918 | int security_task_fix_setuid(struct cred *new, const struct cred *old, |
| 897 | int flags) | 919 | int flags) |
| 898 | { | 920 | { |
| 899 | return security_ops->task_fix_setuid(new, old, flags); | 921 | return call_int_hook(task_fix_setuid, 0, new, old, flags); |
| 900 | } | 922 | } |
| 901 | 923 | ||
| 902 | int security_task_setpgid(struct task_struct *p, pid_t pgid) | 924 | int security_task_setpgid(struct task_struct *p, pid_t pgid) |
| 903 | { | 925 | { |
| 904 | return security_ops->task_setpgid(p, pgid); | 926 | return call_int_hook(task_setpgid, 0, p, pgid); |
| 905 | } | 927 | } |
| 906 | 928 | ||
| 907 | int security_task_getpgid(struct task_struct *p) | 929 | int security_task_getpgid(struct task_struct *p) |
| 908 | { | 930 | { |
| 909 | return security_ops->task_getpgid(p); | 931 | return call_int_hook(task_getpgid, 0, p); |
| 910 | } | 932 | } |
| 911 | 933 | ||
| 912 | int security_task_getsid(struct task_struct *p) | 934 | int security_task_getsid(struct task_struct *p) |
| 913 | { | 935 | { |
| 914 | return security_ops->task_getsid(p); | 936 | return call_int_hook(task_getsid, 0, p); |
| 915 | } | 937 | } |
| 916 | 938 | ||
| 917 | void security_task_getsecid(struct task_struct *p, u32 *secid) | 939 | void security_task_getsecid(struct task_struct *p, u32 *secid) |
| 918 | { | 940 | { |
| 919 | security_ops->task_getsecid(p, secid); | 941 | *secid = 0; |
| 942 | call_void_hook(task_getsecid, p, secid); | ||
| 920 | } | 943 | } |
| 921 | EXPORT_SYMBOL(security_task_getsecid); | 944 | EXPORT_SYMBOL(security_task_getsecid); |
| 922 | 945 | ||
| 923 | int security_task_setnice(struct task_struct *p, int nice) | 946 | int security_task_setnice(struct task_struct *p, int nice) |
| 924 | { | 947 | { |
| 925 | return security_ops->task_setnice(p, nice); | 948 | return call_int_hook(task_setnice, 0, p, nice); |
| 926 | } | 949 | } |
| 927 | 950 | ||
| 928 | int security_task_setioprio(struct task_struct *p, int ioprio) | 951 | int security_task_setioprio(struct task_struct *p, int ioprio) |
| 929 | { | 952 | { |
| 930 | return security_ops->task_setioprio(p, ioprio); | 953 | return call_int_hook(task_setioprio, 0, p, ioprio); |
| 931 | } | 954 | } |
| 932 | 955 | ||
| 933 | int security_task_getioprio(struct task_struct *p) | 956 | int security_task_getioprio(struct task_struct *p) |
| 934 | { | 957 | { |
| 935 | return security_ops->task_getioprio(p); | 958 | return call_int_hook(task_getioprio, 0, p); |
| 936 | } | 959 | } |
| 937 | 960 | ||
| 938 | int security_task_setrlimit(struct task_struct *p, unsigned int resource, | 961 | int security_task_setrlimit(struct task_struct *p, unsigned int resource, |
| 939 | struct rlimit *new_rlim) | 962 | struct rlimit *new_rlim) |
| 940 | { | 963 | { |
| 941 | return security_ops->task_setrlimit(p, resource, new_rlim); | 964 | return call_int_hook(task_setrlimit, 0, p, resource, new_rlim); |
| 942 | } | 965 | } |
| 943 | 966 | ||
| 944 | int security_task_setscheduler(struct task_struct *p) | 967 | int security_task_setscheduler(struct task_struct *p) |
| 945 | { | 968 | { |
| 946 | return security_ops->task_setscheduler(p); | 969 | return call_int_hook(task_setscheduler, 0, p); |
| 947 | } | 970 | } |
| 948 | 971 | ||
| 949 | int security_task_getscheduler(struct task_struct *p) | 972 | int security_task_getscheduler(struct task_struct *p) |
| 950 | { | 973 | { |
| 951 | return security_ops->task_getscheduler(p); | 974 | return call_int_hook(task_getscheduler, 0, p); |
| 952 | } | 975 | } |
| 953 | 976 | ||
| 954 | int security_task_movememory(struct task_struct *p) | 977 | int security_task_movememory(struct task_struct *p) |
| 955 | { | 978 | { |
| 956 | return security_ops->task_movememory(p); | 979 | return call_int_hook(task_movememory, 0, p); |
| 957 | } | 980 | } |
| 958 | 981 | ||
| 959 | int security_task_kill(struct task_struct *p, struct siginfo *info, | 982 | int security_task_kill(struct task_struct *p, struct siginfo *info, |
| 960 | int sig, u32 secid) | 983 | int sig, u32 secid) |
| 961 | { | 984 | { |
| 962 | return security_ops->task_kill(p, info, sig, secid); | 985 | return call_int_hook(task_kill, 0, p, info, sig, secid); |
| 963 | } | 986 | } |
| 964 | 987 | ||
| 965 | int security_task_wait(struct task_struct *p) | 988 | int security_task_wait(struct task_struct *p) |
| 966 | { | 989 | { |
| 967 | return security_ops->task_wait(p); | 990 | return call_int_hook(task_wait, 0, p); |
| 968 | } | 991 | } |
| 969 | 992 | ||
| 970 | int security_task_prctl(int option, unsigned long arg2, unsigned long arg3, | 993 | int security_task_prctl(int option, unsigned long arg2, unsigned long arg3, |
| 971 | unsigned long arg4, unsigned long arg5) | 994 | unsigned long arg4, unsigned long arg5) |
| 972 | { | 995 | { |
| 973 | #ifdef CONFIG_SECURITY_YAMA_STACKED | 996 | int thisrc; |
| 974 | int rc; | 997 | int rc = -ENOSYS; |
| 975 | rc = yama_task_prctl(option, arg2, arg3, arg4, arg5); | 998 | struct security_hook_list *hp; |
| 976 | if (rc != -ENOSYS) | 999 | |
| 977 | return rc; | 1000 | list_for_each_entry(hp, &security_hook_heads.task_prctl, list) { |
| 978 | #endif | 1001 | thisrc = hp->hook.task_prctl(option, arg2, arg3, arg4, arg5); |
| 979 | return security_ops->task_prctl(option, arg2, arg3, arg4, arg5); | 1002 | if (thisrc != -ENOSYS) { |
| 1003 | rc = thisrc; | ||
| 1004 | if (thisrc != 0) | ||
| 1005 | break; | ||
| 1006 | } | ||
| 1007 | } | ||
| 1008 | return rc; | ||
| 980 | } | 1009 | } |
| 981 | 1010 | ||
| 982 | void security_task_to_inode(struct task_struct *p, struct inode *inode) | 1011 | void security_task_to_inode(struct task_struct *p, struct inode *inode) |
| 983 | { | 1012 | { |
| 984 | security_ops->task_to_inode(p, inode); | 1013 | call_void_hook(task_to_inode, p, inode); |
| 985 | } | 1014 | } |
| 986 | 1015 | ||
| 987 | int security_ipc_permission(struct kern_ipc_perm *ipcp, short flag) | 1016 | int security_ipc_permission(struct kern_ipc_perm *ipcp, short flag) |
| 988 | { | 1017 | { |
| 989 | return security_ops->ipc_permission(ipcp, flag); | 1018 | return call_int_hook(ipc_permission, 0, ipcp, flag); |
| 990 | } | 1019 | } |
| 991 | 1020 | ||
| 992 | void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid) | 1021 | void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid) |
| 993 | { | 1022 | { |
| 994 | security_ops->ipc_getsecid(ipcp, secid); | 1023 | *secid = 0; |
| 1024 | call_void_hook(ipc_getsecid, ipcp, secid); | ||
| 995 | } | 1025 | } |
| 996 | 1026 | ||
| 997 | int security_msg_msg_alloc(struct msg_msg *msg) | 1027 | int security_msg_msg_alloc(struct msg_msg *msg) |
| 998 | { | 1028 | { |
| 999 | return security_ops->msg_msg_alloc_security(msg); | 1029 | return call_int_hook(msg_msg_alloc_security, 0, msg); |
| 1000 | } | 1030 | } |
| 1001 | 1031 | ||
| 1002 | void security_msg_msg_free(struct msg_msg *msg) | 1032 | void security_msg_msg_free(struct msg_msg *msg) |
| 1003 | { | 1033 | { |
| 1004 | security_ops->msg_msg_free_security(msg); | 1034 | call_void_hook(msg_msg_free_security, msg); |
| 1005 | } | 1035 | } |
| 1006 | 1036 | ||
| 1007 | int security_msg_queue_alloc(struct msg_queue *msq) | 1037 | int security_msg_queue_alloc(struct msg_queue *msq) |
| 1008 | { | 1038 | { |
| 1009 | return security_ops->msg_queue_alloc_security(msq); | 1039 | return call_int_hook(msg_queue_alloc_security, 0, msq); |
| 1010 | } | 1040 | } |
| 1011 | 1041 | ||
| 1012 | void security_msg_queue_free(struct msg_queue *msq) | 1042 | void security_msg_queue_free(struct msg_queue *msq) |
| 1013 | { | 1043 | { |
| 1014 | security_ops->msg_queue_free_security(msq); | 1044 | call_void_hook(msg_queue_free_security, msq); |
| 1015 | } | 1045 | } |
| 1016 | 1046 | ||
| 1017 | int security_msg_queue_associate(struct msg_queue *msq, int msqflg) | 1047 | int security_msg_queue_associate(struct msg_queue *msq, int msqflg) |
| 1018 | { | 1048 | { |
| 1019 | return security_ops->msg_queue_associate(msq, msqflg); | 1049 | return call_int_hook(msg_queue_associate, 0, msq, msqflg); |
| 1020 | } | 1050 | } |
| 1021 | 1051 | ||
| 1022 | int security_msg_queue_msgctl(struct msg_queue *msq, int cmd) | 1052 | int security_msg_queue_msgctl(struct msg_queue *msq, int cmd) |
| 1023 | { | 1053 | { |
| 1024 | return security_ops->msg_queue_msgctl(msq, cmd); | 1054 | return call_int_hook(msg_queue_msgctl, 0, msq, cmd); |
| 1025 | } | 1055 | } |
| 1026 | 1056 | ||
| 1027 | int security_msg_queue_msgsnd(struct msg_queue *msq, | 1057 | int security_msg_queue_msgsnd(struct msg_queue *msq, |
| 1028 | struct msg_msg *msg, int msqflg) | 1058 | struct msg_msg *msg, int msqflg) |
| 1029 | { | 1059 | { |
| 1030 | return security_ops->msg_queue_msgsnd(msq, msg, msqflg); | 1060 | return call_int_hook(msg_queue_msgsnd, 0, msq, msg, msqflg); |
| 1031 | } | 1061 | } |
| 1032 | 1062 | ||
| 1033 | int security_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, | 1063 | int security_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, |
| 1034 | struct task_struct *target, long type, int mode) | 1064 | struct task_struct *target, long type, int mode) |
| 1035 | { | 1065 | { |
| 1036 | return security_ops->msg_queue_msgrcv(msq, msg, target, type, mode); | 1066 | return call_int_hook(msg_queue_msgrcv, 0, msq, msg, target, type, mode); |
| 1037 | } | 1067 | } |
| 1038 | 1068 | ||
| 1039 | int security_shm_alloc(struct shmid_kernel *shp) | 1069 | int security_shm_alloc(struct shmid_kernel *shp) |
| 1040 | { | 1070 | { |
| 1041 | return security_ops->shm_alloc_security(shp); | 1071 | return call_int_hook(shm_alloc_security, 0, shp); |
| 1042 | } | 1072 | } |
| 1043 | 1073 | ||
| 1044 | void security_shm_free(struct shmid_kernel *shp) | 1074 | void security_shm_free(struct shmid_kernel *shp) |
| 1045 | { | 1075 | { |
| 1046 | security_ops->shm_free_security(shp); | 1076 | call_void_hook(shm_free_security, shp); |
| 1047 | } | 1077 | } |
| 1048 | 1078 | ||
| 1049 | int security_shm_associate(struct shmid_kernel *shp, int shmflg) | 1079 | int security_shm_associate(struct shmid_kernel *shp, int shmflg) |
| 1050 | { | 1080 | { |
| 1051 | return security_ops->shm_associate(shp, shmflg); | 1081 | return call_int_hook(shm_associate, 0, shp, shmflg); |
| 1052 | } | 1082 | } |
| 1053 | 1083 | ||
| 1054 | int security_shm_shmctl(struct shmid_kernel *shp, int cmd) | 1084 | int security_shm_shmctl(struct shmid_kernel *shp, int cmd) |
| 1055 | { | 1085 | { |
| 1056 | return security_ops->shm_shmctl(shp, cmd); | 1086 | return call_int_hook(shm_shmctl, 0, shp, cmd); |
| 1057 | } | 1087 | } |
| 1058 | 1088 | ||
| 1059 | int security_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, int shmflg) | 1089 | int security_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, int shmflg) |
| 1060 | { | 1090 | { |
| 1061 | return security_ops->shm_shmat(shp, shmaddr, shmflg); | 1091 | return call_int_hook(shm_shmat, 0, shp, shmaddr, shmflg); |
| 1062 | } | 1092 | } |
| 1063 | 1093 | ||
| 1064 | int security_sem_alloc(struct sem_array *sma) | 1094 | int security_sem_alloc(struct sem_array *sma) |
| 1065 | { | 1095 | { |
| 1066 | return security_ops->sem_alloc_security(sma); | 1096 | return call_int_hook(sem_alloc_security, 0, sma); |
| 1067 | } | 1097 | } |
| 1068 | 1098 | ||
| 1069 | void security_sem_free(struct sem_array *sma) | 1099 | void security_sem_free(struct sem_array *sma) |
| 1070 | { | 1100 | { |
| 1071 | security_ops->sem_free_security(sma); | 1101 | call_void_hook(sem_free_security, sma); |
| 1072 | } | 1102 | } |
| 1073 | 1103 | ||
| 1074 | int security_sem_associate(struct sem_array *sma, int semflg) | 1104 | int security_sem_associate(struct sem_array *sma, int semflg) |
| 1075 | { | 1105 | { |
| 1076 | return security_ops->sem_associate(sma, semflg); | 1106 | return call_int_hook(sem_associate, 0, sma, semflg); |
| 1077 | } | 1107 | } |
| 1078 | 1108 | ||
| 1079 | int security_sem_semctl(struct sem_array *sma, int cmd) | 1109 | int security_sem_semctl(struct sem_array *sma, int cmd) |
| 1080 | { | 1110 | { |
| 1081 | return security_ops->sem_semctl(sma, cmd); | 1111 | return call_int_hook(sem_semctl, 0, sma, cmd); |
| 1082 | } | 1112 | } |
| 1083 | 1113 | ||
| 1084 | int security_sem_semop(struct sem_array *sma, struct sembuf *sops, | 1114 | int security_sem_semop(struct sem_array *sma, struct sembuf *sops, |
| 1085 | unsigned nsops, int alter) | 1115 | unsigned nsops, int alter) |
| 1086 | { | 1116 | { |
| 1087 | return security_ops->sem_semop(sma, sops, nsops, alter); | 1117 | return call_int_hook(sem_semop, 0, sma, sops, nsops, alter); |
| 1088 | } | 1118 | } |
| 1089 | 1119 | ||
| 1090 | void security_d_instantiate(struct dentry *dentry, struct inode *inode) | 1120 | void security_d_instantiate(struct dentry *dentry, struct inode *inode) |
| 1091 | { | 1121 | { |
| 1092 | if (unlikely(inode && IS_PRIVATE(inode))) | 1122 | if (unlikely(inode && IS_PRIVATE(inode))) |
| 1093 | return; | 1123 | return; |
| 1094 | security_ops->d_instantiate(dentry, inode); | 1124 | call_void_hook(d_instantiate, dentry, inode); |
| 1095 | } | 1125 | } |
| 1096 | EXPORT_SYMBOL(security_d_instantiate); | 1126 | EXPORT_SYMBOL(security_d_instantiate); |
| 1097 | 1127 | ||
| 1098 | int security_getprocattr(struct task_struct *p, char *name, char **value) | 1128 | int security_getprocattr(struct task_struct *p, char *name, char **value) |
| 1099 | { | 1129 | { |
| 1100 | return security_ops->getprocattr(p, name, value); | 1130 | return call_int_hook(getprocattr, -EINVAL, p, name, value); |
| 1101 | } | 1131 | } |
| 1102 | 1132 | ||
| 1103 | int security_setprocattr(struct task_struct *p, char *name, void *value, size_t size) | 1133 | int security_setprocattr(struct task_struct *p, char *name, void *value, size_t size) |
| 1104 | { | 1134 | { |
| 1105 | return security_ops->setprocattr(p, name, value, size); | 1135 | return call_int_hook(setprocattr, -EINVAL, p, name, value, size); |
| 1106 | } | 1136 | } |
| 1107 | 1137 | ||
| 1108 | int security_netlink_send(struct sock *sk, struct sk_buff *skb) | 1138 | int security_netlink_send(struct sock *sk, struct sk_buff *skb) |
| 1109 | { | 1139 | { |
| 1110 | return security_ops->netlink_send(sk, skb); | 1140 | return call_int_hook(netlink_send, 0, sk, skb); |
| 1111 | } | 1141 | } |
| 1112 | 1142 | ||
| 1113 | int security_ismaclabel(const char *name) | 1143 | int security_ismaclabel(const char *name) |
| 1114 | { | 1144 | { |
| 1115 | return security_ops->ismaclabel(name); | 1145 | return call_int_hook(ismaclabel, 0, name); |
| 1116 | } | 1146 | } |
| 1117 | EXPORT_SYMBOL(security_ismaclabel); | 1147 | EXPORT_SYMBOL(security_ismaclabel); |
| 1118 | 1148 | ||
| 1119 | int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) | 1149 | int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) |
| 1120 | { | 1150 | { |
| 1121 | return security_ops->secid_to_secctx(secid, secdata, seclen); | 1151 | return call_int_hook(secid_to_secctx, -EOPNOTSUPP, secid, secdata, |
| 1152 | seclen); | ||
| 1122 | } | 1153 | } |
| 1123 | EXPORT_SYMBOL(security_secid_to_secctx); | 1154 | EXPORT_SYMBOL(security_secid_to_secctx); |
| 1124 | 1155 | ||
| 1125 | int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) | 1156 | int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) |
| 1126 | { | 1157 | { |
| 1127 | return security_ops->secctx_to_secid(secdata, seclen, secid); | 1158 | *secid = 0; |
| 1159 | return call_int_hook(secctx_to_secid, 0, secdata, seclen, secid); | ||
| 1128 | } | 1160 | } |
| 1129 | EXPORT_SYMBOL(security_secctx_to_secid); | 1161 | EXPORT_SYMBOL(security_secctx_to_secid); |
| 1130 | 1162 | ||
| 1131 | void security_release_secctx(char *secdata, u32 seclen) | 1163 | void security_release_secctx(char *secdata, u32 seclen) |
| 1132 | { | 1164 | { |
| 1133 | security_ops->release_secctx(secdata, seclen); | 1165 | call_void_hook(release_secctx, secdata, seclen); |
| 1134 | } | 1166 | } |
| 1135 | EXPORT_SYMBOL(security_release_secctx); | 1167 | EXPORT_SYMBOL(security_release_secctx); |
| 1136 | 1168 | ||
| 1137 | int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) | 1169 | int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) |
| 1138 | { | 1170 | { |
| 1139 | return security_ops->inode_notifysecctx(inode, ctx, ctxlen); | 1171 | return call_int_hook(inode_notifysecctx, 0, inode, ctx, ctxlen); |
| 1140 | } | 1172 | } |
| 1141 | EXPORT_SYMBOL(security_inode_notifysecctx); | 1173 | EXPORT_SYMBOL(security_inode_notifysecctx); |
| 1142 | 1174 | ||
| 1143 | int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen) | 1175 | int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen) |
| 1144 | { | 1176 | { |
| 1145 | return security_ops->inode_setsecctx(dentry, ctx, ctxlen); | 1177 | return call_int_hook(inode_setsecctx, 0, dentry, ctx, ctxlen); |
| 1146 | } | 1178 | } |
| 1147 | EXPORT_SYMBOL(security_inode_setsecctx); | 1179 | EXPORT_SYMBOL(security_inode_setsecctx); |
| 1148 | 1180 | ||
| 1149 | int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen) | 1181 | int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen) |
| 1150 | { | 1182 | { |
| 1151 | return security_ops->inode_getsecctx(inode, ctx, ctxlen); | 1183 | return call_int_hook(inode_getsecctx, -EOPNOTSUPP, inode, ctx, ctxlen); |
| 1152 | } | 1184 | } |
| 1153 | EXPORT_SYMBOL(security_inode_getsecctx); | 1185 | EXPORT_SYMBOL(security_inode_getsecctx); |
| 1154 | 1186 | ||
| @@ -1156,214 +1188,210 @@ EXPORT_SYMBOL(security_inode_getsecctx); | |||
| 1156 | 1188 | ||
| 1157 | int security_unix_stream_connect(struct sock *sock, struct sock *other, struct sock *newsk) | 1189 | int security_unix_stream_connect(struct sock *sock, struct sock *other, struct sock *newsk) |
| 1158 | { | 1190 | { |
| 1159 | return security_ops->unix_stream_connect(sock, other, newsk); | 1191 | return call_int_hook(unix_stream_connect, 0, sock, other, newsk); |
| 1160 | } | 1192 | } |
| 1161 | EXPORT_SYMBOL(security_unix_stream_connect); | 1193 | EXPORT_SYMBOL(security_unix_stream_connect); |
| 1162 | 1194 | ||
| 1163 | int security_unix_may_send(struct socket *sock, struct socket *other) | 1195 | int security_unix_may_send(struct socket *sock, struct socket *other) |
| 1164 | { | 1196 | { |
| 1165 | return security_ops->unix_may_send(sock, other); | 1197 | return call_int_hook(unix_may_send, 0, sock, other); |
| 1166 | } | 1198 | } |
| 1167 | EXPORT_SYMBOL(security_unix_may_send); | 1199 | EXPORT_SYMBOL(security_unix_may_send); |
| 1168 | 1200 | ||
| 1169 | int security_socket_create(int family, int type, int protocol, int kern) | 1201 | int security_socket_create(int family, int type, int protocol, int kern) |
| 1170 | { | 1202 | { |
| 1171 | return security_ops->socket_create(family, type, protocol, kern); | 1203 | return call_int_hook(socket_create, 0, family, type, protocol, kern); |
| 1172 | } | 1204 | } |
| 1173 | 1205 | ||
| 1174 | int security_socket_post_create(struct socket *sock, int family, | 1206 | int security_socket_post_create(struct socket *sock, int family, |
| 1175 | int type, int protocol, int kern) | 1207 | int type, int protocol, int kern) |
| 1176 | { | 1208 | { |
| 1177 | return security_ops->socket_post_create(sock, family, type, | 1209 | return call_int_hook(socket_post_create, 0, sock, family, type, |
| 1178 | protocol, kern); | 1210 | protocol, kern); |
| 1179 | } | 1211 | } |
| 1180 | 1212 | ||
| 1181 | int security_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen) | 1213 | int security_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen) |
| 1182 | { | 1214 | { |
| 1183 | return security_ops->socket_bind(sock, address, addrlen); | 1215 | return call_int_hook(socket_bind, 0, sock, address, addrlen); |
| 1184 | } | 1216 | } |
| 1185 | 1217 | ||
| 1186 | int security_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen) | 1218 | int security_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen) |
| 1187 | { | 1219 | { |
| 1188 | return security_ops->socket_connect(sock, address, addrlen); | 1220 | return call_int_hook(socket_connect, 0, sock, address, addrlen); |
| 1189 | } | 1221 | } |
| 1190 | 1222 | ||
| 1191 | int security_socket_listen(struct socket *sock, int backlog) | 1223 | int security_socket_listen(struct socket *sock, int backlog) |
| 1192 | { | 1224 | { |
| 1193 | return security_ops->socket_listen(sock, backlog); | 1225 | return call_int_hook(socket_listen, 0, sock, backlog); |
| 1194 | } | 1226 | } |
| 1195 | 1227 | ||
| 1196 | int security_socket_accept(struct socket *sock, struct socket *newsock) | 1228 | int security_socket_accept(struct socket *sock, struct socket *newsock) |
| 1197 | { | 1229 | { |
| 1198 | return security_ops->socket_accept(sock, newsock); | 1230 | return call_int_hook(socket_accept, 0, sock, newsock); |
| 1199 | } | 1231 | } |
| 1200 | 1232 | ||
| 1201 | int security_socket_sendmsg(struct socket *sock, struct msghdr *msg, int size) | 1233 | int security_socket_sendmsg(struct socket *sock, struct msghdr *msg, int size) |
| 1202 | { | 1234 | { |
| 1203 | return security_ops->socket_sendmsg(sock, msg, size); | 1235 | return call_int_hook(socket_sendmsg, 0, sock, msg, size); |
| 1204 | } | 1236 | } |
| 1205 | 1237 | ||
| 1206 | int security_socket_recvmsg(struct socket *sock, struct msghdr *msg, | 1238 | int security_socket_recvmsg(struct socket *sock, struct msghdr *msg, |
| 1207 | int size, int flags) | 1239 | int size, int flags) |
| 1208 | { | 1240 | { |
| 1209 | return security_ops->socket_recvmsg(sock, msg, size, flags); | 1241 | return call_int_hook(socket_recvmsg, 0, sock, msg, size, flags); |
| 1210 | } | 1242 | } |
| 1211 | 1243 | ||
| 1212 | int security_socket_getsockname(struct socket *sock) | 1244 | int security_socket_getsockname(struct socket *sock) |
| 1213 | { | 1245 | { |
| 1214 | return security_ops->socket_getsockname(sock); | 1246 | return call_int_hook(socket_getsockname, 0, sock); |
| 1215 | } | 1247 | } |
| 1216 | 1248 | ||
| 1217 | int security_socket_getpeername(struct socket *sock) | 1249 | int security_socket_getpeername(struct socket *sock) |
| 1218 | { | 1250 | { |
| 1219 | return security_ops->socket_getpeername(sock); | 1251 | return call_int_hook(socket_getpeername, 0, sock); |
| 1220 | } | 1252 | } |
| 1221 | 1253 | ||
| 1222 | int security_socket_getsockopt(struct socket *sock, int level, int optname) | 1254 | int security_socket_getsockopt(struct socket *sock, int level, int optname) |
| 1223 | { | 1255 | { |
| 1224 | return security_ops->socket_getsockopt(sock, level, optname); | 1256 | return call_int_hook(socket_getsockopt, 0, sock, level, optname); |
| 1225 | } | 1257 | } |
| 1226 | 1258 | ||
| 1227 | int security_socket_setsockopt(struct socket *sock, int level, int optname) | 1259 | int security_socket_setsockopt(struct socket *sock, int level, int optname) |
| 1228 | { | 1260 | { |
| 1229 | return security_ops->socket_setsockopt(sock, level, optname); | 1261 | return call_int_hook(socket_setsockopt, 0, sock, level, optname); |
| 1230 | } | 1262 | } |
| 1231 | 1263 | ||
| 1232 | int security_socket_shutdown(struct socket *sock, int how) | 1264 | int security_socket_shutdown(struct socket *sock, int how) |
| 1233 | { | 1265 | { |
| 1234 | return security_ops->socket_shutdown(sock, how); | 1266 | return call_int_hook(socket_shutdown, 0, sock, how); |
| 1235 | } | 1267 | } |
| 1236 | 1268 | ||
| 1237 | int security_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) | 1269 | int security_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) |
| 1238 | { | 1270 | { |
| 1239 | return security_ops->socket_sock_rcv_skb(sk, skb); | 1271 | return call_int_hook(socket_sock_rcv_skb, 0, sk, skb); |
| 1240 | } | 1272 | } |
| 1241 | EXPORT_SYMBOL(security_sock_rcv_skb); | 1273 | EXPORT_SYMBOL(security_sock_rcv_skb); |
| 1242 | 1274 | ||
| 1243 | int security_socket_getpeersec_stream(struct socket *sock, char __user *optval, | 1275 | int security_socket_getpeersec_stream(struct socket *sock, char __user *optval, |
| 1244 | int __user *optlen, unsigned len) | 1276 | int __user *optlen, unsigned len) |
| 1245 | { | 1277 | { |
| 1246 | return security_ops->socket_getpeersec_stream(sock, optval, optlen, len); | 1278 | return call_int_hook(socket_getpeersec_stream, -ENOPROTOOPT, sock, |
| 1279 | optval, optlen, len); | ||
| 1247 | } | 1280 | } |
| 1248 | 1281 | ||
| 1249 | int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid) | 1282 | int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid) |
| 1250 | { | 1283 | { |
| 1251 | return security_ops->socket_getpeersec_dgram(sock, skb, secid); | 1284 | return call_int_hook(socket_getpeersec_dgram, 0, sock, skb, secid); |
| 1252 | } | 1285 | } |
| 1253 | EXPORT_SYMBOL(security_socket_getpeersec_dgram); | 1286 | EXPORT_SYMBOL(security_socket_getpeersec_dgram); |
| 1254 | 1287 | ||
| 1255 | int security_sk_alloc(struct sock *sk, int family, gfp_t priority) | 1288 | int security_sk_alloc(struct sock *sk, int family, gfp_t priority) |
| 1256 | { | 1289 | { |
| 1257 | return security_ops->sk_alloc_security(sk, family, priority); | 1290 | return call_int_hook(sk_alloc_security, 0, sk, family, priority); |
| 1258 | } | 1291 | } |
| 1259 | 1292 | ||
| 1260 | void security_sk_free(struct sock *sk) | 1293 | void security_sk_free(struct sock *sk) |
| 1261 | { | 1294 | { |
| 1262 | security_ops->sk_free_security(sk); | 1295 | call_void_hook(sk_free_security, sk); |
| 1263 | } | 1296 | } |
| 1264 | 1297 | ||
| 1265 | void security_sk_clone(const struct sock *sk, struct sock *newsk) | 1298 | void security_sk_clone(const struct sock *sk, struct sock *newsk) |
| 1266 | { | 1299 | { |
| 1267 | security_ops->sk_clone_security(sk, newsk); | 1300 | call_void_hook(sk_clone_security, sk, newsk); |
| 1268 | } | 1301 | } |
| 1269 | EXPORT_SYMBOL(security_sk_clone); | 1302 | EXPORT_SYMBOL(security_sk_clone); |
| 1270 | 1303 | ||
| 1271 | void security_sk_classify_flow(struct sock *sk, struct flowi *fl) | 1304 | void security_sk_classify_flow(struct sock *sk, struct flowi *fl) |
| 1272 | { | 1305 | { |
| 1273 | security_ops->sk_getsecid(sk, &fl->flowi_secid); | 1306 | call_void_hook(sk_getsecid, sk, &fl->flowi_secid); |
| 1274 | } | 1307 | } |
| 1275 | EXPORT_SYMBOL(security_sk_classify_flow); | 1308 | EXPORT_SYMBOL(security_sk_classify_flow); |
| 1276 | 1309 | ||
| 1277 | void security_req_classify_flow(const struct request_sock *req, struct flowi *fl) | 1310 | void security_req_classify_flow(const struct request_sock *req, struct flowi *fl) |
| 1278 | { | 1311 | { |
| 1279 | security_ops->req_classify_flow(req, fl); | 1312 | call_void_hook(req_classify_flow, req, fl); |
| 1280 | } | 1313 | } |
| 1281 | EXPORT_SYMBOL(security_req_classify_flow); | 1314 | EXPORT_SYMBOL(security_req_classify_flow); |
| 1282 | 1315 | ||
| 1283 | void security_sock_graft(struct sock *sk, struct socket *parent) | 1316 | void security_sock_graft(struct sock *sk, struct socket *parent) |
| 1284 | { | 1317 | { |
| 1285 | security_ops->sock_graft(sk, parent); | 1318 | call_void_hook(sock_graft, sk, parent); |
| 1286 | } | 1319 | } |
| 1287 | EXPORT_SYMBOL(security_sock_graft); | 1320 | EXPORT_SYMBOL(security_sock_graft); |
| 1288 | 1321 | ||
| 1289 | int security_inet_conn_request(struct sock *sk, | 1322 | int security_inet_conn_request(struct sock *sk, |
| 1290 | struct sk_buff *skb, struct request_sock *req) | 1323 | struct sk_buff *skb, struct request_sock *req) |
| 1291 | { | 1324 | { |
| 1292 | return security_ops->inet_conn_request(sk, skb, req); | 1325 | return call_int_hook(inet_conn_request, 0, sk, skb, req); |
| 1293 | } | 1326 | } |
| 1294 | EXPORT_SYMBOL(security_inet_conn_request); | 1327 | EXPORT_SYMBOL(security_inet_conn_request); |
| 1295 | 1328 | ||
| 1296 | void security_inet_csk_clone(struct sock *newsk, | 1329 | void security_inet_csk_clone(struct sock *newsk, |
| 1297 | const struct request_sock *req) | 1330 | const struct request_sock *req) |
| 1298 | { | 1331 | { |
| 1299 | security_ops->inet_csk_clone(newsk, req); | 1332 | call_void_hook(inet_csk_clone, newsk, req); |
| 1300 | } | 1333 | } |
| 1301 | 1334 | ||
| 1302 | void security_inet_conn_established(struct sock *sk, | 1335 | void security_inet_conn_established(struct sock *sk, |
| 1303 | struct sk_buff *skb) | 1336 | struct sk_buff *skb) |
| 1304 | { | 1337 | { |
| 1305 | security_ops->inet_conn_established(sk, skb); | 1338 | call_void_hook(inet_conn_established, sk, skb); |
| 1306 | } | 1339 | } |
| 1307 | 1340 | ||
| 1308 | int security_secmark_relabel_packet(u32 secid) | 1341 | int security_secmark_relabel_packet(u32 secid) |
| 1309 | { | 1342 | { |
| 1310 | return security_ops->secmark_relabel_packet(secid); | 1343 | return call_int_hook(secmark_relabel_packet, 0, secid); |
| 1311 | } | 1344 | } |
| 1312 | EXPORT_SYMBOL(security_secmark_relabel_packet); | 1345 | EXPORT_SYMBOL(security_secmark_relabel_packet); |
| 1313 | 1346 | ||
| 1314 | void security_secmark_refcount_inc(void) | 1347 | void security_secmark_refcount_inc(void) |
| 1315 | { | 1348 | { |
| 1316 | security_ops->secmark_refcount_inc(); | 1349 | call_void_hook(secmark_refcount_inc); |
| 1317 | } | 1350 | } |
| 1318 | EXPORT_SYMBOL(security_secmark_refcount_inc); | 1351 | EXPORT_SYMBOL(security_secmark_refcount_inc); |
| 1319 | 1352 | ||
| 1320 | void security_secmark_refcount_dec(void) | 1353 | void security_secmark_refcount_dec(void) |
| 1321 | { | 1354 | { |
| 1322 | security_ops->secmark_refcount_dec(); | 1355 | call_void_hook(secmark_refcount_dec); |
| 1323 | } | 1356 | } |
| 1324 | EXPORT_SYMBOL(security_secmark_refcount_dec); | 1357 | EXPORT_SYMBOL(security_secmark_refcount_dec); |
| 1325 | 1358 | ||
| 1326 | int security_tun_dev_alloc_security(void **security) | 1359 | int security_tun_dev_alloc_security(void **security) |
| 1327 | { | 1360 | { |
| 1328 | return security_ops->tun_dev_alloc_security(security); | 1361 | return call_int_hook(tun_dev_alloc_security, 0, security); |
| 1329 | } | 1362 | } |
| 1330 | EXPORT_SYMBOL(security_tun_dev_alloc_security); | 1363 | EXPORT_SYMBOL(security_tun_dev_alloc_security); |
| 1331 | 1364 | ||
| 1332 | void security_tun_dev_free_security(void *security) | 1365 | void security_tun_dev_free_security(void *security) |
| 1333 | { | 1366 | { |
| 1334 | security_ops->tun_dev_free_security(security); | 1367 | call_void_hook(tun_dev_free_security, security); |
| 1335 | } | 1368 | } |
| 1336 | EXPORT_SYMBOL(security_tun_dev_free_security); | 1369 | EXPORT_SYMBOL(security_tun_dev_free_security); |
| 1337 | 1370 | ||
| 1338 | int security_tun_dev_create(void) | 1371 | int security_tun_dev_create(void) |
| 1339 | { | 1372 | { |
| 1340 | return security_ops->tun_dev_create(); | 1373 | return call_int_hook(tun_dev_create, 0); |
| 1341 | } | 1374 | } |
| 1342 | EXPORT_SYMBOL(security_tun_dev_create); | 1375 | EXPORT_SYMBOL(security_tun_dev_create); |
| 1343 | 1376 | ||
| 1344 | int security_tun_dev_attach_queue(void *security) | 1377 | int security_tun_dev_attach_queue(void *security) |
| 1345 | { | 1378 | { |
| 1346 | return security_ops->tun_dev_attach_queue(security); | 1379 | return call_int_hook(tun_dev_attach_queue, 0, security); |
| 1347 | } | 1380 | } |
| 1348 | EXPORT_SYMBOL(security_tun_dev_attach_queue); | 1381 | EXPORT_SYMBOL(security_tun_dev_attach_queue); |
| 1349 | 1382 | ||
| 1350 | int security_tun_dev_attach(struct sock *sk, void *security) | 1383 | int security_tun_dev_attach(struct sock *sk, void *security) |
| 1351 | { | 1384 | { |
| 1352 | return security_ops->tun_dev_attach(sk, security); | 1385 | return call_int_hook(tun_dev_attach, 0, sk, security); |
| 1353 | } | 1386 | } |
| 1354 | EXPORT_SYMBOL(security_tun_dev_attach); | 1387 | EXPORT_SYMBOL(security_tun_dev_attach); |
| 1355 | 1388 | ||
| 1356 | int security_tun_dev_open(void *security) | 1389 | int security_tun_dev_open(void *security) |
| 1357 | { | 1390 | { |
| 1358 | return security_ops->tun_dev_open(security); | 1391 | return call_int_hook(tun_dev_open, 0, security); |
| 1359 | } | 1392 | } |
| 1360 | EXPORT_SYMBOL(security_tun_dev_open); | 1393 | EXPORT_SYMBOL(security_tun_dev_open); |
| 1361 | 1394 | ||
| 1362 | void security_skb_owned_by(struct sk_buff *skb, struct sock *sk) | ||
| 1363 | { | ||
| 1364 | security_ops->skb_owned_by(skb, sk); | ||
| 1365 | } | ||
| 1366 | |||
| 1367 | #endif /* CONFIG_SECURITY_NETWORK */ | 1395 | #endif /* CONFIG_SECURITY_NETWORK */ |
| 1368 | 1396 | ||
| 1369 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | 1397 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
| @@ -1372,71 +1400,89 @@ int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, | |||
| 1372 | struct xfrm_user_sec_ctx *sec_ctx, | 1400 | struct xfrm_user_sec_ctx *sec_ctx, |
| 1373 | gfp_t gfp) | 1401 | gfp_t gfp) |
| 1374 | { | 1402 | { |
| 1375 | return security_ops->xfrm_policy_alloc_security(ctxp, sec_ctx, gfp); | 1403 | return call_int_hook(xfrm_policy_alloc_security, 0, ctxp, sec_ctx, gfp); |
| 1376 | } | 1404 | } |
| 1377 | EXPORT_SYMBOL(security_xfrm_policy_alloc); | 1405 | EXPORT_SYMBOL(security_xfrm_policy_alloc); |
| 1378 | 1406 | ||
| 1379 | int security_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx, | 1407 | int security_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx, |
| 1380 | struct xfrm_sec_ctx **new_ctxp) | 1408 | struct xfrm_sec_ctx **new_ctxp) |
| 1381 | { | 1409 | { |
| 1382 | return security_ops->xfrm_policy_clone_security(old_ctx, new_ctxp); | 1410 | return call_int_hook(xfrm_policy_clone_security, 0, old_ctx, new_ctxp); |
| 1383 | } | 1411 | } |
| 1384 | 1412 | ||
| 1385 | void security_xfrm_policy_free(struct xfrm_sec_ctx *ctx) | 1413 | void security_xfrm_policy_free(struct xfrm_sec_ctx *ctx) |
| 1386 | { | 1414 | { |
| 1387 | security_ops->xfrm_policy_free_security(ctx); | 1415 | call_void_hook(xfrm_policy_free_security, ctx); |
| 1388 | } | 1416 | } |
| 1389 | EXPORT_SYMBOL(security_xfrm_policy_free); | 1417 | EXPORT_SYMBOL(security_xfrm_policy_free); |
| 1390 | 1418 | ||
| 1391 | int security_xfrm_policy_delete(struct xfrm_sec_ctx *ctx) | 1419 | int security_xfrm_policy_delete(struct xfrm_sec_ctx *ctx) |
| 1392 | { | 1420 | { |
| 1393 | return security_ops->xfrm_policy_delete_security(ctx); | 1421 | return call_int_hook(xfrm_policy_delete_security, 0, ctx); |
| 1394 | } | 1422 | } |
| 1395 | 1423 | ||
| 1396 | int security_xfrm_state_alloc(struct xfrm_state *x, | 1424 | int security_xfrm_state_alloc(struct xfrm_state *x, |
| 1397 | struct xfrm_user_sec_ctx *sec_ctx) | 1425 | struct xfrm_user_sec_ctx *sec_ctx) |
| 1398 | { | 1426 | { |
| 1399 | return security_ops->xfrm_state_alloc(x, sec_ctx); | 1427 | return call_int_hook(xfrm_state_alloc, 0, x, sec_ctx); |
| 1400 | } | 1428 | } |
| 1401 | EXPORT_SYMBOL(security_xfrm_state_alloc); | 1429 | EXPORT_SYMBOL(security_xfrm_state_alloc); |
| 1402 | 1430 | ||
| 1403 | int security_xfrm_state_alloc_acquire(struct xfrm_state *x, | 1431 | int security_xfrm_state_alloc_acquire(struct xfrm_state *x, |
| 1404 | struct xfrm_sec_ctx *polsec, u32 secid) | 1432 | struct xfrm_sec_ctx *polsec, u32 secid) |
| 1405 | { | 1433 | { |
| 1406 | return security_ops->xfrm_state_alloc_acquire(x, polsec, secid); | 1434 | return call_int_hook(xfrm_state_alloc_acquire, 0, x, polsec, secid); |
| 1407 | } | 1435 | } |
| 1408 | 1436 | ||
| 1409 | int security_xfrm_state_delete(struct xfrm_state *x) | 1437 | int security_xfrm_state_delete(struct xfrm_state *x) |
| 1410 | { | 1438 | { |
| 1411 | return security_ops->xfrm_state_delete_security(x); | 1439 | return call_int_hook(xfrm_state_delete_security, 0, x); |
| 1412 | } | 1440 | } |
| 1413 | EXPORT_SYMBOL(security_xfrm_state_delete); | 1441 | EXPORT_SYMBOL(security_xfrm_state_delete); |
| 1414 | 1442 | ||
| 1415 | void security_xfrm_state_free(struct xfrm_state *x) | 1443 | void security_xfrm_state_free(struct xfrm_state *x) |
| 1416 | { | 1444 | { |
| 1417 | security_ops->xfrm_state_free_security(x); | 1445 | call_void_hook(xfrm_state_free_security, x); |
| 1418 | } | 1446 | } |
| 1419 | 1447 | ||
| 1420 | int security_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir) | 1448 | int security_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir) |
| 1421 | { | 1449 | { |
| 1422 | return security_ops->xfrm_policy_lookup(ctx, fl_secid, dir); | 1450 | return call_int_hook(xfrm_policy_lookup, 0, ctx, fl_secid, dir); |
| 1423 | } | 1451 | } |
| 1424 | 1452 | ||
| 1425 | int security_xfrm_state_pol_flow_match(struct xfrm_state *x, | 1453 | int security_xfrm_state_pol_flow_match(struct xfrm_state *x, |
| 1426 | struct xfrm_policy *xp, | 1454 | struct xfrm_policy *xp, |
| 1427 | const struct flowi *fl) | 1455 | const struct flowi *fl) |
| 1428 | { | 1456 | { |
| 1429 | return security_ops->xfrm_state_pol_flow_match(x, xp, fl); | 1457 | struct security_hook_list *hp; |
| 1458 | int rc = 1; | ||
| 1459 | |||
| 1460 | /* | ||
| 1461 | * Since this function is expected to return 0 or 1, the judgment | ||
| 1462 | * becomes difficult if multiple LSMs supply this call. Fortunately, | ||
| 1463 | * we can use the first LSM's judgment because currently only SELinux | ||
| 1464 | * supplies this call. | ||
| 1465 | * | ||
| 1466 | * For speed optimization, we explicitly break the loop rather than | ||
| 1467 | * using the macro | ||
| 1468 | */ | ||
| 1469 | list_for_each_entry(hp, &security_hook_heads.xfrm_state_pol_flow_match, | ||
| 1470 | list) { | ||
| 1471 | rc = hp->hook.xfrm_state_pol_flow_match(x, xp, fl); | ||
| 1472 | break; | ||
| 1473 | } | ||
| 1474 | return rc; | ||
| 1430 | } | 1475 | } |
| 1431 | 1476 | ||
| 1432 | int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid) | 1477 | int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid) |
| 1433 | { | 1478 | { |
| 1434 | return security_ops->xfrm_decode_session(skb, secid, 1); | 1479 | return call_int_hook(xfrm_decode_session, 0, skb, secid, 1); |
| 1435 | } | 1480 | } |
| 1436 | 1481 | ||
| 1437 | void security_skb_classify_flow(struct sk_buff *skb, struct flowi *fl) | 1482 | void security_skb_classify_flow(struct sk_buff *skb, struct flowi *fl) |
| 1438 | { | 1483 | { |
| 1439 | int rc = security_ops->xfrm_decode_session(skb, &fl->flowi_secid, 0); | 1484 | int rc = call_int_hook(xfrm_decode_session, 0, skb, &fl->flowi_secid, |
| 1485 | 0); | ||
| 1440 | 1486 | ||
| 1441 | BUG_ON(rc); | 1487 | BUG_ON(rc); |
| 1442 | } | 1488 | } |
| @@ -1449,23 +1495,24 @@ EXPORT_SYMBOL(security_skb_classify_flow); | |||
| 1449 | int security_key_alloc(struct key *key, const struct cred *cred, | 1495 | int security_key_alloc(struct key *key, const struct cred *cred, |
| 1450 | unsigned long flags) | 1496 | unsigned long flags) |
| 1451 | { | 1497 | { |
| 1452 | return security_ops->key_alloc(key, cred, flags); | 1498 | return call_int_hook(key_alloc, 0, key, cred, flags); |
| 1453 | } | 1499 | } |
| 1454 | 1500 | ||
| 1455 | void security_key_free(struct key *key) | 1501 | void security_key_free(struct key *key) |
| 1456 | { | 1502 | { |
| 1457 | security_ops->key_free(key); | 1503 | call_void_hook(key_free, key); |
| 1458 | } | 1504 | } |
| 1459 | 1505 | ||
| 1460 | int security_key_permission(key_ref_t key_ref, | 1506 | int security_key_permission(key_ref_t key_ref, |
| 1461 | const struct cred *cred, unsigned perm) | 1507 | const struct cred *cred, unsigned perm) |
| 1462 | { | 1508 | { |
| 1463 | return security_ops->key_permission(key_ref, cred, perm); | 1509 | return call_int_hook(key_permission, 0, key_ref, cred, perm); |
| 1464 | } | 1510 | } |
| 1465 | 1511 | ||
| 1466 | int security_key_getsecurity(struct key *key, char **_buffer) | 1512 | int security_key_getsecurity(struct key *key, char **_buffer) |
| 1467 | { | 1513 | { |
| 1468 | return security_ops->key_getsecurity(key, _buffer); | 1514 | *_buffer = NULL; |
| 1515 | return call_int_hook(key_getsecurity, 0, key, _buffer); | ||
| 1469 | } | 1516 | } |
| 1470 | 1517 | ||
| 1471 | #endif /* CONFIG_KEYS */ | 1518 | #endif /* CONFIG_KEYS */ |
| @@ -1474,23 +1521,369 @@ int security_key_getsecurity(struct key *key, char **_buffer) | |||
| 1474 | 1521 | ||
| 1475 | int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule) | 1522 | int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule) |
| 1476 | { | 1523 | { |
| 1477 | return security_ops->audit_rule_init(field, op, rulestr, lsmrule); | 1524 | return call_int_hook(audit_rule_init, 0, field, op, rulestr, lsmrule); |
| 1478 | } | 1525 | } |
| 1479 | 1526 | ||
| 1480 | int security_audit_rule_known(struct audit_krule *krule) | 1527 | int security_audit_rule_known(struct audit_krule *krule) |
| 1481 | { | 1528 | { |
| 1482 | return security_ops->audit_rule_known(krule); | 1529 | return call_int_hook(audit_rule_known, 0, krule); |
| 1483 | } | 1530 | } |
| 1484 | 1531 | ||
| 1485 | void security_audit_rule_free(void *lsmrule) | 1532 | void security_audit_rule_free(void *lsmrule) |
| 1486 | { | 1533 | { |
| 1487 | security_ops->audit_rule_free(lsmrule); | 1534 | call_void_hook(audit_rule_free, lsmrule); |
| 1488 | } | 1535 | } |
| 1489 | 1536 | ||
| 1490 | int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule, | 1537 | int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule, |
| 1491 | struct audit_context *actx) | 1538 | struct audit_context *actx) |
| 1492 | { | 1539 | { |
| 1493 | return security_ops->audit_rule_match(secid, field, op, lsmrule, actx); | 1540 | return call_int_hook(audit_rule_match, 0, secid, field, op, lsmrule, |
| 1541 | actx); | ||
| 1494 | } | 1542 | } |
| 1543 | #endif /* CONFIG_AUDIT */ | ||
| 1495 | 1544 | ||
| 1545 | struct security_hook_heads security_hook_heads = { | ||
| 1546 | .binder_set_context_mgr = | ||
| 1547 | LIST_HEAD_INIT(security_hook_heads.binder_set_context_mgr), | ||
| 1548 | .binder_transaction = | ||
| 1549 | LIST_HEAD_INIT(security_hook_heads.binder_transaction), | ||
| 1550 | .binder_transfer_binder = | ||
| 1551 | LIST_HEAD_INIT(security_hook_heads.binder_transfer_binder), | ||
| 1552 | .binder_transfer_file = | ||
| 1553 | LIST_HEAD_INIT(security_hook_heads.binder_transfer_file), | ||
| 1554 | |||
| 1555 | .ptrace_access_check = | ||
| 1556 | LIST_HEAD_INIT(security_hook_heads.ptrace_access_check), | ||
| 1557 | .ptrace_traceme = | ||
| 1558 | LIST_HEAD_INIT(security_hook_heads.ptrace_traceme), | ||
| 1559 | .capget = LIST_HEAD_INIT(security_hook_heads.capget), | ||
| 1560 | .capset = LIST_HEAD_INIT(security_hook_heads.capset), | ||
| 1561 | .capable = LIST_HEAD_INIT(security_hook_heads.capable), | ||
| 1562 | .quotactl = LIST_HEAD_INIT(security_hook_heads.quotactl), | ||
| 1563 | .quota_on = LIST_HEAD_INIT(security_hook_heads.quota_on), | ||
| 1564 | .syslog = LIST_HEAD_INIT(security_hook_heads.syslog), | ||
| 1565 | .settime = LIST_HEAD_INIT(security_hook_heads.settime), | ||
| 1566 | .vm_enough_memory = | ||
| 1567 | LIST_HEAD_INIT(security_hook_heads.vm_enough_memory), | ||
| 1568 | .bprm_set_creds = | ||
| 1569 | LIST_HEAD_INIT(security_hook_heads.bprm_set_creds), | ||
| 1570 | .bprm_check_security = | ||
| 1571 | LIST_HEAD_INIT(security_hook_heads.bprm_check_security), | ||
| 1572 | .bprm_secureexec = | ||
| 1573 | LIST_HEAD_INIT(security_hook_heads.bprm_secureexec), | ||
| 1574 | .bprm_committing_creds = | ||
| 1575 | LIST_HEAD_INIT(security_hook_heads.bprm_committing_creds), | ||
| 1576 | .bprm_committed_creds = | ||
| 1577 | LIST_HEAD_INIT(security_hook_heads.bprm_committed_creds), | ||
| 1578 | .sb_alloc_security = | ||
| 1579 | LIST_HEAD_INIT(security_hook_heads.sb_alloc_security), | ||
| 1580 | .sb_free_security = | ||
| 1581 | LIST_HEAD_INIT(security_hook_heads.sb_free_security), | ||
| 1582 | .sb_copy_data = LIST_HEAD_INIT(security_hook_heads.sb_copy_data), | ||
| 1583 | .sb_remount = LIST_HEAD_INIT(security_hook_heads.sb_remount), | ||
| 1584 | .sb_kern_mount = | ||
| 1585 | LIST_HEAD_INIT(security_hook_heads.sb_kern_mount), | ||
| 1586 | .sb_show_options = | ||
| 1587 | LIST_HEAD_INIT(security_hook_heads.sb_show_options), | ||
| 1588 | .sb_statfs = LIST_HEAD_INIT(security_hook_heads.sb_statfs), | ||
| 1589 | .sb_mount = LIST_HEAD_INIT(security_hook_heads.sb_mount), | ||
| 1590 | .sb_umount = LIST_HEAD_INIT(security_hook_heads.sb_umount), | ||
| 1591 | .sb_pivotroot = LIST_HEAD_INIT(security_hook_heads.sb_pivotroot), | ||
| 1592 | .sb_set_mnt_opts = | ||
| 1593 | LIST_HEAD_INIT(security_hook_heads.sb_set_mnt_opts), | ||
| 1594 | .sb_clone_mnt_opts = | ||
| 1595 | LIST_HEAD_INIT(security_hook_heads.sb_clone_mnt_opts), | ||
| 1596 | .sb_parse_opts_str = | ||
| 1597 | LIST_HEAD_INIT(security_hook_heads.sb_parse_opts_str), | ||
| 1598 | .dentry_init_security = | ||
| 1599 | LIST_HEAD_INIT(security_hook_heads.dentry_init_security), | ||
| 1600 | #ifdef CONFIG_SECURITY_PATH | ||
| 1601 | .path_unlink = LIST_HEAD_INIT(security_hook_heads.path_unlink), | ||
| 1602 | .path_mkdir = LIST_HEAD_INIT(security_hook_heads.path_mkdir), | ||
| 1603 | .path_rmdir = LIST_HEAD_INIT(security_hook_heads.path_rmdir), | ||
| 1604 | .path_mknod = LIST_HEAD_INIT(security_hook_heads.path_mknod), | ||
| 1605 | .path_truncate = | ||
| 1606 | LIST_HEAD_INIT(security_hook_heads.path_truncate), | ||
| 1607 | .path_symlink = LIST_HEAD_INIT(security_hook_heads.path_symlink), | ||
| 1608 | .path_link = LIST_HEAD_INIT(security_hook_heads.path_link), | ||
| 1609 | .path_rename = LIST_HEAD_INIT(security_hook_heads.path_rename), | ||
| 1610 | .path_chmod = LIST_HEAD_INIT(security_hook_heads.path_chmod), | ||
| 1611 | .path_chown = LIST_HEAD_INIT(security_hook_heads.path_chown), | ||
| 1612 | .path_chroot = LIST_HEAD_INIT(security_hook_heads.path_chroot), | ||
| 1613 | #endif | ||
| 1614 | .inode_alloc_security = | ||
| 1615 | LIST_HEAD_INIT(security_hook_heads.inode_alloc_security), | ||
| 1616 | .inode_free_security = | ||
| 1617 | LIST_HEAD_INIT(security_hook_heads.inode_free_security), | ||
| 1618 | .inode_init_security = | ||
| 1619 | LIST_HEAD_INIT(security_hook_heads.inode_init_security), | ||
| 1620 | .inode_create = LIST_HEAD_INIT(security_hook_heads.inode_create), | ||
| 1621 | .inode_link = LIST_HEAD_INIT(security_hook_heads.inode_link), | ||
| 1622 | .inode_unlink = LIST_HEAD_INIT(security_hook_heads.inode_unlink), | ||
| 1623 | .inode_symlink = | ||
| 1624 | LIST_HEAD_INIT(security_hook_heads.inode_symlink), | ||
| 1625 | .inode_mkdir = LIST_HEAD_INIT(security_hook_heads.inode_mkdir), | ||
| 1626 | .inode_rmdir = LIST_HEAD_INIT(security_hook_heads.inode_rmdir), | ||
| 1627 | .inode_mknod = LIST_HEAD_INIT(security_hook_heads.inode_mknod), | ||
| 1628 | .inode_rename = LIST_HEAD_INIT(security_hook_heads.inode_rename), | ||
| 1629 | .inode_readlink = | ||
| 1630 | LIST_HEAD_INIT(security_hook_heads.inode_readlink), | ||
| 1631 | .inode_follow_link = | ||
| 1632 | LIST_HEAD_INIT(security_hook_heads.inode_follow_link), | ||
| 1633 | .inode_permission = | ||
| 1634 | LIST_HEAD_INIT(security_hook_heads.inode_permission), | ||
| 1635 | .inode_setattr = | ||
| 1636 | LIST_HEAD_INIT(security_hook_heads.inode_setattr), | ||
| 1637 | .inode_getattr = | ||
| 1638 | LIST_HEAD_INIT(security_hook_heads.inode_getattr), | ||
| 1639 | .inode_setxattr = | ||
| 1640 | LIST_HEAD_INIT(security_hook_heads.inode_setxattr), | ||
| 1641 | .inode_post_setxattr = | ||
| 1642 | LIST_HEAD_INIT(security_hook_heads.inode_post_setxattr), | ||
| 1643 | .inode_getxattr = | ||
| 1644 | LIST_HEAD_INIT(security_hook_heads.inode_getxattr), | ||
| 1645 | .inode_listxattr = | ||
| 1646 | LIST_HEAD_INIT(security_hook_heads.inode_listxattr), | ||
| 1647 | .inode_removexattr = | ||
| 1648 | LIST_HEAD_INIT(security_hook_heads.inode_removexattr), | ||
| 1649 | .inode_need_killpriv = | ||
| 1650 | LIST_HEAD_INIT(security_hook_heads.inode_need_killpriv), | ||
| 1651 | .inode_killpriv = | ||
| 1652 | LIST_HEAD_INIT(security_hook_heads.inode_killpriv), | ||
| 1653 | .inode_getsecurity = | ||
| 1654 | LIST_HEAD_INIT(security_hook_heads.inode_getsecurity), | ||
| 1655 | .inode_setsecurity = | ||
| 1656 | LIST_HEAD_INIT(security_hook_heads.inode_setsecurity), | ||
| 1657 | .inode_listsecurity = | ||
| 1658 | LIST_HEAD_INIT(security_hook_heads.inode_listsecurity), | ||
| 1659 | .inode_getsecid = | ||
| 1660 | LIST_HEAD_INIT(security_hook_heads.inode_getsecid), | ||
| 1661 | .file_permission = | ||
| 1662 | LIST_HEAD_INIT(security_hook_heads.file_permission), | ||
| 1663 | .file_alloc_security = | ||
| 1664 | LIST_HEAD_INIT(security_hook_heads.file_alloc_security), | ||
| 1665 | .file_free_security = | ||
| 1666 | LIST_HEAD_INIT(security_hook_heads.file_free_security), | ||
| 1667 | .file_ioctl = LIST_HEAD_INIT(security_hook_heads.file_ioctl), | ||
| 1668 | .mmap_addr = LIST_HEAD_INIT(security_hook_heads.mmap_addr), | ||
| 1669 | .mmap_file = LIST_HEAD_INIT(security_hook_heads.mmap_file), | ||
| 1670 | .file_mprotect = | ||
| 1671 | LIST_HEAD_INIT(security_hook_heads.file_mprotect), | ||
| 1672 | .file_lock = LIST_HEAD_INIT(security_hook_heads.file_lock), | ||
| 1673 | .file_fcntl = LIST_HEAD_INIT(security_hook_heads.file_fcntl), | ||
| 1674 | .file_set_fowner = | ||
| 1675 | LIST_HEAD_INIT(security_hook_heads.file_set_fowner), | ||
| 1676 | .file_send_sigiotask = | ||
| 1677 | LIST_HEAD_INIT(security_hook_heads.file_send_sigiotask), | ||
| 1678 | .file_receive = LIST_HEAD_INIT(security_hook_heads.file_receive), | ||
| 1679 | .file_open = LIST_HEAD_INIT(security_hook_heads.file_open), | ||
| 1680 | .task_create = LIST_HEAD_INIT(security_hook_heads.task_create), | ||
| 1681 | .task_free = LIST_HEAD_INIT(security_hook_heads.task_free), | ||
| 1682 | .cred_alloc_blank = | ||
| 1683 | LIST_HEAD_INIT(security_hook_heads.cred_alloc_blank), | ||
| 1684 | .cred_free = LIST_HEAD_INIT(security_hook_heads.cred_free), | ||
| 1685 | .cred_prepare = LIST_HEAD_INIT(security_hook_heads.cred_prepare), | ||
| 1686 | .cred_transfer = | ||
| 1687 | LIST_HEAD_INIT(security_hook_heads.cred_transfer), | ||
| 1688 | .kernel_act_as = | ||
| 1689 | LIST_HEAD_INIT(security_hook_heads.kernel_act_as), | ||
| 1690 | .kernel_create_files_as = | ||
| 1691 | LIST_HEAD_INIT(security_hook_heads.kernel_create_files_as), | ||
| 1692 | .kernel_fw_from_file = | ||
| 1693 | LIST_HEAD_INIT(security_hook_heads.kernel_fw_from_file), | ||
| 1694 | .kernel_module_request = | ||
| 1695 | LIST_HEAD_INIT(security_hook_heads.kernel_module_request), | ||
| 1696 | .kernel_module_from_file = | ||
| 1697 | LIST_HEAD_INIT(security_hook_heads.kernel_module_from_file), | ||
| 1698 | .task_fix_setuid = | ||
| 1699 | LIST_HEAD_INIT(security_hook_heads.task_fix_setuid), | ||
| 1700 | .task_setpgid = LIST_HEAD_INIT(security_hook_heads.task_setpgid), | ||
| 1701 | .task_getpgid = LIST_HEAD_INIT(security_hook_heads.task_getpgid), | ||
| 1702 | .task_getsid = LIST_HEAD_INIT(security_hook_heads.task_getsid), | ||
| 1703 | .task_getsecid = | ||
| 1704 | LIST_HEAD_INIT(security_hook_heads.task_getsecid), | ||
| 1705 | .task_setnice = LIST_HEAD_INIT(security_hook_heads.task_setnice), | ||
| 1706 | .task_setioprio = | ||
| 1707 | LIST_HEAD_INIT(security_hook_heads.task_setioprio), | ||
| 1708 | .task_getioprio = | ||
| 1709 | LIST_HEAD_INIT(security_hook_heads.task_getioprio), | ||
| 1710 | .task_setrlimit = | ||
| 1711 | LIST_HEAD_INIT(security_hook_heads.task_setrlimit), | ||
| 1712 | .task_setscheduler = | ||
| 1713 | LIST_HEAD_INIT(security_hook_heads.task_setscheduler), | ||
| 1714 | .task_getscheduler = | ||
| 1715 | LIST_HEAD_INIT(security_hook_heads.task_getscheduler), | ||
| 1716 | .task_movememory = | ||
| 1717 | LIST_HEAD_INIT(security_hook_heads.task_movememory), | ||
| 1718 | .task_kill = LIST_HEAD_INIT(security_hook_heads.task_kill), | ||
| 1719 | .task_wait = LIST_HEAD_INIT(security_hook_heads.task_wait), | ||
| 1720 | .task_prctl = LIST_HEAD_INIT(security_hook_heads.task_prctl), | ||
| 1721 | .task_to_inode = | ||
| 1722 | LIST_HEAD_INIT(security_hook_heads.task_to_inode), | ||
| 1723 | .ipc_permission = | ||
| 1724 | LIST_HEAD_INIT(security_hook_heads.ipc_permission), | ||
| 1725 | .ipc_getsecid = LIST_HEAD_INIT(security_hook_heads.ipc_getsecid), | ||
| 1726 | .msg_msg_alloc_security = | ||
| 1727 | LIST_HEAD_INIT(security_hook_heads.msg_msg_alloc_security), | ||
| 1728 | .msg_msg_free_security = | ||
| 1729 | LIST_HEAD_INIT(security_hook_heads.msg_msg_free_security), | ||
| 1730 | .msg_queue_alloc_security = | ||
| 1731 | LIST_HEAD_INIT(security_hook_heads.msg_queue_alloc_security), | ||
| 1732 | .msg_queue_free_security = | ||
| 1733 | LIST_HEAD_INIT(security_hook_heads.msg_queue_free_security), | ||
| 1734 | .msg_queue_associate = | ||
| 1735 | LIST_HEAD_INIT(security_hook_heads.msg_queue_associate), | ||
| 1736 | .msg_queue_msgctl = | ||
| 1737 | LIST_HEAD_INIT(security_hook_heads.msg_queue_msgctl), | ||
| 1738 | .msg_queue_msgsnd = | ||
| 1739 | LIST_HEAD_INIT(security_hook_heads.msg_queue_msgsnd), | ||
| 1740 | .msg_queue_msgrcv = | ||
| 1741 | LIST_HEAD_INIT(security_hook_heads.msg_queue_msgrcv), | ||
| 1742 | .shm_alloc_security = | ||
| 1743 | LIST_HEAD_INIT(security_hook_heads.shm_alloc_security), | ||
| 1744 | .shm_free_security = | ||
| 1745 | LIST_HEAD_INIT(security_hook_heads.shm_free_security), | ||
| 1746 | .shm_associate = | ||
| 1747 | LIST_HEAD_INIT(security_hook_heads.shm_associate), | ||
| 1748 | .shm_shmctl = LIST_HEAD_INIT(security_hook_heads.shm_shmctl), | ||
| 1749 | .shm_shmat = LIST_HEAD_INIT(security_hook_heads.shm_shmat), | ||
| 1750 | .sem_alloc_security = | ||
| 1751 | LIST_HEAD_INIT(security_hook_heads.sem_alloc_security), | ||
| 1752 | .sem_free_security = | ||
| 1753 | LIST_HEAD_INIT(security_hook_heads.sem_free_security), | ||
| 1754 | .sem_associate = | ||
| 1755 | LIST_HEAD_INIT(security_hook_heads.sem_associate), | ||
| 1756 | .sem_semctl = LIST_HEAD_INIT(security_hook_heads.sem_semctl), | ||
| 1757 | .sem_semop = LIST_HEAD_INIT(security_hook_heads.sem_semop), | ||
| 1758 | .netlink_send = LIST_HEAD_INIT(security_hook_heads.netlink_send), | ||
| 1759 | .d_instantiate = | ||
| 1760 | LIST_HEAD_INIT(security_hook_heads.d_instantiate), | ||
| 1761 | .getprocattr = LIST_HEAD_INIT(security_hook_heads.getprocattr), | ||
| 1762 | .setprocattr = LIST_HEAD_INIT(security_hook_heads.setprocattr), | ||
| 1763 | .ismaclabel = LIST_HEAD_INIT(security_hook_heads.ismaclabel), | ||
| 1764 | .secid_to_secctx = | ||
| 1765 | LIST_HEAD_INIT(security_hook_heads.secid_to_secctx), | ||
| 1766 | .secctx_to_secid = | ||
| 1767 | LIST_HEAD_INIT(security_hook_heads.secctx_to_secid), | ||
| 1768 | .release_secctx = | ||
| 1769 | LIST_HEAD_INIT(security_hook_heads.release_secctx), | ||
| 1770 | .inode_notifysecctx = | ||
| 1771 | LIST_HEAD_INIT(security_hook_heads.inode_notifysecctx), | ||
| 1772 | .inode_setsecctx = | ||
| 1773 | LIST_HEAD_INIT(security_hook_heads.inode_setsecctx), | ||
| 1774 | .inode_getsecctx = | ||
| 1775 | LIST_HEAD_INIT(security_hook_heads.inode_getsecctx), | ||
| 1776 | #ifdef CONFIG_SECURITY_NETWORK | ||
| 1777 | .unix_stream_connect = | ||
| 1778 | LIST_HEAD_INIT(security_hook_heads.unix_stream_connect), | ||
| 1779 | .unix_may_send = | ||
| 1780 | LIST_HEAD_INIT(security_hook_heads.unix_may_send), | ||
| 1781 | .socket_create = | ||
| 1782 | LIST_HEAD_INIT(security_hook_heads.socket_create), | ||
| 1783 | .socket_post_create = | ||
| 1784 | LIST_HEAD_INIT(security_hook_heads.socket_post_create), | ||
| 1785 | .socket_bind = LIST_HEAD_INIT(security_hook_heads.socket_bind), | ||
| 1786 | .socket_connect = | ||
| 1787 | LIST_HEAD_INIT(security_hook_heads.socket_connect), | ||
| 1788 | .socket_listen = | ||
| 1789 | LIST_HEAD_INIT(security_hook_heads.socket_listen), | ||
| 1790 | .socket_accept = | ||
| 1791 | LIST_HEAD_INIT(security_hook_heads.socket_accept), | ||
| 1792 | .socket_sendmsg = | ||
| 1793 | LIST_HEAD_INIT(security_hook_heads.socket_sendmsg), | ||
| 1794 | .socket_recvmsg = | ||
| 1795 | LIST_HEAD_INIT(security_hook_heads.socket_recvmsg), | ||
| 1796 | .socket_getsockname = | ||
| 1797 | LIST_HEAD_INIT(security_hook_heads.socket_getsockname), | ||
| 1798 | .socket_getpeername = | ||
| 1799 | LIST_HEAD_INIT(security_hook_heads.socket_getpeername), | ||
| 1800 | .socket_getsockopt = | ||
| 1801 | LIST_HEAD_INIT(security_hook_heads.socket_getsockopt), | ||
| 1802 | .socket_setsockopt = | ||
| 1803 | LIST_HEAD_INIT(security_hook_heads.socket_setsockopt), | ||
| 1804 | .socket_shutdown = | ||
| 1805 | LIST_HEAD_INIT(security_hook_heads.socket_shutdown), | ||
| 1806 | .socket_sock_rcv_skb = | ||
| 1807 | LIST_HEAD_INIT(security_hook_heads.socket_sock_rcv_skb), | ||
| 1808 | .socket_getpeersec_stream = | ||
| 1809 | LIST_HEAD_INIT(security_hook_heads.socket_getpeersec_stream), | ||
| 1810 | .socket_getpeersec_dgram = | ||
| 1811 | LIST_HEAD_INIT(security_hook_heads.socket_getpeersec_dgram), | ||
| 1812 | .sk_alloc_security = | ||
| 1813 | LIST_HEAD_INIT(security_hook_heads.sk_alloc_security), | ||
| 1814 | .sk_free_security = | ||
| 1815 | LIST_HEAD_INIT(security_hook_heads.sk_free_security), | ||
| 1816 | .sk_clone_security = | ||
| 1817 | LIST_HEAD_INIT(security_hook_heads.sk_clone_security), | ||
| 1818 | .sk_getsecid = LIST_HEAD_INIT(security_hook_heads.sk_getsecid), | ||
| 1819 | .sock_graft = LIST_HEAD_INIT(security_hook_heads.sock_graft), | ||
| 1820 | .inet_conn_request = | ||
| 1821 | LIST_HEAD_INIT(security_hook_heads.inet_conn_request), | ||
| 1822 | .inet_csk_clone = | ||
| 1823 | LIST_HEAD_INIT(security_hook_heads.inet_csk_clone), | ||
| 1824 | .inet_conn_established = | ||
| 1825 | LIST_HEAD_INIT(security_hook_heads.inet_conn_established), | ||
| 1826 | .secmark_relabel_packet = | ||
| 1827 | LIST_HEAD_INIT(security_hook_heads.secmark_relabel_packet), | ||
| 1828 | .secmark_refcount_inc = | ||
| 1829 | LIST_HEAD_INIT(security_hook_heads.secmark_refcount_inc), | ||
| 1830 | .secmark_refcount_dec = | ||
| 1831 | LIST_HEAD_INIT(security_hook_heads.secmark_refcount_dec), | ||
| 1832 | .req_classify_flow = | ||
| 1833 | LIST_HEAD_INIT(security_hook_heads.req_classify_flow), | ||
| 1834 | .tun_dev_alloc_security = | ||
| 1835 | LIST_HEAD_INIT(security_hook_heads.tun_dev_alloc_security), | ||
| 1836 | .tun_dev_free_security = | ||
| 1837 | LIST_HEAD_INIT(security_hook_heads.tun_dev_free_security), | ||
| 1838 | .tun_dev_create = | ||
| 1839 | LIST_HEAD_INIT(security_hook_heads.tun_dev_create), | ||
| 1840 | .tun_dev_attach_queue = | ||
| 1841 | LIST_HEAD_INIT(security_hook_heads.tun_dev_attach_queue), | ||
| 1842 | .tun_dev_attach = | ||
| 1843 | LIST_HEAD_INIT(security_hook_heads.tun_dev_attach), | ||
| 1844 | .tun_dev_open = LIST_HEAD_INIT(security_hook_heads.tun_dev_open), | ||
| 1845 | .skb_owned_by = LIST_HEAD_INIT(security_hook_heads.skb_owned_by), | ||
| 1846 | #endif /* CONFIG_SECURITY_NETWORK */ | ||
| 1847 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | ||
| 1848 | .xfrm_policy_alloc_security = | ||
| 1849 | LIST_HEAD_INIT(security_hook_heads.xfrm_policy_alloc_security), | ||
| 1850 | .xfrm_policy_clone_security = | ||
| 1851 | LIST_HEAD_INIT(security_hook_heads.xfrm_policy_clone_security), | ||
| 1852 | .xfrm_policy_free_security = | ||
| 1853 | LIST_HEAD_INIT(security_hook_heads.xfrm_policy_free_security), | ||
| 1854 | .xfrm_policy_delete_security = | ||
| 1855 | LIST_HEAD_INIT(security_hook_heads.xfrm_policy_delete_security), | ||
| 1856 | .xfrm_state_alloc = | ||
| 1857 | LIST_HEAD_INIT(security_hook_heads.xfrm_state_alloc), | ||
| 1858 | .xfrm_state_alloc_acquire = | ||
| 1859 | LIST_HEAD_INIT(security_hook_heads.xfrm_state_alloc_acquire), | ||
| 1860 | .xfrm_state_free_security = | ||
| 1861 | LIST_HEAD_INIT(security_hook_heads.xfrm_state_free_security), | ||
| 1862 | .xfrm_state_delete_security = | ||
| 1863 | LIST_HEAD_INIT(security_hook_heads.xfrm_state_delete_security), | ||
| 1864 | .xfrm_policy_lookup = | ||
| 1865 | LIST_HEAD_INIT(security_hook_heads.xfrm_policy_lookup), | ||
| 1866 | .xfrm_state_pol_flow_match = | ||
| 1867 | LIST_HEAD_INIT(security_hook_heads.xfrm_state_pol_flow_match), | ||
| 1868 | .xfrm_decode_session = | ||
| 1869 | LIST_HEAD_INIT(security_hook_heads.xfrm_decode_session), | ||
| 1870 | #endif /* CONFIG_SECURITY_NETWORK_XFRM */ | ||
| 1871 | #ifdef CONFIG_KEYS | ||
| 1872 | .key_alloc = LIST_HEAD_INIT(security_hook_heads.key_alloc), | ||
| 1873 | .key_free = LIST_HEAD_INIT(security_hook_heads.key_free), | ||
| 1874 | .key_permission = | ||
| 1875 | LIST_HEAD_INIT(security_hook_heads.key_permission), | ||
| 1876 | .key_getsecurity = | ||
| 1877 | LIST_HEAD_INIT(security_hook_heads.key_getsecurity), | ||
| 1878 | #endif /* CONFIG_KEYS */ | ||
| 1879 | #ifdef CONFIG_AUDIT | ||
| 1880 | .audit_rule_init = | ||
| 1881 | LIST_HEAD_INIT(security_hook_heads.audit_rule_init), | ||
| 1882 | .audit_rule_known = | ||
| 1883 | LIST_HEAD_INIT(security_hook_heads.audit_rule_known), | ||
| 1884 | .audit_rule_match = | ||
| 1885 | LIST_HEAD_INIT(security_hook_heads.audit_rule_match), | ||
| 1886 | .audit_rule_free = | ||
| 1887 | LIST_HEAD_INIT(security_hook_heads.audit_rule_free), | ||
| 1496 | #endif /* CONFIG_AUDIT */ | 1888 | #endif /* CONFIG_AUDIT */ |
| 1889 | }; | ||
diff --git a/security/selinux/avc.c b/security/selinux/avc.c index afcc0aed9393..0b122b1421a9 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c | |||
| @@ -724,12 +724,10 @@ inline int avc_has_perm_noaudit(u32 ssid, u32 tsid, | |||
| 724 | rcu_read_lock(); | 724 | rcu_read_lock(); |
| 725 | 725 | ||
| 726 | node = avc_lookup(ssid, tsid, tclass); | 726 | node = avc_lookup(ssid, tsid, tclass); |
| 727 | if (unlikely(!node)) { | 727 | if (unlikely(!node)) |
| 728 | node = avc_compute_av(ssid, tsid, tclass, avd); | 728 | node = avc_compute_av(ssid, tsid, tclass, avd); |
| 729 | } else { | 729 | else |
| 730 | memcpy(avd, &node->ae.avd, sizeof(*avd)); | 730 | memcpy(avd, &node->ae.avd, sizeof(*avd)); |
| 731 | avd = &node->ae.avd; | ||
| 732 | } | ||
| 733 | 731 | ||
| 734 | denied = requested & ~(avd->allowed); | 732 | denied = requested & ~(avd->allowed); |
| 735 | if (unlikely(denied)) | 733 | if (unlikely(denied)) |
| @@ -763,7 +761,23 @@ int avc_has_perm(u32 ssid, u32 tsid, u16 tclass, | |||
| 763 | 761 | ||
| 764 | rc = avc_has_perm_noaudit(ssid, tsid, tclass, requested, 0, &avd); | 762 | rc = avc_has_perm_noaudit(ssid, tsid, tclass, requested, 0, &avd); |
| 765 | 763 | ||
| 766 | rc2 = avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata); | 764 | rc2 = avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata, 0); |
| 765 | if (rc2) | ||
| 766 | return rc2; | ||
| 767 | return rc; | ||
| 768 | } | ||
| 769 | |||
| 770 | int avc_has_perm_flags(u32 ssid, u32 tsid, u16 tclass, | ||
| 771 | u32 requested, struct common_audit_data *auditdata, | ||
| 772 | int flags) | ||
| 773 | { | ||
| 774 | struct av_decision avd; | ||
| 775 | int rc, rc2; | ||
| 776 | |||
| 777 | rc = avc_has_perm_noaudit(ssid, tsid, tclass, requested, 0, &avd); | ||
| 778 | |||
| 779 | rc2 = avc_audit(ssid, tsid, tclass, requested, &avd, rc, | ||
| 780 | auditdata, flags); | ||
| 767 | if (rc2) | 781 | if (rc2) |
| 768 | return rc2; | 782 | return rc2; |
| 769 | return rc; | 783 | return rc; |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 4d1a54190388..564079c5c49d 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -29,7 +29,7 @@ | |||
| 29 | #include <linux/tracehook.h> | 29 | #include <linux/tracehook.h> |
| 30 | #include <linux/errno.h> | 30 | #include <linux/errno.h> |
| 31 | #include <linux/sched.h> | 31 | #include <linux/sched.h> |
| 32 | #include <linux/security.h> | 32 | #include <linux/lsm_hooks.h> |
| 33 | #include <linux/xattr.h> | 33 | #include <linux/xattr.h> |
| 34 | #include <linux/capability.h> | 34 | #include <linux/capability.h> |
| 35 | #include <linux/unistd.h> | 35 | #include <linux/unistd.h> |
| @@ -51,7 +51,6 @@ | |||
| 51 | #include <linux/tty.h> | 51 | #include <linux/tty.h> |
| 52 | #include <net/icmp.h> | 52 | #include <net/icmp.h> |
| 53 | #include <net/ip.h> /* for local_port_range[] */ | 53 | #include <net/ip.h> /* for local_port_range[] */ |
| 54 | #include <net/sock.h> | ||
| 55 | #include <net/tcp.h> /* struct or_callable used in sock_rcv_skb */ | 54 | #include <net/tcp.h> /* struct or_callable used in sock_rcv_skb */ |
| 56 | #include <net/inet_connection_sock.h> | 55 | #include <net/inet_connection_sock.h> |
| 57 | #include <net/net_namespace.h> | 56 | #include <net/net_namespace.h> |
| @@ -404,6 +403,7 @@ static int selinux_is_sblabel_mnt(struct super_block *sb) | |||
| 404 | return sbsec->behavior == SECURITY_FS_USE_XATTR || | 403 | return sbsec->behavior == SECURITY_FS_USE_XATTR || |
| 405 | sbsec->behavior == SECURITY_FS_USE_TRANS || | 404 | sbsec->behavior == SECURITY_FS_USE_TRANS || |
| 406 | sbsec->behavior == SECURITY_FS_USE_TASK || | 405 | sbsec->behavior == SECURITY_FS_USE_TASK || |
| 406 | sbsec->behavior == SECURITY_FS_USE_NATIVE || | ||
| 407 | /* Special handling. Genfs but also in-core setxattr handler */ | 407 | /* Special handling. Genfs but also in-core setxattr handler */ |
| 408 | !strcmp(sb->s_type->name, "sysfs") || | 408 | !strcmp(sb->s_type->name, "sysfs") || |
| 409 | !strcmp(sb->s_type->name, "pstore") || | 409 | !strcmp(sb->s_type->name, "pstore") || |
| @@ -415,7 +415,7 @@ static int sb_finish_set_opts(struct super_block *sb) | |||
| 415 | { | 415 | { |
| 416 | struct superblock_security_struct *sbsec = sb->s_security; | 416 | struct superblock_security_struct *sbsec = sb->s_security; |
| 417 | struct dentry *root = sb->s_root; | 417 | struct dentry *root = sb->s_root; |
| 418 | struct inode *root_inode = root->d_inode; | 418 | struct inode *root_inode = d_backing_inode(root); |
| 419 | int rc = 0; | 419 | int rc = 0; |
| 420 | 420 | ||
| 421 | if (sbsec->behavior == SECURITY_FS_USE_XATTR) { | 421 | if (sbsec->behavior == SECURITY_FS_USE_XATTR) { |
| @@ -553,7 +553,7 @@ static int selinux_get_mnt_opts(const struct super_block *sb, | |||
| 553 | opts->mnt_opts_flags[i++] = DEFCONTEXT_MNT; | 553 | opts->mnt_opts_flags[i++] = DEFCONTEXT_MNT; |
| 554 | } | 554 | } |
| 555 | if (sbsec->flags & ROOTCONTEXT_MNT) { | 555 | if (sbsec->flags & ROOTCONTEXT_MNT) { |
| 556 | struct inode *root = sbsec->sb->s_root->d_inode; | 556 | struct inode *root = d_backing_inode(sbsec->sb->s_root); |
| 557 | struct inode_security_struct *isec = root->i_security; | 557 | struct inode_security_struct *isec = root->i_security; |
| 558 | 558 | ||
| 559 | rc = security_sid_to_context(isec->sid, &context, &len); | 559 | rc = security_sid_to_context(isec->sid, &context, &len); |
| @@ -609,7 +609,7 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
| 609 | int rc = 0, i; | 609 | int rc = 0, i; |
| 610 | struct superblock_security_struct *sbsec = sb->s_security; | 610 | struct superblock_security_struct *sbsec = sb->s_security; |
| 611 | const char *name = sb->s_type->name; | 611 | const char *name = sb->s_type->name; |
| 612 | struct inode *inode = sbsec->sb->s_root->d_inode; | 612 | struct inode *inode = d_backing_inode(sbsec->sb->s_root); |
| 613 | struct inode_security_struct *root_isec = inode->i_security; | 613 | struct inode_security_struct *root_isec = inode->i_security; |
| 614 | u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0; | 614 | u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0; |
| 615 | u32 defcontext_sid = 0; | 615 | u32 defcontext_sid = 0; |
| @@ -725,7 +725,12 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
| 725 | } | 725 | } |
| 726 | 726 | ||
| 727 | if (strcmp(sb->s_type->name, "proc") == 0) | 727 | if (strcmp(sb->s_type->name, "proc") == 0) |
| 728 | sbsec->flags |= SE_SBPROC; | 728 | sbsec->flags |= SE_SBPROC | SE_SBGENFS; |
| 729 | |||
| 730 | if (!strcmp(sb->s_type->name, "debugfs") || | ||
| 731 | !strcmp(sb->s_type->name, "sysfs") || | ||
| 732 | !strcmp(sb->s_type->name, "pstore")) | ||
| 733 | sbsec->flags |= SE_SBGENFS; | ||
| 729 | 734 | ||
| 730 | if (!sbsec->behavior) { | 735 | if (!sbsec->behavior) { |
| 731 | /* | 736 | /* |
| @@ -836,8 +841,8 @@ static int selinux_cmp_sb_context(const struct super_block *oldsb, | |||
| 836 | if ((oldflags & DEFCONTEXT_MNT) && old->def_sid != new->def_sid) | 841 | if ((oldflags & DEFCONTEXT_MNT) && old->def_sid != new->def_sid) |
| 837 | goto mismatch; | 842 | goto mismatch; |
| 838 | if (oldflags & ROOTCONTEXT_MNT) { | 843 | if (oldflags & ROOTCONTEXT_MNT) { |
| 839 | struct inode_security_struct *oldroot = oldsb->s_root->d_inode->i_security; | 844 | struct inode_security_struct *oldroot = d_backing_inode(oldsb->s_root)->i_security; |
| 840 | struct inode_security_struct *newroot = newsb->s_root->d_inode->i_security; | 845 | struct inode_security_struct *newroot = d_backing_inode(newsb->s_root)->i_security; |
| 841 | if (oldroot->sid != newroot->sid) | 846 | if (oldroot->sid != newroot->sid) |
| 842 | goto mismatch; | 847 | goto mismatch; |
| 843 | } | 848 | } |
| @@ -887,16 +892,16 @@ static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb, | |||
| 887 | if (!set_fscontext) | 892 | if (!set_fscontext) |
| 888 | newsbsec->sid = sid; | 893 | newsbsec->sid = sid; |
| 889 | if (!set_rootcontext) { | 894 | if (!set_rootcontext) { |
| 890 | struct inode *newinode = newsb->s_root->d_inode; | 895 | struct inode *newinode = d_backing_inode(newsb->s_root); |
| 891 | struct inode_security_struct *newisec = newinode->i_security; | 896 | struct inode_security_struct *newisec = newinode->i_security; |
| 892 | newisec->sid = sid; | 897 | newisec->sid = sid; |
| 893 | } | 898 | } |
| 894 | newsbsec->mntpoint_sid = sid; | 899 | newsbsec->mntpoint_sid = sid; |
| 895 | } | 900 | } |
| 896 | if (set_rootcontext) { | 901 | if (set_rootcontext) { |
| 897 | const struct inode *oldinode = oldsb->s_root->d_inode; | 902 | const struct inode *oldinode = d_backing_inode(oldsb->s_root); |
| 898 | const struct inode_security_struct *oldisec = oldinode->i_security; | 903 | const struct inode_security_struct *oldisec = oldinode->i_security; |
| 899 | struct inode *newinode = newsb->s_root->d_inode; | 904 | struct inode *newinode = d_backing_inode(newsb->s_root); |
| 900 | struct inode_security_struct *newisec = newinode->i_security; | 905 | struct inode_security_struct *newisec = newinode->i_security; |
| 901 | 906 | ||
| 902 | newisec->sid = oldisec->sid; | 907 | newisec->sid = oldisec->sid; |
| @@ -1189,8 +1194,6 @@ static inline u16 socket_type_to_security_class(int family, int type, int protoc | |||
| 1189 | switch (protocol) { | 1194 | switch (protocol) { |
| 1190 | case NETLINK_ROUTE: | 1195 | case NETLINK_ROUTE: |
| 1191 | return SECCLASS_NETLINK_ROUTE_SOCKET; | 1196 | return SECCLASS_NETLINK_ROUTE_SOCKET; |
| 1192 | case NETLINK_FIREWALL: | ||
| 1193 | return SECCLASS_NETLINK_FIREWALL_SOCKET; | ||
| 1194 | case NETLINK_SOCK_DIAG: | 1197 | case NETLINK_SOCK_DIAG: |
| 1195 | return SECCLASS_NETLINK_TCPDIAG_SOCKET; | 1198 | return SECCLASS_NETLINK_TCPDIAG_SOCKET; |
| 1196 | case NETLINK_NFLOG: | 1199 | case NETLINK_NFLOG: |
| @@ -1199,14 +1202,28 @@ static inline u16 socket_type_to_security_class(int family, int type, int protoc | |||
| 1199 | return SECCLASS_NETLINK_XFRM_SOCKET; | 1202 | return SECCLASS_NETLINK_XFRM_SOCKET; |
| 1200 | case NETLINK_SELINUX: | 1203 | case NETLINK_SELINUX: |
| 1201 | return SECCLASS_NETLINK_SELINUX_SOCKET; | 1204 | return SECCLASS_NETLINK_SELINUX_SOCKET; |
| 1205 | case NETLINK_ISCSI: | ||
| 1206 | return SECCLASS_NETLINK_ISCSI_SOCKET; | ||
| 1202 | case NETLINK_AUDIT: | 1207 | case NETLINK_AUDIT: |
| 1203 | return SECCLASS_NETLINK_AUDIT_SOCKET; | 1208 | return SECCLASS_NETLINK_AUDIT_SOCKET; |
| 1204 | case NETLINK_IP6_FW: | 1209 | case NETLINK_FIB_LOOKUP: |
| 1205 | return SECCLASS_NETLINK_IP6FW_SOCKET; | 1210 | return SECCLASS_NETLINK_FIB_LOOKUP_SOCKET; |
| 1211 | case NETLINK_CONNECTOR: | ||
| 1212 | return SECCLASS_NETLINK_CONNECTOR_SOCKET; | ||
| 1213 | case NETLINK_NETFILTER: | ||
| 1214 | return SECCLASS_NETLINK_NETFILTER_SOCKET; | ||
| 1206 | case NETLINK_DNRTMSG: | 1215 | case NETLINK_DNRTMSG: |
| 1207 | return SECCLASS_NETLINK_DNRT_SOCKET; | 1216 | return SECCLASS_NETLINK_DNRT_SOCKET; |
| 1208 | case NETLINK_KOBJECT_UEVENT: | 1217 | case NETLINK_KOBJECT_UEVENT: |
| 1209 | return SECCLASS_NETLINK_KOBJECT_UEVENT_SOCKET; | 1218 | return SECCLASS_NETLINK_KOBJECT_UEVENT_SOCKET; |
| 1219 | case NETLINK_GENERIC: | ||
| 1220 | return SECCLASS_NETLINK_GENERIC_SOCKET; | ||
| 1221 | case NETLINK_SCSITRANSPORT: | ||
| 1222 | return SECCLASS_NETLINK_SCSITRANSPORT_SOCKET; | ||
| 1223 | case NETLINK_RDMA: | ||
| 1224 | return SECCLASS_NETLINK_RDMA_SOCKET; | ||
| 1225 | case NETLINK_CRYPTO: | ||
| 1226 | return SECCLASS_NETLINK_CRYPTO_SOCKET; | ||
| 1210 | default: | 1227 | default: |
| 1211 | return SECCLASS_NETLINK_SOCKET; | 1228 | return SECCLASS_NETLINK_SOCKET; |
| 1212 | } | 1229 | } |
| @@ -1221,12 +1238,13 @@ static inline u16 socket_type_to_security_class(int family, int type, int protoc | |||
| 1221 | return SECCLASS_SOCKET; | 1238 | return SECCLASS_SOCKET; |
| 1222 | } | 1239 | } |
| 1223 | 1240 | ||
| 1224 | #ifdef CONFIG_PROC_FS | 1241 | static int selinux_genfs_get_sid(struct dentry *dentry, |
| 1225 | static int selinux_proc_get_sid(struct dentry *dentry, | 1242 | u16 tclass, |
| 1226 | u16 tclass, | 1243 | u16 flags, |
| 1227 | u32 *sid) | 1244 | u32 *sid) |
| 1228 | { | 1245 | { |
| 1229 | int rc; | 1246 | int rc; |
| 1247 | struct super_block *sb = dentry->d_inode->i_sb; | ||
| 1230 | char *buffer, *path; | 1248 | char *buffer, *path; |
| 1231 | 1249 | ||
| 1232 | buffer = (char *)__get_free_page(GFP_KERNEL); | 1250 | buffer = (char *)__get_free_page(GFP_KERNEL); |
| @@ -1237,26 +1255,20 @@ static int selinux_proc_get_sid(struct dentry *dentry, | |||
| 1237 | if (IS_ERR(path)) | 1255 | if (IS_ERR(path)) |
| 1238 | rc = PTR_ERR(path); | 1256 | rc = PTR_ERR(path); |
| 1239 | else { | 1257 | else { |
| 1240 | /* each process gets a /proc/PID/ entry. Strip off the | 1258 | if (flags & SE_SBPROC) { |
| 1241 | * PID part to get a valid selinux labeling. | 1259 | /* each process gets a /proc/PID/ entry. Strip off the |
| 1242 | * e.g. /proc/1/net/rpc/nfs -> /net/rpc/nfs */ | 1260 | * PID part to get a valid selinux labeling. |
| 1243 | while (path[1] >= '0' && path[1] <= '9') { | 1261 | * e.g. /proc/1/net/rpc/nfs -> /net/rpc/nfs */ |
| 1244 | path[1] = '/'; | 1262 | while (path[1] >= '0' && path[1] <= '9') { |
| 1245 | path++; | 1263 | path[1] = '/'; |
| 1264 | path++; | ||
| 1265 | } | ||
| 1246 | } | 1266 | } |
| 1247 | rc = security_genfs_sid("proc", path, tclass, sid); | 1267 | rc = security_genfs_sid(sb->s_type->name, path, tclass, sid); |
| 1248 | } | 1268 | } |
| 1249 | free_page((unsigned long)buffer); | 1269 | free_page((unsigned long)buffer); |
| 1250 | return rc; | 1270 | return rc; |
| 1251 | } | 1271 | } |
| 1252 | #else | ||
| 1253 | static int selinux_proc_get_sid(struct dentry *dentry, | ||
| 1254 | u16 tclass, | ||
| 1255 | u32 *sid) | ||
| 1256 | { | ||
| 1257 | return -EINVAL; | ||
| 1258 | } | ||
| 1259 | #endif | ||
| 1260 | 1272 | ||
| 1261 | /* The inode's security attributes must be initialized before first use. */ | 1273 | /* The inode's security attributes must be initialized before first use. */ |
| 1262 | static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry) | 1274 | static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry) |
| @@ -1413,7 +1425,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent | |||
| 1413 | /* Default to the fs superblock SID. */ | 1425 | /* Default to the fs superblock SID. */ |
| 1414 | isec->sid = sbsec->sid; | 1426 | isec->sid = sbsec->sid; |
| 1415 | 1427 | ||
| 1416 | if ((sbsec->flags & SE_SBPROC) && !S_ISLNK(inode->i_mode)) { | 1428 | if ((sbsec->flags & SE_SBGENFS) && !S_ISLNK(inode->i_mode)) { |
| 1417 | /* We must have a dentry to determine the label on | 1429 | /* We must have a dentry to determine the label on |
| 1418 | * procfs inodes */ | 1430 | * procfs inodes */ |
| 1419 | if (opt_dentry) | 1431 | if (opt_dentry) |
| @@ -1436,7 +1448,8 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent | |||
| 1436 | if (!dentry) | 1448 | if (!dentry) |
| 1437 | goto out_unlock; | 1449 | goto out_unlock; |
| 1438 | isec->sclass = inode_mode_to_security_class(inode->i_mode); | 1450 | isec->sclass = inode_mode_to_security_class(inode->i_mode); |
| 1439 | rc = selinux_proc_get_sid(dentry, isec->sclass, &sid); | 1451 | rc = selinux_genfs_get_sid(dentry, isec->sclass, |
| 1452 | sbsec->flags, &sid); | ||
| 1440 | dput(dentry); | 1453 | dput(dentry); |
| 1441 | if (rc) | 1454 | if (rc) |
| 1442 | goto out_unlock; | 1455 | goto out_unlock; |
| @@ -1565,7 +1578,7 @@ static int cred_has_capability(const struct cred *cred, | |||
| 1565 | 1578 | ||
| 1566 | rc = avc_has_perm_noaudit(sid, sid, sclass, av, 0, &avd); | 1579 | rc = avc_has_perm_noaudit(sid, sid, sclass, av, 0, &avd); |
| 1567 | if (audit == SECURITY_CAP_AUDIT) { | 1580 | if (audit == SECURITY_CAP_AUDIT) { |
| 1568 | int rc2 = avc_audit(sid, sid, sclass, av, &avd, rc, &ad); | 1581 | int rc2 = avc_audit(sid, sid, sclass, av, &avd, rc, &ad, 0); |
| 1569 | if (rc2) | 1582 | if (rc2) |
| 1570 | return rc2; | 1583 | return rc2; |
| 1571 | } | 1584 | } |
| @@ -1611,7 +1624,7 @@ static inline int dentry_has_perm(const struct cred *cred, | |||
| 1611 | struct dentry *dentry, | 1624 | struct dentry *dentry, |
| 1612 | u32 av) | 1625 | u32 av) |
| 1613 | { | 1626 | { |
| 1614 | struct inode *inode = dentry->d_inode; | 1627 | struct inode *inode = d_backing_inode(dentry); |
| 1615 | struct common_audit_data ad; | 1628 | struct common_audit_data ad; |
| 1616 | 1629 | ||
| 1617 | ad.type = LSM_AUDIT_DATA_DENTRY; | 1630 | ad.type = LSM_AUDIT_DATA_DENTRY; |
| @@ -1623,10 +1636,10 @@ static inline int dentry_has_perm(const struct cred *cred, | |||
| 1623 | the path to help the auditing code to more easily generate the | 1636 | the path to help the auditing code to more easily generate the |
| 1624 | pathname if needed. */ | 1637 | pathname if needed. */ |
| 1625 | static inline int path_has_perm(const struct cred *cred, | 1638 | static inline int path_has_perm(const struct cred *cred, |
| 1626 | struct path *path, | 1639 | const struct path *path, |
| 1627 | u32 av) | 1640 | u32 av) |
| 1628 | { | 1641 | { |
| 1629 | struct inode *inode = path->dentry->d_inode; | 1642 | struct inode *inode = d_backing_inode(path->dentry); |
| 1630 | struct common_audit_data ad; | 1643 | struct common_audit_data ad; |
| 1631 | 1644 | ||
| 1632 | ad.type = LSM_AUDIT_DATA_PATH; | 1645 | ad.type = LSM_AUDIT_DATA_PATH; |
| @@ -1754,7 +1767,7 @@ static int may_link(struct inode *dir, | |||
| 1754 | int rc; | 1767 | int rc; |
| 1755 | 1768 | ||
| 1756 | dsec = dir->i_security; | 1769 | dsec = dir->i_security; |
| 1757 | isec = dentry->d_inode->i_security; | 1770 | isec = d_backing_inode(dentry)->i_security; |
| 1758 | 1771 | ||
| 1759 | ad.type = LSM_AUDIT_DATA_DENTRY; | 1772 | ad.type = LSM_AUDIT_DATA_DENTRY; |
| 1760 | ad.u.dentry = dentry; | 1773 | ad.u.dentry = dentry; |
| @@ -1798,7 +1811,7 @@ static inline int may_rename(struct inode *old_dir, | |||
| 1798 | int rc; | 1811 | int rc; |
| 1799 | 1812 | ||
| 1800 | old_dsec = old_dir->i_security; | 1813 | old_dsec = old_dir->i_security; |
| 1801 | old_isec = old_dentry->d_inode->i_security; | 1814 | old_isec = d_backing_inode(old_dentry)->i_security; |
| 1802 | old_is_dir = d_is_dir(old_dentry); | 1815 | old_is_dir = d_is_dir(old_dentry); |
| 1803 | new_dsec = new_dir->i_security; | 1816 | new_dsec = new_dir->i_security; |
| 1804 | 1817 | ||
| @@ -1828,7 +1841,7 @@ static inline int may_rename(struct inode *old_dir, | |||
| 1828 | if (rc) | 1841 | if (rc) |
| 1829 | return rc; | 1842 | return rc; |
| 1830 | if (d_is_positive(new_dentry)) { | 1843 | if (d_is_positive(new_dentry)) { |
| 1831 | new_isec = new_dentry->d_inode->i_security; | 1844 | new_isec = d_backing_inode(new_dentry)->i_security; |
| 1832 | new_is_dir = d_is_dir(new_dentry); | 1845 | new_is_dir = d_is_dir(new_dentry); |
| 1833 | rc = avc_has_perm(sid, new_isec->sid, | 1846 | rc = avc_has_perm(sid, new_isec->sid, |
| 1834 | new_isec->sclass, | 1847 | new_isec->sclass, |
| @@ -1964,7 +1977,7 @@ static int selinux_binder_transfer_file(struct task_struct *from, | |||
| 1964 | { | 1977 | { |
| 1965 | u32 sid = task_sid(to); | 1978 | u32 sid = task_sid(to); |
| 1966 | struct file_security_struct *fsec = file->f_security; | 1979 | struct file_security_struct *fsec = file->f_security; |
| 1967 | struct inode *inode = file->f_path.dentry->d_inode; | 1980 | struct inode *inode = d_backing_inode(file->f_path.dentry); |
| 1968 | struct inode_security_struct *isec = inode->i_security; | 1981 | struct inode_security_struct *isec = inode->i_security; |
| 1969 | struct common_audit_data ad; | 1982 | struct common_audit_data ad; |
| 1970 | int rc; | 1983 | int rc; |
| @@ -1991,12 +2004,6 @@ static int selinux_binder_transfer_file(struct task_struct *from, | |||
| 1991 | static int selinux_ptrace_access_check(struct task_struct *child, | 2004 | static int selinux_ptrace_access_check(struct task_struct *child, |
| 1992 | unsigned int mode) | 2005 | unsigned int mode) |
| 1993 | { | 2006 | { |
| 1994 | int rc; | ||
| 1995 | |||
| 1996 | rc = cap_ptrace_access_check(child, mode); | ||
| 1997 | if (rc) | ||
| 1998 | return rc; | ||
| 1999 | |||
| 2000 | if (mode & PTRACE_MODE_READ) { | 2007 | if (mode & PTRACE_MODE_READ) { |
| 2001 | u32 sid = current_sid(); | 2008 | u32 sid = current_sid(); |
| 2002 | u32 csid = task_sid(child); | 2009 | u32 csid = task_sid(child); |
| @@ -2008,25 +2015,13 @@ static int selinux_ptrace_access_check(struct task_struct *child, | |||
| 2008 | 2015 | ||
| 2009 | static int selinux_ptrace_traceme(struct task_struct *parent) | 2016 | static int selinux_ptrace_traceme(struct task_struct *parent) |
| 2010 | { | 2017 | { |
| 2011 | int rc; | ||
| 2012 | |||
| 2013 | rc = cap_ptrace_traceme(parent); | ||
| 2014 | if (rc) | ||
| 2015 | return rc; | ||
| 2016 | |||
| 2017 | return task_has_perm(parent, current, PROCESS__PTRACE); | 2018 | return task_has_perm(parent, current, PROCESS__PTRACE); |
| 2018 | } | 2019 | } |
| 2019 | 2020 | ||
| 2020 | static int selinux_capget(struct task_struct *target, kernel_cap_t *effective, | 2021 | static int selinux_capget(struct task_struct *target, kernel_cap_t *effective, |
| 2021 | kernel_cap_t *inheritable, kernel_cap_t *permitted) | 2022 | kernel_cap_t *inheritable, kernel_cap_t *permitted) |
| 2022 | { | 2023 | { |
| 2023 | int error; | 2024 | return current_has_perm(target, PROCESS__GETCAP); |
| 2024 | |||
| 2025 | error = current_has_perm(target, PROCESS__GETCAP); | ||
| 2026 | if (error) | ||
| 2027 | return error; | ||
| 2028 | |||
| 2029 | return cap_capget(target, effective, inheritable, permitted); | ||
| 2030 | } | 2025 | } |
| 2031 | 2026 | ||
| 2032 | static int selinux_capset(struct cred *new, const struct cred *old, | 2027 | static int selinux_capset(struct cred *new, const struct cred *old, |
| @@ -2034,13 +2029,6 @@ static int selinux_capset(struct cred *new, const struct cred *old, | |||
| 2034 | const kernel_cap_t *inheritable, | 2029 | const kernel_cap_t *inheritable, |
| 2035 | const kernel_cap_t *permitted) | 2030 | const kernel_cap_t *permitted) |
| 2036 | { | 2031 | { |
| 2037 | int error; | ||
| 2038 | |||
| 2039 | error = cap_capset(new, old, | ||
| 2040 | effective, inheritable, permitted); | ||
| 2041 | if (error) | ||
| 2042 | return error; | ||
| 2043 | |||
| 2044 | return cred_has_perm(old, new, PROCESS__SETCAP); | 2032 | return cred_has_perm(old, new, PROCESS__SETCAP); |
| 2045 | } | 2033 | } |
| 2046 | 2034 | ||
| @@ -2057,12 +2045,6 @@ static int selinux_capset(struct cred *new, const struct cred *old, | |||
| 2057 | static int selinux_capable(const struct cred *cred, struct user_namespace *ns, | 2045 | static int selinux_capable(const struct cred *cred, struct user_namespace *ns, |
| 2058 | int cap, int audit) | 2046 | int cap, int audit) |
| 2059 | { | 2047 | { |
| 2060 | int rc; | ||
| 2061 | |||
| 2062 | rc = cap_capable(cred, ns, cap, audit); | ||
| 2063 | if (rc) | ||
| 2064 | return rc; | ||
| 2065 | |||
| 2066 | return cred_has_capability(cred, cap, audit); | 2048 | return cred_has_capability(cred, cap, audit); |
| 2067 | } | 2049 | } |
| 2068 | 2050 | ||
| @@ -2140,12 +2122,12 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages) | |||
| 2140 | { | 2122 | { |
| 2141 | int rc, cap_sys_admin = 0; | 2123 | int rc, cap_sys_admin = 0; |
| 2142 | 2124 | ||
| 2143 | rc = selinux_capable(current_cred(), &init_user_ns, CAP_SYS_ADMIN, | 2125 | rc = cred_has_capability(current_cred(), CAP_SYS_ADMIN, |
| 2144 | SECURITY_CAP_NOAUDIT); | 2126 | SECURITY_CAP_NOAUDIT); |
| 2145 | if (rc == 0) | 2127 | if (rc == 0) |
| 2146 | cap_sys_admin = 1; | 2128 | cap_sys_admin = 1; |
| 2147 | 2129 | ||
| 2148 | return __vm_enough_memory(mm, pages, cap_sys_admin); | 2130 | return cap_sys_admin; |
| 2149 | } | 2131 | } |
| 2150 | 2132 | ||
| 2151 | /* binprm security operations */ | 2133 | /* binprm security operations */ |
| @@ -2194,10 +2176,6 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) | |||
| 2194 | struct inode *inode = file_inode(bprm->file); | 2176 | struct inode *inode = file_inode(bprm->file); |
| 2195 | int rc; | 2177 | int rc; |
| 2196 | 2178 | ||
| 2197 | rc = cap_bprm_set_creds(bprm); | ||
| 2198 | if (rc) | ||
| 2199 | return rc; | ||
| 2200 | |||
| 2201 | /* SELinux context only depends on initial program or script and not | 2179 | /* SELinux context only depends on initial program or script and not |
| 2202 | * the script interpreter */ | 2180 | * the script interpreter */ |
| 2203 | if (bprm->cred_prepared) | 2181 | if (bprm->cred_prepared) |
| @@ -2321,7 +2299,7 @@ static int selinux_bprm_secureexec(struct linux_binprm *bprm) | |||
| 2321 | PROCESS__NOATSECURE, NULL); | 2299 | PROCESS__NOATSECURE, NULL); |
| 2322 | } | 2300 | } |
| 2323 | 2301 | ||
| 2324 | return (atsecure || cap_bprm_secureexec(bprm)); | 2302 | return !!atsecure; |
| 2325 | } | 2303 | } |
| 2326 | 2304 | ||
| 2327 | static int match_file(const void *p, struct file *file, unsigned fd) | 2305 | static int match_file(const void *p, struct file *file, unsigned fd) |
| @@ -2452,10 +2430,12 @@ static void selinux_bprm_committed_creds(struct linux_binprm *bprm) | |||
| 2452 | for (i = 0; i < 3; i++) | 2430 | for (i = 0; i < 3; i++) |
| 2453 | do_setitimer(i, &itimer, NULL); | 2431 | do_setitimer(i, &itimer, NULL); |
| 2454 | spin_lock_irq(¤t->sighand->siglock); | 2432 | spin_lock_irq(¤t->sighand->siglock); |
| 2455 | if (!(current->signal->flags & SIGNAL_GROUP_EXIT)) { | 2433 | if (!fatal_signal_pending(current)) { |
| 2456 | __flush_signals(current); | 2434 | flush_sigqueue(¤t->pending); |
| 2435 | flush_sigqueue(¤t->signal->shared_pending); | ||
| 2457 | flush_signal_handlers(current, 1); | 2436 | flush_signal_handlers(current, 1); |
| 2458 | sigemptyset(¤t->blocked); | 2437 | sigemptyset(¤t->blocked); |
| 2438 | recalc_sigpending(); | ||
| 2459 | } | 2439 | } |
| 2460 | spin_unlock_irq(¤t->sighand->siglock); | 2440 | spin_unlock_irq(¤t->sighand->siglock); |
| 2461 | } | 2441 | } |
| @@ -2628,7 +2608,7 @@ static int selinux_sb_remount(struct super_block *sb, void *data) | |||
| 2628 | break; | 2608 | break; |
| 2629 | case ROOTCONTEXT_MNT: { | 2609 | case ROOTCONTEXT_MNT: { |
| 2630 | struct inode_security_struct *root_isec; | 2610 | struct inode_security_struct *root_isec; |
| 2631 | root_isec = sb->s_root->d_inode->i_security; | 2611 | root_isec = d_backing_inode(sb->s_root)->i_security; |
| 2632 | 2612 | ||
| 2633 | if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, sid)) | 2613 | if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, sid)) |
| 2634 | goto out_bad_option; | 2614 | goto out_bad_option; |
| @@ -2728,7 +2708,7 @@ static int selinux_dentry_init_security(struct dentry *dentry, int mode, | |||
| 2728 | struct task_security_struct *tsec; | 2708 | struct task_security_struct *tsec; |
| 2729 | struct inode_security_struct *dsec; | 2709 | struct inode_security_struct *dsec; |
| 2730 | struct superblock_security_struct *sbsec; | 2710 | struct superblock_security_struct *sbsec; |
| 2731 | struct inode *dir = dentry->d_parent->d_inode; | 2711 | struct inode *dir = d_backing_inode(dentry->d_parent); |
| 2732 | u32 newsid; | 2712 | u32 newsid; |
| 2733 | int rc; | 2713 | int rc; |
| 2734 | 2714 | ||
| @@ -2862,11 +2842,23 @@ static int selinux_inode_readlink(struct dentry *dentry) | |||
| 2862 | return dentry_has_perm(cred, dentry, FILE__READ); | 2842 | return dentry_has_perm(cred, dentry, FILE__READ); |
| 2863 | } | 2843 | } |
| 2864 | 2844 | ||
| 2865 | static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *nameidata) | 2845 | static int selinux_inode_follow_link(struct dentry *dentry, struct inode *inode, |
| 2846 | bool rcu) | ||
| 2866 | { | 2847 | { |
| 2867 | const struct cred *cred = current_cred(); | 2848 | const struct cred *cred = current_cred(); |
| 2849 | struct common_audit_data ad; | ||
| 2850 | struct inode_security_struct *isec; | ||
| 2851 | u32 sid; | ||
| 2868 | 2852 | ||
| 2869 | return dentry_has_perm(cred, dentry, FILE__READ); | 2853 | validate_creds(cred); |
| 2854 | |||
| 2855 | ad.type = LSM_AUDIT_DATA_DENTRY; | ||
| 2856 | ad.u.dentry = dentry; | ||
| 2857 | sid = cred_sid(cred); | ||
| 2858 | isec = inode->i_security; | ||
| 2859 | |||
| 2860 | return avc_has_perm_flags(sid, isec->sid, isec->sclass, FILE__READ, &ad, | ||
| 2861 | rcu ? MAY_NOT_BLOCK : 0); | ||
| 2870 | } | 2862 | } |
| 2871 | 2863 | ||
| 2872 | static noinline int audit_inode_permission(struct inode *inode, | 2864 | static noinline int audit_inode_permission(struct inode *inode, |
| @@ -2954,15 +2946,9 @@ static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) | |||
| 2954 | return dentry_has_perm(cred, dentry, av); | 2946 | return dentry_has_perm(cred, dentry, av); |
| 2955 | } | 2947 | } |
| 2956 | 2948 | ||
| 2957 | static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) | 2949 | static int selinux_inode_getattr(const struct path *path) |
| 2958 | { | 2950 | { |
| 2959 | const struct cred *cred = current_cred(); | 2951 | return path_has_perm(current_cred(), path, FILE__GETATTR); |
| 2960 | struct path path; | ||
| 2961 | |||
| 2962 | path.dentry = dentry; | ||
| 2963 | path.mnt = mnt; | ||
| 2964 | |||
| 2965 | return path_has_perm(cred, &path, FILE__GETATTR); | ||
| 2966 | } | 2952 | } |
| 2967 | 2953 | ||
| 2968 | static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name) | 2954 | static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name) |
| @@ -2989,7 +2975,7 @@ static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name) | |||
| 2989 | static int selinux_inode_setxattr(struct dentry *dentry, const char *name, | 2975 | static int selinux_inode_setxattr(struct dentry *dentry, const char *name, |
| 2990 | const void *value, size_t size, int flags) | 2976 | const void *value, size_t size, int flags) |
| 2991 | { | 2977 | { |
| 2992 | struct inode *inode = dentry->d_inode; | 2978 | struct inode *inode = d_backing_inode(dentry); |
| 2993 | struct inode_security_struct *isec = inode->i_security; | 2979 | struct inode_security_struct *isec = inode->i_security; |
| 2994 | struct superblock_security_struct *sbsec; | 2980 | struct superblock_security_struct *sbsec; |
| 2995 | struct common_audit_data ad; | 2981 | struct common_audit_data ad; |
| @@ -3066,7 +3052,7 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name, | |||
| 3066 | const void *value, size_t size, | 3052 | const void *value, size_t size, |
| 3067 | int flags) | 3053 | int flags) |
| 3068 | { | 3054 | { |
| 3069 | struct inode *inode = dentry->d_inode; | 3055 | struct inode *inode = d_backing_inode(dentry); |
| 3070 | struct inode_security_struct *isec = inode->i_security; | 3056 | struct inode_security_struct *isec = inode->i_security; |
| 3071 | u32 newsid; | 3057 | u32 newsid; |
| 3072 | int rc; | 3058 | int rc; |
| @@ -3139,8 +3125,11 @@ static int selinux_inode_getsecurity(const struct inode *inode, const char *name | |||
| 3139 | * and lack of permission just means that we fall back to the | 3125 | * and lack of permission just means that we fall back to the |
| 3140 | * in-core context value, not a denial. | 3126 | * in-core context value, not a denial. |
| 3141 | */ | 3127 | */ |
| 3142 | error = selinux_capable(current_cred(), &init_user_ns, CAP_MAC_ADMIN, | 3128 | error = cap_capable(current_cred(), &init_user_ns, CAP_MAC_ADMIN, |
| 3143 | SECURITY_CAP_NOAUDIT); | 3129 | SECURITY_CAP_NOAUDIT); |
| 3130 | if (!error) | ||
| 3131 | error = cred_has_capability(current_cred(), CAP_MAC_ADMIN, | ||
| 3132 | SECURITY_CAP_NOAUDIT); | ||
| 3144 | if (!error) | 3133 | if (!error) |
| 3145 | error = security_sid_to_context_force(isec->sid, &context, | 3134 | error = security_sid_to_context_force(isec->sid, &context, |
| 3146 | &size); | 3135 | &size); |
| @@ -3294,7 +3283,8 @@ static int file_map_prot_check(struct file *file, unsigned long prot, int shared | |||
| 3294 | int rc = 0; | 3283 | int rc = 0; |
| 3295 | 3284 | ||
| 3296 | if (default_noexec && | 3285 | if (default_noexec && |
| 3297 | (prot & PROT_EXEC) && (!file || (!shared && (prot & PROT_WRITE)))) { | 3286 | (prot & PROT_EXEC) && (!file || IS_PRIVATE(file_inode(file)) || |
| 3287 | (!shared && (prot & PROT_WRITE)))) { | ||
| 3298 | /* | 3288 | /* |
| 3299 | * We are making executable an anonymous mapping or a | 3289 | * We are making executable an anonymous mapping or a |
| 3300 | * private file mapping that will also be writable. | 3290 | * private file mapping that will also be writable. |
| @@ -3325,12 +3315,7 @@ error: | |||
| 3325 | 3315 | ||
| 3326 | static int selinux_mmap_addr(unsigned long addr) | 3316 | static int selinux_mmap_addr(unsigned long addr) |
| 3327 | { | 3317 | { |
| 3328 | int rc; | 3318 | int rc = 0; |
| 3329 | |||
| 3330 | /* do DAC check on address space usage */ | ||
| 3331 | rc = cap_mmap_addr(addr); | ||
| 3332 | if (rc) | ||
| 3333 | return rc; | ||
| 3334 | 3319 | ||
| 3335 | if (addr < CONFIG_LSM_MMAP_MIN_ADDR) { | 3320 | if (addr < CONFIG_LSM_MMAP_MIN_ADDR) { |
| 3336 | u32 sid = current_sid(); | 3321 | u32 sid = current_sid(); |
| @@ -3646,23 +3631,11 @@ static void selinux_task_getsecid(struct task_struct *p, u32 *secid) | |||
| 3646 | 3631 | ||
| 3647 | static int selinux_task_setnice(struct task_struct *p, int nice) | 3632 | static int selinux_task_setnice(struct task_struct *p, int nice) |
| 3648 | { | 3633 | { |
| 3649 | int rc; | ||
| 3650 | |||
| 3651 | rc = cap_task_setnice(p, nice); | ||
| 3652 | if (rc) | ||
| 3653 | return rc; | ||
| 3654 | |||
| 3655 | return current_has_perm(p, PROCESS__SETSCHED); | 3634 | return current_has_perm(p, PROCESS__SETSCHED); |
| 3656 | } | 3635 | } |
| 3657 | 3636 | ||
| 3658 | static int selinux_task_setioprio(struct task_struct *p, int ioprio) | 3637 | static int selinux_task_setioprio(struct task_struct *p, int ioprio) |
| 3659 | { | 3638 | { |
| 3660 | int rc; | ||
| 3661 | |||
| 3662 | rc = cap_task_setioprio(p, ioprio); | ||
| 3663 | if (rc) | ||
| 3664 | return rc; | ||
| 3665 | |||
| 3666 | return current_has_perm(p, PROCESS__SETSCHED); | 3639 | return current_has_perm(p, PROCESS__SETSCHED); |
| 3667 | } | 3640 | } |
| 3668 | 3641 | ||
| @@ -3688,12 +3661,6 @@ static int selinux_task_setrlimit(struct task_struct *p, unsigned int resource, | |||
| 3688 | 3661 | ||
| 3689 | static int selinux_task_setscheduler(struct task_struct *p) | 3662 | static int selinux_task_setscheduler(struct task_struct *p) |
| 3690 | { | 3663 | { |
| 3691 | int rc; | ||
| 3692 | |||
| 3693 | rc = cap_task_setscheduler(p); | ||
| 3694 | if (rc) | ||
| 3695 | return rc; | ||
| 3696 | |||
| 3697 | return current_has_perm(p, PROCESS__SETSCHED); | 3664 | return current_has_perm(p, PROCESS__SETSCHED); |
| 3698 | } | 3665 | } |
| 3699 | 3666 | ||
| @@ -4652,11 +4619,6 @@ static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb) | |||
| 4652 | selinux_skb_peerlbl_sid(skb, family, &sksec->peer_sid); | 4619 | selinux_skb_peerlbl_sid(skb, family, &sksec->peer_sid); |
| 4653 | } | 4620 | } |
| 4654 | 4621 | ||
| 4655 | static void selinux_skb_owned_by(struct sk_buff *skb, struct sock *sk) | ||
| 4656 | { | ||
| 4657 | skb_set_owner_w(skb, sk); | ||
| 4658 | } | ||
| 4659 | |||
| 4660 | static int selinux_secmark_relabel_packet(u32 sid) | 4622 | static int selinux_secmark_relabel_packet(u32 sid) |
| 4661 | { | 4623 | { |
| 4662 | const struct task_security_struct *__tsec; | 4624 | const struct task_security_struct *__tsec; |
| @@ -4780,8 +4742,9 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb) | |||
| 4780 | if (err == -EINVAL) { | 4742 | if (err == -EINVAL) { |
| 4781 | printk(KERN_WARNING | 4743 | printk(KERN_WARNING |
| 4782 | "SELinux: unrecognized netlink message:" | 4744 | "SELinux: unrecognized netlink message:" |
| 4783 | " protocol=%hu nlmsg_type=%hu sclass=%hu\n", | 4745 | " protocol=%hu nlmsg_type=%hu sclass=%s\n", |
| 4784 | sk->sk_protocol, nlh->nlmsg_type, sksec->sclass); | 4746 | sk->sk_protocol, nlh->nlmsg_type, |
| 4747 | secclass_map[sksec->sclass - 1].name); | ||
| 4785 | if (!selinux_enforcing || security_get_allow_unknown()) | 4748 | if (!selinux_enforcing || security_get_allow_unknown()) |
| 4786 | err = 0; | 4749 | err = 0; |
| 4787 | } | 4750 | } |
| @@ -4858,21 +4821,17 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, | |||
| 4858 | 4821 | ||
| 4859 | static unsigned int selinux_ipv4_forward(const struct nf_hook_ops *ops, | 4822 | static unsigned int selinux_ipv4_forward(const struct nf_hook_ops *ops, |
| 4860 | struct sk_buff *skb, | 4823 | struct sk_buff *skb, |
| 4861 | const struct net_device *in, | 4824 | const struct nf_hook_state *state) |
| 4862 | const struct net_device *out, | ||
| 4863 | int (*okfn)(struct sk_buff *)) | ||
| 4864 | { | 4825 | { |
| 4865 | return selinux_ip_forward(skb, in, PF_INET); | 4826 | return selinux_ip_forward(skb, state->in, PF_INET); |
| 4866 | } | 4827 | } |
| 4867 | 4828 | ||
| 4868 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 4829 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
| 4869 | static unsigned int selinux_ipv6_forward(const struct nf_hook_ops *ops, | 4830 | static unsigned int selinux_ipv6_forward(const struct nf_hook_ops *ops, |
| 4870 | struct sk_buff *skb, | 4831 | struct sk_buff *skb, |
| 4871 | const struct net_device *in, | 4832 | const struct nf_hook_state *state) |
| 4872 | const struct net_device *out, | ||
| 4873 | int (*okfn)(struct sk_buff *)) | ||
| 4874 | { | 4833 | { |
| 4875 | return selinux_ip_forward(skb, in, PF_INET6); | 4834 | return selinux_ip_forward(skb, state->in, PF_INET6); |
| 4876 | } | 4835 | } |
| 4877 | #endif /* IPV6 */ | 4836 | #endif /* IPV6 */ |
| 4878 | 4837 | ||
| @@ -4920,9 +4879,7 @@ static unsigned int selinux_ip_output(struct sk_buff *skb, | |||
| 4920 | 4879 | ||
| 4921 | static unsigned int selinux_ipv4_output(const struct nf_hook_ops *ops, | 4880 | static unsigned int selinux_ipv4_output(const struct nf_hook_ops *ops, |
| 4922 | struct sk_buff *skb, | 4881 | struct sk_buff *skb, |
| 4923 | const struct net_device *in, | 4882 | const struct nf_hook_state *state) |
| 4924 | const struct net_device *out, | ||
| 4925 | int (*okfn)(struct sk_buff *)) | ||
| 4926 | { | 4883 | { |
| 4927 | return selinux_ip_output(skb, PF_INET); | 4884 | return selinux_ip_output(skb, PF_INET); |
| 4928 | } | 4885 | } |
| @@ -5097,21 +5054,17 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, | |||
| 5097 | 5054 | ||
| 5098 | static unsigned int selinux_ipv4_postroute(const struct nf_hook_ops *ops, | 5055 | static unsigned int selinux_ipv4_postroute(const struct nf_hook_ops *ops, |
| 5099 | struct sk_buff *skb, | 5056 | struct sk_buff *skb, |
| 5100 | const struct net_device *in, | 5057 | const struct nf_hook_state *state) |
| 5101 | const struct net_device *out, | ||
| 5102 | int (*okfn)(struct sk_buff *)) | ||
| 5103 | { | 5058 | { |
| 5104 | return selinux_ip_postroute(skb, out, PF_INET); | 5059 | return selinux_ip_postroute(skb, state->out, PF_INET); |
| 5105 | } | 5060 | } |
| 5106 | 5061 | ||
| 5107 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 5062 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
| 5108 | static unsigned int selinux_ipv6_postroute(const struct nf_hook_ops *ops, | 5063 | static unsigned int selinux_ipv6_postroute(const struct nf_hook_ops *ops, |
| 5109 | struct sk_buff *skb, | 5064 | struct sk_buff *skb, |
| 5110 | const struct net_device *in, | 5065 | const struct nf_hook_state *state) |
| 5111 | const struct net_device *out, | ||
| 5112 | int (*okfn)(struct sk_buff *)) | ||
| 5113 | { | 5066 | { |
| 5114 | return selinux_ip_postroute(skb, out, PF_INET6); | 5067 | return selinux_ip_postroute(skb, state->out, PF_INET6); |
| 5115 | } | 5068 | } |
| 5116 | #endif /* IPV6 */ | 5069 | #endif /* IPV6 */ |
| 5117 | 5070 | ||
| @@ -5119,12 +5072,6 @@ static unsigned int selinux_ipv6_postroute(const struct nf_hook_ops *ops, | |||
| 5119 | 5072 | ||
| 5120 | static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb) | 5073 | static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb) |
| 5121 | { | 5074 | { |
| 5122 | int err; | ||
| 5123 | |||
| 5124 | err = cap_netlink_send(sk, skb); | ||
| 5125 | if (err) | ||
| 5126 | return err; | ||
| 5127 | |||
| 5128 | return selinux_nlmsg_perm(sk, skb); | 5075 | return selinux_nlmsg_perm(sk, skb); |
| 5129 | } | 5076 | } |
| 5130 | 5077 | ||
| @@ -5862,219 +5809,220 @@ static int selinux_key_getsecurity(struct key *key, char **_buffer) | |||
| 5862 | 5809 | ||
| 5863 | #endif | 5810 | #endif |
| 5864 | 5811 | ||
| 5865 | static struct security_operations selinux_ops = { | 5812 | static struct security_hook_list selinux_hooks[] = { |
| 5866 | .name = "selinux", | 5813 | LSM_HOOK_INIT(binder_set_context_mgr, selinux_binder_set_context_mgr), |
| 5867 | 5814 | LSM_HOOK_INIT(binder_transaction, selinux_binder_transaction), | |
| 5868 | .binder_set_context_mgr = selinux_binder_set_context_mgr, | 5815 | LSM_HOOK_INIT(binder_transfer_binder, selinux_binder_transfer_binder), |
| 5869 | .binder_transaction = selinux_binder_transaction, | 5816 | LSM_HOOK_INIT(binder_transfer_file, selinux_binder_transfer_file), |
| 5870 | .binder_transfer_binder = selinux_binder_transfer_binder, | 5817 | |
| 5871 | .binder_transfer_file = selinux_binder_transfer_file, | 5818 | LSM_HOOK_INIT(ptrace_access_check, selinux_ptrace_access_check), |
| 5872 | 5819 | LSM_HOOK_INIT(ptrace_traceme, selinux_ptrace_traceme), | |
| 5873 | .ptrace_access_check = selinux_ptrace_access_check, | 5820 | LSM_HOOK_INIT(capget, selinux_capget), |
| 5874 | .ptrace_traceme = selinux_ptrace_traceme, | 5821 | LSM_HOOK_INIT(capset, selinux_capset), |
| 5875 | .capget = selinux_capget, | 5822 | LSM_HOOK_INIT(capable, selinux_capable), |
| 5876 | .capset = selinux_capset, | 5823 | LSM_HOOK_INIT(quotactl, selinux_quotactl), |
| 5877 | .capable = selinux_capable, | 5824 | LSM_HOOK_INIT(quota_on, selinux_quota_on), |
| 5878 | .quotactl = selinux_quotactl, | 5825 | LSM_HOOK_INIT(syslog, selinux_syslog), |
| 5879 | .quota_on = selinux_quota_on, | 5826 | LSM_HOOK_INIT(vm_enough_memory, selinux_vm_enough_memory), |
| 5880 | .syslog = selinux_syslog, | 5827 | |
| 5881 | .vm_enough_memory = selinux_vm_enough_memory, | 5828 | LSM_HOOK_INIT(netlink_send, selinux_netlink_send), |
| 5882 | 5829 | ||
| 5883 | .netlink_send = selinux_netlink_send, | 5830 | LSM_HOOK_INIT(bprm_set_creds, selinux_bprm_set_creds), |
| 5884 | 5831 | LSM_HOOK_INIT(bprm_committing_creds, selinux_bprm_committing_creds), | |
| 5885 | .bprm_set_creds = selinux_bprm_set_creds, | 5832 | LSM_HOOK_INIT(bprm_committed_creds, selinux_bprm_committed_creds), |
| 5886 | .bprm_committing_creds = selinux_bprm_committing_creds, | 5833 | LSM_HOOK_INIT(bprm_secureexec, selinux_bprm_secureexec), |
| 5887 | .bprm_committed_creds = selinux_bprm_committed_creds, | 5834 | |
| 5888 | .bprm_secureexec = selinux_bprm_secureexec, | 5835 | LSM_HOOK_INIT(sb_alloc_security, selinux_sb_alloc_security), |
| 5889 | 5836 | LSM_HOOK_INIT(sb_free_security, selinux_sb_free_security), | |
| 5890 | .sb_alloc_security = selinux_sb_alloc_security, | 5837 | LSM_HOOK_INIT(sb_copy_data, selinux_sb_copy_data), |
| 5891 | .sb_free_security = selinux_sb_free_security, | 5838 | LSM_HOOK_INIT(sb_remount, selinux_sb_remount), |
| 5892 | .sb_copy_data = selinux_sb_copy_data, | 5839 | LSM_HOOK_INIT(sb_kern_mount, selinux_sb_kern_mount), |
| 5893 | .sb_remount = selinux_sb_remount, | 5840 | LSM_HOOK_INIT(sb_show_options, selinux_sb_show_options), |
| 5894 | .sb_kern_mount = selinux_sb_kern_mount, | 5841 | LSM_HOOK_INIT(sb_statfs, selinux_sb_statfs), |
| 5895 | .sb_show_options = selinux_sb_show_options, | 5842 | LSM_HOOK_INIT(sb_mount, selinux_mount), |
| 5896 | .sb_statfs = selinux_sb_statfs, | 5843 | LSM_HOOK_INIT(sb_umount, selinux_umount), |
| 5897 | .sb_mount = selinux_mount, | 5844 | LSM_HOOK_INIT(sb_set_mnt_opts, selinux_set_mnt_opts), |
| 5898 | .sb_umount = selinux_umount, | 5845 | LSM_HOOK_INIT(sb_clone_mnt_opts, selinux_sb_clone_mnt_opts), |
| 5899 | .sb_set_mnt_opts = selinux_set_mnt_opts, | 5846 | LSM_HOOK_INIT(sb_parse_opts_str, selinux_parse_opts_str), |
| 5900 | .sb_clone_mnt_opts = selinux_sb_clone_mnt_opts, | 5847 | |
| 5901 | .sb_parse_opts_str = selinux_parse_opts_str, | 5848 | LSM_HOOK_INIT(dentry_init_security, selinux_dentry_init_security), |
| 5902 | 5849 | ||
| 5903 | .dentry_init_security = selinux_dentry_init_security, | 5850 | LSM_HOOK_INIT(inode_alloc_security, selinux_inode_alloc_security), |
| 5904 | 5851 | LSM_HOOK_INIT(inode_free_security, selinux_inode_free_security), | |
| 5905 | .inode_alloc_security = selinux_inode_alloc_security, | 5852 | LSM_HOOK_INIT(inode_init_security, selinux_inode_init_security), |
| 5906 | .inode_free_security = selinux_inode_free_security, | 5853 | LSM_HOOK_INIT(inode_create, selinux_inode_create), |
| 5907 | .inode_init_security = selinux_inode_init_security, | 5854 | LSM_HOOK_INIT(inode_link, selinux_inode_link), |
| 5908 | .inode_create = selinux_inode_create, | 5855 | LSM_HOOK_INIT(inode_unlink, selinux_inode_unlink), |
| 5909 | .inode_link = selinux_inode_link, | 5856 | LSM_HOOK_INIT(inode_symlink, selinux_inode_symlink), |
| 5910 | .inode_unlink = selinux_inode_unlink, | 5857 | LSM_HOOK_INIT(inode_mkdir, selinux_inode_mkdir), |
| 5911 | .inode_symlink = selinux_inode_symlink, | 5858 | LSM_HOOK_INIT(inode_rmdir, selinux_inode_rmdir), |
| 5912 | .inode_mkdir = selinux_inode_mkdir, | 5859 | LSM_HOOK_INIT(inode_mknod, selinux_inode_mknod), |
| 5913 | .inode_rmdir = selinux_inode_rmdir, | 5860 | LSM_HOOK_INIT(inode_rename, selinux_inode_rename), |
| 5914 | .inode_mknod = selinux_inode_mknod, | 5861 | LSM_HOOK_INIT(inode_readlink, selinux_inode_readlink), |
| 5915 | .inode_rename = selinux_inode_rename, | 5862 | LSM_HOOK_INIT(inode_follow_link, selinux_inode_follow_link), |
| 5916 | .inode_readlink = selinux_inode_readlink, | 5863 | LSM_HOOK_INIT(inode_permission, selinux_inode_permission), |
| 5917 | .inode_follow_link = selinux_inode_follow_link, | 5864 | LSM_HOOK_INIT(inode_setattr, selinux_inode_setattr), |
| 5918 | .inode_permission = selinux_inode_permission, | 5865 | LSM_HOOK_INIT(inode_getattr, selinux_inode_getattr), |
| 5919 | .inode_setattr = selinux_inode_setattr, | 5866 | LSM_HOOK_INIT(inode_setxattr, selinux_inode_setxattr), |
| 5920 | .inode_getattr = selinux_inode_getattr, | 5867 | LSM_HOOK_INIT(inode_post_setxattr, selinux_inode_post_setxattr), |
| 5921 | .inode_setxattr = selinux_inode_setxattr, | 5868 | LSM_HOOK_INIT(inode_getxattr, selinux_inode_getxattr), |
| 5922 | .inode_post_setxattr = selinux_inode_post_setxattr, | 5869 | LSM_HOOK_INIT(inode_listxattr, selinux_inode_listxattr), |
| 5923 | .inode_getxattr = selinux_inode_getxattr, | 5870 | LSM_HOOK_INIT(inode_removexattr, selinux_inode_removexattr), |
| 5924 | .inode_listxattr = selinux_inode_listxattr, | 5871 | LSM_HOOK_INIT(inode_getsecurity, selinux_inode_getsecurity), |
| 5925 | .inode_removexattr = selinux_inode_removexattr, | 5872 | LSM_HOOK_INIT(inode_setsecurity, selinux_inode_setsecurity), |
| 5926 | .inode_getsecurity = selinux_inode_getsecurity, | 5873 | LSM_HOOK_INIT(inode_listsecurity, selinux_inode_listsecurity), |
| 5927 | .inode_setsecurity = selinux_inode_setsecurity, | 5874 | LSM_HOOK_INIT(inode_getsecid, selinux_inode_getsecid), |
| 5928 | .inode_listsecurity = selinux_inode_listsecurity, | 5875 | |
| 5929 | .inode_getsecid = selinux_inode_getsecid, | 5876 | LSM_HOOK_INIT(file_permission, selinux_file_permission), |
| 5930 | 5877 | LSM_HOOK_INIT(file_alloc_security, selinux_file_alloc_security), | |
| 5931 | .file_permission = selinux_file_permission, | 5878 | LSM_HOOK_INIT(file_free_security, selinux_file_free_security), |
| 5932 | .file_alloc_security = selinux_file_alloc_security, | 5879 | LSM_HOOK_INIT(file_ioctl, selinux_file_ioctl), |
| 5933 | .file_free_security = selinux_file_free_security, | 5880 | LSM_HOOK_INIT(mmap_file, selinux_mmap_file), |
| 5934 | .file_ioctl = selinux_file_ioctl, | 5881 | LSM_HOOK_INIT(mmap_addr, selinux_mmap_addr), |
| 5935 | .mmap_file = selinux_mmap_file, | 5882 | LSM_HOOK_INIT(file_mprotect, selinux_file_mprotect), |
| 5936 | .mmap_addr = selinux_mmap_addr, | 5883 | LSM_HOOK_INIT(file_lock, selinux_file_lock), |
| 5937 | .file_mprotect = selinux_file_mprotect, | 5884 | LSM_HOOK_INIT(file_fcntl, selinux_file_fcntl), |
| 5938 | .file_lock = selinux_file_lock, | 5885 | LSM_HOOK_INIT(file_set_fowner, selinux_file_set_fowner), |
| 5939 | .file_fcntl = selinux_file_fcntl, | 5886 | LSM_HOOK_INIT(file_send_sigiotask, selinux_file_send_sigiotask), |
| 5940 | .file_set_fowner = selinux_file_set_fowner, | 5887 | LSM_HOOK_INIT(file_receive, selinux_file_receive), |
| 5941 | .file_send_sigiotask = selinux_file_send_sigiotask, | 5888 | |
| 5942 | .file_receive = selinux_file_receive, | 5889 | LSM_HOOK_INIT(file_open, selinux_file_open), |
| 5943 | 5890 | ||
| 5944 | .file_open = selinux_file_open, | 5891 | LSM_HOOK_INIT(task_create, selinux_task_create), |
| 5945 | 5892 | LSM_HOOK_INIT(cred_alloc_blank, selinux_cred_alloc_blank), | |
| 5946 | .task_create = selinux_task_create, | 5893 | LSM_HOOK_INIT(cred_free, selinux_cred_free), |
| 5947 | .cred_alloc_blank = selinux_cred_alloc_blank, | 5894 | LSM_HOOK_INIT(cred_prepare, selinux_cred_prepare), |
| 5948 | .cred_free = selinux_cred_free, | 5895 | LSM_HOOK_INIT(cred_transfer, selinux_cred_transfer), |
| 5949 | .cred_prepare = selinux_cred_prepare, | 5896 | LSM_HOOK_INIT(kernel_act_as, selinux_kernel_act_as), |
| 5950 | .cred_transfer = selinux_cred_transfer, | 5897 | LSM_HOOK_INIT(kernel_create_files_as, selinux_kernel_create_files_as), |
| 5951 | .kernel_act_as = selinux_kernel_act_as, | 5898 | LSM_HOOK_INIT(kernel_module_request, selinux_kernel_module_request), |
| 5952 | .kernel_create_files_as = selinux_kernel_create_files_as, | 5899 | LSM_HOOK_INIT(task_setpgid, selinux_task_setpgid), |
| 5953 | .kernel_module_request = selinux_kernel_module_request, | 5900 | LSM_HOOK_INIT(task_getpgid, selinux_task_getpgid), |
| 5954 | .task_setpgid = selinux_task_setpgid, | 5901 | LSM_HOOK_INIT(task_getsid, selinux_task_getsid), |
| 5955 | .task_getpgid = selinux_task_getpgid, | 5902 | LSM_HOOK_INIT(task_getsecid, selinux_task_getsecid), |
| 5956 | .task_getsid = selinux_task_getsid, | 5903 | LSM_HOOK_INIT(task_setnice, selinux_task_setnice), |
| 5957 | .task_getsecid = selinux_task_getsecid, | 5904 | LSM_HOOK_INIT(task_setioprio, selinux_task_setioprio), |
| 5958 | .task_setnice = selinux_task_setnice, | 5905 | LSM_HOOK_INIT(task_getioprio, selinux_task_getioprio), |
| 5959 | .task_setioprio = selinux_task_setioprio, | 5906 | LSM_HOOK_INIT(task_setrlimit, selinux_task_setrlimit), |
| 5960 | .task_getioprio = selinux_task_getioprio, | 5907 | LSM_HOOK_INIT(task_setscheduler, selinux_task_setscheduler), |
| 5961 | .task_setrlimit = selinux_task_setrlimit, | 5908 | LSM_HOOK_INIT(task_getscheduler, selinux_task_getscheduler), |
| 5962 | .task_setscheduler = selinux_task_setscheduler, | 5909 | LSM_HOOK_INIT(task_movememory, selinux_task_movememory), |
| 5963 | .task_getscheduler = selinux_task_getscheduler, | 5910 | LSM_HOOK_INIT(task_kill, selinux_task_kill), |
| 5964 | .task_movememory = selinux_task_movememory, | 5911 | LSM_HOOK_INIT(task_wait, selinux_task_wait), |
| 5965 | .task_kill = selinux_task_kill, | 5912 | LSM_HOOK_INIT(task_to_inode, selinux_task_to_inode), |
| 5966 | .task_wait = selinux_task_wait, | 5913 | |
| 5967 | .task_to_inode = selinux_task_to_inode, | 5914 | LSM_HOOK_INIT(ipc_permission, selinux_ipc_permission), |
| 5968 | 5915 | LSM_HOOK_INIT(ipc_getsecid, selinux_ipc_getsecid), | |
| 5969 | .ipc_permission = selinux_ipc_permission, | 5916 | |
| 5970 | .ipc_getsecid = selinux_ipc_getsecid, | 5917 | LSM_HOOK_INIT(msg_msg_alloc_security, selinux_msg_msg_alloc_security), |
| 5971 | 5918 | LSM_HOOK_INIT(msg_msg_free_security, selinux_msg_msg_free_security), | |
| 5972 | .msg_msg_alloc_security = selinux_msg_msg_alloc_security, | 5919 | |
| 5973 | .msg_msg_free_security = selinux_msg_msg_free_security, | 5920 | LSM_HOOK_INIT(msg_queue_alloc_security, |
| 5974 | 5921 | selinux_msg_queue_alloc_security), | |
| 5975 | .msg_queue_alloc_security = selinux_msg_queue_alloc_security, | 5922 | LSM_HOOK_INIT(msg_queue_free_security, selinux_msg_queue_free_security), |
| 5976 | .msg_queue_free_security = selinux_msg_queue_free_security, | 5923 | LSM_HOOK_INIT(msg_queue_associate, selinux_msg_queue_associate), |
| 5977 | .msg_queue_associate = selinux_msg_queue_associate, | 5924 | LSM_HOOK_INIT(msg_queue_msgctl, selinux_msg_queue_msgctl), |
| 5978 | .msg_queue_msgctl = selinux_msg_queue_msgctl, | 5925 | LSM_HOOK_INIT(msg_queue_msgsnd, selinux_msg_queue_msgsnd), |
| 5979 | .msg_queue_msgsnd = selinux_msg_queue_msgsnd, | 5926 | LSM_HOOK_INIT(msg_queue_msgrcv, selinux_msg_queue_msgrcv), |
| 5980 | .msg_queue_msgrcv = selinux_msg_queue_msgrcv, | 5927 | |
| 5981 | 5928 | LSM_HOOK_INIT(shm_alloc_security, selinux_shm_alloc_security), | |
| 5982 | .shm_alloc_security = selinux_shm_alloc_security, | 5929 | LSM_HOOK_INIT(shm_free_security, selinux_shm_free_security), |
| 5983 | .shm_free_security = selinux_shm_free_security, | 5930 | LSM_HOOK_INIT(shm_associate, selinux_shm_associate), |
| 5984 | .shm_associate = selinux_shm_associate, | 5931 | LSM_HOOK_INIT(shm_shmctl, selinux_shm_shmctl), |
| 5985 | .shm_shmctl = selinux_shm_shmctl, | 5932 | LSM_HOOK_INIT(shm_shmat, selinux_shm_shmat), |
| 5986 | .shm_shmat = selinux_shm_shmat, | 5933 | |
| 5987 | 5934 | LSM_HOOK_INIT(sem_alloc_security, selinux_sem_alloc_security), | |
| 5988 | .sem_alloc_security = selinux_sem_alloc_security, | 5935 | LSM_HOOK_INIT(sem_free_security, selinux_sem_free_security), |
| 5989 | .sem_free_security = selinux_sem_free_security, | 5936 | LSM_HOOK_INIT(sem_associate, selinux_sem_associate), |
| 5990 | .sem_associate = selinux_sem_associate, | 5937 | LSM_HOOK_INIT(sem_semctl, selinux_sem_semctl), |
| 5991 | .sem_semctl = selinux_sem_semctl, | 5938 | LSM_HOOK_INIT(sem_semop, selinux_sem_semop), |
| 5992 | .sem_semop = selinux_sem_semop, | 5939 | |
| 5993 | 5940 | LSM_HOOK_INIT(d_instantiate, selinux_d_instantiate), | |
| 5994 | .d_instantiate = selinux_d_instantiate, | 5941 | |
| 5995 | 5942 | LSM_HOOK_INIT(getprocattr, selinux_getprocattr), | |
| 5996 | .getprocattr = selinux_getprocattr, | 5943 | LSM_HOOK_INIT(setprocattr, selinux_setprocattr), |
| 5997 | .setprocattr = selinux_setprocattr, | 5944 | |
| 5998 | 5945 | LSM_HOOK_INIT(ismaclabel, selinux_ismaclabel), | |
| 5999 | .ismaclabel = selinux_ismaclabel, | 5946 | LSM_HOOK_INIT(secid_to_secctx, selinux_secid_to_secctx), |
| 6000 | .secid_to_secctx = selinux_secid_to_secctx, | 5947 | LSM_HOOK_INIT(secctx_to_secid, selinux_secctx_to_secid), |
| 6001 | .secctx_to_secid = selinux_secctx_to_secid, | 5948 | LSM_HOOK_INIT(release_secctx, selinux_release_secctx), |
| 6002 | .release_secctx = selinux_release_secctx, | 5949 | LSM_HOOK_INIT(inode_notifysecctx, selinux_inode_notifysecctx), |
| 6003 | .inode_notifysecctx = selinux_inode_notifysecctx, | 5950 | LSM_HOOK_INIT(inode_setsecctx, selinux_inode_setsecctx), |
| 6004 | .inode_setsecctx = selinux_inode_setsecctx, | 5951 | LSM_HOOK_INIT(inode_getsecctx, selinux_inode_getsecctx), |
| 6005 | .inode_getsecctx = selinux_inode_getsecctx, | 5952 | |
| 6006 | 5953 | LSM_HOOK_INIT(unix_stream_connect, selinux_socket_unix_stream_connect), | |
| 6007 | .unix_stream_connect = selinux_socket_unix_stream_connect, | 5954 | LSM_HOOK_INIT(unix_may_send, selinux_socket_unix_may_send), |
| 6008 | .unix_may_send = selinux_socket_unix_may_send, | 5955 | |
| 6009 | 5956 | LSM_HOOK_INIT(socket_create, selinux_socket_create), | |
| 6010 | .socket_create = selinux_socket_create, | 5957 | LSM_HOOK_INIT(socket_post_create, selinux_socket_post_create), |
| 6011 | .socket_post_create = selinux_socket_post_create, | 5958 | LSM_HOOK_INIT(socket_bind, selinux_socket_bind), |
| 6012 | .socket_bind = selinux_socket_bind, | 5959 | LSM_HOOK_INIT(socket_connect, selinux_socket_connect), |
| 6013 | .socket_connect = selinux_socket_connect, | 5960 | LSM_HOOK_INIT(socket_listen, selinux_socket_listen), |
| 6014 | .socket_listen = selinux_socket_listen, | 5961 | LSM_HOOK_INIT(socket_accept, selinux_socket_accept), |
| 6015 | .socket_accept = selinux_socket_accept, | 5962 | LSM_HOOK_INIT(socket_sendmsg, selinux_socket_sendmsg), |
| 6016 | .socket_sendmsg = selinux_socket_sendmsg, | 5963 | LSM_HOOK_INIT(socket_recvmsg, selinux_socket_recvmsg), |
| 6017 | .socket_recvmsg = selinux_socket_recvmsg, | 5964 | LSM_HOOK_INIT(socket_getsockname, selinux_socket_getsockname), |
| 6018 | .socket_getsockname = selinux_socket_getsockname, | 5965 | LSM_HOOK_INIT(socket_getpeername, selinux_socket_getpeername), |
| 6019 | .socket_getpeername = selinux_socket_getpeername, | 5966 | LSM_HOOK_INIT(socket_getsockopt, selinux_socket_getsockopt), |
| 6020 | .socket_getsockopt = selinux_socket_getsockopt, | 5967 | LSM_HOOK_INIT(socket_setsockopt, selinux_socket_setsockopt), |
| 6021 | .socket_setsockopt = selinux_socket_setsockopt, | 5968 | LSM_HOOK_INIT(socket_shutdown, selinux_socket_shutdown), |
| 6022 | .socket_shutdown = selinux_socket_shutdown, | 5969 | LSM_HOOK_INIT(socket_sock_rcv_skb, selinux_socket_sock_rcv_skb), |
| 6023 | .socket_sock_rcv_skb = selinux_socket_sock_rcv_skb, | 5970 | LSM_HOOK_INIT(socket_getpeersec_stream, |
| 6024 | .socket_getpeersec_stream = selinux_socket_getpeersec_stream, | 5971 | selinux_socket_getpeersec_stream), |
| 6025 | .socket_getpeersec_dgram = selinux_socket_getpeersec_dgram, | 5972 | LSM_HOOK_INIT(socket_getpeersec_dgram, selinux_socket_getpeersec_dgram), |
| 6026 | .sk_alloc_security = selinux_sk_alloc_security, | 5973 | LSM_HOOK_INIT(sk_alloc_security, selinux_sk_alloc_security), |
| 6027 | .sk_free_security = selinux_sk_free_security, | 5974 | LSM_HOOK_INIT(sk_free_security, selinux_sk_free_security), |
| 6028 | .sk_clone_security = selinux_sk_clone_security, | 5975 | LSM_HOOK_INIT(sk_clone_security, selinux_sk_clone_security), |
| 6029 | .sk_getsecid = selinux_sk_getsecid, | 5976 | LSM_HOOK_INIT(sk_getsecid, selinux_sk_getsecid), |
| 6030 | .sock_graft = selinux_sock_graft, | 5977 | LSM_HOOK_INIT(sock_graft, selinux_sock_graft), |
| 6031 | .inet_conn_request = selinux_inet_conn_request, | 5978 | LSM_HOOK_INIT(inet_conn_request, selinux_inet_conn_request), |
| 6032 | .inet_csk_clone = selinux_inet_csk_clone, | 5979 | LSM_HOOK_INIT(inet_csk_clone, selinux_inet_csk_clone), |
| 6033 | .inet_conn_established = selinux_inet_conn_established, | 5980 | LSM_HOOK_INIT(inet_conn_established, selinux_inet_conn_established), |
| 6034 | .secmark_relabel_packet = selinux_secmark_relabel_packet, | 5981 | LSM_HOOK_INIT(secmark_relabel_packet, selinux_secmark_relabel_packet), |
| 6035 | .secmark_refcount_inc = selinux_secmark_refcount_inc, | 5982 | LSM_HOOK_INIT(secmark_refcount_inc, selinux_secmark_refcount_inc), |
| 6036 | .secmark_refcount_dec = selinux_secmark_refcount_dec, | 5983 | LSM_HOOK_INIT(secmark_refcount_dec, selinux_secmark_refcount_dec), |
| 6037 | .req_classify_flow = selinux_req_classify_flow, | 5984 | LSM_HOOK_INIT(req_classify_flow, selinux_req_classify_flow), |
| 6038 | .tun_dev_alloc_security = selinux_tun_dev_alloc_security, | 5985 | LSM_HOOK_INIT(tun_dev_alloc_security, selinux_tun_dev_alloc_security), |
| 6039 | .tun_dev_free_security = selinux_tun_dev_free_security, | 5986 | LSM_HOOK_INIT(tun_dev_free_security, selinux_tun_dev_free_security), |
| 6040 | .tun_dev_create = selinux_tun_dev_create, | 5987 | LSM_HOOK_INIT(tun_dev_create, selinux_tun_dev_create), |
| 6041 | .tun_dev_attach_queue = selinux_tun_dev_attach_queue, | 5988 | LSM_HOOK_INIT(tun_dev_attach_queue, selinux_tun_dev_attach_queue), |
| 6042 | .tun_dev_attach = selinux_tun_dev_attach, | 5989 | LSM_HOOK_INIT(tun_dev_attach, selinux_tun_dev_attach), |
| 6043 | .tun_dev_open = selinux_tun_dev_open, | 5990 | LSM_HOOK_INIT(tun_dev_open, selinux_tun_dev_open), |
| 6044 | .skb_owned_by = selinux_skb_owned_by, | ||
| 6045 | 5991 | ||
| 6046 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | 5992 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
| 6047 | .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc, | 5993 | LSM_HOOK_INIT(xfrm_policy_alloc_security, selinux_xfrm_policy_alloc), |
| 6048 | .xfrm_policy_clone_security = selinux_xfrm_policy_clone, | 5994 | LSM_HOOK_INIT(xfrm_policy_clone_security, selinux_xfrm_policy_clone), |
| 6049 | .xfrm_policy_free_security = selinux_xfrm_policy_free, | 5995 | LSM_HOOK_INIT(xfrm_policy_free_security, selinux_xfrm_policy_free), |
| 6050 | .xfrm_policy_delete_security = selinux_xfrm_policy_delete, | 5996 | LSM_HOOK_INIT(xfrm_policy_delete_security, selinux_xfrm_policy_delete), |
| 6051 | .xfrm_state_alloc = selinux_xfrm_state_alloc, | 5997 | LSM_HOOK_INIT(xfrm_state_alloc, selinux_xfrm_state_alloc), |
| 6052 | .xfrm_state_alloc_acquire = selinux_xfrm_state_alloc_acquire, | 5998 | LSM_HOOK_INIT(xfrm_state_alloc_acquire, |
| 6053 | .xfrm_state_free_security = selinux_xfrm_state_free, | 5999 | selinux_xfrm_state_alloc_acquire), |
| 6054 | .xfrm_state_delete_security = selinux_xfrm_state_delete, | 6000 | LSM_HOOK_INIT(xfrm_state_free_security, selinux_xfrm_state_free), |
| 6055 | .xfrm_policy_lookup = selinux_xfrm_policy_lookup, | 6001 | LSM_HOOK_INIT(xfrm_state_delete_security, selinux_xfrm_state_delete), |
| 6056 | .xfrm_state_pol_flow_match = selinux_xfrm_state_pol_flow_match, | 6002 | LSM_HOOK_INIT(xfrm_policy_lookup, selinux_xfrm_policy_lookup), |
| 6057 | .xfrm_decode_session = selinux_xfrm_decode_session, | 6003 | LSM_HOOK_INIT(xfrm_state_pol_flow_match, |
| 6004 | selinux_xfrm_state_pol_flow_match), | ||
| 6005 | LSM_HOOK_INIT(xfrm_decode_session, selinux_xfrm_decode_session), | ||
| 6058 | #endif | 6006 | #endif |
| 6059 | 6007 | ||
| 6060 | #ifdef CONFIG_KEYS | 6008 | #ifdef CONFIG_KEYS |
| 6061 | .key_alloc = selinux_key_alloc, | 6009 | LSM_HOOK_INIT(key_alloc, selinux_key_alloc), |
| 6062 | .key_free = selinux_key_free, | 6010 | LSM_HOOK_INIT(key_free, selinux_key_free), |
| 6063 | .key_permission = selinux_key_permission, | 6011 | LSM_HOOK_INIT(key_permission, selinux_key_permission), |
| 6064 | .key_getsecurity = selinux_key_getsecurity, | 6012 | LSM_HOOK_INIT(key_getsecurity, selinux_key_getsecurity), |
| 6065 | #endif | 6013 | #endif |
| 6066 | 6014 | ||
| 6067 | #ifdef CONFIG_AUDIT | 6015 | #ifdef CONFIG_AUDIT |
| 6068 | .audit_rule_init = selinux_audit_rule_init, | 6016 | LSM_HOOK_INIT(audit_rule_init, selinux_audit_rule_init), |
| 6069 | .audit_rule_known = selinux_audit_rule_known, | 6017 | LSM_HOOK_INIT(audit_rule_known, selinux_audit_rule_known), |
| 6070 | .audit_rule_match = selinux_audit_rule_match, | 6018 | LSM_HOOK_INIT(audit_rule_match, selinux_audit_rule_match), |
| 6071 | .audit_rule_free = selinux_audit_rule_free, | 6019 | LSM_HOOK_INIT(audit_rule_free, selinux_audit_rule_free), |
| 6072 | #endif | 6020 | #endif |
| 6073 | }; | 6021 | }; |
| 6074 | 6022 | ||
| 6075 | static __init int selinux_init(void) | 6023 | static __init int selinux_init(void) |
| 6076 | { | 6024 | { |
| 6077 | if (!security_module_enable(&selinux_ops)) { | 6025 | if (!security_module_enable("selinux")) { |
| 6078 | selinux_enabled = 0; | 6026 | selinux_enabled = 0; |
| 6079 | return 0; | 6027 | return 0; |
| 6080 | } | 6028 | } |
| @@ -6096,8 +6044,7 @@ static __init int selinux_init(void) | |||
| 6096 | 0, SLAB_PANIC, NULL); | 6044 | 0, SLAB_PANIC, NULL); |
| 6097 | avc_init(); | 6045 | avc_init(); |
| 6098 | 6046 | ||
| 6099 | if (register_security(&selinux_ops)) | 6047 | security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks)); |
| 6100 | panic("SELinux: Unable to register with kernel.\n"); | ||
| 6101 | 6048 | ||
| 6102 | if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET)) | 6049 | if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET)) |
| 6103 | panic("SELinux: Unable to register AVC netcache callback\n"); | 6050 | panic("SELinux: Unable to register AVC netcache callback\n"); |
| @@ -6225,7 +6172,7 @@ int selinux_disable(void) | |||
| 6225 | selinux_disabled = 1; | 6172 | selinux_disabled = 1; |
| 6226 | selinux_enabled = 0; | 6173 | selinux_enabled = 0; |
| 6227 | 6174 | ||
| 6228 | reset_security_ops(); | 6175 | security_delete_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks)); |
| 6229 | 6176 | ||
| 6230 | /* Try to destroy the avc node cache */ | 6177 | /* Try to destroy the avc node cache */ |
| 6231 | avc_disable(); | 6178 | avc_disable(); |
diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h index ddf8eec03f21..5973c327c54e 100644 --- a/security/selinux/include/avc.h +++ b/security/selinux/include/avc.h | |||
| @@ -130,7 +130,8 @@ static inline int avc_audit(u32 ssid, u32 tsid, | |||
| 130 | u16 tclass, u32 requested, | 130 | u16 tclass, u32 requested, |
| 131 | struct av_decision *avd, | 131 | struct av_decision *avd, |
| 132 | int result, | 132 | int result, |
| 133 | struct common_audit_data *a) | 133 | struct common_audit_data *a, |
| 134 | int flags) | ||
| 134 | { | 135 | { |
| 135 | u32 audited, denied; | 136 | u32 audited, denied; |
| 136 | audited = avc_audit_required(requested, avd, result, 0, &denied); | 137 | audited = avc_audit_required(requested, avd, result, 0, &denied); |
| @@ -138,7 +139,7 @@ static inline int avc_audit(u32 ssid, u32 tsid, | |||
| 138 | return 0; | 139 | return 0; |
| 139 | return slow_avc_audit(ssid, tsid, tclass, | 140 | return slow_avc_audit(ssid, tsid, tclass, |
| 140 | requested, audited, denied, result, | 141 | requested, audited, denied, result, |
| 141 | a, 0); | 142 | a, flags); |
| 142 | } | 143 | } |
| 143 | 144 | ||
| 144 | #define AVC_STRICT 1 /* Ignore permissive mode. */ | 145 | #define AVC_STRICT 1 /* Ignore permissive mode. */ |
| @@ -150,6 +151,10 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid, | |||
| 150 | int avc_has_perm(u32 ssid, u32 tsid, | 151 | int avc_has_perm(u32 ssid, u32 tsid, |
| 151 | u16 tclass, u32 requested, | 152 | u16 tclass, u32 requested, |
| 152 | struct common_audit_data *auditdata); | 153 | struct common_audit_data *auditdata); |
| 154 | int avc_has_perm_flags(u32 ssid, u32 tsid, | ||
| 155 | u16 tclass, u32 requested, | ||
| 156 | struct common_audit_data *auditdata, | ||
| 157 | int flags); | ||
| 153 | 158 | ||
| 154 | u32 avc_policy_seqno(void); | 159 | u32 avc_policy_seqno(void); |
| 155 | 160 | ||
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h index eccd61b3de8a..5a4eef59aeff 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h | |||
| @@ -2,12 +2,12 @@ | |||
| 2 | "getattr", "setattr", "lock", "relabelfrom", "relabelto", "append" | 2 | "getattr", "setattr", "lock", "relabelfrom", "relabelto", "append" |
| 3 | 3 | ||
| 4 | #define COMMON_FILE_PERMS COMMON_FILE_SOCK_PERMS, "unlink", "link", \ | 4 | #define COMMON_FILE_PERMS COMMON_FILE_SOCK_PERMS, "unlink", "link", \ |
| 5 | "rename", "execute", "swapon", "quotaon", "mounton", "audit_access", \ | 5 | "rename", "execute", "quotaon", "mounton", "audit_access", \ |
| 6 | "open", "execmod" | 6 | "open", "execmod" |
| 7 | 7 | ||
| 8 | #define COMMON_SOCK_PERMS COMMON_FILE_SOCK_PERMS, "bind", "connect", \ | 8 | #define COMMON_SOCK_PERMS COMMON_FILE_SOCK_PERMS, "bind", "connect", \ |
| 9 | "listen", "accept", "getopt", "setopt", "shutdown", "recvfrom", \ | 9 | "listen", "accept", "getopt", "setopt", "shutdown", "recvfrom", \ |
| 10 | "sendto", "recv_msg", "send_msg", "name_bind" | 10 | "sendto", "name_bind" |
| 11 | 11 | ||
| 12 | #define COMMON_IPC_PERMS "create", "destroy", "getattr", "setattr", "read", \ | 12 | #define COMMON_IPC_PERMS "create", "destroy", "getattr", "setattr", "read", \ |
| 13 | "write", "associate", "unix_read", "unix_write" | 13 | "write", "associate", "unix_read", "unix_write" |
| @@ -44,7 +44,7 @@ struct security_class_mapping secclass_map[] = { | |||
| 44 | "audit_control", "setfcap", NULL } }, | 44 | "audit_control", "setfcap", NULL } }, |
| 45 | { "filesystem", | 45 | { "filesystem", |
| 46 | { "mount", "remount", "unmount", "getattr", | 46 | { "mount", "remount", "unmount", "getattr", |
| 47 | "relabelfrom", "relabelto", "transition", "associate", "quotamod", | 47 | "relabelfrom", "relabelto", "associate", "quotamod", |
| 48 | "quotaget", NULL } }, | 48 | "quotaget", NULL } }, |
| 49 | { "file", | 49 | { "file", |
| 50 | { COMMON_FILE_PERMS, | 50 | { COMMON_FILE_PERMS, |
| @@ -67,7 +67,7 @@ struct security_class_mapping secclass_map[] = { | |||
| 67 | { COMMON_SOCK_PERMS, NULL } }, | 67 | { COMMON_SOCK_PERMS, NULL } }, |
| 68 | { "tcp_socket", | 68 | { "tcp_socket", |
| 69 | { COMMON_SOCK_PERMS, | 69 | { COMMON_SOCK_PERMS, |
| 70 | "connectto", "newconn", "acceptfrom", "node_bind", "name_connect", | 70 | "node_bind", "name_connect", |
| 71 | NULL } }, | 71 | NULL } }, |
| 72 | { "udp_socket", | 72 | { "udp_socket", |
| 73 | { COMMON_SOCK_PERMS, | 73 | { COMMON_SOCK_PERMS, |
| @@ -76,13 +76,9 @@ struct security_class_mapping secclass_map[] = { | |||
| 76 | { COMMON_SOCK_PERMS, | 76 | { COMMON_SOCK_PERMS, |
| 77 | "node_bind", NULL } }, | 77 | "node_bind", NULL } }, |
| 78 | { "node", | 78 | { "node", |
| 79 | { "tcp_recv", "tcp_send", "udp_recv", "udp_send", | 79 | { "recvfrom", "sendto", NULL } }, |
| 80 | "rawip_recv", "rawip_send", "enforce_dest", | ||
| 81 | "dccp_recv", "dccp_send", "recvfrom", "sendto", NULL } }, | ||
| 82 | { "netif", | 80 | { "netif", |
| 83 | { "tcp_recv", "tcp_send", "udp_recv", "udp_send", | 81 | { "ingress", "egress", NULL } }, |
| 84 | "rawip_recv", "rawip_send", "dccp_recv", "dccp_send", | ||
| 85 | "ingress", "egress", NULL } }, | ||
| 86 | { "netlink_socket", | 82 | { "netlink_socket", |
| 87 | { COMMON_SOCK_PERMS, NULL } }, | 83 | { COMMON_SOCK_PERMS, NULL } }, |
| 88 | { "packet_socket", | 84 | { "packet_socket", |
| @@ -90,11 +86,9 @@ struct security_class_mapping secclass_map[] = { | |||
| 90 | { "key_socket", | 86 | { "key_socket", |
| 91 | { COMMON_SOCK_PERMS, NULL } }, | 87 | { COMMON_SOCK_PERMS, NULL } }, |
| 92 | { "unix_stream_socket", | 88 | { "unix_stream_socket", |
| 93 | { COMMON_SOCK_PERMS, "connectto", "newconn", "acceptfrom", NULL | 89 | { COMMON_SOCK_PERMS, "connectto", NULL } }, |
| 94 | } }, | ||
| 95 | { "unix_dgram_socket", | 90 | { "unix_dgram_socket", |
| 96 | { COMMON_SOCK_PERMS, NULL | 91 | { COMMON_SOCK_PERMS, NULL } }, |
| 97 | } }, | ||
| 98 | { "sem", | 92 | { "sem", |
| 99 | { COMMON_IPC_PERMS, NULL } }, | 93 | { COMMON_IPC_PERMS, NULL } }, |
| 100 | { "msg", { "send", "receive", NULL } }, | 94 | { "msg", { "send", "receive", NULL } }, |
| @@ -107,9 +101,6 @@ struct security_class_mapping secclass_map[] = { | |||
| 107 | { "netlink_route_socket", | 101 | { "netlink_route_socket", |
| 108 | { COMMON_SOCK_PERMS, | 102 | { COMMON_SOCK_PERMS, |
| 109 | "nlmsg_read", "nlmsg_write", NULL } }, | 103 | "nlmsg_read", "nlmsg_write", NULL } }, |
| 110 | { "netlink_firewall_socket", | ||
| 111 | { COMMON_SOCK_PERMS, | ||
| 112 | "nlmsg_read", "nlmsg_write", NULL } }, | ||
| 113 | { "netlink_tcpdiag_socket", | 104 | { "netlink_tcpdiag_socket", |
| 114 | { COMMON_SOCK_PERMS, | 105 | { COMMON_SOCK_PERMS, |
| 115 | "nlmsg_read", "nlmsg_write", NULL } }, | 106 | "nlmsg_read", "nlmsg_write", NULL } }, |
| @@ -120,19 +111,32 @@ struct security_class_mapping secclass_map[] = { | |||
| 120 | "nlmsg_read", "nlmsg_write", NULL } }, | 111 | "nlmsg_read", "nlmsg_write", NULL } }, |
| 121 | { "netlink_selinux_socket", | 112 | { "netlink_selinux_socket", |
| 122 | { COMMON_SOCK_PERMS, NULL } }, | 113 | { COMMON_SOCK_PERMS, NULL } }, |
| 114 | { "netlink_iscsi_socket", | ||
| 115 | { COMMON_SOCK_PERMS, NULL } }, | ||
| 123 | { "netlink_audit_socket", | 116 | { "netlink_audit_socket", |
| 124 | { COMMON_SOCK_PERMS, | 117 | { COMMON_SOCK_PERMS, |
| 125 | "nlmsg_read", "nlmsg_write", "nlmsg_relay", "nlmsg_readpriv", | 118 | "nlmsg_read", "nlmsg_write", "nlmsg_relay", "nlmsg_readpriv", |
| 126 | "nlmsg_tty_audit", NULL } }, | 119 | "nlmsg_tty_audit", NULL } }, |
| 127 | { "netlink_ip6fw_socket", | 120 | { "netlink_fib_lookup_socket", |
| 128 | { COMMON_SOCK_PERMS, | 121 | { COMMON_SOCK_PERMS, NULL } }, |
| 129 | "nlmsg_read", "nlmsg_write", NULL } }, | 122 | { "netlink_connector_socket", |
| 123 | { COMMON_SOCK_PERMS, NULL } }, | ||
| 124 | { "netlink_netfilter_socket", | ||
| 125 | { COMMON_SOCK_PERMS, NULL } }, | ||
| 130 | { "netlink_dnrt_socket", | 126 | { "netlink_dnrt_socket", |
| 131 | { COMMON_SOCK_PERMS, NULL } }, | 127 | { COMMON_SOCK_PERMS, NULL } }, |
| 132 | { "association", | 128 | { "association", |
| 133 | { "sendto", "recvfrom", "setcontext", "polmatch", NULL } }, | 129 | { "sendto", "recvfrom", "setcontext", "polmatch", NULL } }, |
| 134 | { "netlink_kobject_uevent_socket", | 130 | { "netlink_kobject_uevent_socket", |
| 135 | { COMMON_SOCK_PERMS, NULL } }, | 131 | { COMMON_SOCK_PERMS, NULL } }, |
| 132 | { "netlink_generic_socket", | ||
| 133 | { COMMON_SOCK_PERMS, NULL } }, | ||
| 134 | { "netlink_scsitransport_socket", | ||
| 135 | { COMMON_SOCK_PERMS, NULL } }, | ||
| 136 | { "netlink_rdma_socket", | ||
| 137 | { COMMON_SOCK_PERMS, NULL } }, | ||
| 138 | { "netlink_crypto_socket", | ||
| 139 | { COMMON_SOCK_PERMS, NULL } }, | ||
| 136 | { "appletalk_socket", | 140 | { "appletalk_socket", |
| 137 | { COMMON_SOCK_PERMS, NULL } }, | 141 | { COMMON_SOCK_PERMS, NULL } }, |
| 138 | { "packet", | 142 | { "packet", |
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index d1e0b239b602..36993ad1c067 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h | |||
| @@ -56,6 +56,7 @@ | |||
| 56 | /* Non-mount related flags */ | 56 | /* Non-mount related flags */ |
| 57 | #define SE_SBINITIALIZED 0x0100 | 57 | #define SE_SBINITIALIZED 0x0100 |
| 58 | #define SE_SBPROC 0x0200 | 58 | #define SE_SBPROC 0x0200 |
| 59 | #define SE_SBGENFS 0x0400 | ||
| 59 | 60 | ||
| 60 | #define CONTEXT_STR "context=" | 61 | #define CONTEXT_STR "context=" |
| 61 | #define FSCONTEXT_STR "fscontext=" | 62 | #define FSCONTEXT_STR "fscontext=" |
diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c index 2df7b900e259..2bbb41822d8e 100644 --- a/security/selinux/nlmsgtab.c +++ b/security/selinux/nlmsgtab.c | |||
| @@ -73,6 +73,9 @@ static struct nlmsg_perm nlmsg_route_perms[] = | |||
| 73 | { RTM_NEWMDB, NETLINK_ROUTE_SOCKET__NLMSG_WRITE }, | 73 | { RTM_NEWMDB, NETLINK_ROUTE_SOCKET__NLMSG_WRITE }, |
| 74 | { RTM_DELMDB, NETLINK_ROUTE_SOCKET__NLMSG_WRITE }, | 74 | { RTM_DELMDB, NETLINK_ROUTE_SOCKET__NLMSG_WRITE }, |
| 75 | { RTM_GETMDB, NETLINK_ROUTE_SOCKET__NLMSG_READ }, | 75 | { RTM_GETMDB, NETLINK_ROUTE_SOCKET__NLMSG_READ }, |
| 76 | { RTM_NEWNSID, NETLINK_ROUTE_SOCKET__NLMSG_WRITE }, | ||
| 77 | { RTM_DELNSID, NETLINK_ROUTE_SOCKET__NLMSG_READ }, | ||
| 78 | { RTM_GETNSID, NETLINK_ROUTE_SOCKET__NLMSG_READ }, | ||
| 76 | }; | 79 | }; |
| 77 | 80 | ||
| 78 | static struct nlmsg_perm nlmsg_tcpdiag_perms[] = | 81 | static struct nlmsg_perm nlmsg_tcpdiag_perms[] = |
| @@ -100,6 +103,13 @@ static struct nlmsg_perm nlmsg_xfrm_perms[] = | |||
| 100 | { XFRM_MSG_FLUSHPOLICY, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, | 103 | { XFRM_MSG_FLUSHPOLICY, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, |
| 101 | { XFRM_MSG_NEWAE, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, | 104 | { XFRM_MSG_NEWAE, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, |
| 102 | { XFRM_MSG_GETAE, NETLINK_XFRM_SOCKET__NLMSG_READ }, | 105 | { XFRM_MSG_GETAE, NETLINK_XFRM_SOCKET__NLMSG_READ }, |
| 106 | { XFRM_MSG_REPORT, NETLINK_XFRM_SOCKET__NLMSG_READ }, | ||
| 107 | { XFRM_MSG_MIGRATE, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, | ||
| 108 | { XFRM_MSG_NEWSADINFO, NETLINK_XFRM_SOCKET__NLMSG_READ }, | ||
| 109 | { XFRM_MSG_GETSADINFO, NETLINK_XFRM_SOCKET__NLMSG_READ }, | ||
| 110 | { XFRM_MSG_NEWSPDINFO, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, | ||
| 111 | { XFRM_MSG_GETSPDINFO, NETLINK_XFRM_SOCKET__NLMSG_READ }, | ||
| 112 | { XFRM_MSG_MAPPING, NETLINK_XFRM_SOCKET__NLMSG_READ }, | ||
| 103 | }; | 113 | }; |
| 104 | 114 | ||
| 105 | static struct nlmsg_perm nlmsg_audit_perms[] = | 115 | static struct nlmsg_perm nlmsg_audit_perms[] = |
| @@ -143,6 +153,8 @@ int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm) | |||
| 143 | 153 | ||
| 144 | switch (sclass) { | 154 | switch (sclass) { |
| 145 | case SECCLASS_NETLINK_ROUTE_SOCKET: | 155 | case SECCLASS_NETLINK_ROUTE_SOCKET: |
| 156 | /* RTM_MAX always point to RTM_SETxxxx, ie RTM_NEWxxx + 3 */ | ||
| 157 | BUILD_BUG_ON(RTM_MAX != (RTM_NEWNSID + 3)); | ||
| 146 | err = nlmsg_perm(nlmsg_type, perm, nlmsg_route_perms, | 158 | err = nlmsg_perm(nlmsg_type, perm, nlmsg_route_perms, |
| 147 | sizeof(nlmsg_route_perms)); | 159 | sizeof(nlmsg_route_perms)); |
| 148 | break; | 160 | break; |
| @@ -153,6 +165,7 @@ int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm) | |||
| 153 | break; | 165 | break; |
| 154 | 166 | ||
| 155 | case SECCLASS_NETLINK_XFRM_SOCKET: | 167 | case SECCLASS_NETLINK_XFRM_SOCKET: |
| 168 | BUILD_BUG_ON(XFRM_MSG_MAX != XFRM_MSG_MAPPING); | ||
| 156 | err = nlmsg_perm(nlmsg_type, perm, nlmsg_xfrm_perms, | 169 | err = nlmsg_perm(nlmsg_type, perm, nlmsg_xfrm_perms, |
| 157 | sizeof(nlmsg_xfrm_perms)); | 170 | sizeof(nlmsg_xfrm_perms)); |
| 158 | break; | 171 | break; |
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 5fde34326dcf..3d2201413028 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c | |||
| @@ -1737,7 +1737,7 @@ static struct dentry *sel_make_dir(struct dentry *dir, const char *name, | |||
| 1737 | inc_nlink(inode); | 1737 | inc_nlink(inode); |
| 1738 | d_add(dentry, inode); | 1738 | d_add(dentry, inode); |
| 1739 | /* bump link count on parent directory, too */ | 1739 | /* bump link count on parent directory, too */ |
| 1740 | inc_nlink(dir->d_inode); | 1740 | inc_nlink(d_inode(dir)); |
| 1741 | 1741 | ||
| 1742 | return dentry; | 1742 | return dentry; |
| 1743 | } | 1743 | } |
| @@ -1853,7 +1853,6 @@ static struct file_system_type sel_fs_type = { | |||
| 1853 | }; | 1853 | }; |
| 1854 | 1854 | ||
| 1855 | struct vfsmount *selinuxfs_mount; | 1855 | struct vfsmount *selinuxfs_mount; |
| 1856 | static struct kobject *selinuxfs_kobj; | ||
| 1857 | 1856 | ||
| 1858 | static int __init init_sel_fs(void) | 1857 | static int __init init_sel_fs(void) |
| 1859 | { | 1858 | { |
| @@ -1862,13 +1861,13 @@ static int __init init_sel_fs(void) | |||
| 1862 | if (!selinux_enabled) | 1861 | if (!selinux_enabled) |
| 1863 | return 0; | 1862 | return 0; |
| 1864 | 1863 | ||
| 1865 | selinuxfs_kobj = kobject_create_and_add("selinux", fs_kobj); | 1864 | err = sysfs_create_mount_point(fs_kobj, "selinux"); |
| 1866 | if (!selinuxfs_kobj) | 1865 | if (err) |
| 1867 | return -ENOMEM; | 1866 | return err; |
| 1868 | 1867 | ||
| 1869 | err = register_filesystem(&sel_fs_type); | 1868 | err = register_filesystem(&sel_fs_type); |
| 1870 | if (err) { | 1869 | if (err) { |
| 1871 | kobject_put(selinuxfs_kobj); | 1870 | sysfs_remove_mount_point(fs_kobj, "selinux"); |
| 1872 | return err; | 1871 | return err; |
| 1873 | } | 1872 | } |
| 1874 | 1873 | ||
| @@ -1887,7 +1886,7 @@ __initcall(init_sel_fs); | |||
| 1887 | #ifdef CONFIG_SECURITY_SELINUX_DISABLE | 1886 | #ifdef CONFIG_SECURITY_SELINUX_DISABLE |
| 1888 | void exit_sel_fs(void) | 1887 | void exit_sel_fs(void) |
| 1889 | { | 1888 | { |
| 1890 | kobject_put(selinuxfs_kobj); | 1889 | sysfs_remove_mount_point(fs_kobj, "selinux"); |
| 1891 | kern_unmount(selinuxfs_mount); | 1890 | kern_unmount(selinuxfs_mount); |
| 1892 | unregister_filesystem(&sel_fs_type); | 1891 | unregister_filesystem(&sel_fs_type); |
| 1893 | } | 1892 | } |
diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c index a3dd9faa19c0..b64f2772b030 100644 --- a/security/selinux/ss/avtab.c +++ b/security/selinux/ss/avtab.c | |||
| @@ -25,10 +25,43 @@ | |||
| 25 | 25 | ||
| 26 | static struct kmem_cache *avtab_node_cachep; | 26 | static struct kmem_cache *avtab_node_cachep; |
| 27 | 27 | ||
| 28 | static inline int avtab_hash(struct avtab_key *keyp, u16 mask) | 28 | /* Based on MurmurHash3, written by Austin Appleby and placed in the |
| 29 | * public domain. | ||
| 30 | */ | ||
| 31 | static inline int avtab_hash(struct avtab_key *keyp, u32 mask) | ||
| 29 | { | 32 | { |
| 30 | return ((keyp->target_class + (keyp->target_type << 2) + | 33 | static const u32 c1 = 0xcc9e2d51; |
| 31 | (keyp->source_type << 9)) & mask); | 34 | static const u32 c2 = 0x1b873593; |
| 35 | static const u32 r1 = 15; | ||
| 36 | static const u32 r2 = 13; | ||
| 37 | static const u32 m = 5; | ||
| 38 | static const u32 n = 0xe6546b64; | ||
| 39 | |||
| 40 | u32 hash = 0; | ||
| 41 | |||
| 42 | #define mix(input) { \ | ||
| 43 | u32 v = input; \ | ||
| 44 | v *= c1; \ | ||
| 45 | v = (v << r1) | (v >> (32 - r1)); \ | ||
| 46 | v *= c2; \ | ||
| 47 | hash ^= v; \ | ||
| 48 | hash = (hash << r2) | (hash >> (32 - r2)); \ | ||
| 49 | hash = hash * m + n; \ | ||
| 50 | } | ||
| 51 | |||
| 52 | mix(keyp->target_class); | ||
| 53 | mix(keyp->target_type); | ||
| 54 | mix(keyp->source_type); | ||
| 55 | |||
| 56 | #undef mix | ||
| 57 | |||
| 58 | hash ^= hash >> 16; | ||
| 59 | hash *= 0x85ebca6b; | ||
| 60 | hash ^= hash >> 13; | ||
| 61 | hash *= 0xc2b2ae35; | ||
| 62 | hash ^= hash >> 16; | ||
| 63 | |||
| 64 | return hash & mask; | ||
| 32 | } | 65 | } |
| 33 | 66 | ||
| 34 | static struct avtab_node* | 67 | static struct avtab_node* |
| @@ -46,8 +79,12 @@ avtab_insert_node(struct avtab *h, int hvalue, | |||
| 46 | newnode->next = prev->next; | 79 | newnode->next = prev->next; |
| 47 | prev->next = newnode; | 80 | prev->next = newnode; |
| 48 | } else { | 81 | } else { |
| 49 | newnode->next = h->htable[hvalue]; | 82 | newnode->next = flex_array_get_ptr(h->htable, hvalue); |
| 50 | h->htable[hvalue] = newnode; | 83 | if (flex_array_put_ptr(h->htable, hvalue, newnode, |
| 84 | GFP_KERNEL|__GFP_ZERO)) { | ||
| 85 | kmem_cache_free(avtab_node_cachep, newnode); | ||
| 86 | return NULL; | ||
| 87 | } | ||
| 51 | } | 88 | } |
| 52 | 89 | ||
| 53 | h->nel++; | 90 | h->nel++; |
| @@ -64,7 +101,7 @@ static int avtab_insert(struct avtab *h, struct avtab_key *key, struct avtab_dat | |||
| 64 | return -EINVAL; | 101 | return -EINVAL; |
| 65 | 102 | ||
| 66 | hvalue = avtab_hash(key, h->mask); | 103 | hvalue = avtab_hash(key, h->mask); |
| 67 | for (prev = NULL, cur = h->htable[hvalue]; | 104 | for (prev = NULL, cur = flex_array_get_ptr(h->htable, hvalue); |
| 68 | cur; | 105 | cur; |
| 69 | prev = cur, cur = cur->next) { | 106 | prev = cur, cur = cur->next) { |
| 70 | if (key->source_type == cur->key.source_type && | 107 | if (key->source_type == cur->key.source_type && |
| @@ -104,7 +141,7 @@ avtab_insert_nonunique(struct avtab *h, struct avtab_key *key, struct avtab_datu | |||
| 104 | if (!h || !h->htable) | 141 | if (!h || !h->htable) |
| 105 | return NULL; | 142 | return NULL; |
| 106 | hvalue = avtab_hash(key, h->mask); | 143 | hvalue = avtab_hash(key, h->mask); |
| 107 | for (prev = NULL, cur = h->htable[hvalue]; | 144 | for (prev = NULL, cur = flex_array_get_ptr(h->htable, hvalue); |
| 108 | cur; | 145 | cur; |
| 109 | prev = cur, cur = cur->next) { | 146 | prev = cur, cur = cur->next) { |
| 110 | if (key->source_type == cur->key.source_type && | 147 | if (key->source_type == cur->key.source_type && |
| @@ -135,7 +172,8 @@ struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *key) | |||
| 135 | return NULL; | 172 | return NULL; |
| 136 | 173 | ||
| 137 | hvalue = avtab_hash(key, h->mask); | 174 | hvalue = avtab_hash(key, h->mask); |
| 138 | for (cur = h->htable[hvalue]; cur; cur = cur->next) { | 175 | for (cur = flex_array_get_ptr(h->htable, hvalue); cur; |
| 176 | cur = cur->next) { | ||
| 139 | if (key->source_type == cur->key.source_type && | 177 | if (key->source_type == cur->key.source_type && |
| 140 | key->target_type == cur->key.target_type && | 178 | key->target_type == cur->key.target_type && |
| 141 | key->target_class == cur->key.target_class && | 179 | key->target_class == cur->key.target_class && |
| @@ -170,7 +208,8 @@ avtab_search_node(struct avtab *h, struct avtab_key *key) | |||
| 170 | return NULL; | 208 | return NULL; |
| 171 | 209 | ||
| 172 | hvalue = avtab_hash(key, h->mask); | 210 | hvalue = avtab_hash(key, h->mask); |
| 173 | for (cur = h->htable[hvalue]; cur; cur = cur->next) { | 211 | for (cur = flex_array_get_ptr(h->htable, hvalue); cur; |
| 212 | cur = cur->next) { | ||
| 174 | if (key->source_type == cur->key.source_type && | 213 | if (key->source_type == cur->key.source_type && |
| 175 | key->target_type == cur->key.target_type && | 214 | key->target_type == cur->key.target_type && |
| 176 | key->target_class == cur->key.target_class && | 215 | key->target_class == cur->key.target_class && |
| @@ -228,15 +267,14 @@ void avtab_destroy(struct avtab *h) | |||
| 228 | return; | 267 | return; |
| 229 | 268 | ||
| 230 | for (i = 0; i < h->nslot; i++) { | 269 | for (i = 0; i < h->nslot; i++) { |
| 231 | cur = h->htable[i]; | 270 | cur = flex_array_get_ptr(h->htable, i); |
| 232 | while (cur) { | 271 | while (cur) { |
| 233 | temp = cur; | 272 | temp = cur; |
| 234 | cur = cur->next; | 273 | cur = cur->next; |
| 235 | kmem_cache_free(avtab_node_cachep, temp); | 274 | kmem_cache_free(avtab_node_cachep, temp); |
| 236 | } | 275 | } |
| 237 | h->htable[i] = NULL; | ||
| 238 | } | 276 | } |
| 239 | kfree(h->htable); | 277 | flex_array_free(h->htable); |
| 240 | h->htable = NULL; | 278 | h->htable = NULL; |
| 241 | h->nslot = 0; | 279 | h->nslot = 0; |
| 242 | h->mask = 0; | 280 | h->mask = 0; |
| @@ -251,7 +289,7 @@ int avtab_init(struct avtab *h) | |||
| 251 | 289 | ||
| 252 | int avtab_alloc(struct avtab *h, u32 nrules) | 290 | int avtab_alloc(struct avtab *h, u32 nrules) |
| 253 | { | 291 | { |
| 254 | u16 mask = 0; | 292 | u32 mask = 0; |
| 255 | u32 shift = 0; | 293 | u32 shift = 0; |
| 256 | u32 work = nrules; | 294 | u32 work = nrules; |
| 257 | u32 nslot = 0; | 295 | u32 nslot = 0; |
| @@ -270,7 +308,8 @@ int avtab_alloc(struct avtab *h, u32 nrules) | |||
| 270 | nslot = MAX_AVTAB_HASH_BUCKETS; | 308 | nslot = MAX_AVTAB_HASH_BUCKETS; |
| 271 | mask = nslot - 1; | 309 | mask = nslot - 1; |
| 272 | 310 | ||
| 273 | h->htable = kcalloc(nslot, sizeof(*(h->htable)), GFP_KERNEL); | 311 | h->htable = flex_array_alloc(sizeof(struct avtab_node *), nslot, |
| 312 | GFP_KERNEL | __GFP_ZERO); | ||
| 274 | if (!h->htable) | 313 | if (!h->htable) |
| 275 | return -ENOMEM; | 314 | return -ENOMEM; |
| 276 | 315 | ||
| @@ -293,7 +332,7 @@ void avtab_hash_eval(struct avtab *h, char *tag) | |||
| 293 | max_chain_len = 0; | 332 | max_chain_len = 0; |
| 294 | chain2_len_sum = 0; | 333 | chain2_len_sum = 0; |
| 295 | for (i = 0; i < h->nslot; i++) { | 334 | for (i = 0; i < h->nslot; i++) { |
| 296 | cur = h->htable[i]; | 335 | cur = flex_array_get_ptr(h->htable, i); |
| 297 | if (cur) { | 336 | if (cur) { |
| 298 | slots_used++; | 337 | slots_used++; |
| 299 | chain_len = 0; | 338 | chain_len = 0; |
| @@ -534,7 +573,8 @@ int avtab_write(struct policydb *p, struct avtab *a, void *fp) | |||
| 534 | return rc; | 573 | return rc; |
| 535 | 574 | ||
| 536 | for (i = 0; i < a->nslot; i++) { | 575 | for (i = 0; i < a->nslot; i++) { |
| 537 | for (cur = a->htable[i]; cur; cur = cur->next) { | 576 | for (cur = flex_array_get_ptr(a->htable, i); cur; |
| 577 | cur = cur->next) { | ||
| 538 | rc = avtab_write_item(p, cur, fp); | 578 | rc = avtab_write_item(p, cur, fp); |
| 539 | if (rc) | 579 | if (rc) |
| 540 | return rc; | 580 | return rc; |
diff --git a/security/selinux/ss/avtab.h b/security/selinux/ss/avtab.h index 63ce2f9e441d..adb451cd44f9 100644 --- a/security/selinux/ss/avtab.h +++ b/security/selinux/ss/avtab.h | |||
| @@ -23,6 +23,8 @@ | |||
| 23 | #ifndef _SS_AVTAB_H_ | 23 | #ifndef _SS_AVTAB_H_ |
| 24 | #define _SS_AVTAB_H_ | 24 | #define _SS_AVTAB_H_ |
| 25 | 25 | ||
| 26 | #include <linux/flex_array.h> | ||
| 27 | |||
| 26 | struct avtab_key { | 28 | struct avtab_key { |
| 27 | u16 source_type; /* source type */ | 29 | u16 source_type; /* source type */ |
| 28 | u16 target_type; /* target type */ | 30 | u16 target_type; /* target type */ |
| @@ -51,10 +53,10 @@ struct avtab_node { | |||
| 51 | }; | 53 | }; |
| 52 | 54 | ||
| 53 | struct avtab { | 55 | struct avtab { |
| 54 | struct avtab_node **htable; | 56 | struct flex_array *htable; |
| 55 | u32 nel; /* number of elements */ | 57 | u32 nel; /* number of elements */ |
| 56 | u32 nslot; /* number of hash slots */ | 58 | u32 nslot; /* number of hash slots */ |
| 57 | u16 mask; /* mask to compute hash func */ | 59 | u32 mask; /* mask to compute hash func */ |
| 58 | 60 | ||
| 59 | }; | 61 | }; |
| 60 | 62 | ||
| @@ -84,7 +86,7 @@ struct avtab_node *avtab_search_node_next(struct avtab_node *node, int specified | |||
| 84 | void avtab_cache_init(void); | 86 | void avtab_cache_init(void); |
| 85 | void avtab_cache_destroy(void); | 87 | void avtab_cache_destroy(void); |
| 86 | 88 | ||
| 87 | #define MAX_AVTAB_HASH_BITS 11 | 89 | #define MAX_AVTAB_HASH_BITS 16 |
| 88 | #define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS) | 90 | #define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS) |
| 89 | 91 | ||
| 90 | #endif /* _SS_AVTAB_H_ */ | 92 | #endif /* _SS_AVTAB_H_ */ |
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c index afe6a269ec17..57644b1dc42e 100644 --- a/security/selinux/ss/ebitmap.c +++ b/security/selinux/ss/ebitmap.c | |||
| @@ -153,6 +153,12 @@ int ebitmap_netlbl_import(struct ebitmap *ebmap, | |||
| 153 | if (offset == (u32)-1) | 153 | if (offset == (u32)-1) |
| 154 | return 0; | 154 | return 0; |
| 155 | 155 | ||
| 156 | /* don't waste ebitmap space if the netlabel bitmap is empty */ | ||
| 157 | if (bitmap == 0) { | ||
| 158 | offset += EBITMAP_UNIT_SIZE; | ||
| 159 | continue; | ||
| 160 | } | ||
| 161 | |||
| 156 | if (e_iter == NULL || | 162 | if (e_iter == NULL || |
| 157 | offset >= e_iter->startbit + EBITMAP_SIZE) { | 163 | offset >= e_iter->startbit + EBITMAP_SIZE) { |
| 158 | e_prev = e_iter; | 164 | e_prev = e_iter; |
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c index d307b37ddc2b..e1088842232c 100644 --- a/security/selinux/ss/mls.c +++ b/security/selinux/ss/mls.c | |||
| @@ -654,19 +654,15 @@ int mls_import_netlbl_cat(struct context *context, | |||
| 654 | 654 | ||
| 655 | rc = ebitmap_netlbl_import(&context->range.level[0].cat, | 655 | rc = ebitmap_netlbl_import(&context->range.level[0].cat, |
| 656 | secattr->attr.mls.cat); | 656 | secattr->attr.mls.cat); |
| 657 | if (rc != 0) | 657 | if (rc) |
| 658 | goto import_netlbl_cat_failure; | ||
| 659 | |||
| 660 | rc = ebitmap_cpy(&context->range.level[1].cat, | ||
| 661 | &context->range.level[0].cat); | ||
| 662 | if (rc != 0) | ||
| 663 | goto import_netlbl_cat_failure; | 658 | goto import_netlbl_cat_failure; |
| 659 | memcpy(&context->range.level[1].cat, &context->range.level[0].cat, | ||
| 660 | sizeof(context->range.level[0].cat)); | ||
| 664 | 661 | ||
| 665 | return 0; | 662 | return 0; |
| 666 | 663 | ||
| 667 | import_netlbl_cat_failure: | 664 | import_netlbl_cat_failure: |
| 668 | ebitmap_destroy(&context->range.level[0].cat); | 665 | ebitmap_destroy(&context->range.level[0].cat); |
| 669 | ebitmap_destroy(&context->range.level[1].cat); | ||
| 670 | return rc; | 666 | return rc; |
| 671 | } | 667 | } |
| 672 | #endif /* CONFIG_NETLABEL */ | 668 | #endif /* CONFIG_NETLABEL */ |
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index a1d3944751b9..9e2d82070915 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
| @@ -3179,13 +3179,9 @@ int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr, | |||
| 3179 | ctx_new.type = ctx->type; | 3179 | ctx_new.type = ctx->type; |
| 3180 | mls_import_netlbl_lvl(&ctx_new, secattr); | 3180 | mls_import_netlbl_lvl(&ctx_new, secattr); |
| 3181 | if (secattr->flags & NETLBL_SECATTR_MLS_CAT) { | 3181 | if (secattr->flags & NETLBL_SECATTR_MLS_CAT) { |
| 3182 | rc = ebitmap_netlbl_import(&ctx_new.range.level[0].cat, | 3182 | rc = mls_import_netlbl_cat(&ctx_new, secattr); |
| 3183 | secattr->attr.mls.cat); | ||
| 3184 | if (rc) | 3183 | if (rc) |
| 3185 | goto out; | 3184 | goto out; |
| 3186 | memcpy(&ctx_new.range.level[1].cat, | ||
| 3187 | &ctx_new.range.level[0].cat, | ||
| 3188 | sizeof(ctx_new.range.level[0].cat)); | ||
| 3189 | } | 3185 | } |
| 3190 | rc = -EIDRM; | 3186 | rc = -EIDRM; |
| 3191 | if (!mls_context_isvalid(&policydb, &ctx_new)) | 3187 | if (!mls_context_isvalid(&policydb, &ctx_new)) |
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c index 98b042630a9e..56e354fcdfc6 100644 --- a/security/selinux/xfrm.c +++ b/security/selinux/xfrm.c | |||
| @@ -35,9 +35,6 @@ | |||
| 35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
| 36 | #include <linux/security.h> | 36 | #include <linux/security.h> |
| 37 | #include <linux/types.h> | 37 | #include <linux/types.h> |
| 38 | #include <linux/netfilter.h> | ||
| 39 | #include <linux/netfilter_ipv4.h> | ||
| 40 | #include <linux/netfilter_ipv6.h> | ||
| 41 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
| 42 | #include <linux/ip.h> | 39 | #include <linux/ip.h> |
| 43 | #include <linux/tcp.h> | 40 | #include <linux/tcp.h> |
diff --git a/security/smack/smack.h b/security/smack/smack.h index 67ccb7b2b89b..244e035e5a99 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h | |||
| @@ -15,7 +15,7 @@ | |||
| 15 | 15 | ||
| 16 | #include <linux/capability.h> | 16 | #include <linux/capability.h> |
| 17 | #include <linux/spinlock.h> | 17 | #include <linux/spinlock.h> |
| 18 | #include <linux/security.h> | 18 | #include <linux/lsm_hooks.h> |
| 19 | #include <linux/in.h> | 19 | #include <linux/in.h> |
| 20 | #include <net/netlabel.h> | 20 | #include <net/netlabel.h> |
| 21 | #include <linux/list.h> | 21 | #include <linux/list.h> |
| @@ -105,6 +105,7 @@ struct task_smack { | |||
| 105 | #define SMK_INODE_INSTANT 0x01 /* inode is instantiated */ | 105 | #define SMK_INODE_INSTANT 0x01 /* inode is instantiated */ |
| 106 | #define SMK_INODE_TRANSMUTE 0x02 /* directory is transmuting */ | 106 | #define SMK_INODE_TRANSMUTE 0x02 /* directory is transmuting */ |
| 107 | #define SMK_INODE_CHANGED 0x04 /* smack was transmuted */ | 107 | #define SMK_INODE_CHANGED 0x04 /* smack was transmuted */ |
| 108 | #define SMK_INODE_IMPURE 0x08 /* involved in an impure transaction */ | ||
| 108 | 109 | ||
| 109 | /* | 110 | /* |
| 110 | * A label access rule. | 111 | * A label access rule. |
| @@ -137,6 +138,11 @@ struct smk_port_label { | |||
| 137 | struct smack_known *smk_out; /* outgoing label */ | 138 | struct smack_known *smk_out; /* outgoing label */ |
| 138 | }; | 139 | }; |
| 139 | 140 | ||
| 141 | struct smack_onlycap { | ||
| 142 | struct list_head list; | ||
| 143 | struct smack_known *smk_label; | ||
| 144 | }; | ||
| 145 | |||
| 140 | /* | 146 | /* |
| 141 | * Mount options | 147 | * Mount options |
| 142 | */ | 148 | */ |
| @@ -193,6 +199,10 @@ struct smk_port_label { | |||
| 193 | #define MAY_LOCK 0x00002000 /* Locks should be writes, but ... */ | 199 | #define MAY_LOCK 0x00002000 /* Locks should be writes, but ... */ |
| 194 | #define MAY_BRINGUP 0x00004000 /* Report use of this rule */ | 200 | #define MAY_BRINGUP 0x00004000 /* Report use of this rule */ |
| 195 | 201 | ||
| 202 | #define SMACK_BRINGUP_ALLOW 1 /* Allow bringup mode */ | ||
| 203 | #define SMACK_UNCONFINED_SUBJECT 2 /* Allow unconfined label */ | ||
| 204 | #define SMACK_UNCONFINED_OBJECT 3 /* Allow unconfined label */ | ||
| 205 | |||
| 196 | /* | 206 | /* |
| 197 | * Just to make the common cases easier to deal with | 207 | * Just to make the common cases easier to deal with |
| 198 | */ | 208 | */ |
| @@ -244,6 +254,7 @@ int smk_netlbl_mls(int, char *, struct netlbl_lsm_secattr *, int); | |||
| 244 | struct smack_known *smk_import_entry(const char *, int); | 254 | struct smack_known *smk_import_entry(const char *, int); |
| 245 | void smk_insert_entry(struct smack_known *skp); | 255 | void smk_insert_entry(struct smack_known *skp); |
| 246 | struct smack_known *smk_find_entry(const char *); | 256 | struct smack_known *smk_find_entry(const char *); |
| 257 | int smack_privileged(int cap); | ||
| 247 | 258 | ||
| 248 | /* | 259 | /* |
| 249 | * Shared data. | 260 | * Shared data. |
| @@ -252,8 +263,10 @@ extern int smack_enabled; | |||
| 252 | extern int smack_cipso_direct; | 263 | extern int smack_cipso_direct; |
| 253 | extern int smack_cipso_mapped; | 264 | extern int smack_cipso_mapped; |
| 254 | extern struct smack_known *smack_net_ambient; | 265 | extern struct smack_known *smack_net_ambient; |
| 255 | extern struct smack_known *smack_onlycap; | ||
| 256 | extern struct smack_known *smack_syslog_label; | 266 | extern struct smack_known *smack_syslog_label; |
| 267 | #ifdef CONFIG_SECURITY_SMACK_BRINGUP | ||
| 268 | extern struct smack_known *smack_unconfined; | ||
| 269 | #endif | ||
| 257 | extern struct smack_known smack_cipso_option; | 270 | extern struct smack_known smack_cipso_option; |
| 258 | extern int smack_ptrace_rule; | 271 | extern int smack_ptrace_rule; |
| 259 | 272 | ||
| @@ -268,7 +281,8 @@ extern struct mutex smack_known_lock; | |||
| 268 | extern struct list_head smack_known_list; | 281 | extern struct list_head smack_known_list; |
| 269 | extern struct list_head smk_netlbladdr_list; | 282 | extern struct list_head smk_netlbladdr_list; |
| 270 | 283 | ||
| 271 | extern struct security_operations smack_ops; | 284 | extern struct mutex smack_onlycap_lock; |
| 285 | extern struct list_head smack_onlycap_list; | ||
| 272 | 286 | ||
| 273 | #define SMACK_HASH_SLOTS 16 | 287 | #define SMACK_HASH_SLOTS 16 |
| 274 | extern struct hlist_head smack_known_hash[SMACK_HASH_SLOTS]; | 288 | extern struct hlist_head smack_known_hash[SMACK_HASH_SLOTS]; |
| @@ -326,21 +340,6 @@ static inline struct smack_known *smk_of_current(void) | |||
| 326 | } | 340 | } |
| 327 | 341 | ||
| 328 | /* | 342 | /* |
| 329 | * Is the task privileged and allowed to be privileged | ||
| 330 | * by the onlycap rule. | ||
| 331 | */ | ||
| 332 | static inline int smack_privileged(int cap) | ||
| 333 | { | ||
| 334 | struct smack_known *skp = smk_of_current(); | ||
| 335 | |||
| 336 | if (!capable(cap)) | ||
| 337 | return 0; | ||
| 338 | if (smack_onlycap == NULL || smack_onlycap == skp) | ||
| 339 | return 1; | ||
| 340 | return 0; | ||
| 341 | } | ||
| 342 | |||
| 343 | /* | ||
| 344 | * logging functions | 343 | * logging functions |
| 345 | */ | 344 | */ |
| 346 | #define SMACK_AUDIT_DENIED 0x1 | 345 | #define SMACK_AUDIT_DENIED 0x1 |
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c index 1158430f5bb9..00f6b38bffbd 100644 --- a/security/smack/smack_access.c +++ b/security/smack/smack_access.c | |||
| @@ -130,7 +130,8 @@ int smk_access(struct smack_known *subject, struct smack_known *object, | |||
| 130 | 130 | ||
| 131 | /* | 131 | /* |
| 132 | * Hardcoded comparisons. | 132 | * Hardcoded comparisons. |
| 133 | * | 133 | */ |
| 134 | /* | ||
| 134 | * A star subject can't access any object. | 135 | * A star subject can't access any object. |
| 135 | */ | 136 | */ |
| 136 | if (subject == &smack_known_star) { | 137 | if (subject == &smack_known_star) { |
| @@ -189,10 +190,20 @@ int smk_access(struct smack_known *subject, struct smack_known *object, | |||
| 189 | * succeed because of "b" rules. | 190 | * succeed because of "b" rules. |
| 190 | */ | 191 | */ |
| 191 | if (may & MAY_BRINGUP) | 192 | if (may & MAY_BRINGUP) |
| 192 | rc = MAY_BRINGUP; | 193 | rc = SMACK_BRINGUP_ALLOW; |
| 193 | #endif | 194 | #endif |
| 194 | 195 | ||
| 195 | out_audit: | 196 | out_audit: |
| 197 | |||
| 198 | #ifdef CONFIG_SECURITY_SMACK_BRINGUP | ||
| 199 | if (rc < 0) { | ||
| 200 | if (object == smack_unconfined) | ||
| 201 | rc = SMACK_UNCONFINED_OBJECT; | ||
| 202 | if (subject == smack_unconfined) | ||
| 203 | rc = SMACK_UNCONFINED_SUBJECT; | ||
| 204 | } | ||
| 205 | #endif | ||
| 206 | |||
| 196 | #ifdef CONFIG_AUDIT | 207 | #ifdef CONFIG_AUDIT |
| 197 | if (a) | 208 | if (a) |
| 198 | smack_log(subject->smk_known, object->smk_known, | 209 | smack_log(subject->smk_known, object->smk_known, |
| @@ -338,19 +349,16 @@ static void smack_log_callback(struct audit_buffer *ab, void *a) | |||
| 338 | void smack_log(char *subject_label, char *object_label, int request, | 349 | void smack_log(char *subject_label, char *object_label, int request, |
| 339 | int result, struct smk_audit_info *ad) | 350 | int result, struct smk_audit_info *ad) |
| 340 | { | 351 | { |
| 352 | #ifdef CONFIG_SECURITY_SMACK_BRINGUP | ||
| 353 | char request_buffer[SMK_NUM_ACCESS_TYPE + 5]; | ||
| 354 | #else | ||
| 341 | char request_buffer[SMK_NUM_ACCESS_TYPE + 1]; | 355 | char request_buffer[SMK_NUM_ACCESS_TYPE + 1]; |
| 356 | #endif | ||
| 342 | struct smack_audit_data *sad; | 357 | struct smack_audit_data *sad; |
| 343 | struct common_audit_data *a = &ad->a; | 358 | struct common_audit_data *a = &ad->a; |
| 344 | 359 | ||
| 345 | #ifdef CONFIG_SECURITY_SMACK_BRINGUP | ||
| 346 | /* | ||
| 347 | * The result may be positive in bringup mode. | ||
| 348 | */ | ||
| 349 | if (result > 0) | ||
| 350 | result = 0; | ||
| 351 | #endif | ||
| 352 | /* check if we have to log the current event */ | 360 | /* check if we have to log the current event */ |
| 353 | if (result != 0 && (log_policy & SMACK_AUDIT_DENIED) == 0) | 361 | if (result < 0 && (log_policy & SMACK_AUDIT_DENIED) == 0) |
| 354 | return; | 362 | return; |
| 355 | if (result == 0 && (log_policy & SMACK_AUDIT_ACCEPT) == 0) | 363 | if (result == 0 && (log_policy & SMACK_AUDIT_ACCEPT) == 0) |
| 356 | return; | 364 | return; |
| @@ -364,6 +372,21 @@ void smack_log(char *subject_label, char *object_label, int request, | |||
| 364 | smack_str_from_perm(request_buffer, request); | 372 | smack_str_from_perm(request_buffer, request); |
| 365 | sad->subject = subject_label; | 373 | sad->subject = subject_label; |
| 366 | sad->object = object_label; | 374 | sad->object = object_label; |
| 375 | #ifdef CONFIG_SECURITY_SMACK_BRINGUP | ||
| 376 | /* | ||
| 377 | * The result may be positive in bringup mode. | ||
| 378 | * A positive result is an allow, but not for normal reasons. | ||
| 379 | * Mark it as successful, but don't filter it out even if | ||
| 380 | * the logging policy says to do so. | ||
| 381 | */ | ||
| 382 | if (result == SMACK_UNCONFINED_SUBJECT) | ||
| 383 | strcat(request_buffer, "(US)"); | ||
| 384 | else if (result == SMACK_UNCONFINED_OBJECT) | ||
| 385 | strcat(request_buffer, "(UO)"); | ||
| 386 | |||
| 387 | if (result > 0) | ||
| 388 | result = 0; | ||
| 389 | #endif | ||
| 367 | sad->request = request_buffer; | 390 | sad->request = request_buffer; |
| 368 | sad->result = result; | 391 | sad->result = result; |
| 369 | 392 | ||
| @@ -402,7 +425,7 @@ void smk_insert_entry(struct smack_known *skp) | |||
| 402 | * @string: a text string that might be a Smack label | 425 | * @string: a text string that might be a Smack label |
| 403 | * | 426 | * |
| 404 | * Returns a pointer to the entry in the label list that | 427 | * Returns a pointer to the entry in the label list that |
| 405 | * matches the passed string. | 428 | * matches the passed string or NULL if not found. |
| 406 | */ | 429 | */ |
| 407 | struct smack_known *smk_find_entry(const char *string) | 430 | struct smack_known *smk_find_entry(const char *string) |
| 408 | { | 431 | { |
| @@ -425,7 +448,7 @@ struct smack_known *smk_find_entry(const char *string) | |||
| 425 | * @string: a text string that might contain a Smack label | 448 | * @string: a text string that might contain a Smack label |
| 426 | * @len: the maximum size, or zero if it is NULL terminated. | 449 | * @len: the maximum size, or zero if it is NULL terminated. |
| 427 | * | 450 | * |
| 428 | * Returns a pointer to the clean label, or NULL | 451 | * Returns a pointer to the clean label or an error code. |
| 429 | */ | 452 | */ |
| 430 | char *smk_parse_smack(const char *string, int len) | 453 | char *smk_parse_smack(const char *string, int len) |
| 431 | { | 454 | { |
| @@ -441,7 +464,7 @@ char *smk_parse_smack(const char *string, int len) | |||
| 441 | * including /smack/cipso and /smack/cipso2 | 464 | * including /smack/cipso and /smack/cipso2 |
| 442 | */ | 465 | */ |
| 443 | if (string[0] == '-') | 466 | if (string[0] == '-') |
| 444 | return NULL; | 467 | return ERR_PTR(-EINVAL); |
| 445 | 468 | ||
| 446 | for (i = 0; i < len; i++) | 469 | for (i = 0; i < len; i++) |
| 447 | if (string[i] > '~' || string[i] <= ' ' || string[i] == '/' || | 470 | if (string[i] > '~' || string[i] <= ' ' || string[i] == '/' || |
| @@ -449,11 +472,13 @@ char *smk_parse_smack(const char *string, int len) | |||
| 449 | break; | 472 | break; |
| 450 | 473 | ||
| 451 | if (i == 0 || i >= SMK_LONGLABEL) | 474 | if (i == 0 || i >= SMK_LONGLABEL) |
| 452 | return NULL; | 475 | return ERR_PTR(-EINVAL); |
| 453 | 476 | ||
| 454 | smack = kzalloc(i + 1, GFP_KERNEL); | 477 | smack = kzalloc(i + 1, GFP_KERNEL); |
| 455 | if (smack != NULL) | 478 | if (smack == NULL) |
| 456 | strncpy(smack, string, i); | 479 | return ERR_PTR(-ENOMEM); |
| 480 | |||
| 481 | strncpy(smack, string, i); | ||
| 457 | 482 | ||
| 458 | return smack; | 483 | return smack; |
| 459 | } | 484 | } |
| @@ -500,7 +525,8 @@ int smk_netlbl_mls(int level, char *catset, struct netlbl_lsm_secattr *sap, | |||
| 500 | * @len: the maximum size, or zero if it is NULL terminated. | 525 | * @len: the maximum size, or zero if it is NULL terminated. |
| 501 | * | 526 | * |
| 502 | * Returns a pointer to the entry in the label list that | 527 | * Returns a pointer to the entry in the label list that |
| 503 | * matches the passed string, adding it if necessary. | 528 | * matches the passed string, adding it if necessary, |
| 529 | * or an error code. | ||
| 504 | */ | 530 | */ |
| 505 | struct smack_known *smk_import_entry(const char *string, int len) | 531 | struct smack_known *smk_import_entry(const char *string, int len) |
| 506 | { | 532 | { |
| @@ -510,8 +536,8 @@ struct smack_known *smk_import_entry(const char *string, int len) | |||
| 510 | int rc; | 536 | int rc; |
| 511 | 537 | ||
| 512 | smack = smk_parse_smack(string, len); | 538 | smack = smk_parse_smack(string, len); |
| 513 | if (smack == NULL) | 539 | if (IS_ERR(smack)) |
| 514 | return NULL; | 540 | return ERR_CAST(smack); |
| 515 | 541 | ||
| 516 | mutex_lock(&smack_known_lock); | 542 | mutex_lock(&smack_known_lock); |
| 517 | 543 | ||
| @@ -520,8 +546,10 @@ struct smack_known *smk_import_entry(const char *string, int len) | |||
| 520 | goto freeout; | 546 | goto freeout; |
| 521 | 547 | ||
| 522 | skp = kzalloc(sizeof(*skp), GFP_KERNEL); | 548 | skp = kzalloc(sizeof(*skp), GFP_KERNEL); |
| 523 | if (skp == NULL) | 549 | if (skp == NULL) { |
| 550 | skp = ERR_PTR(-ENOMEM); | ||
| 524 | goto freeout; | 551 | goto freeout; |
| 552 | } | ||
| 525 | 553 | ||
| 526 | skp->smk_known = smack; | 554 | skp->smk_known = smack; |
| 527 | skp->smk_secid = smack_next_secid++; | 555 | skp->smk_secid = smack_next_secid++; |
| @@ -554,7 +582,7 @@ struct smack_known *smk_import_entry(const char *string, int len) | |||
| 554 | * smk_netlbl_mls failed. | 582 | * smk_netlbl_mls failed. |
| 555 | */ | 583 | */ |
| 556 | kfree(skp); | 584 | kfree(skp); |
| 557 | skp = NULL; | 585 | skp = ERR_PTR(rc); |
| 558 | freeout: | 586 | freeout: |
| 559 | kfree(smack); | 587 | kfree(smack); |
| 560 | unlockout: | 588 | unlockout: |
| @@ -589,3 +617,44 @@ struct smack_known *smack_from_secid(const u32 secid) | |||
| 589 | rcu_read_unlock(); | 617 | rcu_read_unlock(); |
| 590 | return &smack_known_invalid; | 618 | return &smack_known_invalid; |
| 591 | } | 619 | } |
| 620 | |||
| 621 | /* | ||
| 622 | * Unless a process is running with one of these labels | ||
| 623 | * even having CAP_MAC_OVERRIDE isn't enough to grant | ||
| 624 | * privilege to violate MAC policy. If no labels are | ||
| 625 | * designated (the empty list case) capabilities apply to | ||
| 626 | * everyone. | ||
| 627 | */ | ||
| 628 | LIST_HEAD(smack_onlycap_list); | ||
| 629 | DEFINE_MUTEX(smack_onlycap_lock); | ||
| 630 | |||
| 631 | /* | ||
| 632 | * Is the task privileged and allowed to be privileged | ||
| 633 | * by the onlycap rule. | ||
| 634 | * | ||
| 635 | * Returns 1 if the task is allowed to be privileged, 0 if it's not. | ||
| 636 | */ | ||
| 637 | int smack_privileged(int cap) | ||
| 638 | { | ||
| 639 | struct smack_known *skp = smk_of_current(); | ||
| 640 | struct smack_onlycap *sop; | ||
| 641 | |||
| 642 | if (!capable(cap)) | ||
| 643 | return 0; | ||
| 644 | |||
| 645 | rcu_read_lock(); | ||
| 646 | if (list_empty(&smack_onlycap_list)) { | ||
| 647 | rcu_read_unlock(); | ||
| 648 | return 1; | ||
| 649 | } | ||
| 650 | |||
| 651 | list_for_each_entry_rcu(sop, &smack_onlycap_list, list) { | ||
| 652 | if (sop->smk_label == skp) { | ||
| 653 | rcu_read_unlock(); | ||
| 654 | return 1; | ||
| 655 | } | ||
| 656 | } | ||
| 657 | rcu_read_unlock(); | ||
| 658 | |||
| 659 | return 0; | ||
| 660 | } | ||
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index c934311812f1..a143328f75eb 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
| @@ -57,6 +57,13 @@ static struct kmem_cache *smack_inode_cache; | |||
| 57 | int smack_enabled; | 57 | int smack_enabled; |
| 58 | 58 | ||
| 59 | #ifdef CONFIG_SECURITY_SMACK_BRINGUP | 59 | #ifdef CONFIG_SECURITY_SMACK_BRINGUP |
| 60 | static char *smk_bu_mess[] = { | ||
| 61 | "Bringup Error", /* Unused */ | ||
| 62 | "Bringup", /* SMACK_BRINGUP_ALLOW */ | ||
| 63 | "Unconfined Subject", /* SMACK_UNCONFINED_SUBJECT */ | ||
| 64 | "Unconfined Object", /* SMACK_UNCONFINED_OBJECT */ | ||
| 65 | }; | ||
| 66 | |||
| 60 | static void smk_bu_mode(int mode, char *s) | 67 | static void smk_bu_mode(int mode, char *s) |
| 61 | { | 68 | { |
| 62 | int i = 0; | 69 | int i = 0; |
| @@ -87,9 +94,11 @@ static int smk_bu_note(char *note, struct smack_known *sskp, | |||
| 87 | 94 | ||
| 88 | if (rc <= 0) | 95 | if (rc <= 0) |
| 89 | return rc; | 96 | return rc; |
| 97 | if (rc > SMACK_UNCONFINED_OBJECT) | ||
| 98 | rc = 0; | ||
| 90 | 99 | ||
| 91 | smk_bu_mode(mode, acc); | 100 | smk_bu_mode(mode, acc); |
| 92 | pr_info("Smack Bringup: (%s %s %s) %s\n", | 101 | pr_info("Smack %s: (%s %s %s) %s\n", smk_bu_mess[rc], |
| 93 | sskp->smk_known, oskp->smk_known, acc, note); | 102 | sskp->smk_known, oskp->smk_known, acc, note); |
| 94 | return 0; | 103 | return 0; |
| 95 | } | 104 | } |
| @@ -106,9 +115,11 @@ static int smk_bu_current(char *note, struct smack_known *oskp, | |||
| 106 | 115 | ||
| 107 | if (rc <= 0) | 116 | if (rc <= 0) |
| 108 | return rc; | 117 | return rc; |
| 118 | if (rc > SMACK_UNCONFINED_OBJECT) | ||
| 119 | rc = 0; | ||
| 109 | 120 | ||
| 110 | smk_bu_mode(mode, acc); | 121 | smk_bu_mode(mode, acc); |
| 111 | pr_info("Smack Bringup: (%s %s %s) %s %s\n", | 122 | pr_info("Smack %s: (%s %s %s) %s %s\n", smk_bu_mess[rc], |
| 112 | tsp->smk_task->smk_known, oskp->smk_known, | 123 | tsp->smk_task->smk_known, oskp->smk_known, |
| 113 | acc, current->comm, note); | 124 | acc, current->comm, note); |
| 114 | return 0; | 125 | return 0; |
| @@ -126,9 +137,11 @@ static int smk_bu_task(struct task_struct *otp, int mode, int rc) | |||
| 126 | 137 | ||
| 127 | if (rc <= 0) | 138 | if (rc <= 0) |
| 128 | return rc; | 139 | return rc; |
| 140 | if (rc > SMACK_UNCONFINED_OBJECT) | ||
| 141 | rc = 0; | ||
| 129 | 142 | ||
| 130 | smk_bu_mode(mode, acc); | 143 | smk_bu_mode(mode, acc); |
| 131 | pr_info("Smack Bringup: (%s %s %s) %s to %s\n", | 144 | pr_info("Smack %s: (%s %s %s) %s to %s\n", smk_bu_mess[rc], |
| 132 | tsp->smk_task->smk_known, smk_task->smk_known, acc, | 145 | tsp->smk_task->smk_known, smk_task->smk_known, acc, |
| 133 | current->comm, otp->comm); | 146 | current->comm, otp->comm); |
| 134 | return 0; | 147 | return 0; |
| @@ -141,14 +154,25 @@ static int smk_bu_task(struct task_struct *otp, int mode, int rc) | |||
| 141 | static int smk_bu_inode(struct inode *inode, int mode, int rc) | 154 | static int smk_bu_inode(struct inode *inode, int mode, int rc) |
| 142 | { | 155 | { |
| 143 | struct task_smack *tsp = current_security(); | 156 | struct task_smack *tsp = current_security(); |
| 157 | struct inode_smack *isp = inode->i_security; | ||
| 144 | char acc[SMK_NUM_ACCESS_TYPE + 1]; | 158 | char acc[SMK_NUM_ACCESS_TYPE + 1]; |
| 145 | 159 | ||
| 160 | if (isp->smk_flags & SMK_INODE_IMPURE) | ||
| 161 | pr_info("Smack Unconfined Corruption: inode=(%s %ld) %s\n", | ||
| 162 | inode->i_sb->s_id, inode->i_ino, current->comm); | ||
| 163 | |||
| 146 | if (rc <= 0) | 164 | if (rc <= 0) |
| 147 | return rc; | 165 | return rc; |
| 166 | if (rc > SMACK_UNCONFINED_OBJECT) | ||
| 167 | rc = 0; | ||
| 168 | if (rc == SMACK_UNCONFINED_SUBJECT && | ||
| 169 | (mode & (MAY_WRITE | MAY_APPEND))) | ||
| 170 | isp->smk_flags |= SMK_INODE_IMPURE; | ||
| 148 | 171 | ||
| 149 | smk_bu_mode(mode, acc); | 172 | smk_bu_mode(mode, acc); |
| 150 | pr_info("Smack Bringup: (%s %s %s) inode=(%s %ld) %s\n", | 173 | |
| 151 | tsp->smk_task->smk_known, smk_of_inode(inode)->smk_known, acc, | 174 | pr_info("Smack %s: (%s %s %s) inode=(%s %ld) %s\n", smk_bu_mess[rc], |
| 175 | tsp->smk_task->smk_known, isp->smk_inode->smk_known, acc, | ||
| 152 | inode->i_sb->s_id, inode->i_ino, current->comm); | 176 | inode->i_sb->s_id, inode->i_ino, current->comm); |
| 153 | return 0; | 177 | return 0; |
| 154 | } | 178 | } |
| @@ -162,13 +186,20 @@ static int smk_bu_file(struct file *file, int mode, int rc) | |||
| 162 | struct task_smack *tsp = current_security(); | 186 | struct task_smack *tsp = current_security(); |
| 163 | struct smack_known *sskp = tsp->smk_task; | 187 | struct smack_known *sskp = tsp->smk_task; |
| 164 | struct inode *inode = file_inode(file); | 188 | struct inode *inode = file_inode(file); |
| 189 | struct inode_smack *isp = inode->i_security; | ||
| 165 | char acc[SMK_NUM_ACCESS_TYPE + 1]; | 190 | char acc[SMK_NUM_ACCESS_TYPE + 1]; |
| 166 | 191 | ||
| 192 | if (isp->smk_flags & SMK_INODE_IMPURE) | ||
| 193 | pr_info("Smack Unconfined Corruption: inode=(%s %ld) %s\n", | ||
| 194 | inode->i_sb->s_id, inode->i_ino, current->comm); | ||
| 195 | |||
| 167 | if (rc <= 0) | 196 | if (rc <= 0) |
| 168 | return rc; | 197 | return rc; |
| 198 | if (rc > SMACK_UNCONFINED_OBJECT) | ||
| 199 | rc = 0; | ||
| 169 | 200 | ||
| 170 | smk_bu_mode(mode, acc); | 201 | smk_bu_mode(mode, acc); |
| 171 | pr_info("Smack Bringup: (%s %s %s) file=(%s %ld %pD) %s\n", | 202 | pr_info("Smack %s: (%s %s %s) file=(%s %ld %pD) %s\n", smk_bu_mess[rc], |
| 172 | sskp->smk_known, smk_of_inode(inode)->smk_known, acc, | 203 | sskp->smk_known, smk_of_inode(inode)->smk_known, acc, |
| 173 | inode->i_sb->s_id, inode->i_ino, file, | 204 | inode->i_sb->s_id, inode->i_ino, file, |
| 174 | current->comm); | 205 | current->comm); |
| @@ -185,13 +216,20 @@ static int smk_bu_credfile(const struct cred *cred, struct file *file, | |||
| 185 | struct task_smack *tsp = cred->security; | 216 | struct task_smack *tsp = cred->security; |
| 186 | struct smack_known *sskp = tsp->smk_task; | 217 | struct smack_known *sskp = tsp->smk_task; |
| 187 | struct inode *inode = file->f_inode; | 218 | struct inode *inode = file->f_inode; |
| 219 | struct inode_smack *isp = inode->i_security; | ||
| 188 | char acc[SMK_NUM_ACCESS_TYPE + 1]; | 220 | char acc[SMK_NUM_ACCESS_TYPE + 1]; |
| 189 | 221 | ||
| 222 | if (isp->smk_flags & SMK_INODE_IMPURE) | ||
| 223 | pr_info("Smack Unconfined Corruption: inode=(%s %ld) %s\n", | ||
| 224 | inode->i_sb->s_id, inode->i_ino, current->comm); | ||
| 225 | |||
| 190 | if (rc <= 0) | 226 | if (rc <= 0) |
| 191 | return rc; | 227 | return rc; |
| 228 | if (rc > SMACK_UNCONFINED_OBJECT) | ||
| 229 | rc = 0; | ||
| 192 | 230 | ||
| 193 | smk_bu_mode(mode, acc); | 231 | smk_bu_mode(mode, acc); |
| 194 | pr_info("Smack Bringup: (%s %s %s) file=(%s %ld %pD) %s\n", | 232 | pr_info("Smack %s: (%s %s %s) file=(%s %ld %pD) %s\n", smk_bu_mess[rc], |
| 195 | sskp->smk_known, smk_of_inode(inode)->smk_known, acc, | 233 | sskp->smk_known, smk_of_inode(inode)->smk_known, acc, |
| 196 | inode->i_sb->s_id, inode->i_ino, file, | 234 | inode->i_sb->s_id, inode->i_ino, file, |
| 197 | current->comm); | 235 | current->comm); |
| @@ -207,8 +245,8 @@ static int smk_bu_credfile(const struct cred *cred, struct file *file, | |||
| 207 | * @ip: a pointer to the inode | 245 | * @ip: a pointer to the inode |
| 208 | * @dp: a pointer to the dentry | 246 | * @dp: a pointer to the dentry |
| 209 | * | 247 | * |
| 210 | * Returns a pointer to the master list entry for the Smack label | 248 | * Returns a pointer to the master list entry for the Smack label, |
| 211 | * or NULL if there was no label to fetch. | 249 | * NULL if there was no label to fetch, or an error code. |
| 212 | */ | 250 | */ |
| 213 | static struct smack_known *smk_fetch(const char *name, struct inode *ip, | 251 | static struct smack_known *smk_fetch(const char *name, struct inode *ip, |
| 214 | struct dentry *dp) | 252 | struct dentry *dp) |
| @@ -218,14 +256,18 @@ static struct smack_known *smk_fetch(const char *name, struct inode *ip, | |||
| 218 | struct smack_known *skp = NULL; | 256 | struct smack_known *skp = NULL; |
| 219 | 257 | ||
| 220 | if (ip->i_op->getxattr == NULL) | 258 | if (ip->i_op->getxattr == NULL) |
| 221 | return NULL; | 259 | return ERR_PTR(-EOPNOTSUPP); |
| 222 | 260 | ||
| 223 | buffer = kzalloc(SMK_LONGLABEL, GFP_KERNEL); | 261 | buffer = kzalloc(SMK_LONGLABEL, GFP_KERNEL); |
| 224 | if (buffer == NULL) | 262 | if (buffer == NULL) |
| 225 | return NULL; | 263 | return ERR_PTR(-ENOMEM); |
| 226 | 264 | ||
| 227 | rc = ip->i_op->getxattr(dp, name, buffer, SMK_LONGLABEL); | 265 | rc = ip->i_op->getxattr(dp, name, buffer, SMK_LONGLABEL); |
| 228 | if (rc > 0) | 266 | if (rc < 0) |
| 267 | skp = ERR_PTR(rc); | ||
| 268 | else if (rc == 0) | ||
| 269 | skp = NULL; | ||
| 270 | else | ||
| 229 | skp = smk_import_entry(buffer, rc); | 271 | skp = smk_import_entry(buffer, rc); |
| 230 | 272 | ||
| 231 | kfree(buffer); | 273 | kfree(buffer); |
| @@ -398,17 +440,11 @@ static int smk_ptrace_rule_check(struct task_struct *tracer, | |||
| 398 | */ | 440 | */ |
| 399 | static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode) | 441 | static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode) |
| 400 | { | 442 | { |
| 401 | int rc; | ||
| 402 | struct smack_known *skp; | 443 | struct smack_known *skp; |
| 403 | 444 | ||
| 404 | rc = cap_ptrace_access_check(ctp, mode); | ||
| 405 | if (rc != 0) | ||
| 406 | return rc; | ||
| 407 | |||
| 408 | skp = smk_of_task_struct(ctp); | 445 | skp = smk_of_task_struct(ctp); |
| 409 | 446 | ||
| 410 | rc = smk_ptrace_rule_check(current, skp, mode, __func__); | 447 | return smk_ptrace_rule_check(current, skp, mode, __func__); |
| 411 | return rc; | ||
| 412 | } | 448 | } |
| 413 | 449 | ||
| 414 | /** | 450 | /** |
| @@ -424,10 +460,6 @@ static int smack_ptrace_traceme(struct task_struct *ptp) | |||
| 424 | int rc; | 460 | int rc; |
| 425 | struct smack_known *skp; | 461 | struct smack_known *skp; |
| 426 | 462 | ||
| 427 | rc = cap_ptrace_traceme(ptp); | ||
| 428 | if (rc != 0) | ||
| 429 | return rc; | ||
| 430 | |||
| 431 | skp = smk_of_task(current_security()); | 463 | skp = smk_of_task(current_security()); |
| 432 | 464 | ||
| 433 | rc = smk_ptrace_rule_check(ptp, skp, PTRACE_MODE_ATTACH, __func__); | 465 | rc = smk_ptrace_rule_check(ptp, skp, PTRACE_MODE_ATTACH, __func__); |
| @@ -555,7 +587,7 @@ static int smack_sb_copy_data(char *orig, char *smackopts) | |||
| 555 | static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data) | 587 | static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data) |
| 556 | { | 588 | { |
| 557 | struct dentry *root = sb->s_root; | 589 | struct dentry *root = sb->s_root; |
| 558 | struct inode *inode = root->d_inode; | 590 | struct inode *inode = d_backing_inode(root); |
| 559 | struct superblock_smack *sp = sb->s_security; | 591 | struct superblock_smack *sp = sb->s_security; |
| 560 | struct inode_smack *isp; | 592 | struct inode_smack *isp; |
| 561 | struct smack_known *skp; | 593 | struct smack_known *skp; |
| @@ -577,40 +609,44 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data) | |||
| 577 | if (strncmp(op, SMK_FSHAT, strlen(SMK_FSHAT)) == 0) { | 609 | if (strncmp(op, SMK_FSHAT, strlen(SMK_FSHAT)) == 0) { |
| 578 | op += strlen(SMK_FSHAT); | 610 | op += strlen(SMK_FSHAT); |
| 579 | skp = smk_import_entry(op, 0); | 611 | skp = smk_import_entry(op, 0); |
| 580 | if (skp != NULL) { | 612 | if (IS_ERR(skp)) |
| 581 | sp->smk_hat = skp; | 613 | return PTR_ERR(skp); |
| 582 | specified = 1; | 614 | sp->smk_hat = skp; |
| 583 | } | 615 | specified = 1; |
| 616 | |||
| 584 | } else if (strncmp(op, SMK_FSFLOOR, strlen(SMK_FSFLOOR)) == 0) { | 617 | } else if (strncmp(op, SMK_FSFLOOR, strlen(SMK_FSFLOOR)) == 0) { |
| 585 | op += strlen(SMK_FSFLOOR); | 618 | op += strlen(SMK_FSFLOOR); |
| 586 | skp = smk_import_entry(op, 0); | 619 | skp = smk_import_entry(op, 0); |
| 587 | if (skp != NULL) { | 620 | if (IS_ERR(skp)) |
| 588 | sp->smk_floor = skp; | 621 | return PTR_ERR(skp); |
| 589 | specified = 1; | 622 | sp->smk_floor = skp; |
| 590 | } | 623 | specified = 1; |
| 624 | |||
| 591 | } else if (strncmp(op, SMK_FSDEFAULT, | 625 | } else if (strncmp(op, SMK_FSDEFAULT, |
| 592 | strlen(SMK_FSDEFAULT)) == 0) { | 626 | strlen(SMK_FSDEFAULT)) == 0) { |
| 593 | op += strlen(SMK_FSDEFAULT); | 627 | op += strlen(SMK_FSDEFAULT); |
| 594 | skp = smk_import_entry(op, 0); | 628 | skp = smk_import_entry(op, 0); |
| 595 | if (skp != NULL) { | 629 | if (IS_ERR(skp)) |
| 596 | sp->smk_default = skp; | 630 | return PTR_ERR(skp); |
| 597 | specified = 1; | 631 | sp->smk_default = skp; |
| 598 | } | 632 | specified = 1; |
| 633 | |||
| 599 | } else if (strncmp(op, SMK_FSROOT, strlen(SMK_FSROOT)) == 0) { | 634 | } else if (strncmp(op, SMK_FSROOT, strlen(SMK_FSROOT)) == 0) { |
| 600 | op += strlen(SMK_FSROOT); | 635 | op += strlen(SMK_FSROOT); |
| 601 | skp = smk_import_entry(op, 0); | 636 | skp = smk_import_entry(op, 0); |
| 602 | if (skp != NULL) { | 637 | if (IS_ERR(skp)) |
| 603 | sp->smk_root = skp; | 638 | return PTR_ERR(skp); |
| 604 | specified = 1; | 639 | sp->smk_root = skp; |
| 605 | } | 640 | specified = 1; |
| 641 | |||
| 606 | } else if (strncmp(op, SMK_FSTRANS, strlen(SMK_FSTRANS)) == 0) { | 642 | } else if (strncmp(op, SMK_FSTRANS, strlen(SMK_FSTRANS)) == 0) { |
| 607 | op += strlen(SMK_FSTRANS); | 643 | op += strlen(SMK_FSTRANS); |
| 608 | skp = smk_import_entry(op, 0); | 644 | skp = smk_import_entry(op, 0); |
| 609 | if (skp != NULL) { | 645 | if (IS_ERR(skp)) |
| 610 | sp->smk_root = skp; | 646 | return PTR_ERR(skp); |
| 611 | transmute = 1; | 647 | sp->smk_root = skp; |
| 612 | specified = 1; | 648 | transmute = 1; |
| 613 | } | 649 | specified = 1; |
| 614 | } | 650 | } |
| 615 | } | 651 | } |
| 616 | 652 | ||
| @@ -683,10 +719,6 @@ static int smack_bprm_set_creds(struct linux_binprm *bprm) | |||
| 683 | struct inode_smack *isp; | 719 | struct inode_smack *isp; |
| 684 | int rc; | 720 | int rc; |
| 685 | 721 | ||
| 686 | rc = cap_bprm_set_creds(bprm); | ||
| 687 | if (rc != 0) | ||
| 688 | return rc; | ||
| 689 | |||
| 690 | if (bprm->cred_prepared) | 722 | if (bprm->cred_prepared) |
| 691 | return 0; | 723 | return 0; |
| 692 | 724 | ||
| @@ -741,12 +773,11 @@ static void smack_bprm_committing_creds(struct linux_binprm *bprm) | |||
| 741 | static int smack_bprm_secureexec(struct linux_binprm *bprm) | 773 | static int smack_bprm_secureexec(struct linux_binprm *bprm) |
| 742 | { | 774 | { |
| 743 | struct task_smack *tsp = current_security(); | 775 | struct task_smack *tsp = current_security(); |
| 744 | int ret = cap_bprm_secureexec(bprm); | ||
| 745 | 776 | ||
| 746 | if (!ret && (tsp->smk_task != tsp->smk_forked)) | 777 | if (tsp->smk_task != tsp->smk_forked) |
| 747 | ret = 1; | 778 | return 1; |
| 748 | 779 | ||
| 749 | return ret; | 780 | return 0; |
| 750 | } | 781 | } |
| 751 | 782 | ||
| 752 | /* | 783 | /* |
| @@ -851,15 +882,15 @@ static int smack_inode_link(struct dentry *old_dentry, struct inode *dir, | |||
| 851 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); | 882 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); |
| 852 | smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry); | 883 | smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry); |
| 853 | 884 | ||
| 854 | isp = smk_of_inode(old_dentry->d_inode); | 885 | isp = smk_of_inode(d_backing_inode(old_dentry)); |
| 855 | rc = smk_curacc(isp, MAY_WRITE, &ad); | 886 | rc = smk_curacc(isp, MAY_WRITE, &ad); |
| 856 | rc = smk_bu_inode(old_dentry->d_inode, MAY_WRITE, rc); | 887 | rc = smk_bu_inode(d_backing_inode(old_dentry), MAY_WRITE, rc); |
| 857 | 888 | ||
| 858 | if (rc == 0 && d_is_positive(new_dentry)) { | 889 | if (rc == 0 && d_is_positive(new_dentry)) { |
| 859 | isp = smk_of_inode(new_dentry->d_inode); | 890 | isp = smk_of_inode(d_backing_inode(new_dentry)); |
| 860 | smk_ad_setfield_u_fs_path_dentry(&ad, new_dentry); | 891 | smk_ad_setfield_u_fs_path_dentry(&ad, new_dentry); |
| 861 | rc = smk_curacc(isp, MAY_WRITE, &ad); | 892 | rc = smk_curacc(isp, MAY_WRITE, &ad); |
| 862 | rc = smk_bu_inode(new_dentry->d_inode, MAY_WRITE, rc); | 893 | rc = smk_bu_inode(d_backing_inode(new_dentry), MAY_WRITE, rc); |
| 863 | } | 894 | } |
| 864 | 895 | ||
| 865 | return rc; | 896 | return rc; |
| @@ -875,7 +906,7 @@ static int smack_inode_link(struct dentry *old_dentry, struct inode *dir, | |||
| 875 | */ | 906 | */ |
| 876 | static int smack_inode_unlink(struct inode *dir, struct dentry *dentry) | 907 | static int smack_inode_unlink(struct inode *dir, struct dentry *dentry) |
| 877 | { | 908 | { |
| 878 | struct inode *ip = dentry->d_inode; | 909 | struct inode *ip = d_backing_inode(dentry); |
| 879 | struct smk_audit_info ad; | 910 | struct smk_audit_info ad; |
| 880 | int rc; | 911 | int rc; |
| 881 | 912 | ||
| @@ -918,8 +949,8 @@ static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry) | |||
| 918 | /* | 949 | /* |
| 919 | * You need write access to the thing you're removing | 950 | * You need write access to the thing you're removing |
| 920 | */ | 951 | */ |
| 921 | rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); | 952 | rc = smk_curacc(smk_of_inode(d_backing_inode(dentry)), MAY_WRITE, &ad); |
| 922 | rc = smk_bu_inode(dentry->d_inode, MAY_WRITE, rc); | 953 | rc = smk_bu_inode(d_backing_inode(dentry), MAY_WRITE, rc); |
| 923 | if (rc == 0) { | 954 | if (rc == 0) { |
| 924 | /* | 955 | /* |
| 925 | * You also need write access to the containing directory | 956 | * You also need write access to the containing directory |
| @@ -957,15 +988,15 @@ static int smack_inode_rename(struct inode *old_inode, | |||
| 957 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); | 988 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); |
| 958 | smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry); | 989 | smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry); |
| 959 | 990 | ||
| 960 | isp = smk_of_inode(old_dentry->d_inode); | 991 | isp = smk_of_inode(d_backing_inode(old_dentry)); |
| 961 | rc = smk_curacc(isp, MAY_READWRITE, &ad); | 992 | rc = smk_curacc(isp, MAY_READWRITE, &ad); |
| 962 | rc = smk_bu_inode(old_dentry->d_inode, MAY_READWRITE, rc); | 993 | rc = smk_bu_inode(d_backing_inode(old_dentry), MAY_READWRITE, rc); |
| 963 | 994 | ||
| 964 | if (rc == 0 && d_is_positive(new_dentry)) { | 995 | if (rc == 0 && d_is_positive(new_dentry)) { |
| 965 | isp = smk_of_inode(new_dentry->d_inode); | 996 | isp = smk_of_inode(d_backing_inode(new_dentry)); |
| 966 | smk_ad_setfield_u_fs_path_dentry(&ad, new_dentry); | 997 | smk_ad_setfield_u_fs_path_dentry(&ad, new_dentry); |
| 967 | rc = smk_curacc(isp, MAY_READWRITE, &ad); | 998 | rc = smk_curacc(isp, MAY_READWRITE, &ad); |
| 968 | rc = smk_bu_inode(new_dentry->d_inode, MAY_READWRITE, rc); | 999 | rc = smk_bu_inode(d_backing_inode(new_dentry), MAY_READWRITE, rc); |
| 969 | } | 1000 | } |
| 970 | return rc; | 1001 | return rc; |
| 971 | } | 1002 | } |
| @@ -1022,8 +1053,8 @@ static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr) | |||
| 1022 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); | 1053 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); |
| 1023 | smk_ad_setfield_u_fs_path_dentry(&ad, dentry); | 1054 | smk_ad_setfield_u_fs_path_dentry(&ad, dentry); |
| 1024 | 1055 | ||
| 1025 | rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); | 1056 | rc = smk_curacc(smk_of_inode(d_backing_inode(dentry)), MAY_WRITE, &ad); |
| 1026 | rc = smk_bu_inode(dentry->d_inode, MAY_WRITE, rc); | 1057 | rc = smk_bu_inode(d_backing_inode(dentry), MAY_WRITE, rc); |
| 1027 | return rc; | 1058 | return rc; |
| 1028 | } | 1059 | } |
| 1029 | 1060 | ||
| @@ -1034,19 +1065,16 @@ static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr) | |||
| 1034 | * | 1065 | * |
| 1035 | * Returns 0 if access is permitted, an error code otherwise | 1066 | * Returns 0 if access is permitted, an error code otherwise |
| 1036 | */ | 1067 | */ |
| 1037 | static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) | 1068 | static int smack_inode_getattr(const struct path *path) |
| 1038 | { | 1069 | { |
| 1039 | struct smk_audit_info ad; | 1070 | struct smk_audit_info ad; |
| 1040 | struct path path; | 1071 | struct inode *inode = d_backing_inode(path->dentry); |
| 1041 | int rc; | 1072 | int rc; |
| 1042 | 1073 | ||
| 1043 | path.dentry = dentry; | ||
| 1044 | path.mnt = mnt; | ||
| 1045 | |||
| 1046 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); | 1074 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); |
| 1047 | smk_ad_setfield_u_fs_path(&ad, path); | 1075 | smk_ad_setfield_u_fs_path(&ad, *path); |
| 1048 | rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad); | 1076 | rc = smk_curacc(smk_of_inode(inode), MAY_READ, &ad); |
| 1049 | rc = smk_bu_inode(dentry->d_inode, MAY_READ, rc); | 1077 | rc = smk_bu_inode(inode, MAY_READ, rc); |
| 1050 | return rc; | 1078 | return rc; |
| 1051 | } | 1079 | } |
| 1052 | 1080 | ||
| @@ -1098,7 +1126,9 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name, | |||
| 1098 | 1126 | ||
| 1099 | if (rc == 0 && check_import) { | 1127 | if (rc == 0 && check_import) { |
| 1100 | skp = size ? smk_import_entry(value, size) : NULL; | 1128 | skp = size ? smk_import_entry(value, size) : NULL; |
| 1101 | if (skp == NULL || (check_star && | 1129 | if (IS_ERR(skp)) |
| 1130 | rc = PTR_ERR(skp); | ||
| 1131 | else if (skp == NULL || (check_star && | ||
| 1102 | (skp == &smack_known_star || skp == &smack_known_web))) | 1132 | (skp == &smack_known_star || skp == &smack_known_web))) |
| 1103 | rc = -EINVAL; | 1133 | rc = -EINVAL; |
| 1104 | } | 1134 | } |
| @@ -1107,8 +1137,8 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name, | |||
| 1107 | smk_ad_setfield_u_fs_path_dentry(&ad, dentry); | 1137 | smk_ad_setfield_u_fs_path_dentry(&ad, dentry); |
| 1108 | 1138 | ||
| 1109 | if (rc == 0) { | 1139 | if (rc == 0) { |
| 1110 | rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); | 1140 | rc = smk_curacc(smk_of_inode(d_backing_inode(dentry)), MAY_WRITE, &ad); |
| 1111 | rc = smk_bu_inode(dentry->d_inode, MAY_WRITE, rc); | 1141 | rc = smk_bu_inode(d_backing_inode(dentry), MAY_WRITE, rc); |
| 1112 | } | 1142 | } |
| 1113 | 1143 | ||
| 1114 | return rc; | 1144 | return rc; |
| @@ -1129,7 +1159,7 @@ static void smack_inode_post_setxattr(struct dentry *dentry, const char *name, | |||
| 1129 | const void *value, size_t size, int flags) | 1159 | const void *value, size_t size, int flags) |
| 1130 | { | 1160 | { |
| 1131 | struct smack_known *skp; | 1161 | struct smack_known *skp; |
| 1132 | struct inode_smack *isp = dentry->d_inode->i_security; | 1162 | struct inode_smack *isp = d_backing_inode(dentry)->i_security; |
| 1133 | 1163 | ||
| 1134 | if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) { | 1164 | if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) { |
| 1135 | isp->smk_flags |= SMK_INODE_TRANSMUTE; | 1165 | isp->smk_flags |= SMK_INODE_TRANSMUTE; |
| @@ -1138,19 +1168,19 @@ static void smack_inode_post_setxattr(struct dentry *dentry, const char *name, | |||
| 1138 | 1168 | ||
| 1139 | if (strcmp(name, XATTR_NAME_SMACK) == 0) { | 1169 | if (strcmp(name, XATTR_NAME_SMACK) == 0) { |
| 1140 | skp = smk_import_entry(value, size); | 1170 | skp = smk_import_entry(value, size); |
| 1141 | if (skp != NULL) | 1171 | if (!IS_ERR(skp)) |
| 1142 | isp->smk_inode = skp; | 1172 | isp->smk_inode = skp; |
| 1143 | else | 1173 | else |
| 1144 | isp->smk_inode = &smack_known_invalid; | 1174 | isp->smk_inode = &smack_known_invalid; |
| 1145 | } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) { | 1175 | } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) { |
| 1146 | skp = smk_import_entry(value, size); | 1176 | skp = smk_import_entry(value, size); |
| 1147 | if (skp != NULL) | 1177 | if (!IS_ERR(skp)) |
| 1148 | isp->smk_task = skp; | 1178 | isp->smk_task = skp; |
| 1149 | else | 1179 | else |
| 1150 | isp->smk_task = &smack_known_invalid; | 1180 | isp->smk_task = &smack_known_invalid; |
| 1151 | } else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0) { | 1181 | } else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0) { |
| 1152 | skp = smk_import_entry(value, size); | 1182 | skp = smk_import_entry(value, size); |
| 1153 | if (skp != NULL) | 1183 | if (!IS_ERR(skp)) |
| 1154 | isp->smk_mmap = skp; | 1184 | isp->smk_mmap = skp; |
| 1155 | else | 1185 | else |
| 1156 | isp->smk_mmap = &smack_known_invalid; | 1186 | isp->smk_mmap = &smack_known_invalid; |
| @@ -1174,8 +1204,8 @@ static int smack_inode_getxattr(struct dentry *dentry, const char *name) | |||
| 1174 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); | 1204 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); |
| 1175 | smk_ad_setfield_u_fs_path_dentry(&ad, dentry); | 1205 | smk_ad_setfield_u_fs_path_dentry(&ad, dentry); |
| 1176 | 1206 | ||
| 1177 | rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad); | 1207 | rc = smk_curacc(smk_of_inode(d_backing_inode(dentry)), MAY_READ, &ad); |
| 1178 | rc = smk_bu_inode(dentry->d_inode, MAY_READ, rc); | 1208 | rc = smk_bu_inode(d_backing_inode(dentry), MAY_READ, rc); |
| 1179 | return rc; | 1209 | return rc; |
| 1180 | } | 1210 | } |
| 1181 | 1211 | ||
| @@ -1211,12 +1241,12 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name) | |||
| 1211 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); | 1241 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); |
| 1212 | smk_ad_setfield_u_fs_path_dentry(&ad, dentry); | 1242 | smk_ad_setfield_u_fs_path_dentry(&ad, dentry); |
| 1213 | 1243 | ||
| 1214 | rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); | 1244 | rc = smk_curacc(smk_of_inode(d_backing_inode(dentry)), MAY_WRITE, &ad); |
| 1215 | rc = smk_bu_inode(dentry->d_inode, MAY_WRITE, rc); | 1245 | rc = smk_bu_inode(d_backing_inode(dentry), MAY_WRITE, rc); |
| 1216 | if (rc != 0) | 1246 | if (rc != 0) |
| 1217 | return rc; | 1247 | return rc; |
| 1218 | 1248 | ||
| 1219 | isp = dentry->d_inode->i_security; | 1249 | isp = d_backing_inode(dentry)->i_security; |
| 1220 | /* | 1250 | /* |
| 1221 | * Don't do anything special for these. | 1251 | * Don't do anything special for these. |
| 1222 | * XATTR_NAME_SMACKIPIN | 1252 | * XATTR_NAME_SMACKIPIN |
| @@ -1638,6 +1668,9 @@ static int smack_file_receive(struct file *file) | |||
| 1638 | struct smk_audit_info ad; | 1668 | struct smk_audit_info ad; |
| 1639 | struct inode *inode = file_inode(file); | 1669 | struct inode *inode = file_inode(file); |
| 1640 | 1670 | ||
| 1671 | if (unlikely(IS_PRIVATE(inode))) | ||
| 1672 | return 0; | ||
| 1673 | |||
| 1641 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); | 1674 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); |
| 1642 | smk_ad_setfield_u_fs_path(&ad, file->f_path); | 1675 | smk_ad_setfield_u_fs_path(&ad, file->f_path); |
| 1643 | /* | 1676 | /* |
| @@ -1899,12 +1932,7 @@ static void smack_task_getsecid(struct task_struct *p, u32 *secid) | |||
| 1899 | */ | 1932 | */ |
| 1900 | static int smack_task_setnice(struct task_struct *p, int nice) | 1933 | static int smack_task_setnice(struct task_struct *p, int nice) |
| 1901 | { | 1934 | { |
| 1902 | int rc; | 1935 | return smk_curacc_on_task(p, MAY_WRITE, __func__); |
| 1903 | |||
| 1904 | rc = cap_task_setnice(p, nice); | ||
| 1905 | if (rc == 0) | ||
| 1906 | rc = smk_curacc_on_task(p, MAY_WRITE, __func__); | ||
| 1907 | return rc; | ||
| 1908 | } | 1936 | } |
| 1909 | 1937 | ||
| 1910 | /** | 1938 | /** |
| @@ -1916,12 +1944,7 @@ static int smack_task_setnice(struct task_struct *p, int nice) | |||
| 1916 | */ | 1944 | */ |
| 1917 | static int smack_task_setioprio(struct task_struct *p, int ioprio) | 1945 | static int smack_task_setioprio(struct task_struct *p, int ioprio) |
| 1918 | { | 1946 | { |
| 1919 | int rc; | 1947 | return smk_curacc_on_task(p, MAY_WRITE, __func__); |
| 1920 | |||
| 1921 | rc = cap_task_setioprio(p, ioprio); | ||
| 1922 | if (rc == 0) | ||
| 1923 | rc = smk_curacc_on_task(p, MAY_WRITE, __func__); | ||
| 1924 | return rc; | ||
| 1925 | } | 1948 | } |
| 1926 | 1949 | ||
| 1927 | /** | 1950 | /** |
| @@ -1945,12 +1968,7 @@ static int smack_task_getioprio(struct task_struct *p) | |||
| 1945 | */ | 1968 | */ |
| 1946 | static int smack_task_setscheduler(struct task_struct *p) | 1969 | static int smack_task_setscheduler(struct task_struct *p) |
| 1947 | { | 1970 | { |
| 1948 | int rc; | 1971 | return smk_curacc_on_task(p, MAY_WRITE, __func__); |
| 1949 | |||
| 1950 | rc = cap_task_setscheduler(p); | ||
| 1951 | if (rc == 0) | ||
| 1952 | rc = smk_curacc_on_task(p, MAY_WRITE, __func__); | ||
| 1953 | return rc; | ||
| 1954 | } | 1972 | } |
| 1955 | 1973 | ||
| 1956 | /** | 1974 | /** |
| @@ -2395,8 +2413,8 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, | |||
| 2395 | return -EINVAL; | 2413 | return -EINVAL; |
| 2396 | 2414 | ||
| 2397 | skp = smk_import_entry(value, size); | 2415 | skp = smk_import_entry(value, size); |
| 2398 | if (skp == NULL) | 2416 | if (IS_ERR(skp)) |
| 2399 | return -EINVAL; | 2417 | return PTR_ERR(skp); |
| 2400 | 2418 | ||
| 2401 | if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) { | 2419 | if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) { |
| 2402 | nsp->smk_inode = skp; | 2420 | nsp->smk_inode = skp; |
| @@ -2452,7 +2470,21 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, | |||
| 2452 | static int smack_socket_post_create(struct socket *sock, int family, | 2470 | static int smack_socket_post_create(struct socket *sock, int family, |
| 2453 | int type, int protocol, int kern) | 2471 | int type, int protocol, int kern) |
| 2454 | { | 2472 | { |
| 2455 | if (family != PF_INET || sock->sk == NULL) | 2473 | struct socket_smack *ssp; |
| 2474 | |||
| 2475 | if (sock->sk == NULL) | ||
| 2476 | return 0; | ||
| 2477 | |||
| 2478 | /* | ||
| 2479 | * Sockets created by kernel threads receive web label. | ||
| 2480 | */ | ||
| 2481 | if (unlikely(current->flags & PF_KTHREAD)) { | ||
| 2482 | ssp = sock->sk->sk_security; | ||
| 2483 | ssp->smk_in = &smack_known_web; | ||
| 2484 | ssp->smk_out = &smack_known_web; | ||
| 2485 | } | ||
| 2486 | |||
| 2487 | if (family != PF_INET) | ||
| 2456 | return 0; | 2488 | return 0; |
| 2457 | /* | 2489 | /* |
| 2458 | * Set the outbound netlbl. | 2490 | * Set the outbound netlbl. |
| @@ -3155,7 +3187,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) | |||
| 3155 | */ | 3187 | */ |
| 3156 | dp = dget(opt_dentry); | 3188 | dp = dget(opt_dentry); |
| 3157 | skp = smk_fetch(XATTR_NAME_SMACK, inode, dp); | 3189 | skp = smk_fetch(XATTR_NAME_SMACK, inode, dp); |
| 3158 | if (skp != NULL) | 3190 | if (!IS_ERR_OR_NULL(skp)) |
| 3159 | final = skp; | 3191 | final = skp; |
| 3160 | 3192 | ||
| 3161 | /* | 3193 | /* |
| @@ -3192,11 +3224,14 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) | |||
| 3192 | * Don't let the exec or mmap label be "*" or "@". | 3224 | * Don't let the exec or mmap label be "*" or "@". |
| 3193 | */ | 3225 | */ |
| 3194 | skp = smk_fetch(XATTR_NAME_SMACKEXEC, inode, dp); | 3226 | skp = smk_fetch(XATTR_NAME_SMACKEXEC, inode, dp); |
| 3195 | if (skp == &smack_known_star || skp == &smack_known_web) | 3227 | if (IS_ERR(skp) || skp == &smack_known_star || |
| 3228 | skp == &smack_known_web) | ||
| 3196 | skp = NULL; | 3229 | skp = NULL; |
| 3197 | isp->smk_task = skp; | 3230 | isp->smk_task = skp; |
| 3231 | |||
| 3198 | skp = smk_fetch(XATTR_NAME_SMACKMMAP, inode, dp); | 3232 | skp = smk_fetch(XATTR_NAME_SMACKMMAP, inode, dp); |
| 3199 | if (skp == &smack_known_star || skp == &smack_known_web) | 3233 | if (IS_ERR(skp) || skp == &smack_known_star || |
| 3234 | skp == &smack_known_web) | ||
| 3200 | skp = NULL; | 3235 | skp = NULL; |
| 3201 | isp->smk_mmap = skp; | 3236 | isp->smk_mmap = skp; |
| 3202 | 3237 | ||
| @@ -3280,8 +3315,8 @@ static int smack_setprocattr(struct task_struct *p, char *name, | |||
| 3280 | return -EINVAL; | 3315 | return -EINVAL; |
| 3281 | 3316 | ||
| 3282 | skp = smk_import_entry(value, size); | 3317 | skp = smk_import_entry(value, size); |
| 3283 | if (skp == NULL) | 3318 | if (IS_ERR(skp)) |
| 3284 | return -EINVAL; | 3319 | return PTR_ERR(skp); |
| 3285 | 3320 | ||
| 3286 | /* | 3321 | /* |
| 3287 | * No process is ever allowed the web ("@") label. | 3322 | * No process is ever allowed the web ("@") label. |
| @@ -3986,6 +4021,36 @@ static int smack_key_permission(key_ref_t key_ref, | |||
| 3986 | rc = smk_bu_note("key access", tkp, keyp->security, request, rc); | 4021 | rc = smk_bu_note("key access", tkp, keyp->security, request, rc); |
| 3987 | return rc; | 4022 | return rc; |
| 3988 | } | 4023 | } |
| 4024 | |||
| 4025 | /* | ||
| 4026 | * smack_key_getsecurity - Smack label tagging the key | ||
| 4027 | * @key points to the key to be queried | ||
| 4028 | * @_buffer points to a pointer that should be set to point to the | ||
| 4029 | * resulting string (if no label or an error occurs). | ||
| 4030 | * Return the length of the string (including terminating NUL) or -ve if | ||
| 4031 | * an error. | ||
| 4032 | * May also return 0 (and a NULL buffer pointer) if there is no label. | ||
| 4033 | */ | ||
| 4034 | static int smack_key_getsecurity(struct key *key, char **_buffer) | ||
| 4035 | { | ||
| 4036 | struct smack_known *skp = key->security; | ||
| 4037 | size_t length; | ||
| 4038 | char *copy; | ||
| 4039 | |||
| 4040 | if (key->security == NULL) { | ||
| 4041 | *_buffer = NULL; | ||
| 4042 | return 0; | ||
| 4043 | } | ||
| 4044 | |||
| 4045 | copy = kstrdup(skp->smk_known, GFP_KERNEL); | ||
| 4046 | if (copy == NULL) | ||
| 4047 | return -ENOMEM; | ||
| 4048 | length = strlen(copy) + 1; | ||
| 4049 | |||
| 4050 | *_buffer = copy; | ||
| 4051 | return length; | ||
| 4052 | } | ||
| 4053 | |||
| 3989 | #endif /* CONFIG_KEYS */ | 4054 | #endif /* CONFIG_KEYS */ |
| 3990 | 4055 | ||
| 3991 | /* | 4056 | /* |
| @@ -4026,8 +4091,10 @@ static int smack_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) | |||
| 4026 | return -EINVAL; | 4091 | return -EINVAL; |
| 4027 | 4092 | ||
| 4028 | skp = smk_import_entry(rulestr, 0); | 4093 | skp = smk_import_entry(rulestr, 0); |
| 4029 | if (skp) | 4094 | if (IS_ERR(skp)) |
| 4030 | *rule = skp->smk_known; | 4095 | return PTR_ERR(skp); |
| 4096 | |||
| 4097 | *rule = skp->smk_known; | ||
| 4031 | 4098 | ||
| 4032 | return 0; | 4099 | return 0; |
| 4033 | } | 4100 | } |
| @@ -4187,146 +4254,145 @@ static int smack_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen) | |||
| 4187 | return 0; | 4254 | return 0; |
| 4188 | } | 4255 | } |
| 4189 | 4256 | ||
| 4190 | struct security_operations smack_ops = { | 4257 | struct security_hook_list smack_hooks[] = { |
| 4191 | .name = "smack", | 4258 | LSM_HOOK_INIT(ptrace_access_check, smack_ptrace_access_check), |
| 4192 | 4259 | LSM_HOOK_INIT(ptrace_traceme, smack_ptrace_traceme), | |
| 4193 | .ptrace_access_check = smack_ptrace_access_check, | 4260 | LSM_HOOK_INIT(syslog, smack_syslog), |
| 4194 | .ptrace_traceme = smack_ptrace_traceme, | 4261 | |
| 4195 | .syslog = smack_syslog, | 4262 | LSM_HOOK_INIT(sb_alloc_security, smack_sb_alloc_security), |
| 4196 | 4263 | LSM_HOOK_INIT(sb_free_security, smack_sb_free_security), | |
| 4197 | .sb_alloc_security = smack_sb_alloc_security, | 4264 | LSM_HOOK_INIT(sb_copy_data, smack_sb_copy_data), |
| 4198 | .sb_free_security = smack_sb_free_security, | 4265 | LSM_HOOK_INIT(sb_kern_mount, smack_sb_kern_mount), |
| 4199 | .sb_copy_data = smack_sb_copy_data, | 4266 | LSM_HOOK_INIT(sb_statfs, smack_sb_statfs), |
| 4200 | .sb_kern_mount = smack_sb_kern_mount, | 4267 | |
| 4201 | .sb_statfs = smack_sb_statfs, | 4268 | LSM_HOOK_INIT(bprm_set_creds, smack_bprm_set_creds), |
| 4202 | 4269 | LSM_HOOK_INIT(bprm_committing_creds, smack_bprm_committing_creds), | |
| 4203 | .bprm_set_creds = smack_bprm_set_creds, | 4270 | LSM_HOOK_INIT(bprm_secureexec, smack_bprm_secureexec), |
| 4204 | .bprm_committing_creds = smack_bprm_committing_creds, | 4271 | |
| 4205 | .bprm_secureexec = smack_bprm_secureexec, | 4272 | LSM_HOOK_INIT(inode_alloc_security, smack_inode_alloc_security), |
| 4206 | 4273 | LSM_HOOK_INIT(inode_free_security, smack_inode_free_security), | |
| 4207 | .inode_alloc_security = smack_inode_alloc_security, | 4274 | LSM_HOOK_INIT(inode_init_security, smack_inode_init_security), |
| 4208 | .inode_free_security = smack_inode_free_security, | 4275 | LSM_HOOK_INIT(inode_link, smack_inode_link), |
| 4209 | .inode_init_security = smack_inode_init_security, | 4276 | LSM_HOOK_INIT(inode_unlink, smack_inode_unlink), |
| 4210 | .inode_link = smack_inode_link, | 4277 | LSM_HOOK_INIT(inode_rmdir, smack_inode_rmdir), |
| 4211 | .inode_unlink = smack_inode_unlink, | 4278 | LSM_HOOK_INIT(inode_rename, smack_inode_rename), |
| 4212 | .inode_rmdir = smack_inode_rmdir, | 4279 | LSM_HOOK_INIT(inode_permission, smack_inode_permission), |
| 4213 | .inode_rename = smack_inode_rename, | 4280 | LSM_HOOK_INIT(inode_setattr, smack_inode_setattr), |
| 4214 | .inode_permission = smack_inode_permission, | 4281 | LSM_HOOK_INIT(inode_getattr, smack_inode_getattr), |
| 4215 | .inode_setattr = smack_inode_setattr, | 4282 | LSM_HOOK_INIT(inode_setxattr, smack_inode_setxattr), |
| 4216 | .inode_getattr = smack_inode_getattr, | 4283 | LSM_HOOK_INIT(inode_post_setxattr, smack_inode_post_setxattr), |
| 4217 | .inode_setxattr = smack_inode_setxattr, | 4284 | LSM_HOOK_INIT(inode_getxattr, smack_inode_getxattr), |
| 4218 | .inode_post_setxattr = smack_inode_post_setxattr, | 4285 | LSM_HOOK_INIT(inode_removexattr, smack_inode_removexattr), |
| 4219 | .inode_getxattr = smack_inode_getxattr, | 4286 | LSM_HOOK_INIT(inode_getsecurity, smack_inode_getsecurity), |
| 4220 | .inode_removexattr = smack_inode_removexattr, | 4287 | LSM_HOOK_INIT(inode_setsecurity, smack_inode_setsecurity), |
| 4221 | .inode_getsecurity = smack_inode_getsecurity, | 4288 | LSM_HOOK_INIT(inode_listsecurity, smack_inode_listsecurity), |
| 4222 | .inode_setsecurity = smack_inode_setsecurity, | 4289 | LSM_HOOK_INIT(inode_getsecid, smack_inode_getsecid), |
| 4223 | .inode_listsecurity = smack_inode_listsecurity, | 4290 | |
| 4224 | .inode_getsecid = smack_inode_getsecid, | 4291 | LSM_HOOK_INIT(file_permission, smack_file_permission), |
| 4225 | 4292 | LSM_HOOK_INIT(file_alloc_security, smack_file_alloc_security), | |
| 4226 | .file_permission = smack_file_permission, | 4293 | LSM_HOOK_INIT(file_free_security, smack_file_free_security), |
| 4227 | .file_alloc_security = smack_file_alloc_security, | 4294 | LSM_HOOK_INIT(file_ioctl, smack_file_ioctl), |
| 4228 | .file_free_security = smack_file_free_security, | 4295 | LSM_HOOK_INIT(file_lock, smack_file_lock), |
| 4229 | .file_ioctl = smack_file_ioctl, | 4296 | LSM_HOOK_INIT(file_fcntl, smack_file_fcntl), |
| 4230 | .file_lock = smack_file_lock, | 4297 | LSM_HOOK_INIT(mmap_file, smack_mmap_file), |
| 4231 | .file_fcntl = smack_file_fcntl, | 4298 | LSM_HOOK_INIT(mmap_addr, cap_mmap_addr), |
| 4232 | .mmap_file = smack_mmap_file, | 4299 | LSM_HOOK_INIT(file_set_fowner, smack_file_set_fowner), |
| 4233 | .mmap_addr = cap_mmap_addr, | 4300 | LSM_HOOK_INIT(file_send_sigiotask, smack_file_send_sigiotask), |
| 4234 | .file_set_fowner = smack_file_set_fowner, | 4301 | LSM_HOOK_INIT(file_receive, smack_file_receive), |
| 4235 | .file_send_sigiotask = smack_file_send_sigiotask, | 4302 | |
| 4236 | .file_receive = smack_file_receive, | 4303 | LSM_HOOK_INIT(file_open, smack_file_open), |
| 4237 | 4304 | ||
| 4238 | .file_open = smack_file_open, | 4305 | LSM_HOOK_INIT(cred_alloc_blank, smack_cred_alloc_blank), |
| 4239 | 4306 | LSM_HOOK_INIT(cred_free, smack_cred_free), | |
| 4240 | .cred_alloc_blank = smack_cred_alloc_blank, | 4307 | LSM_HOOK_INIT(cred_prepare, smack_cred_prepare), |
| 4241 | .cred_free = smack_cred_free, | 4308 | LSM_HOOK_INIT(cred_transfer, smack_cred_transfer), |
| 4242 | .cred_prepare = smack_cred_prepare, | 4309 | LSM_HOOK_INIT(kernel_act_as, smack_kernel_act_as), |
| 4243 | .cred_transfer = smack_cred_transfer, | 4310 | LSM_HOOK_INIT(kernel_create_files_as, smack_kernel_create_files_as), |
| 4244 | .kernel_act_as = smack_kernel_act_as, | 4311 | LSM_HOOK_INIT(task_setpgid, smack_task_setpgid), |
| 4245 | .kernel_create_files_as = smack_kernel_create_files_as, | 4312 | LSM_HOOK_INIT(task_getpgid, smack_task_getpgid), |
| 4246 | .task_setpgid = smack_task_setpgid, | 4313 | LSM_HOOK_INIT(task_getsid, smack_task_getsid), |
| 4247 | .task_getpgid = smack_task_getpgid, | 4314 | LSM_HOOK_INIT(task_getsecid, smack_task_getsecid), |
| 4248 | .task_getsid = smack_task_getsid, | 4315 | LSM_HOOK_INIT(task_setnice, smack_task_setnice), |
| 4249 | .task_getsecid = smack_task_getsecid, | 4316 | LSM_HOOK_INIT(task_setioprio, smack_task_setioprio), |
| 4250 | .task_setnice = smack_task_setnice, | 4317 | LSM_HOOK_INIT(task_getioprio, smack_task_getioprio), |
| 4251 | .task_setioprio = smack_task_setioprio, | 4318 | LSM_HOOK_INIT(task_setscheduler, smack_task_setscheduler), |
| 4252 | .task_getioprio = smack_task_getioprio, | 4319 | LSM_HOOK_INIT(task_getscheduler, smack_task_getscheduler), |
| 4253 | .task_setscheduler = smack_task_setscheduler, | 4320 | LSM_HOOK_INIT(task_movememory, smack_task_movememory), |
| 4254 | .task_getscheduler = smack_task_getscheduler, | 4321 | LSM_HOOK_INIT(task_kill, smack_task_kill), |
| 4255 | .task_movememory = smack_task_movememory, | 4322 | LSM_HOOK_INIT(task_wait, smack_task_wait), |
| 4256 | .task_kill = smack_task_kill, | 4323 | LSM_HOOK_INIT(task_to_inode, smack_task_to_inode), |
| 4257 | .task_wait = smack_task_wait, | 4324 | |
| 4258 | .task_to_inode = smack_task_to_inode, | 4325 | LSM_HOOK_INIT(ipc_permission, smack_ipc_permission), |
| 4259 | 4326 | LSM_HOOK_INIT(ipc_getsecid, smack_ipc_getsecid), | |
| 4260 | .ipc_permission = smack_ipc_permission, | 4327 | |
| 4261 | .ipc_getsecid = smack_ipc_getsecid, | 4328 | LSM_HOOK_INIT(msg_msg_alloc_security, smack_msg_msg_alloc_security), |
| 4262 | 4329 | LSM_HOOK_INIT(msg_msg_free_security, smack_msg_msg_free_security), | |
| 4263 | .msg_msg_alloc_security = smack_msg_msg_alloc_security, | 4330 | |
| 4264 | .msg_msg_free_security = smack_msg_msg_free_security, | 4331 | LSM_HOOK_INIT(msg_queue_alloc_security, smack_msg_queue_alloc_security), |
| 4265 | 4332 | LSM_HOOK_INIT(msg_queue_free_security, smack_msg_queue_free_security), | |
| 4266 | .msg_queue_alloc_security = smack_msg_queue_alloc_security, | 4333 | LSM_HOOK_INIT(msg_queue_associate, smack_msg_queue_associate), |
| 4267 | .msg_queue_free_security = smack_msg_queue_free_security, | 4334 | LSM_HOOK_INIT(msg_queue_msgctl, smack_msg_queue_msgctl), |
| 4268 | .msg_queue_associate = smack_msg_queue_associate, | 4335 | LSM_HOOK_INIT(msg_queue_msgsnd, smack_msg_queue_msgsnd), |
| 4269 | .msg_queue_msgctl = smack_msg_queue_msgctl, | 4336 | LSM_HOOK_INIT(msg_queue_msgrcv, smack_msg_queue_msgrcv), |
| 4270 | .msg_queue_msgsnd = smack_msg_queue_msgsnd, | 4337 | |
| 4271 | .msg_queue_msgrcv = smack_msg_queue_msgrcv, | 4338 | LSM_HOOK_INIT(shm_alloc_security, smack_shm_alloc_security), |
| 4272 | 4339 | LSM_HOOK_INIT(shm_free_security, smack_shm_free_security), | |
| 4273 | .shm_alloc_security = smack_shm_alloc_security, | 4340 | LSM_HOOK_INIT(shm_associate, smack_shm_associate), |
| 4274 | .shm_free_security = smack_shm_free_security, | 4341 | LSM_HOOK_INIT(shm_shmctl, smack_shm_shmctl), |
| 4275 | .shm_associate = smack_shm_associate, | 4342 | LSM_HOOK_INIT(shm_shmat, smack_shm_shmat), |
| 4276 | .shm_shmctl = smack_shm_shmctl, | 4343 | |
| 4277 | .shm_shmat = smack_shm_shmat, | 4344 | LSM_HOOK_INIT(sem_alloc_security, smack_sem_alloc_security), |
| 4278 | 4345 | LSM_HOOK_INIT(sem_free_security, smack_sem_free_security), | |
| 4279 | .sem_alloc_security = smack_sem_alloc_security, | 4346 | LSM_HOOK_INIT(sem_associate, smack_sem_associate), |
| 4280 | .sem_free_security = smack_sem_free_security, | 4347 | LSM_HOOK_INIT(sem_semctl, smack_sem_semctl), |
| 4281 | .sem_associate = smack_sem_associate, | 4348 | LSM_HOOK_INIT(sem_semop, smack_sem_semop), |
| 4282 | .sem_semctl = smack_sem_semctl, | 4349 | |
| 4283 | .sem_semop = smack_sem_semop, | 4350 | LSM_HOOK_INIT(d_instantiate, smack_d_instantiate), |
| 4284 | 4351 | ||
| 4285 | .d_instantiate = smack_d_instantiate, | 4352 | LSM_HOOK_INIT(getprocattr, smack_getprocattr), |
| 4286 | 4353 | LSM_HOOK_INIT(setprocattr, smack_setprocattr), | |
| 4287 | .getprocattr = smack_getprocattr, | 4354 | |
| 4288 | .setprocattr = smack_setprocattr, | 4355 | LSM_HOOK_INIT(unix_stream_connect, smack_unix_stream_connect), |
| 4289 | 4356 | LSM_HOOK_INIT(unix_may_send, smack_unix_may_send), | |
| 4290 | .unix_stream_connect = smack_unix_stream_connect, | 4357 | |
| 4291 | .unix_may_send = smack_unix_may_send, | 4358 | LSM_HOOK_INIT(socket_post_create, smack_socket_post_create), |
| 4292 | |||
| 4293 | .socket_post_create = smack_socket_post_create, | ||
| 4294 | #ifndef CONFIG_SECURITY_SMACK_NETFILTER | 4359 | #ifndef CONFIG_SECURITY_SMACK_NETFILTER |
| 4295 | .socket_bind = smack_socket_bind, | 4360 | LSM_HOOK_INIT(socket_bind, smack_socket_bind), |
| 4296 | #endif /* CONFIG_SECURITY_SMACK_NETFILTER */ | 4361 | #endif /* CONFIG_SECURITY_SMACK_NETFILTER */ |
| 4297 | .socket_connect = smack_socket_connect, | 4362 | LSM_HOOK_INIT(socket_connect, smack_socket_connect), |
| 4298 | .socket_sendmsg = smack_socket_sendmsg, | 4363 | LSM_HOOK_INIT(socket_sendmsg, smack_socket_sendmsg), |
| 4299 | .socket_sock_rcv_skb = smack_socket_sock_rcv_skb, | 4364 | LSM_HOOK_INIT(socket_sock_rcv_skb, smack_socket_sock_rcv_skb), |
| 4300 | .socket_getpeersec_stream = smack_socket_getpeersec_stream, | 4365 | LSM_HOOK_INIT(socket_getpeersec_stream, smack_socket_getpeersec_stream), |
| 4301 | .socket_getpeersec_dgram = smack_socket_getpeersec_dgram, | 4366 | LSM_HOOK_INIT(socket_getpeersec_dgram, smack_socket_getpeersec_dgram), |
| 4302 | .sk_alloc_security = smack_sk_alloc_security, | 4367 | LSM_HOOK_INIT(sk_alloc_security, smack_sk_alloc_security), |
| 4303 | .sk_free_security = smack_sk_free_security, | 4368 | LSM_HOOK_INIT(sk_free_security, smack_sk_free_security), |
| 4304 | .sock_graft = smack_sock_graft, | 4369 | LSM_HOOK_INIT(sock_graft, smack_sock_graft), |
| 4305 | .inet_conn_request = smack_inet_conn_request, | 4370 | LSM_HOOK_INIT(inet_conn_request, smack_inet_conn_request), |
| 4306 | .inet_csk_clone = smack_inet_csk_clone, | 4371 | LSM_HOOK_INIT(inet_csk_clone, smack_inet_csk_clone), |
| 4307 | 4372 | ||
| 4308 | /* key management security hooks */ | 4373 | /* key management security hooks */ |
| 4309 | #ifdef CONFIG_KEYS | 4374 | #ifdef CONFIG_KEYS |
| 4310 | .key_alloc = smack_key_alloc, | 4375 | LSM_HOOK_INIT(key_alloc, smack_key_alloc), |
| 4311 | .key_free = smack_key_free, | 4376 | LSM_HOOK_INIT(key_free, smack_key_free), |
| 4312 | .key_permission = smack_key_permission, | 4377 | LSM_HOOK_INIT(key_permission, smack_key_permission), |
| 4378 | LSM_HOOK_INIT(key_getsecurity, smack_key_getsecurity), | ||
| 4313 | #endif /* CONFIG_KEYS */ | 4379 | #endif /* CONFIG_KEYS */ |
| 4314 | 4380 | ||
| 4315 | /* Audit hooks */ | 4381 | /* Audit hooks */ |
| 4316 | #ifdef CONFIG_AUDIT | 4382 | #ifdef CONFIG_AUDIT |
| 4317 | .audit_rule_init = smack_audit_rule_init, | 4383 | LSM_HOOK_INIT(audit_rule_init, smack_audit_rule_init), |
| 4318 | .audit_rule_known = smack_audit_rule_known, | 4384 | LSM_HOOK_INIT(audit_rule_known, smack_audit_rule_known), |
| 4319 | .audit_rule_match = smack_audit_rule_match, | 4385 | LSM_HOOK_INIT(audit_rule_match, smack_audit_rule_match), |
| 4320 | .audit_rule_free = smack_audit_rule_free, | 4386 | LSM_HOOK_INIT(audit_rule_free, smack_audit_rule_free), |
| 4321 | #endif /* CONFIG_AUDIT */ | 4387 | #endif /* CONFIG_AUDIT */ |
| 4322 | 4388 | ||
| 4323 | .ismaclabel = smack_ismaclabel, | 4389 | LSM_HOOK_INIT(ismaclabel, smack_ismaclabel), |
| 4324 | .secid_to_secctx = smack_secid_to_secctx, | 4390 | LSM_HOOK_INIT(secid_to_secctx, smack_secid_to_secctx), |
| 4325 | .secctx_to_secid = smack_secctx_to_secid, | 4391 | LSM_HOOK_INIT(secctx_to_secid, smack_secctx_to_secid), |
| 4326 | .release_secctx = smack_release_secctx, | 4392 | LSM_HOOK_INIT(release_secctx, smack_release_secctx), |
| 4327 | .inode_notifysecctx = smack_inode_notifysecctx, | 4393 | LSM_HOOK_INIT(inode_notifysecctx, smack_inode_notifysecctx), |
| 4328 | .inode_setsecctx = smack_inode_setsecctx, | 4394 | LSM_HOOK_INIT(inode_setsecctx, smack_inode_setsecctx), |
| 4329 | .inode_getsecctx = smack_inode_getsecctx, | 4395 | LSM_HOOK_INIT(inode_getsecctx, smack_inode_getsecctx), |
| 4330 | }; | 4396 | }; |
| 4331 | 4397 | ||
| 4332 | 4398 | ||
| @@ -4371,7 +4437,7 @@ static __init int smack_init(void) | |||
| 4371 | struct cred *cred; | 4437 | struct cred *cred; |
| 4372 | struct task_smack *tsp; | 4438 | struct task_smack *tsp; |
| 4373 | 4439 | ||
| 4374 | if (!security_module_enable(&smack_ops)) | 4440 | if (!security_module_enable("smack")) |
| 4375 | return 0; | 4441 | return 0; |
| 4376 | 4442 | ||
| 4377 | smack_enabled = 1; | 4443 | smack_enabled = 1; |
| @@ -4401,8 +4467,7 @@ static __init int smack_init(void) | |||
| 4401 | /* | 4467 | /* |
| 4402 | * Register with LSM | 4468 | * Register with LSM |
| 4403 | */ | 4469 | */ |
| 4404 | if (register_security(&smack_ops)) | 4470 | security_add_hooks(smack_hooks, ARRAY_SIZE(smack_hooks)); |
| 4405 | panic("smack: Unable to register with kernel.\n"); | ||
| 4406 | 4471 | ||
| 4407 | return 0; | 4472 | return 0; |
| 4408 | } | 4473 | } |
diff --git a/security/smack/smack_netfilter.c b/security/smack/smack_netfilter.c index c952632afb0d..a455cfc9ec1f 100644 --- a/security/smack/smack_netfilter.c +++ b/security/smack/smack_netfilter.c | |||
| @@ -23,9 +23,7 @@ | |||
| 23 | 23 | ||
| 24 | static unsigned int smack_ipv6_output(const struct nf_hook_ops *ops, | 24 | static unsigned int smack_ipv6_output(const struct nf_hook_ops *ops, |
| 25 | struct sk_buff *skb, | 25 | struct sk_buff *skb, |
| 26 | const struct net_device *in, | 26 | const struct nf_hook_state *state) |
| 27 | const struct net_device *out, | ||
| 28 | int (*okfn)(struct sk_buff *)) | ||
| 29 | { | 27 | { |
| 30 | struct socket_smack *ssp; | 28 | struct socket_smack *ssp; |
| 31 | struct smack_known *skp; | 29 | struct smack_known *skp; |
| @@ -42,9 +40,7 @@ static unsigned int smack_ipv6_output(const struct nf_hook_ops *ops, | |||
| 42 | 40 | ||
| 43 | static unsigned int smack_ipv4_output(const struct nf_hook_ops *ops, | 41 | static unsigned int smack_ipv4_output(const struct nf_hook_ops *ops, |
| 44 | struct sk_buff *skb, | 42 | struct sk_buff *skb, |
| 45 | const struct net_device *in, | 43 | const struct nf_hook_state *state) |
| 46 | const struct net_device *out, | ||
| 47 | int (*okfn)(struct sk_buff *)) | ||
| 48 | { | 44 | { |
| 49 | struct socket_smack *ssp; | 45 | struct socket_smack *ssp; |
| 50 | struct smack_known *skp; | 46 | struct smack_known *skp; |
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index bce4e8f1b267..2716d02119f3 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c | |||
| @@ -54,6 +54,9 @@ enum smk_inos { | |||
| 54 | SMK_CHANGE_RULE = 19, /* change or add rules (long labels) */ | 54 | SMK_CHANGE_RULE = 19, /* change or add rules (long labels) */ |
| 55 | SMK_SYSLOG = 20, /* change syslog label) */ | 55 | SMK_SYSLOG = 20, /* change syslog label) */ |
| 56 | SMK_PTRACE = 21, /* set ptrace rule */ | 56 | SMK_PTRACE = 21, /* set ptrace rule */ |
| 57 | #ifdef CONFIG_SECURITY_SMACK_BRINGUP | ||
| 58 | SMK_UNCONFINED = 22, /* define an unconfined label */ | ||
| 59 | #endif | ||
| 57 | }; | 60 | }; |
| 58 | 61 | ||
| 59 | /* | 62 | /* |
| @@ -61,7 +64,6 @@ enum smk_inos { | |||
| 61 | */ | 64 | */ |
| 62 | static DEFINE_MUTEX(smack_cipso_lock); | 65 | static DEFINE_MUTEX(smack_cipso_lock); |
| 63 | static DEFINE_MUTEX(smack_ambient_lock); | 66 | static DEFINE_MUTEX(smack_ambient_lock); |
| 64 | static DEFINE_MUTEX(smack_syslog_lock); | ||
| 65 | static DEFINE_MUTEX(smk_netlbladdr_lock); | 67 | static DEFINE_MUTEX(smk_netlbladdr_lock); |
| 66 | 68 | ||
| 67 | /* | 69 | /* |
| @@ -85,15 +87,15 @@ int smack_cipso_direct = SMACK_CIPSO_DIRECT_DEFAULT; | |||
| 85 | */ | 87 | */ |
| 86 | int smack_cipso_mapped = SMACK_CIPSO_MAPPED_DEFAULT; | 88 | int smack_cipso_mapped = SMACK_CIPSO_MAPPED_DEFAULT; |
| 87 | 89 | ||
| 90 | #ifdef CONFIG_SECURITY_SMACK_BRINGUP | ||
| 88 | /* | 91 | /* |
| 89 | * Unless a process is running with this label even | 92 | * Allow one label to be unconfined. This is for |
| 90 | * having CAP_MAC_OVERRIDE isn't enough to grant | 93 | * debugging and application bring-up purposes only. |
| 91 | * privilege to violate MAC policy. If no label is | 94 | * It is bad and wrong, but everyone seems to expect |
| 92 | * designated (the NULL case) capabilities apply to | 95 | * to have it. |
| 93 | * everyone. It is expected that the hat (^) label | ||
| 94 | * will be used if any label is used. | ||
| 95 | */ | 96 | */ |
| 96 | struct smack_known *smack_onlycap; | 97 | struct smack_known *smack_unconfined; |
| 98 | #endif | ||
| 97 | 99 | ||
| 98 | /* | 100 | /* |
| 99 | * If this value is set restrict syslog use to the label specified. | 101 | * If this value is set restrict syslog use to the label specified. |
| @@ -326,8 +328,7 @@ static int smk_perm_from_str(const char *string) | |||
| 326 | * @import: if non-zero, import labels | 328 | * @import: if non-zero, import labels |
| 327 | * @len: label length limit | 329 | * @len: label length limit |
| 328 | * | 330 | * |
| 329 | * Returns 0 on success, -EINVAL on failure and -ENOENT when either subject | 331 | * Returns 0 on success, appropriate error code on failure. |
| 330 | * or object is missing. | ||
| 331 | */ | 332 | */ |
| 332 | static int smk_fill_rule(const char *subject, const char *object, | 333 | static int smk_fill_rule(const char *subject, const char *object, |
| 333 | const char *access1, const char *access2, | 334 | const char *access1, const char *access2, |
| @@ -339,16 +340,16 @@ static int smk_fill_rule(const char *subject, const char *object, | |||
| 339 | 340 | ||
| 340 | if (import) { | 341 | if (import) { |
| 341 | rule->smk_subject = smk_import_entry(subject, len); | 342 | rule->smk_subject = smk_import_entry(subject, len); |
| 342 | if (rule->smk_subject == NULL) | 343 | if (IS_ERR(rule->smk_subject)) |
| 343 | return -EINVAL; | 344 | return PTR_ERR(rule->smk_subject); |
| 344 | 345 | ||
| 345 | rule->smk_object = smk_import_entry(object, len); | 346 | rule->smk_object = smk_import_entry(object, len); |
| 346 | if (rule->smk_object == NULL) | 347 | if (IS_ERR(rule->smk_object)) |
| 347 | return -EINVAL; | 348 | return PTR_ERR(rule->smk_object); |
| 348 | } else { | 349 | } else { |
| 349 | cp = smk_parse_smack(subject, len); | 350 | cp = smk_parse_smack(subject, len); |
| 350 | if (cp == NULL) | 351 | if (IS_ERR(cp)) |
| 351 | return -EINVAL; | 352 | return PTR_ERR(cp); |
| 352 | skp = smk_find_entry(cp); | 353 | skp = smk_find_entry(cp); |
| 353 | kfree(cp); | 354 | kfree(cp); |
| 354 | if (skp == NULL) | 355 | if (skp == NULL) |
| @@ -356,8 +357,8 @@ static int smk_fill_rule(const char *subject, const char *object, | |||
| 356 | rule->smk_subject = skp; | 357 | rule->smk_subject = skp; |
| 357 | 358 | ||
| 358 | cp = smk_parse_smack(object, len); | 359 | cp = smk_parse_smack(object, len); |
| 359 | if (cp == NULL) | 360 | if (IS_ERR(cp)) |
| 360 | return -EINVAL; | 361 | return PTR_ERR(cp); |
| 361 | skp = smk_find_entry(cp); | 362 | skp = smk_find_entry(cp); |
| 362 | kfree(cp); | 363 | kfree(cp); |
| 363 | if (skp == NULL) | 364 | if (skp == NULL) |
| @@ -400,7 +401,7 @@ static int smk_parse_rule(const char *data, struct smack_parsed_rule *rule, | |||
| 400 | * @import: if non-zero, import labels | 401 | * @import: if non-zero, import labels |
| 401 | * @tokens: numer of substrings expected in data | 402 | * @tokens: numer of substrings expected in data |
| 402 | * | 403 | * |
| 403 | * Returns number of processed bytes on success, -1 on failure. | 404 | * Returns number of processed bytes on success, -ERRNO on failure. |
| 404 | */ | 405 | */ |
| 405 | static ssize_t smk_parse_long_rule(char *data, struct smack_parsed_rule *rule, | 406 | static ssize_t smk_parse_long_rule(char *data, struct smack_parsed_rule *rule, |
| 406 | int import, int tokens) | 407 | int import, int tokens) |
| @@ -419,7 +420,7 @@ static ssize_t smk_parse_long_rule(char *data, struct smack_parsed_rule *rule, | |||
| 419 | 420 | ||
| 420 | if (data[cnt] == '\0') | 421 | if (data[cnt] == '\0') |
| 421 | /* Unexpected end of data */ | 422 | /* Unexpected end of data */ |
| 422 | return -1; | 423 | return -EINVAL; |
| 423 | 424 | ||
| 424 | tok[i] = data + cnt; | 425 | tok[i] = data + cnt; |
| 425 | 426 | ||
| @@ -517,14 +518,14 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf, | |||
| 517 | while (cnt < count) { | 518 | while (cnt < count) { |
| 518 | if (format == SMK_FIXED24_FMT) { | 519 | if (format == SMK_FIXED24_FMT) { |
| 519 | rc = smk_parse_rule(data, &rule, 1); | 520 | rc = smk_parse_rule(data, &rule, 1); |
| 520 | if (rc != 0) { | 521 | if (rc < 0) |
| 521 | rc = -EINVAL; | ||
| 522 | goto out; | 522 | goto out; |
| 523 | } | ||
| 524 | cnt = count; | 523 | cnt = count; |
| 525 | } else { | 524 | } else { |
| 526 | rc = smk_parse_long_rule(data + cnt, &rule, 1, tokens); | 525 | rc = smk_parse_long_rule(data + cnt, &rule, 1, tokens); |
| 527 | if (rc <= 0) { | 526 | if (rc < 0) |
| 527 | goto out; | ||
| 528 | if (rc == 0) { | ||
| 528 | rc = -EINVAL; | 529 | rc = -EINVAL; |
| 529 | goto out; | 530 | goto out; |
| 530 | } | 531 | } |
| @@ -555,23 +556,17 @@ static void *smk_seq_start(struct seq_file *s, loff_t *pos, | |||
| 555 | struct list_head *head) | 556 | struct list_head *head) |
| 556 | { | 557 | { |
| 557 | struct list_head *list; | 558 | struct list_head *list; |
| 559 | int i = *pos; | ||
| 560 | |||
| 561 | rcu_read_lock(); | ||
| 562 | for (list = rcu_dereference(list_next_rcu(head)); | ||
| 563 | list != head; | ||
| 564 | list = rcu_dereference(list_next_rcu(list))) { | ||
| 565 | if (i-- == 0) | ||
| 566 | return list; | ||
| 567 | } | ||
| 558 | 568 | ||
| 559 | /* | 569 | return NULL; |
| 560 | * This is 0 the first time through. | ||
| 561 | */ | ||
| 562 | if (s->index == 0) | ||
| 563 | s->private = head; | ||
| 564 | |||
| 565 | if (s->private == NULL) | ||
| 566 | return NULL; | ||
| 567 | |||
| 568 | list = s->private; | ||
| 569 | if (list_empty(list)) | ||
| 570 | return NULL; | ||
| 571 | |||
| 572 | if (s->index == 0) | ||
| 573 | return list->next; | ||
| 574 | return list; | ||
| 575 | } | 570 | } |
| 576 | 571 | ||
| 577 | static void *smk_seq_next(struct seq_file *s, void *v, loff_t *pos, | 572 | static void *smk_seq_next(struct seq_file *s, void *v, loff_t *pos, |
| @@ -579,17 +574,15 @@ static void *smk_seq_next(struct seq_file *s, void *v, loff_t *pos, | |||
| 579 | { | 574 | { |
| 580 | struct list_head *list = v; | 575 | struct list_head *list = v; |
| 581 | 576 | ||
| 582 | if (list_is_last(list, head)) { | 577 | ++*pos; |
| 583 | s->private = NULL; | 578 | list = rcu_dereference(list_next_rcu(list)); |
| 584 | return NULL; | 579 | |
| 585 | } | 580 | return (list == head) ? NULL : list; |
| 586 | s->private = list->next; | ||
| 587 | return list->next; | ||
| 588 | } | 581 | } |
| 589 | 582 | ||
| 590 | static void smk_seq_stop(struct seq_file *s, void *v) | 583 | static void smk_seq_stop(struct seq_file *s, void *v) |
| 591 | { | 584 | { |
| 592 | /* No-op */ | 585 | rcu_read_unlock(); |
| 593 | } | 586 | } |
| 594 | 587 | ||
| 595 | static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max) | 588 | static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max) |
| @@ -649,7 +642,7 @@ static int load_seq_show(struct seq_file *s, void *v) | |||
| 649 | { | 642 | { |
| 650 | struct list_head *list = v; | 643 | struct list_head *list = v; |
| 651 | struct smack_master_list *smlp = | 644 | struct smack_master_list *smlp = |
| 652 | list_entry(list, struct smack_master_list, list); | 645 | list_entry_rcu(list, struct smack_master_list, list); |
| 653 | 646 | ||
| 654 | smk_rule_show(s, smlp->smk_rule, SMK_LABELLEN); | 647 | smk_rule_show(s, smlp->smk_rule, SMK_LABELLEN); |
| 655 | 648 | ||
| @@ -797,7 +790,7 @@ static int cipso_seq_show(struct seq_file *s, void *v) | |||
| 797 | { | 790 | { |
| 798 | struct list_head *list = v; | 791 | struct list_head *list = v; |
| 799 | struct smack_known *skp = | 792 | struct smack_known *skp = |
| 800 | list_entry(list, struct smack_known, list); | 793 | list_entry_rcu(list, struct smack_known, list); |
| 801 | struct netlbl_lsm_catmap *cmp = skp->smk_netlabel.attr.mls.cat; | 794 | struct netlbl_lsm_catmap *cmp = skp->smk_netlabel.attr.mls.cat; |
| 802 | char sep = '/'; | 795 | char sep = '/'; |
| 803 | int i; | 796 | int i; |
| @@ -903,8 +896,10 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf, | |||
| 903 | mutex_lock(&smack_cipso_lock); | 896 | mutex_lock(&smack_cipso_lock); |
| 904 | 897 | ||
| 905 | skp = smk_import_entry(rule, 0); | 898 | skp = smk_import_entry(rule, 0); |
| 906 | if (skp == NULL) | 899 | if (IS_ERR(skp)) { |
| 900 | rc = PTR_ERR(skp); | ||
| 907 | goto out; | 901 | goto out; |
| 902 | } | ||
| 908 | 903 | ||
| 909 | if (format == SMK_FIXED24_FMT) | 904 | if (format == SMK_FIXED24_FMT) |
| 910 | rule += SMK_LABELLEN; | 905 | rule += SMK_LABELLEN; |
| @@ -986,7 +981,7 @@ static int cipso2_seq_show(struct seq_file *s, void *v) | |||
| 986 | { | 981 | { |
| 987 | struct list_head *list = v; | 982 | struct list_head *list = v; |
| 988 | struct smack_known *skp = | 983 | struct smack_known *skp = |
| 989 | list_entry(list, struct smack_known, list); | 984 | list_entry_rcu(list, struct smack_known, list); |
| 990 | struct netlbl_lsm_catmap *cmp = skp->smk_netlabel.attr.mls.cat; | 985 | struct netlbl_lsm_catmap *cmp = skp->smk_netlabel.attr.mls.cat; |
| 991 | char sep = '/'; | 986 | char sep = '/'; |
| 992 | int i; | 987 | int i; |
| @@ -1070,7 +1065,7 @@ static int netlbladdr_seq_show(struct seq_file *s, void *v) | |||
| 1070 | { | 1065 | { |
| 1071 | struct list_head *list = v; | 1066 | struct list_head *list = v; |
| 1072 | struct smk_netlbladdr *skp = | 1067 | struct smk_netlbladdr *skp = |
| 1073 | list_entry(list, struct smk_netlbladdr, list); | 1068 | list_entry_rcu(list, struct smk_netlbladdr, list); |
| 1074 | unsigned char *hp = (char *) &skp->smk_host.sin_addr.s_addr; | 1069 | unsigned char *hp = (char *) &skp->smk_host.sin_addr.s_addr; |
| 1075 | int maskn; | 1070 | int maskn; |
| 1076 | u32 temp_mask = be32_to_cpu(skp->smk_mask.s_addr); | 1071 | u32 temp_mask = be32_to_cpu(skp->smk_mask.s_addr); |
| @@ -1225,8 +1220,8 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf, | |||
| 1225 | */ | 1220 | */ |
| 1226 | if (smack[0] != '-') { | 1221 | if (smack[0] != '-') { |
| 1227 | skp = smk_import_entry(smack, 0); | 1222 | skp = smk_import_entry(smack, 0); |
| 1228 | if (skp == NULL) { | 1223 | if (IS_ERR(skp)) { |
| 1229 | rc = -EINVAL; | 1224 | rc = PTR_ERR(skp); |
| 1230 | goto free_out; | 1225 | goto free_out; |
| 1231 | } | 1226 | } |
| 1232 | } else { | 1227 | } else { |
| @@ -1607,8 +1602,8 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf, | |||
| 1607 | } | 1602 | } |
| 1608 | 1603 | ||
| 1609 | skp = smk_import_entry(data, count); | 1604 | skp = smk_import_entry(data, count); |
| 1610 | if (skp == NULL) { | 1605 | if (IS_ERR(skp)) { |
| 1611 | rc = -EINVAL; | 1606 | rc = PTR_ERR(skp); |
| 1612 | goto out; | 1607 | goto out; |
| 1613 | } | 1608 | } |
| 1614 | 1609 | ||
| @@ -1631,8 +1626,172 @@ static const struct file_operations smk_ambient_ops = { | |||
| 1631 | .llseek = default_llseek, | 1626 | .llseek = default_llseek, |
| 1632 | }; | 1627 | }; |
| 1633 | 1628 | ||
| 1629 | /* | ||
| 1630 | * Seq_file operations for /smack/onlycap | ||
| 1631 | */ | ||
| 1632 | static void *onlycap_seq_start(struct seq_file *s, loff_t *pos) | ||
| 1633 | { | ||
| 1634 | return smk_seq_start(s, pos, &smack_onlycap_list); | ||
| 1635 | } | ||
| 1636 | |||
| 1637 | static void *onlycap_seq_next(struct seq_file *s, void *v, loff_t *pos) | ||
| 1638 | { | ||
| 1639 | return smk_seq_next(s, v, pos, &smack_onlycap_list); | ||
| 1640 | } | ||
| 1641 | |||
| 1642 | static int onlycap_seq_show(struct seq_file *s, void *v) | ||
| 1643 | { | ||
| 1644 | struct list_head *list = v; | ||
| 1645 | struct smack_onlycap *sop = | ||
| 1646 | list_entry_rcu(list, struct smack_onlycap, list); | ||
| 1647 | |||
| 1648 | seq_puts(s, sop->smk_label->smk_known); | ||
| 1649 | seq_putc(s, ' '); | ||
| 1650 | |||
| 1651 | return 0; | ||
| 1652 | } | ||
| 1653 | |||
| 1654 | static const struct seq_operations onlycap_seq_ops = { | ||
| 1655 | .start = onlycap_seq_start, | ||
| 1656 | .next = onlycap_seq_next, | ||
| 1657 | .show = onlycap_seq_show, | ||
| 1658 | .stop = smk_seq_stop, | ||
| 1659 | }; | ||
| 1660 | |||
| 1661 | static int smk_open_onlycap(struct inode *inode, struct file *file) | ||
| 1662 | { | ||
| 1663 | return seq_open(file, &onlycap_seq_ops); | ||
| 1664 | } | ||
| 1665 | |||
| 1634 | /** | 1666 | /** |
| 1635 | * smk_read_onlycap - read() for smackfs/onlycap | 1667 | * smk_list_swap_rcu - swap public list with a private one in RCU-safe way |
| 1668 | * The caller must hold appropriate mutex to prevent concurrent modifications | ||
| 1669 | * to the public list. | ||
| 1670 | * Private list is assumed to be not accessible to other threads yet. | ||
| 1671 | * | ||
| 1672 | * @public: public list | ||
| 1673 | * @private: private list | ||
| 1674 | */ | ||
| 1675 | static void smk_list_swap_rcu(struct list_head *public, | ||
| 1676 | struct list_head *private) | ||
| 1677 | { | ||
| 1678 | struct list_head *first, *last; | ||
| 1679 | |||
| 1680 | if (list_empty(public)) { | ||
| 1681 | list_splice_init_rcu(private, public, synchronize_rcu); | ||
| 1682 | } else { | ||
| 1683 | /* Remember public list before replacing it */ | ||
| 1684 | first = public->next; | ||
| 1685 | last = public->prev; | ||
| 1686 | |||
| 1687 | /* Publish private list in place of public in RCU-safe way */ | ||
| 1688 | private->prev->next = public; | ||
| 1689 | private->next->prev = public; | ||
| 1690 | rcu_assign_pointer(public->next, private->next); | ||
| 1691 | public->prev = private->prev; | ||
| 1692 | |||
| 1693 | synchronize_rcu(); | ||
| 1694 | |||
| 1695 | /* When all readers are done with the old public list, | ||
| 1696 | * attach it in place of private */ | ||
| 1697 | private->next = first; | ||
| 1698 | private->prev = last; | ||
| 1699 | first->prev = private; | ||
| 1700 | last->next = private; | ||
| 1701 | } | ||
| 1702 | } | ||
| 1703 | |||
| 1704 | /** | ||
| 1705 | * smk_write_onlycap - write() for smackfs/onlycap | ||
| 1706 | * @file: file pointer, not actually used | ||
| 1707 | * @buf: where to get the data from | ||
| 1708 | * @count: bytes sent | ||
| 1709 | * @ppos: where to start | ||
| 1710 | * | ||
| 1711 | * Returns number of bytes written or error code, as appropriate | ||
| 1712 | */ | ||
| 1713 | static ssize_t smk_write_onlycap(struct file *file, const char __user *buf, | ||
| 1714 | size_t count, loff_t *ppos) | ||
| 1715 | { | ||
| 1716 | char *data; | ||
| 1717 | char *data_parse; | ||
| 1718 | char *tok; | ||
| 1719 | struct smack_known *skp; | ||
| 1720 | struct smack_onlycap *sop; | ||
| 1721 | struct smack_onlycap *sop2; | ||
| 1722 | LIST_HEAD(list_tmp); | ||
| 1723 | int rc = count; | ||
| 1724 | |||
| 1725 | if (!smack_privileged(CAP_MAC_ADMIN)) | ||
| 1726 | return -EPERM; | ||
| 1727 | |||
| 1728 | data = kzalloc(count + 1, GFP_KERNEL); | ||
| 1729 | if (data == NULL) | ||
| 1730 | return -ENOMEM; | ||
| 1731 | |||
| 1732 | if (copy_from_user(data, buf, count) != 0) { | ||
| 1733 | kfree(data); | ||
| 1734 | return -EFAULT; | ||
| 1735 | } | ||
| 1736 | |||
| 1737 | data_parse = data; | ||
| 1738 | while ((tok = strsep(&data_parse, " ")) != NULL) { | ||
| 1739 | if (!*tok) | ||
| 1740 | continue; | ||
| 1741 | |||
| 1742 | skp = smk_import_entry(tok, 0); | ||
| 1743 | if (IS_ERR(skp)) { | ||
| 1744 | rc = PTR_ERR(skp); | ||
| 1745 | break; | ||
| 1746 | } | ||
| 1747 | |||
| 1748 | sop = kzalloc(sizeof(*sop), GFP_KERNEL); | ||
| 1749 | if (sop == NULL) { | ||
| 1750 | rc = -ENOMEM; | ||
| 1751 | break; | ||
| 1752 | } | ||
| 1753 | |||
| 1754 | sop->smk_label = skp; | ||
| 1755 | list_add_rcu(&sop->list, &list_tmp); | ||
| 1756 | } | ||
| 1757 | kfree(data); | ||
| 1758 | |||
| 1759 | /* | ||
| 1760 | * Clear the smack_onlycap on invalid label errors. This means | ||
| 1761 | * that we can pass a null string to unset the onlycap value. | ||
| 1762 | * | ||
| 1763 | * Importing will also reject a label beginning with '-', | ||
| 1764 | * so "-usecapabilities" will also work. | ||
| 1765 | * | ||
| 1766 | * But do so only on invalid label, not on system errors. | ||
| 1767 | * The invalid label must be first to count as clearing attempt. | ||
| 1768 | */ | ||
| 1769 | if (rc == -EINVAL && list_empty(&list_tmp)) | ||
| 1770 | rc = count; | ||
| 1771 | |||
| 1772 | if (rc >= 0) { | ||
| 1773 | mutex_lock(&smack_onlycap_lock); | ||
| 1774 | smk_list_swap_rcu(&smack_onlycap_list, &list_tmp); | ||
| 1775 | mutex_unlock(&smack_onlycap_lock); | ||
| 1776 | } | ||
| 1777 | |||
| 1778 | list_for_each_entry_safe(sop, sop2, &list_tmp, list) | ||
| 1779 | kfree(sop); | ||
| 1780 | |||
| 1781 | return rc; | ||
| 1782 | } | ||
| 1783 | |||
| 1784 | static const struct file_operations smk_onlycap_ops = { | ||
| 1785 | .open = smk_open_onlycap, | ||
| 1786 | .read = seq_read, | ||
| 1787 | .write = smk_write_onlycap, | ||
| 1788 | .llseek = seq_lseek, | ||
| 1789 | .release = seq_release, | ||
| 1790 | }; | ||
| 1791 | |||
| 1792 | #ifdef CONFIG_SECURITY_SMACK_BRINGUP | ||
| 1793 | /** | ||
| 1794 | * smk_read_unconfined - read() for smackfs/unconfined | ||
| 1636 | * @filp: file pointer, not actually used | 1795 | * @filp: file pointer, not actually used |
| 1637 | * @buf: where to put the result | 1796 | * @buf: where to put the result |
| 1638 | * @cn: maximum to send along | 1797 | * @cn: maximum to send along |
| @@ -1640,8 +1799,8 @@ static const struct file_operations smk_ambient_ops = { | |||
| 1640 | * | 1799 | * |
| 1641 | * Returns number of bytes read or error code, as appropriate | 1800 | * Returns number of bytes read or error code, as appropriate |
| 1642 | */ | 1801 | */ |
| 1643 | static ssize_t smk_read_onlycap(struct file *filp, char __user *buf, | 1802 | static ssize_t smk_read_unconfined(struct file *filp, char __user *buf, |
| 1644 | size_t cn, loff_t *ppos) | 1803 | size_t cn, loff_t *ppos) |
| 1645 | { | 1804 | { |
| 1646 | char *smack = ""; | 1805 | char *smack = ""; |
| 1647 | ssize_t rc = -EINVAL; | 1806 | ssize_t rc = -EINVAL; |
| @@ -1650,8 +1809,8 @@ static ssize_t smk_read_onlycap(struct file *filp, char __user *buf, | |||
| 1650 | if (*ppos != 0) | 1809 | if (*ppos != 0) |
| 1651 | return 0; | 1810 | return 0; |
| 1652 | 1811 | ||
| 1653 | if (smack_onlycap != NULL) | 1812 | if (smack_unconfined != NULL) |
| 1654 | smack = smack_onlycap->smk_known; | 1813 | smack = smack_unconfined->smk_known; |
| 1655 | 1814 | ||
| 1656 | asize = strlen(smack) + 1; | 1815 | asize = strlen(smack) + 1; |
| 1657 | 1816 | ||
| @@ -1662,7 +1821,7 @@ static ssize_t smk_read_onlycap(struct file *filp, char __user *buf, | |||
| 1662 | } | 1821 | } |
| 1663 | 1822 | ||
| 1664 | /** | 1823 | /** |
| 1665 | * smk_write_onlycap - write() for smackfs/onlycap | 1824 | * smk_write_unconfined - write() for smackfs/unconfined |
| 1666 | * @file: file pointer, not actually used | 1825 | * @file: file pointer, not actually used |
| 1667 | * @buf: where to get the data from | 1826 | * @buf: where to get the data from |
| 1668 | * @count: bytes sent | 1827 | * @count: bytes sent |
| @@ -1670,52 +1829,55 @@ static ssize_t smk_read_onlycap(struct file *filp, char __user *buf, | |||
| 1670 | * | 1829 | * |
| 1671 | * Returns number of bytes written or error code, as appropriate | 1830 | * Returns number of bytes written or error code, as appropriate |
| 1672 | */ | 1831 | */ |
| 1673 | static ssize_t smk_write_onlycap(struct file *file, const char __user *buf, | 1832 | static ssize_t smk_write_unconfined(struct file *file, const char __user *buf, |
| 1674 | size_t count, loff_t *ppos) | 1833 | size_t count, loff_t *ppos) |
| 1675 | { | 1834 | { |
| 1676 | char *data; | 1835 | char *data; |
| 1677 | struct smack_known *skp = smk_of_task(current->cred->security); | 1836 | struct smack_known *skp; |
| 1678 | int rc = count; | 1837 | int rc = count; |
| 1679 | 1838 | ||
| 1680 | if (!smack_privileged(CAP_MAC_ADMIN)) | 1839 | if (!smack_privileged(CAP_MAC_ADMIN)) |
| 1681 | return -EPERM; | 1840 | return -EPERM; |
| 1682 | 1841 | ||
| 1683 | /* | ||
| 1684 | * This can be done using smk_access() but is done | ||
| 1685 | * explicitly for clarity. The smk_access() implementation | ||
| 1686 | * would use smk_access(smack_onlycap, MAY_WRITE) | ||
| 1687 | */ | ||
| 1688 | if (smack_onlycap != NULL && smack_onlycap != skp) | ||
| 1689 | return -EPERM; | ||
| 1690 | |||
| 1691 | data = kzalloc(count + 1, GFP_KERNEL); | 1842 | data = kzalloc(count + 1, GFP_KERNEL); |
| 1692 | if (data == NULL) | 1843 | if (data == NULL) |
| 1693 | return -ENOMEM; | 1844 | return -ENOMEM; |
| 1694 | 1845 | ||
| 1846 | if (copy_from_user(data, buf, count) != 0) { | ||
| 1847 | rc = -EFAULT; | ||
| 1848 | goto freeout; | ||
| 1849 | } | ||
| 1850 | |||
| 1695 | /* | 1851 | /* |
| 1696 | * Should the null string be passed in unset the onlycap value. | 1852 | * Clear the smack_unconfined on invalid label errors. This means |
| 1697 | * This seems like something to be careful with as usually | 1853 | * that we can pass a null string to unset the unconfined value. |
| 1698 | * smk_import only expects to return NULL for errors. It | ||
| 1699 | * is usually the case that a nullstring or "\n" would be | ||
| 1700 | * bad to pass to smk_import but in fact this is useful here. | ||
| 1701 | * | 1854 | * |
| 1702 | * smk_import will also reject a label beginning with '-', | 1855 | * Importing will also reject a label beginning with '-', |
| 1703 | * so "-usecapabilities" will also work. | 1856 | * so "-confine" will also work. |
| 1857 | * | ||
| 1858 | * But do so only on invalid label, not on system errors. | ||
| 1704 | */ | 1859 | */ |
| 1705 | if (copy_from_user(data, buf, count) != 0) | 1860 | skp = smk_import_entry(data, count); |
| 1706 | rc = -EFAULT; | 1861 | if (PTR_ERR(skp) == -EINVAL) |
| 1707 | else | 1862 | skp = NULL; |
| 1708 | smack_onlycap = smk_import_entry(data, count); | 1863 | else if (IS_ERR(skp)) { |
| 1864 | rc = PTR_ERR(skp); | ||
| 1865 | goto freeout; | ||
| 1866 | } | ||
| 1709 | 1867 | ||
| 1868 | smack_unconfined = skp; | ||
| 1869 | |||
| 1870 | freeout: | ||
| 1710 | kfree(data); | 1871 | kfree(data); |
| 1711 | return rc; | 1872 | return rc; |
| 1712 | } | 1873 | } |
| 1713 | 1874 | ||
| 1714 | static const struct file_operations smk_onlycap_ops = { | 1875 | static const struct file_operations smk_unconfined_ops = { |
| 1715 | .read = smk_read_onlycap, | 1876 | .read = smk_read_unconfined, |
| 1716 | .write = smk_write_onlycap, | 1877 | .write = smk_write_unconfined, |
| 1717 | .llseek = default_llseek, | 1878 | .llseek = default_llseek, |
| 1718 | }; | 1879 | }; |
| 1880 | #endif /* CONFIG_SECURITY_SMACK_BRINGUP */ | ||
| 1719 | 1881 | ||
| 1720 | /** | 1882 | /** |
| 1721 | * smk_read_logging - read() for /smack/logging | 1883 | * smk_read_logging - read() for /smack/logging |
| @@ -1804,7 +1966,7 @@ static int load_self_seq_show(struct seq_file *s, void *v) | |||
| 1804 | { | 1966 | { |
| 1805 | struct list_head *list = v; | 1967 | struct list_head *list = v; |
| 1806 | struct smack_rule *srp = | 1968 | struct smack_rule *srp = |
| 1807 | list_entry(list, struct smack_rule, list); | 1969 | list_entry_rcu(list, struct smack_rule, list); |
| 1808 | 1970 | ||
| 1809 | smk_rule_show(s, srp, SMK_LABELLEN); | 1971 | smk_rule_show(s, srp, SMK_LABELLEN); |
| 1810 | 1972 | ||
| @@ -1889,7 +2051,7 @@ static ssize_t smk_user_access(struct file *file, const char __user *buf, | |||
| 1889 | res = smk_access(rule.smk_subject, rule.smk_object, | 2051 | res = smk_access(rule.smk_subject, rule.smk_object, |
| 1890 | rule.smk_access1, NULL); | 2052 | rule.smk_access1, NULL); |
| 1891 | else if (res != -ENOENT) | 2053 | else if (res != -ENOENT) |
| 1892 | return -EINVAL; | 2054 | return res; |
| 1893 | 2055 | ||
| 1894 | /* | 2056 | /* |
| 1895 | * smk_access() can return a value > 0 in the "bringup" case. | 2057 | * smk_access() can return a value > 0 in the "bringup" case. |
| @@ -1933,7 +2095,7 @@ static int load2_seq_show(struct seq_file *s, void *v) | |||
| 1933 | { | 2095 | { |
| 1934 | struct list_head *list = v; | 2096 | struct list_head *list = v; |
| 1935 | struct smack_master_list *smlp = | 2097 | struct smack_master_list *smlp = |
| 1936 | list_entry(list, struct smack_master_list, list); | 2098 | list_entry_rcu(list, struct smack_master_list, list); |
| 1937 | 2099 | ||
| 1938 | smk_rule_show(s, smlp->smk_rule, SMK_LONGLABEL); | 2100 | smk_rule_show(s, smlp->smk_rule, SMK_LONGLABEL); |
| 1939 | 2101 | ||
| @@ -2010,7 +2172,7 @@ static int load_self2_seq_show(struct seq_file *s, void *v) | |||
| 2010 | { | 2172 | { |
| 2011 | struct list_head *list = v; | 2173 | struct list_head *list = v; |
| 2012 | struct smack_rule *srp = | 2174 | struct smack_rule *srp = |
| 2013 | list_entry(list, struct smack_rule, list); | 2175 | list_entry_rcu(list, struct smack_rule, list); |
| 2014 | 2176 | ||
| 2015 | smk_rule_show(s, srp, SMK_LONGLABEL); | 2177 | smk_rule_show(s, srp, SMK_LONGLABEL); |
| 2016 | 2178 | ||
| @@ -2091,8 +2253,8 @@ static const struct file_operations smk_access2_ops = { | |||
| 2091 | static ssize_t smk_write_revoke_subj(struct file *file, const char __user *buf, | 2253 | static ssize_t smk_write_revoke_subj(struct file *file, const char __user *buf, |
| 2092 | size_t count, loff_t *ppos) | 2254 | size_t count, loff_t *ppos) |
| 2093 | { | 2255 | { |
| 2094 | char *data = NULL; | 2256 | char *data; |
| 2095 | const char *cp = NULL; | 2257 | const char *cp; |
| 2096 | struct smack_known *skp; | 2258 | struct smack_known *skp; |
| 2097 | struct smack_rule *sp; | 2259 | struct smack_rule *sp; |
| 2098 | struct list_head *rule_list; | 2260 | struct list_head *rule_list; |
| @@ -2114,18 +2276,18 @@ static ssize_t smk_write_revoke_subj(struct file *file, const char __user *buf, | |||
| 2114 | 2276 | ||
| 2115 | if (copy_from_user(data, buf, count) != 0) { | 2277 | if (copy_from_user(data, buf, count) != 0) { |
| 2116 | rc = -EFAULT; | 2278 | rc = -EFAULT; |
| 2117 | goto free_out; | 2279 | goto out_data; |
| 2118 | } | 2280 | } |
| 2119 | 2281 | ||
| 2120 | cp = smk_parse_smack(data, count); | 2282 | cp = smk_parse_smack(data, count); |
| 2121 | if (cp == NULL) { | 2283 | if (IS_ERR(cp)) { |
| 2122 | rc = -EINVAL; | 2284 | rc = PTR_ERR(cp); |
| 2123 | goto free_out; | 2285 | goto out_data; |
| 2124 | } | 2286 | } |
| 2125 | 2287 | ||
| 2126 | skp = smk_find_entry(cp); | 2288 | skp = smk_find_entry(cp); |
| 2127 | if (skp == NULL) | 2289 | if (skp == NULL) |
| 2128 | goto free_out; | 2290 | goto out_cp; |
| 2129 | 2291 | ||
| 2130 | rule_list = &skp->smk_rules; | 2292 | rule_list = &skp->smk_rules; |
| 2131 | rule_lock = &skp->smk_rules_lock; | 2293 | rule_lock = &skp->smk_rules_lock; |
| @@ -2137,9 +2299,11 @@ static ssize_t smk_write_revoke_subj(struct file *file, const char __user *buf, | |||
| 2137 | 2299 | ||
| 2138 | mutex_unlock(rule_lock); | 2300 | mutex_unlock(rule_lock); |
| 2139 | 2301 | ||
| 2140 | free_out: | 2302 | out_cp: |
| 2141 | kfree(data); | ||
| 2142 | kfree(cp); | 2303 | kfree(cp); |
| 2304 | out_data: | ||
| 2305 | kfree(data); | ||
| 2306 | |||
| 2143 | return rc; | 2307 | return rc; |
| 2144 | } | 2308 | } |
| 2145 | 2309 | ||
| @@ -2150,16 +2314,16 @@ static const struct file_operations smk_revoke_subj_ops = { | |||
| 2150 | .llseek = generic_file_llseek, | 2314 | .llseek = generic_file_llseek, |
| 2151 | }; | 2315 | }; |
| 2152 | 2316 | ||
| 2153 | static struct kset *smackfs_kset; | ||
| 2154 | /** | 2317 | /** |
| 2155 | * smk_init_sysfs - initialize /sys/fs/smackfs | 2318 | * smk_init_sysfs - initialize /sys/fs/smackfs |
| 2156 | * | 2319 | * |
| 2157 | */ | 2320 | */ |
| 2158 | static int smk_init_sysfs(void) | 2321 | static int smk_init_sysfs(void) |
| 2159 | { | 2322 | { |
| 2160 | smackfs_kset = kset_create_and_add("smackfs", NULL, fs_kobj); | 2323 | int err; |
| 2161 | if (!smackfs_kset) | 2324 | err = sysfs_create_mount_point(fs_kobj, "smackfs"); |
| 2162 | return -ENOMEM; | 2325 | if (err) |
| 2326 | return err; | ||
| 2163 | return 0; | 2327 | return 0; |
| 2164 | } | 2328 | } |
| 2165 | 2329 | ||
| @@ -2250,10 +2414,10 @@ static ssize_t smk_write_syslog(struct file *file, const char __user *buf, | |||
| 2250 | rc = -EFAULT; | 2414 | rc = -EFAULT; |
| 2251 | else { | 2415 | else { |
| 2252 | skp = smk_import_entry(data, count); | 2416 | skp = smk_import_entry(data, count); |
| 2253 | if (skp == NULL) | 2417 | if (IS_ERR(skp)) |
| 2254 | rc = -EINVAL; | 2418 | rc = PTR_ERR(skp); |
| 2255 | else | 2419 | else |
| 2256 | smack_syslog_label = smk_import_entry(data, count); | 2420 | smack_syslog_label = skp; |
| 2257 | } | 2421 | } |
| 2258 | 2422 | ||
| 2259 | kfree(data); | 2423 | kfree(data); |
| @@ -2384,6 +2548,10 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent) | |||
| 2384 | "syslog", &smk_syslog_ops, S_IRUGO|S_IWUSR}, | 2548 | "syslog", &smk_syslog_ops, S_IRUGO|S_IWUSR}, |
| 2385 | [SMK_PTRACE] = { | 2549 | [SMK_PTRACE] = { |
| 2386 | "ptrace", &smk_ptrace_ops, S_IRUGO|S_IWUSR}, | 2550 | "ptrace", &smk_ptrace_ops, S_IRUGO|S_IWUSR}, |
| 2551 | #ifdef CONFIG_SECURITY_SMACK_BRINGUP | ||
| 2552 | [SMK_UNCONFINED] = { | ||
| 2553 | "unconfined", &smk_unconfined_ops, S_IRUGO|S_IWUSR}, | ||
| 2554 | #endif | ||
| 2387 | /* last one */ | 2555 | /* last one */ |
| 2388 | {""} | 2556 | {""} |
| 2389 | }; | 2557 | }; |
| @@ -2395,7 +2563,7 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent) | |||
| 2395 | return rc; | 2563 | return rc; |
| 2396 | } | 2564 | } |
| 2397 | 2565 | ||
| 2398 | root_inode = sb->s_root->d_inode; | 2566 | root_inode = d_inode(sb->s_root); |
| 2399 | 2567 | ||
| 2400 | return 0; | 2568 | return 0; |
| 2401 | } | 2569 | } |
| @@ -2452,7 +2620,7 @@ static int __init init_smk_fs(void) | |||
| 2452 | int err; | 2620 | int err; |
| 2453 | int rc; | 2621 | int rc; |
| 2454 | 2622 | ||
| 2455 | if (!security_module_enable(&smack_ops)) | 2623 | if (!security_module_enable("smack")) |
| 2456 | return 0; | 2624 | return 0; |
| 2457 | 2625 | ||
| 2458 | err = smk_init_sysfs(); | 2626 | err = smk_init_sysfs(); |
diff --git a/security/tomoyo/.gitignore b/security/tomoyo/.gitignore index 5caf1a6f5907..dc0f220a210b 100644 --- a/security/tomoyo/.gitignore +++ b/security/tomoyo/.gitignore | |||
| @@ -1,2 +1,2 @@ | |||
| 1 | builtin-policy.h | 1 | builtin-policy.h |
| 2 | policy/ | 2 | policy/*.conf |
diff --git a/security/tomoyo/Kconfig b/security/tomoyo/Kconfig index 604e718d68d3..404dce66952a 100644 --- a/security/tomoyo/Kconfig +++ b/security/tomoyo/Kconfig | |||
| @@ -6,6 +6,7 @@ config SECURITY_TOMOYO | |||
| 6 | select SECURITY_PATH | 6 | select SECURITY_PATH |
| 7 | select SECURITY_NETWORK | 7 | select SECURITY_NETWORK |
| 8 | select SRCU | 8 | select SRCU |
| 9 | select BUILD_BIN2C | ||
| 9 | default n | 10 | default n |
| 10 | help | 11 | help |
| 11 | This selects TOMOYO Linux, pathname-based access control. | 12 | This selects TOMOYO Linux, pathname-based access control. |
diff --git a/security/tomoyo/Makefile b/security/tomoyo/Makefile index 56a0c7be409e..65dbcb2fd850 100644 --- a/security/tomoyo/Makefile +++ b/security/tomoyo/Makefile | |||
| @@ -1,48 +1,15 @@ | |||
| 1 | obj-y = audit.o common.o condition.o domain.o environ.o file.o gc.o group.o load_policy.o memory.o mount.o network.o realpath.o securityfs_if.o tomoyo.o util.o | 1 | obj-y = audit.o common.o condition.o domain.o environ.o file.o gc.o group.o load_policy.o memory.o mount.o network.o realpath.o securityfs_if.o tomoyo.o util.o |
| 2 | 2 | ||
| 3 | $(obj)/policy/profile.conf: | 3 | targets += builtin-policy.h |
| 4 | @mkdir -p $(obj)/policy/ | 4 | define do_policy |
| 5 | @echo Creating an empty policy/profile.conf | 5 | echo "static char tomoyo_builtin_$(1)[] __initdata ="; \ |
| 6 | @touch $@ | 6 | $(objtree)/scripts/basic/bin2c <$(firstword $(wildcard $(obj)/policy/$(1).conf $(srctree)/$(src)/policy/$(1).conf.default) /dev/null); \ |
| 7 | 7 | echo ";" | |
| 8 | $(obj)/policy/exception_policy.conf: | 8 | endef |
| 9 | @mkdir -p $(obj)/policy/ | 9 | quiet_cmd_policy = POLICY $@ |
| 10 | @echo Creating a default policy/exception_policy.conf | 10 | cmd_policy = ($(call do_policy,profile); $(call do_policy,exception_policy); $(call do_policy,domain_policy); $(call do_policy,manager); $(call do_policy,stat)) >$@ |
| 11 | @echo initialize_domain /sbin/modprobe from any >> $@ | 11 | |
| 12 | @echo initialize_domain /sbin/hotplug from any >> $@ | 12 | $(obj)/builtin-policy.h: $(wildcard $(obj)/policy/*.conf $(src)/policy/*.conf.default) FORCE |
| 13 | 13 | $(call if_changed,policy) | |
| 14 | $(obj)/policy/domain_policy.conf: | ||
| 15 | @mkdir -p $(obj)/policy/ | ||
| 16 | @echo Creating an empty policy/domain_policy.conf | ||
| 17 | @touch $@ | ||
| 18 | |||
| 19 | $(obj)/policy/manager.conf: | ||
| 20 | @mkdir -p $(obj)/policy/ | ||
| 21 | @echo Creating an empty policy/manager.conf | ||
| 22 | @touch $@ | ||
| 23 | |||
| 24 | $(obj)/policy/stat.conf: | ||
| 25 | @mkdir -p $(obj)/policy/ | ||
| 26 | @echo Creating an empty policy/stat.conf | ||
| 27 | @touch $@ | ||
| 28 | |||
| 29 | $(obj)/builtin-policy.h: $(obj)/policy/profile.conf $(obj)/policy/exception_policy.conf $(obj)/policy/domain_policy.conf $(obj)/policy/manager.conf $(obj)/policy/stat.conf | ||
| 30 | @echo Generating built-in policy for TOMOYO 2.5.x. | ||
| 31 | @echo "static char tomoyo_builtin_profile[] __initdata =" > $@.tmp | ||
| 32 | @sed -e 's/\\/\\\\/g' -e 's/\"/\\"/g' -e 's/\(.*\)/"\1\\n"/' < $(obj)/policy/profile.conf >> $@.tmp | ||
| 33 | @echo "\"\";" >> $@.tmp | ||
| 34 | @echo "static char tomoyo_builtin_exception_policy[] __initdata =" >> $@.tmp | ||
| 35 | @sed -e 's/\\/\\\\/g' -e 's/\"/\\"/g' -e 's/\(.*\)/"\1\\n"/' < $(obj)/policy/exception_policy.conf >> $@.tmp | ||
| 36 | @echo "\"\";" >> $@.tmp | ||
| 37 | @echo "static char tomoyo_builtin_domain_policy[] __initdata =" >> $@.tmp | ||
| 38 | @sed -e 's/\\/\\\\/g' -e 's/\"/\\"/g' -e 's/\(.*\)/"\1\\n"/' < $(obj)/policy/domain_policy.conf >> $@.tmp | ||
| 39 | @echo "\"\";" >> $@.tmp | ||
| 40 | @echo "static char tomoyo_builtin_manager[] __initdata =" >> $@.tmp | ||
| 41 | @sed -e 's/\\/\\\\/g' -e 's/\"/\\"/g' -e 's/\(.*\)/"\1\\n"/' < $(obj)/policy/manager.conf >> $@.tmp | ||
| 42 | @echo "\"\";" >> $@.tmp | ||
| 43 | @echo "static char tomoyo_builtin_stat[] __initdata =" >> $@.tmp | ||
| 44 | @sed -e 's/\\/\\\\/g' -e 's/\"/\\"/g' -e 's/\(.*\)/"\1\\n"/' < $(obj)/policy/stat.conf >> $@.tmp | ||
| 45 | @echo "\"\";" >> $@.tmp | ||
| 46 | @mv $@.tmp $@ | ||
| 47 | 14 | ||
| 48 | $(obj)/common.o: $(obj)/builtin-policy.h | 15 | $(obj)/common.o: $(obj)/builtin-policy.h |
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h index b897d4862016..f9c9fb1d56b4 100644 --- a/security/tomoyo/common.h +++ b/security/tomoyo/common.h | |||
| @@ -945,7 +945,7 @@ char *tomoyo_encode2(const char *str, int str_len); | |||
| 945 | char *tomoyo_init_log(struct tomoyo_request_info *r, int len, const char *fmt, | 945 | char *tomoyo_init_log(struct tomoyo_request_info *r, int len, const char *fmt, |
| 946 | va_list args); | 946 | va_list args); |
| 947 | char *tomoyo_read_token(struct tomoyo_acl_param *param); | 947 | char *tomoyo_read_token(struct tomoyo_acl_param *param); |
| 948 | char *tomoyo_realpath_from_path(struct path *path); | 948 | char *tomoyo_realpath_from_path(const struct path *path); |
| 949 | char *tomoyo_realpath_nofollow(const char *pathname); | 949 | char *tomoyo_realpath_nofollow(const char *pathname); |
| 950 | const char *tomoyo_get_exe(void); | 950 | const char *tomoyo_get_exe(void); |
| 951 | const char *tomoyo_yesno(const unsigned int value); | 951 | const char *tomoyo_yesno(const unsigned int value); |
| @@ -978,7 +978,7 @@ int tomoyo_path2_perm(const u8 operation, struct path *path1, | |||
| 978 | struct path *path2); | 978 | struct path *path2); |
| 979 | int tomoyo_path_number_perm(const u8 operation, struct path *path, | 979 | int tomoyo_path_number_perm(const u8 operation, struct path *path, |
| 980 | unsigned long number); | 980 | unsigned long number); |
| 981 | int tomoyo_path_perm(const u8 operation, struct path *path, | 981 | int tomoyo_path_perm(const u8 operation, const struct path *path, |
| 982 | const char *target); | 982 | const char *target); |
| 983 | unsigned int tomoyo_poll_control(struct file *file, poll_table *wait); | 983 | unsigned int tomoyo_poll_control(struct file *file, poll_table *wait); |
| 984 | unsigned int tomoyo_poll_log(struct file *file, poll_table *wait); | 984 | unsigned int tomoyo_poll_log(struct file *file, poll_table *wait); |
diff --git a/security/tomoyo/condition.c b/security/tomoyo/condition.c index 63681e8be628..6c4528d4b48f 100644 --- a/security/tomoyo/condition.c +++ b/security/tomoyo/condition.c | |||
| @@ -714,7 +714,7 @@ void tomoyo_get_attributes(struct tomoyo_obj_info *obj) | |||
| 714 | dentry = dget_parent(dentry); | 714 | dentry = dget_parent(dentry); |
| 715 | break; | 715 | break; |
| 716 | } | 716 | } |
| 717 | inode = dentry->d_inode; | 717 | inode = d_backing_inode(dentry); |
| 718 | if (inode) { | 718 | if (inode) { |
| 719 | struct tomoyo_mini_stat *stat = &obj->stat[i]; | 719 | struct tomoyo_mini_stat *stat = &obj->stat[i]; |
| 720 | stat->uid = inode->i_uid; | 720 | stat->uid = inode->i_uid; |
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c index c151a1869597..2367b100cc62 100644 --- a/security/tomoyo/file.c +++ b/security/tomoyo/file.c | |||
| @@ -145,7 +145,7 @@ static void tomoyo_add_slash(struct tomoyo_path_info *buf) | |||
| 145 | * | 145 | * |
| 146 | * Returns true on success, false otherwise. | 146 | * Returns true on success, false otherwise. |
| 147 | */ | 147 | */ |
| 148 | static bool tomoyo_get_realpath(struct tomoyo_path_info *buf, struct path *path) | 148 | static bool tomoyo_get_realpath(struct tomoyo_path_info *buf, const struct path *path) |
| 149 | { | 149 | { |
| 150 | buf->name = tomoyo_realpath_from_path(path); | 150 | buf->name = tomoyo_realpath_from_path(path); |
| 151 | if (buf->name) { | 151 | if (buf->name) { |
| @@ -782,7 +782,7 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain, | |||
| 782 | * | 782 | * |
| 783 | * Returns 0 on success, negative value otherwise. | 783 | * Returns 0 on success, negative value otherwise. |
| 784 | */ | 784 | */ |
| 785 | int tomoyo_path_perm(const u8 operation, struct path *path, const char *target) | 785 | int tomoyo_path_perm(const u8 operation, const struct path *path, const char *target) |
| 786 | { | 786 | { |
| 787 | struct tomoyo_request_info r; | 787 | struct tomoyo_request_info r; |
| 788 | struct tomoyo_obj_info obj = { | 788 | struct tomoyo_obj_info obj = { |
diff --git a/security/tomoyo/policy/exception_policy.conf.default b/security/tomoyo/policy/exception_policy.conf.default new file mode 100644 index 000000000000..2678df4964ee --- /dev/null +++ b/security/tomoyo/policy/exception_policy.conf.default | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | initialize_domain /sbin/modprobe from any | ||
| 2 | initialize_domain /sbin/hotplug from any | ||
diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c index bed745c8b1a3..5077f1968841 100644 --- a/security/tomoyo/realpath.c +++ b/security/tomoyo/realpath.c | |||
| @@ -89,7 +89,7 @@ char *tomoyo_encode(const char *str) | |||
| 89 | * | 89 | * |
| 90 | * If dentry is a directory, trailing '/' is appended. | 90 | * If dentry is a directory, trailing '/' is appended. |
| 91 | */ | 91 | */ |
| 92 | static char *tomoyo_get_absolute_path(struct path *path, char * const buffer, | 92 | static char *tomoyo_get_absolute_path(const struct path *path, char * const buffer, |
| 93 | const int buflen) | 93 | const int buflen) |
| 94 | { | 94 | { |
| 95 | char *pos = ERR_PTR(-ENOMEM); | 95 | char *pos = ERR_PTR(-ENOMEM); |
| @@ -97,7 +97,7 @@ static char *tomoyo_get_absolute_path(struct path *path, char * const buffer, | |||
| 97 | /* go to whatever namespace root we are under */ | 97 | /* go to whatever namespace root we are under */ |
| 98 | pos = d_absolute_path(path, buffer, buflen - 1); | 98 | pos = d_absolute_path(path, buffer, buflen - 1); |
| 99 | if (!IS_ERR(pos) && *pos == '/' && pos[1]) { | 99 | if (!IS_ERR(pos) && *pos == '/' && pos[1]) { |
| 100 | struct inode *inode = path->dentry->d_inode; | 100 | struct inode *inode = d_backing_inode(path->dentry); |
| 101 | if (inode && S_ISDIR(inode->i_mode)) { | 101 | if (inode && S_ISDIR(inode->i_mode)) { |
| 102 | buffer[buflen - 2] = '/'; | 102 | buffer[buflen - 2] = '/'; |
| 103 | buffer[buflen - 1] = '\0'; | 103 | buffer[buflen - 1] = '\0'; |
| @@ -125,7 +125,7 @@ static char *tomoyo_get_dentry_path(struct dentry *dentry, char * const buffer, | |||
| 125 | if (buflen >= 256) { | 125 | if (buflen >= 256) { |
| 126 | pos = dentry_path_raw(dentry, buffer, buflen - 1); | 126 | pos = dentry_path_raw(dentry, buffer, buflen - 1); |
| 127 | if (!IS_ERR(pos) && *pos == '/' && pos[1]) { | 127 | if (!IS_ERR(pos) && *pos == '/' && pos[1]) { |
| 128 | struct inode *inode = dentry->d_inode; | 128 | struct inode *inode = d_backing_inode(dentry); |
| 129 | if (inode && S_ISDIR(inode->i_mode)) { | 129 | if (inode && S_ISDIR(inode->i_mode)) { |
| 130 | buffer[buflen - 2] = '/'; | 130 | buffer[buflen - 2] = '/'; |
| 131 | buffer[buflen - 1] = '\0'; | 131 | buffer[buflen - 1] = '\0'; |
| @@ -168,7 +168,7 @@ static char *tomoyo_get_local_path(struct dentry *dentry, char * const buffer, | |||
| 168 | if (!MAJOR(sb->s_dev)) | 168 | if (!MAJOR(sb->s_dev)) |
| 169 | goto prepend_filesystem_name; | 169 | goto prepend_filesystem_name; |
| 170 | { | 170 | { |
| 171 | struct inode *inode = sb->s_root->d_inode; | 171 | struct inode *inode = d_backing_inode(sb->s_root); |
| 172 | /* | 172 | /* |
| 173 | * Use filesystem name if filesystem does not support rename() | 173 | * Use filesystem name if filesystem does not support rename() |
| 174 | * operation. | 174 | * operation. |
| @@ -216,10 +216,10 @@ out: | |||
| 216 | * | 216 | * |
| 217 | * Returns the buffer. | 217 | * Returns the buffer. |
| 218 | */ | 218 | */ |
| 219 | static char *tomoyo_get_socket_name(struct path *path, char * const buffer, | 219 | static char *tomoyo_get_socket_name(const struct path *path, char * const buffer, |
| 220 | const int buflen) | 220 | const int buflen) |
| 221 | { | 221 | { |
| 222 | struct inode *inode = path->dentry->d_inode; | 222 | struct inode *inode = d_backing_inode(path->dentry); |
| 223 | struct socket *sock = inode ? SOCKET_I(inode) : NULL; | 223 | struct socket *sock = inode ? SOCKET_I(inode) : NULL; |
| 224 | struct sock *sk = sock ? sock->sk : NULL; | 224 | struct sock *sk = sock ? sock->sk : NULL; |
| 225 | if (sk) { | 225 | if (sk) { |
| @@ -247,7 +247,7 @@ static char *tomoyo_get_socket_name(struct path *path, char * const buffer, | |||
| 247 | * These functions use kzalloc(), so the caller must call kfree() | 247 | * These functions use kzalloc(), so the caller must call kfree() |
| 248 | * if these functions didn't return NULL. | 248 | * if these functions didn't return NULL. |
| 249 | */ | 249 | */ |
| 250 | char *tomoyo_realpath_from_path(struct path *path) | 250 | char *tomoyo_realpath_from_path(const struct path *path) |
| 251 | { | 251 | { |
| 252 | char *buf = NULL; | 252 | char *buf = NULL; |
| 253 | char *name = NULL; | 253 | char *name = NULL; |
| @@ -277,7 +277,7 @@ char *tomoyo_realpath_from_path(struct path *path) | |||
| 277 | pos = dentry->d_op->d_dname(dentry, buf, buf_len - 1); | 277 | pos = dentry->d_op->d_dname(dentry, buf, buf_len - 1); |
| 278 | goto encode; | 278 | goto encode; |
| 279 | } | 279 | } |
| 280 | inode = sb->s_root->d_inode; | 280 | inode = d_backing_inode(sb->s_root); |
| 281 | /* | 281 | /* |
| 282 | * Get local name for filesystems without rename() operation | 282 | * Get local name for filesystems without rename() operation |
| 283 | * or dentry without vfsmount. | 283 | * or dentry without vfsmount. |
diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c index f0b756e27fed..cbf3df422c87 100644 --- a/security/tomoyo/tomoyo.c +++ b/security/tomoyo/tomoyo.c | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | * Copyright (C) 2005-2011 NTT DATA CORPORATION | 4 | * Copyright (C) 2005-2011 NTT DATA CORPORATION |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | #include <linux/security.h> | 7 | #include <linux/lsm_hooks.h> |
| 8 | #include "common.h" | 8 | #include "common.h" |
| 9 | 9 | ||
| 10 | /** | 10 | /** |
| @@ -72,12 +72,6 @@ static void tomoyo_cred_free(struct cred *cred) | |||
| 72 | */ | 72 | */ |
| 73 | static int tomoyo_bprm_set_creds(struct linux_binprm *bprm) | 73 | static int tomoyo_bprm_set_creds(struct linux_binprm *bprm) |
| 74 | { | 74 | { |
| 75 | int rc; | ||
| 76 | |||
| 77 | rc = cap_bprm_set_creds(bprm); | ||
| 78 | if (rc) | ||
| 79 | return rc; | ||
| 80 | |||
| 81 | /* | 75 | /* |
| 82 | * Do only if this function is called for the first time of an execve | 76 | * Do only if this function is called for the first time of an execve |
| 83 | * operation. | 77 | * operation. |
| @@ -144,10 +138,9 @@ static int tomoyo_bprm_check_security(struct linux_binprm *bprm) | |||
| 144 | * | 138 | * |
| 145 | * Returns 0 on success, negative value otherwise. | 139 | * Returns 0 on success, negative value otherwise. |
| 146 | */ | 140 | */ |
| 147 | static int tomoyo_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) | 141 | static int tomoyo_inode_getattr(const struct path *path) |
| 148 | { | 142 | { |
| 149 | struct path path = { mnt, dentry }; | 143 | return tomoyo_path_perm(TOMOYO_TYPE_GETATTR, path, NULL); |
| 150 | return tomoyo_path_perm(TOMOYO_TYPE_GETATTR, &path, NULL); | ||
| 151 | } | 144 | } |
| 152 | 145 | ||
| 153 | /** | 146 | /** |
| @@ -503,36 +496,35 @@ static int tomoyo_socket_sendmsg(struct socket *sock, struct msghdr *msg, | |||
| 503 | * tomoyo_security_ops is a "struct security_operations" which is used for | 496 | * tomoyo_security_ops is a "struct security_operations" which is used for |
| 504 | * registering TOMOYO. | 497 | * registering TOMOYO. |
| 505 | */ | 498 | */ |
| 506 | static struct security_operations tomoyo_security_ops = { | 499 | static struct security_hook_list tomoyo_hooks[] = { |
| 507 | .name = "tomoyo", | 500 | LSM_HOOK_INIT(cred_alloc_blank, tomoyo_cred_alloc_blank), |
| 508 | .cred_alloc_blank = tomoyo_cred_alloc_blank, | 501 | LSM_HOOK_INIT(cred_prepare, tomoyo_cred_prepare), |
| 509 | .cred_prepare = tomoyo_cred_prepare, | 502 | LSM_HOOK_INIT(cred_transfer, tomoyo_cred_transfer), |
| 510 | .cred_transfer = tomoyo_cred_transfer, | 503 | LSM_HOOK_INIT(cred_free, tomoyo_cred_free), |
| 511 | .cred_free = tomoyo_cred_free, | 504 | LSM_HOOK_INIT(bprm_set_creds, tomoyo_bprm_set_creds), |
| 512 | .bprm_set_creds = tomoyo_bprm_set_creds, | 505 | LSM_HOOK_INIT(bprm_check_security, tomoyo_bprm_check_security), |
| 513 | .bprm_check_security = tomoyo_bprm_check_security, | 506 | LSM_HOOK_INIT(file_fcntl, tomoyo_file_fcntl), |
| 514 | .file_fcntl = tomoyo_file_fcntl, | 507 | LSM_HOOK_INIT(file_open, tomoyo_file_open), |
| 515 | .file_open = tomoyo_file_open, | 508 | LSM_HOOK_INIT(path_truncate, tomoyo_path_truncate), |
| 516 | .path_truncate = tomoyo_path_truncate, | 509 | LSM_HOOK_INIT(path_unlink, tomoyo_path_unlink), |
| 517 | .path_unlink = tomoyo_path_unlink, | 510 | LSM_HOOK_INIT(path_mkdir, tomoyo_path_mkdir), |
| 518 | .path_mkdir = tomoyo_path_mkdir, | 511 | LSM_HOOK_INIT(path_rmdir, tomoyo_path_rmdir), |
| 519 | .path_rmdir = tomoyo_path_rmdir, | 512 | LSM_HOOK_INIT(path_symlink, tomoyo_path_symlink), |
| 520 | .path_symlink = tomoyo_path_symlink, | 513 | LSM_HOOK_INIT(path_mknod, tomoyo_path_mknod), |
| 521 | .path_mknod = tomoyo_path_mknod, | 514 | LSM_HOOK_INIT(path_link, tomoyo_path_link), |
| 522 | .path_link = tomoyo_path_link, | 515 | LSM_HOOK_INIT(path_rename, tomoyo_path_rename), |
| 523 | .path_rename = tomoyo_path_rename, | 516 | LSM_HOOK_INIT(inode_getattr, tomoyo_inode_getattr), |
| 524 | .inode_getattr = tomoyo_inode_getattr, | 517 | LSM_HOOK_INIT(file_ioctl, tomoyo_file_ioctl), |
| 525 | .file_ioctl = tomoyo_file_ioctl, | 518 | LSM_HOOK_INIT(path_chmod, tomoyo_path_chmod), |
| 526 | .path_chmod = tomoyo_path_chmod, | 519 | LSM_HOOK_INIT(path_chown, tomoyo_path_chown), |
| 527 | .path_chown = tomoyo_path_chown, | 520 | LSM_HOOK_INIT(path_chroot, tomoyo_path_chroot), |
| 528 | .path_chroot = tomoyo_path_chroot, | 521 | LSM_HOOK_INIT(sb_mount, tomoyo_sb_mount), |
| 529 | .sb_mount = tomoyo_sb_mount, | 522 | LSM_HOOK_INIT(sb_umount, tomoyo_sb_umount), |
| 530 | .sb_umount = tomoyo_sb_umount, | 523 | LSM_HOOK_INIT(sb_pivotroot, tomoyo_sb_pivotroot), |
| 531 | .sb_pivotroot = tomoyo_sb_pivotroot, | 524 | LSM_HOOK_INIT(socket_bind, tomoyo_socket_bind), |
| 532 | .socket_bind = tomoyo_socket_bind, | 525 | LSM_HOOK_INIT(socket_connect, tomoyo_socket_connect), |
| 533 | .socket_connect = tomoyo_socket_connect, | 526 | LSM_HOOK_INIT(socket_listen, tomoyo_socket_listen), |
| 534 | .socket_listen = tomoyo_socket_listen, | 527 | LSM_HOOK_INIT(socket_sendmsg, tomoyo_socket_sendmsg), |
| 535 | .socket_sendmsg = tomoyo_socket_sendmsg, | ||
| 536 | }; | 528 | }; |
| 537 | 529 | ||
| 538 | /* Lock for GC. */ | 530 | /* Lock for GC. */ |
| @@ -547,11 +539,10 @@ static int __init tomoyo_init(void) | |||
| 547 | { | 539 | { |
| 548 | struct cred *cred = (struct cred *) current_cred(); | 540 | struct cred *cred = (struct cred *) current_cred(); |
| 549 | 541 | ||
| 550 | if (!security_module_enable(&tomoyo_security_ops)) | 542 | if (!security_module_enable("tomoyo")) |
| 551 | return 0; | 543 | return 0; |
| 552 | /* register ourselves with the security framework */ | 544 | /* register ourselves with the security framework */ |
| 553 | if (register_security(&tomoyo_security_ops)) | 545 | security_add_hooks(tomoyo_hooks, ARRAY_SIZE(tomoyo_hooks)); |
| 554 | panic("Failure registering TOMOYO Linux"); | ||
| 555 | printk(KERN_INFO "TOMOYO Linux initialized\n"); | 546 | printk(KERN_INFO "TOMOYO Linux initialized\n"); |
| 556 | cred->security = &tomoyo_kernel_domain; | 547 | cred->security = &tomoyo_kernel_domain; |
| 557 | tomoyo_mm_init(); | 548 | tomoyo_mm_init(); |
diff --git a/security/tomoyo/util.c b/security/tomoyo/util.c index 2952ba576fb9..b974a6997d7f 100644 --- a/security/tomoyo/util.c +++ b/security/tomoyo/util.c | |||
| @@ -948,15 +948,18 @@ bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename, | |||
| 948 | */ | 948 | */ |
| 949 | const char *tomoyo_get_exe(void) | 949 | const char *tomoyo_get_exe(void) |
| 950 | { | 950 | { |
| 951 | struct file *exe_file; | ||
| 952 | const char *cp; | ||
| 951 | struct mm_struct *mm = current->mm; | 953 | struct mm_struct *mm = current->mm; |
| 952 | const char *cp = NULL; | ||
| 953 | 954 | ||
| 954 | if (!mm) | 955 | if (!mm) |
| 955 | return NULL; | 956 | return NULL; |
| 956 | down_read(&mm->mmap_sem); | 957 | exe_file = get_mm_exe_file(mm); |
| 957 | if (mm->exe_file) | 958 | if (!exe_file) |
| 958 | cp = tomoyo_realpath_from_path(&mm->exe_file->f_path); | 959 | return NULL; |
| 959 | up_read(&mm->mmap_sem); | 960 | |
| 961 | cp = tomoyo_realpath_from_path(&exe_file->f_path); | ||
| 962 | fput(exe_file); | ||
| 960 | return cp; | 963 | return cp; |
| 961 | } | 964 | } |
| 962 | 965 | ||
diff --git a/security/yama/Kconfig b/security/yama/Kconfig index 20ef5143c0c0..3123e1da2fed 100644 --- a/security/yama/Kconfig +++ b/security/yama/Kconfig | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | config SECURITY_YAMA | 1 | config SECURITY_YAMA |
| 2 | bool "Yama support" | 2 | bool "Yama support" |
| 3 | depends on SECURITY | 3 | depends on SECURITY |
| 4 | select SECURITYFS | ||
| 5 | select SECURITY_PATH | ||
| 6 | default n | 4 | default n |
| 7 | help | 5 | help |
| 8 | This selects Yama, which extends DAC support with additional | 6 | This selects Yama, which extends DAC support with additional |
diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c index 13c88fbcf037..9ed32502470e 100644 --- a/security/yama/yama_lsm.c +++ b/security/yama/yama_lsm.c | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | * | 12 | * |
| 13 | */ | 13 | */ |
| 14 | 14 | ||
| 15 | #include <linux/security.h> | 15 | #include <linux/lsm_hooks.h> |
| 16 | #include <linux/sysctl.h> | 16 | #include <linux/sysctl.h> |
| 17 | #include <linux/ptrace.h> | 17 | #include <linux/ptrace.h> |
| 18 | #include <linux/prctl.h> | 18 | #include <linux/prctl.h> |
| @@ -154,13 +154,9 @@ void yama_task_free(struct task_struct *task) | |||
| 154 | int yama_task_prctl(int option, unsigned long arg2, unsigned long arg3, | 154 | int yama_task_prctl(int option, unsigned long arg2, unsigned long arg3, |
| 155 | unsigned long arg4, unsigned long arg5) | 155 | unsigned long arg4, unsigned long arg5) |
| 156 | { | 156 | { |
| 157 | int rc; | 157 | int rc = -ENOSYS; |
| 158 | struct task_struct *myself = current; | 158 | struct task_struct *myself = current; |
| 159 | 159 | ||
| 160 | rc = cap_task_prctl(option, arg2, arg3, arg4, arg5); | ||
| 161 | if (rc != -ENOSYS) | ||
| 162 | return rc; | ||
| 163 | |||
| 164 | switch (option) { | 160 | switch (option) { |
| 165 | case PR_SET_PTRACER: | 161 | case PR_SET_PTRACER: |
| 166 | /* Since a thread can call prctl(), find the group leader | 162 | /* Since a thread can call prctl(), find the group leader |
| @@ -279,17 +275,10 @@ static int ptracer_exception_found(struct task_struct *tracer, | |||
| 279 | * | 275 | * |
| 280 | * Returns 0 if following the ptrace is allowed, -ve on error. | 276 | * Returns 0 if following the ptrace is allowed, -ve on error. |
| 281 | */ | 277 | */ |
| 282 | int yama_ptrace_access_check(struct task_struct *child, | 278 | static int yama_ptrace_access_check(struct task_struct *child, |
| 283 | unsigned int mode) | 279 | unsigned int mode) |
| 284 | { | 280 | { |
| 285 | int rc; | 281 | int rc = 0; |
| 286 | |||
| 287 | /* If standard caps disallows it, so does Yama. We should | ||
| 288 | * only tighten restrictions further. | ||
| 289 | */ | ||
| 290 | rc = cap_ptrace_access_check(child, mode); | ||
| 291 | if (rc) | ||
| 292 | return rc; | ||
| 293 | 282 | ||
| 294 | /* require ptrace target be a child of ptracer on attach */ | 283 | /* require ptrace target be a child of ptracer on attach */ |
| 295 | if (mode == PTRACE_MODE_ATTACH) { | 284 | if (mode == PTRACE_MODE_ATTACH) { |
| @@ -335,14 +324,7 @@ int yama_ptrace_access_check(struct task_struct *child, | |||
| 335 | */ | 324 | */ |
| 336 | int yama_ptrace_traceme(struct task_struct *parent) | 325 | int yama_ptrace_traceme(struct task_struct *parent) |
| 337 | { | 326 | { |
| 338 | int rc; | 327 | int rc = 0; |
| 339 | |||
| 340 | /* If standard caps disallows it, so does Yama. We should | ||
| 341 | * only tighten restrictions further. | ||
| 342 | */ | ||
| 343 | rc = cap_ptrace_traceme(parent); | ||
| 344 | if (rc) | ||
| 345 | return rc; | ||
| 346 | 328 | ||
| 347 | /* Only disallow PTRACE_TRACEME on more aggressive settings. */ | 329 | /* Only disallow PTRACE_TRACEME on more aggressive settings. */ |
| 348 | switch (ptrace_scope) { | 330 | switch (ptrace_scope) { |
| @@ -364,35 +346,33 @@ int yama_ptrace_traceme(struct task_struct *parent) | |||
| 364 | return rc; | 346 | return rc; |
| 365 | } | 347 | } |
| 366 | 348 | ||
| 367 | #ifndef CONFIG_SECURITY_YAMA_STACKED | 349 | static struct security_hook_list yama_hooks[] = { |
| 368 | static struct security_operations yama_ops = { | 350 | LSM_HOOK_INIT(ptrace_access_check, yama_ptrace_access_check), |
| 369 | .name = "yama", | 351 | LSM_HOOK_INIT(ptrace_traceme, yama_ptrace_traceme), |
| 370 | 352 | LSM_HOOK_INIT(task_prctl, yama_task_prctl), | |
| 371 | .ptrace_access_check = yama_ptrace_access_check, | 353 | LSM_HOOK_INIT(task_free, yama_task_free), |
| 372 | .ptrace_traceme = yama_ptrace_traceme, | ||
| 373 | .task_prctl = yama_task_prctl, | ||
| 374 | .task_free = yama_task_free, | ||
| 375 | }; | 354 | }; |
| 376 | #endif | 355 | |
| 356 | void __init yama_add_hooks(void) | ||
| 357 | { | ||
| 358 | security_add_hooks(yama_hooks, ARRAY_SIZE(yama_hooks)); | ||
| 359 | } | ||
| 377 | 360 | ||
| 378 | #ifdef CONFIG_SYSCTL | 361 | #ifdef CONFIG_SYSCTL |
| 379 | static int yama_dointvec_minmax(struct ctl_table *table, int write, | 362 | static int yama_dointvec_minmax(struct ctl_table *table, int write, |
| 380 | void __user *buffer, size_t *lenp, loff_t *ppos) | 363 | void __user *buffer, size_t *lenp, loff_t *ppos) |
| 381 | { | 364 | { |
| 382 | int rc; | 365 | struct ctl_table table_copy; |
| 383 | 366 | ||
| 384 | if (write && !capable(CAP_SYS_PTRACE)) | 367 | if (write && !capable(CAP_SYS_PTRACE)) |
| 385 | return -EPERM; | 368 | return -EPERM; |
| 386 | 369 | ||
| 387 | rc = proc_dointvec_minmax(table, write, buffer, lenp, ppos); | ||
| 388 | if (rc) | ||
| 389 | return rc; | ||
| 390 | |||
| 391 | /* Lock the max value if it ever gets set. */ | 370 | /* Lock the max value if it ever gets set. */ |
| 392 | if (write && *(int *)table->data == *(int *)table->extra2) | 371 | table_copy = *table; |
| 393 | table->extra1 = table->extra2; | 372 | if (*(int *)table_copy.data == *(int *)table_copy.extra2) |
| 373 | table_copy.extra1 = table_copy.extra2; | ||
| 394 | 374 | ||
| 395 | return rc; | 375 | return proc_dointvec_minmax(&table_copy, write, buffer, lenp, ppos); |
| 396 | } | 376 | } |
| 397 | 377 | ||
| 398 | static int zero; | 378 | static int zero; |
| @@ -421,16 +401,13 @@ static struct ctl_table yama_sysctl_table[] = { | |||
| 421 | static __init int yama_init(void) | 401 | static __init int yama_init(void) |
| 422 | { | 402 | { |
| 423 | #ifndef CONFIG_SECURITY_YAMA_STACKED | 403 | #ifndef CONFIG_SECURITY_YAMA_STACKED |
| 424 | if (!security_module_enable(&yama_ops)) | 404 | /* |
| 405 | * If yama is being stacked this is already taken care of. | ||
| 406 | */ | ||
| 407 | if (!security_module_enable("yama")) | ||
| 425 | return 0; | 408 | return 0; |
| 426 | #endif | 409 | #endif |
| 427 | 410 | pr_info("Yama: becoming mindful.\n"); | |
| 428 | printk(KERN_INFO "Yama: becoming mindful.\n"); | ||
| 429 | |||
| 430 | #ifndef CONFIG_SECURITY_YAMA_STACKED | ||
| 431 | if (register_security(&yama_ops)) | ||
| 432 | panic("Yama: kernel registration failed.\n"); | ||
| 433 | #endif | ||
| 434 | 411 | ||
| 435 | #ifdef CONFIG_SYSCTL | 412 | #ifdef CONFIG_SYSCTL |
| 436 | if (!register_sysctl_paths(yama_sysctl_path, yama_sysctl_table)) | 413 | if (!register_sysctl_paths(yama_sysctl_path, yama_sysctl_table)) |
