(mensagem de log vazia)
@@ -830,7 +830,7 @@ | ||
830 | 830 | }; |
831 | 831 | |
832 | 832 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) |
833 | -#if defined(CONFIG_STRICT_KERNEL_RWX) && !defined(SECURITY_WRITABLE_HOOKS) | |
833 | +#if defined(CONFIG_STRICT_KERNEL_RWX) && !defined(CONFIG_SECURITY_WRITABLE_HOOKS) | |
834 | 834 | #include <linux/uaccess.h> /* probe_kernel_write() */ |
835 | 835 | #define NEED_TO_CHECK_HOOKS_ARE_WRITABLE |
836 | 836 |
@@ -861,6 +861,23 @@ | ||
861 | 861 | |
862 | 862 | static bool __init check_ro_pages(struct security_hook_heads *hooks) |
863 | 863 | { |
864 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) | |
865 | + struct hlist_head *list = &hooks->capable; | |
866 | + | |
867 | + if (!probe_kernel_write(list, list, sizeof(void *))) | |
868 | + return true; | |
869 | + { | |
870 | + struct hlist_head *head = kpr_hook.head; | |
871 | + struct security_hook_list *shp; | |
872 | + | |
873 | + if (!lsm_test_page_ro(&head->first)) | |
874 | + return false; | |
875 | + hlist_for_each_entry(shp, head, list) | |
876 | + if (!lsm_test_page_ro(&shp->list.next) || | |
877 | + !lsm_test_page_ro(&shp->list.pprev)) | |
878 | + return false; | |
879 | + } | |
880 | +#else | |
864 | 881 | struct list_head *list = &hooks->capable; |
865 | 882 | |
866 | 883 | if (!probe_kernel_write(list, list, sizeof(void *))) |
@@ -877,12 +894,17 @@ | ||
877 | 894 | !lsm_test_page_ro(&shp->list.prev)) |
878 | 895 | return false; |
879 | 896 | } |
897 | +#endif | |
880 | 898 | return true; |
881 | 899 | } |
882 | 900 | #else |
883 | 901 | static bool __init check_ro_pages(struct security_hook_heads *hooks) |
884 | 902 | { |
903 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) | |
904 | + struct hlist_head *list = &hooks->capable; | |
905 | +#else | |
885 | 906 | struct list_head *list = &hooks->capable; |
907 | +#endif | |
886 | 908 | |
887 | 909 | return !probe_kernel_write(list, list, sizeof(void *)); |
888 | 910 | } |
@@ -948,7 +970,11 @@ | ||
948 | 970 | for (idx = 0; idx < ro_pages_len; idx++) |
949 | 971 | set_bit(_PAGE_BIT_RW, &(ro_pages[idx]->flags)); |
950 | 972 | #endif |
973 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) | |
974 | + hlist_add_tail_rcu(&kpr_hook.list, kpr_hook.head); | |
975 | +#else | |
951 | 976 | list_add_tail_rcu(&kpr_hook.list, kpr_hook.head); |
977 | +#endif | |
952 | 978 | #if defined(NEED_TO_CHECK_HOOKS_ARE_WRITABLE) && defined(CONFIG_X86) |
953 | 979 | for (idx = 0; idx < ro_pages_len; idx++) |
954 | 980 | clear_bit(_PAGE_BIT_RW, &(ro_pages[idx]->flags)); |
@@ -201,9 +201,15 @@ | ||
201 | 201 | do { |
202 | 202 | struct security_hook_list *p; |
203 | 203 | |
204 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) | |
205 | + hlist_for_each_entry(p, &probe_dummy_security_hook_heads. | |
206 | + bprm_committed_creds, list) | |
207 | + p->hook.bprm_committed_creds(bprm); | |
208 | +#else | |
204 | 209 | list_for_each_entry(p, &probe_dummy_security_hook_heads. |
205 | 210 | bprm_committed_creds, list) |
206 | 211 | p->hook.bprm_committed_creds(bprm); |
212 | +#endif | |
207 | 213 | } while (0); |
208 | 214 | } |
209 | 215 |
@@ -519,9 +525,15 @@ | ||
519 | 525 | } |
520 | 526 | /* This should be "struct security_hook_heads security_hook_heads;". */ |
521 | 527 | shh = ((void *) (*(unsigned long *) cp)) - offset; |
528 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) | |
529 | + hlist_for_each_entry(entry, &shh->bprm_set_creds, list) | |
530 | + if (entry->hook.bprm_set_creds == cap) | |
531 | + return shh; | |
532 | +#else | |
522 | 533 | list_for_each_entry(entry, &shh->bprm_set_creds, list) |
523 | 534 | if (entry->hook.bprm_set_creds == cap) |
524 | 535 | return shh; |
536 | +#endif | |
525 | 537 | printk(KERN_ERR "Guessed security_hook_heads is 0x%lx\n", |
526 | 538 | (unsigned long) shh); |
527 | 539 | return NULL; |
@@ -201,9 +201,15 @@ | ||
201 | 201 | do { |
202 | 202 | struct security_hook_list *p; |
203 | 203 | |
204 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) | |
205 | + hlist_for_each_entry(p, &probe_dummy_security_hook_heads. | |
206 | + bprm_committed_creds, list) | |
207 | + p->hook.bprm_committed_creds(bprm); | |
208 | +#else | |
204 | 209 | list_for_each_entry(p, &probe_dummy_security_hook_heads. |
205 | 210 | bprm_committed_creds, list) |
206 | 211 | p->hook.bprm_committed_creds(bprm); |
212 | +#endif | |
207 | 213 | } while (0); |
208 | 214 | } |
209 | 215 |
@@ -519,9 +525,15 @@ | ||
519 | 525 | } |
520 | 526 | /* This should be "struct security_hook_heads security_hook_heads;". */ |
521 | 527 | shh = ((void *) (*(unsigned long *) cp)) - offset; |
528 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) | |
529 | + hlist_for_each_entry(entry, &shh->bprm_set_creds, list) | |
530 | + if (entry->hook.bprm_set_creds == cap) | |
531 | + return shh; | |
532 | +#else | |
522 | 533 | list_for_each_entry(entry, &shh->bprm_set_creds, list) |
523 | 534 | if (entry->hook.bprm_set_creds == cap) |
524 | 535 | return shh; |
536 | +#endif | |
525 | 537 | printk(KERN_ERR "Guessed security_hook_heads is 0x%lx\n", |
526 | 538 | (unsigned long) shh); |
527 | 539 | return NULL; |
@@ -607,13 +607,34 @@ | ||
607 | 607 | |
608 | 608 | static inline void add_hook(struct security_hook_list *hook) |
609 | 609 | { |
610 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) | |
611 | + hlist_add_tail_rcu(&hook->list, hook->head); | |
612 | +#else | |
610 | 613 | list_add_tail_rcu(&hook->list, hook->head); |
614 | +#endif | |
611 | 615 | } |
612 | 616 | |
613 | 617 | static void __init swap_hook(struct security_hook_list *hook, |
614 | 618 | union security_list_options *original) |
615 | 619 | { |
620 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) | |
621 | + struct hlist_head *list = hook->head; | |
622 | + | |
623 | + if (hlist_empty(list)) { | |
624 | + add_hook(hook); | |
625 | + } else { | |
626 | + struct security_hook_list *shp = | |
627 | + hlist_entry(list->first, typeof(*shp), list); | |
628 | + | |
629 | + while (shp->list.next) | |
630 | + shp = hlist_entry(shp->list.next, typeof(*shp), list); | |
631 | + *original = shp->hook; | |
632 | + smp_wmb(); | |
633 | + shp->hook = hook->hook; | |
634 | + } | |
635 | +#else | |
616 | 636 | struct list_head *list = hook->head; |
637 | + | |
617 | 638 | if (list_empty(list)) { |
618 | 639 | add_hook(hook); |
619 | 640 | } else { |
@@ -623,10 +644,11 @@ | ||
623 | 644 | smp_wmb(); |
624 | 645 | shp->hook = hook->hook; |
625 | 646 | } |
647 | +#endif | |
626 | 648 | } |
627 | 649 | |
628 | 650 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) |
629 | -#if defined(CONFIG_STRICT_KERNEL_RWX) && !defined(SECURITY_WRITABLE_HOOKS) | |
651 | +#if defined(CONFIG_STRICT_KERNEL_RWX) && !defined(CONFIG_SECURITY_WRITABLE_HOOKS) | |
630 | 652 | #include <linux/uaccess.h> /* probe_kernel_write() */ |
631 | 653 | #define NEED_TO_CHECK_HOOKS_ARE_WRITABLE |
632 | 654 |
@@ -658,6 +680,23 @@ | ||
658 | 680 | static bool __init check_ro_pages(struct security_hook_heads *hooks) |
659 | 681 | { |
660 | 682 | int i; |
683 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) | |
684 | + struct hlist_head *list = &hooks->capable; | |
685 | + | |
686 | + if (!probe_kernel_write(list, list, sizeof(void *))) | |
687 | + return true; | |
688 | + for (i = 0; i < ARRAY_SIZE(tt_hooks); i++) { | |
689 | + struct hlist_head *head = tt_hooks[i].head; | |
690 | + struct security_hook_list *shp; | |
691 | + | |
692 | + if (!lsm_test_page_ro(&head->first)) | |
693 | + return false; | |
694 | + hlist_for_each_entry(shp, head, list) | |
695 | + if (!lsm_test_page_ro(&shp->list.next) || | |
696 | + !lsm_test_page_ro(&shp->list.pprev)) | |
697 | + return false; | |
698 | + } | |
699 | +#else | |
661 | 700 | struct list_head *list = &hooks->capable; |
662 | 701 | |
663 | 702 | if (!probe_kernel_write(list, list, sizeof(void *))) |
@@ -674,12 +713,17 @@ | ||
674 | 713 | !lsm_test_page_ro(&shp->list.prev)) |
675 | 714 | return false; |
676 | 715 | } |
716 | +#endif | |
677 | 717 | return true; |
678 | 718 | } |
679 | 719 | #else |
680 | 720 | static bool __init check_ro_pages(struct security_hook_heads *hooks) |
681 | 721 | { |
722 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) | |
723 | + struct hlist_head *list = &hooks->capable; | |
724 | +#else | |
682 | 725 | struct list_head *list = &hooks->capable; |
726 | +#endif | |
683 | 727 | |
684 | 728 | return !probe_kernel_write(list, list, sizeof(void *)); |
685 | 729 | } |
@@ -752,10 +796,17 @@ | ||
752 | 796 | tt_hooks[idx].head = ((void *) hooks) |
753 | 797 | + ((unsigned long) tt_hooks[idx].head) |
754 | 798 | - ((unsigned long) &probe_dummy_security_hook_heads); |
799 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) | |
800 | + if (!hlist_empty(tt_hooks[1].head) || !hlist_empty(tt_hooks[2].head)) { | |
801 | + printk(KERN_INFO "TaskTracker module needs exclusive access to task_getsecid/secid_to_secctx hooks. Please restart the system with security=none kernel command line option.\n"); | |
802 | + return -EINVAL; | |
803 | + } | |
804 | +#else | |
755 | 805 | if (!list_empty(tt_hooks[1].head) || !list_empty(tt_hooks[2].head)) { |
756 | 806 | printk(KERN_INFO "TaskTracker module needs exclusive access to task_getsecid/secid_to_secctx hooks. Please restart the system with security=none kernel command line option.\n"); |
757 | 807 | return -EINVAL; |
758 | 808 | } |
809 | +#endif | |
759 | 810 | #if defined(NEED_TO_CHECK_HOOKS_ARE_WRITABLE) |
760 | 811 | if (!check_ro_pages(hooks)) { |
761 | 812 | printk(KERN_INFO "Can't update security_hook_heads due to write protected. Retry with rodata=0 kernel command line option added.\n"); |
@@ -1018,13 +1018,34 @@ | ||
1018 | 1018 | |
1019 | 1019 | static inline void add_hook(struct security_hook_list *hook) |
1020 | 1020 | { |
1021 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) | |
1022 | + hlist_add_tail_rcu(&hook->list, hook->head); | |
1023 | +#else | |
1021 | 1024 | list_add_tail_rcu(&hook->list, hook->head); |
1025 | +#endif | |
1022 | 1026 | } |
1023 | 1027 | |
1024 | 1028 | static void __init swap_hook(struct security_hook_list *hook, |
1025 | 1029 | union security_list_options *original) |
1026 | 1030 | { |
1031 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) | |
1032 | + struct hlist_head *list = hook->head; | |
1033 | + | |
1034 | + if (hlist_empty(list)) { | |
1035 | + add_hook(hook); | |
1036 | + } else { | |
1037 | + struct security_hook_list *shp = | |
1038 | + hlist_entry(list->first, typeof(*shp), list); | |
1039 | + | |
1040 | + while (shp->list.next) | |
1041 | + shp = hlist_entry(shp->list.next, typeof(*shp), list); | |
1042 | + *original = shp->hook; | |
1043 | + smp_wmb(); | |
1044 | + shp->hook = hook->hook; | |
1045 | + } | |
1046 | +#else | |
1027 | 1047 | struct list_head *list = hook->head; |
1048 | + | |
1028 | 1049 | if (list_empty(list)) { |
1029 | 1050 | add_hook(hook); |
1030 | 1051 | } else { |
@@ -1034,9 +1055,10 @@ | ||
1034 | 1055 | smp_wmb(); |
1035 | 1056 | shp->hook = hook->hook; |
1036 | 1057 | } |
1058 | +#endif | |
1037 | 1059 | } |
1038 | 1060 | |
1039 | -#if defined(CONFIG_STRICT_KERNEL_RWX) && !defined(SECURITY_WRITABLE_HOOKS) | |
1061 | +#if defined(CONFIG_STRICT_KERNEL_RWX) && !defined(CONFIG_SECURITY_WRITABLE_HOOKS) | |
1040 | 1062 | #include <linux/uaccess.h> /* probe_kernel_write() */ |
1041 | 1063 | #define NEED_TO_CHECK_HOOKS_ARE_WRITABLE |
1042 | 1064 |
@@ -1068,6 +1090,23 @@ | ||
1068 | 1090 | static bool __init check_ro_pages(struct security_hook_heads *hooks) |
1069 | 1091 | { |
1070 | 1092 | int i; |
1093 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) | |
1094 | + struct hlist_head *list = &hooks->capable; | |
1095 | + | |
1096 | + if (!probe_kernel_write(list, list, sizeof(void *))) | |
1097 | + return true; | |
1098 | + for (i = 0; i < ARRAY_SIZE(akari_hooks); i++) { | |
1099 | + struct hlist_head *head = akari_hooks[i].head; | |
1100 | + struct security_hook_list *shp; | |
1101 | + | |
1102 | + if (!lsm_test_page_ro(&head->first)) | |
1103 | + return false; | |
1104 | + hlist_for_each_entry(shp, head, list) | |
1105 | + if (!lsm_test_page_ro(&shp->list.next) || | |
1106 | + !lsm_test_page_ro(&shp->list.pprev)) | |
1107 | + return false; | |
1108 | + } | |
1109 | +#else | |
1071 | 1110 | struct list_head *list = &hooks->capable; |
1072 | 1111 | |
1073 | 1112 | if (!probe_kernel_write(list, list, sizeof(void *))) |
@@ -1084,12 +1123,17 @@ | ||
1084 | 1123 | !lsm_test_page_ro(&shp->list.prev)) |
1085 | 1124 | return false; |
1086 | 1125 | } |
1126 | +#endif | |
1087 | 1127 | return true; |
1088 | 1128 | } |
1089 | 1129 | #else |
1090 | 1130 | static bool __init check_ro_pages(struct security_hook_heads *hooks) |
1091 | 1131 | { |
1132 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) | |
1133 | + struct hlist_head *list = &hooks->capable; | |
1134 | +#else | |
1092 | 1135 | struct list_head *list = &hooks->capable; |
1136 | +#endif | |
1093 | 1137 | |
1094 | 1138 | return !probe_kernel_write(list, list, sizeof(void *)); |
1095 | 1139 | } |
@@ -201,9 +201,15 @@ | ||
201 | 201 | do { |
202 | 202 | struct security_hook_list *p; |
203 | 203 | |
204 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) | |
205 | + hlist_for_each_entry(p, &probe_dummy_security_hook_heads. | |
206 | + bprm_committed_creds, list) | |
207 | + p->hook.bprm_committed_creds(bprm); | |
208 | +#else | |
204 | 209 | list_for_each_entry(p, &probe_dummy_security_hook_heads. |
205 | 210 | bprm_committed_creds, list) |
206 | 211 | p->hook.bprm_committed_creds(bprm); |
212 | +#endif | |
207 | 213 | } while (0); |
208 | 214 | } |
209 | 215 |
@@ -519,9 +525,15 @@ | ||
519 | 525 | } |
520 | 526 | /* This should be "struct security_hook_heads security_hook_heads;". */ |
521 | 527 | shh = ((void *) (*(unsigned long *) cp)) - offset; |
528 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) | |
529 | + hlist_for_each_entry(entry, &shh->bprm_set_creds, list) | |
530 | + if (entry->hook.bprm_set_creds == cap) | |
531 | + return shh; | |
532 | +#else | |
522 | 533 | list_for_each_entry(entry, &shh->bprm_set_creds, list) |
523 | 534 | if (entry->hook.bprm_set_creds == cap) |
524 | 535 | return shh; |
536 | +#endif | |
525 | 537 | printk(KERN_ERR "Guessed security_hook_heads is 0x%lx\n", |
526 | 538 | (unsigned long) shh); |
527 | 539 | return NULL; |