aboutsummaryrefslogtreecommitdiffstats
path: root/net/netlabel/netlabel_unlabeled.c
diff options
context:
space:
mode:
authorPaul Moore <paul.moore@hp.com>2008-01-29 08:44:23 -0500
committerJames Morris <jmorris@namei.org>2008-01-29 16:17:29 -0500
commit13541b3adad2dc2f56761c5193c2b88db3597f0e (patch)
treeef5dfff5135ecb91ccb379d351c9bc5f491e080a /net/netlabel/netlabel_unlabeled.c
parent8cc44579d1bd77ba3a32f2cb76fd9669c229c5fd (diff)
NetLabel: Add auditing to the static labeling mechanism
This patch adds auditing support to the NetLabel static labeling mechanism. Signed-off-by: Paul Moore <paul.moore@hp.com> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'net/netlabel/netlabel_unlabeled.c')
-rw-r--r--net/netlabel/netlabel_unlabeled.c207
1 files changed, 193 insertions, 14 deletions
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index d0c628c875ae..42e81fd8cc49 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -147,6 +147,74 @@ static const struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1
147}; 147};
148 148
149/* 149/*
150 * Audit Helper Functions
151 */
152
153/**
154 * netlbl_unlabel_audit_addr4 - Audit an IPv4 address
155 * @audit_buf: audit buffer
156 * @dev: network interface
157 * @addr: IP address
158 * @mask: IP address mask
159 *
160 * Description:
161 * Write the IPv4 address and address mask, if necessary, to @audit_buf.
162 *
163 */
164static void netlbl_unlabel_audit_addr4(struct audit_buffer *audit_buf,
165 const char *dev,
166 __be32 addr, __be32 mask)
167{
168 u32 mask_val = ntohl(mask);
169
170 if (dev != NULL)
171 audit_log_format(audit_buf, " netif=%s", dev);
172 audit_log_format(audit_buf, " src=" NIPQUAD_FMT, NIPQUAD(addr));
173 if (mask_val != 0xffffffff) {
174 u32 mask_len = 0;
175 while (mask_val > 0) {
176 mask_val <<= 1;
177 mask_len++;
178 }
179 audit_log_format(audit_buf, " src_prefixlen=%d", mask_len);
180 }
181}
182
183/**
184 * netlbl_unlabel_audit_addr6 - Audit an IPv6 address
185 * @audit_buf: audit buffer
186 * @dev: network interface
187 * @addr: IP address
188 * @mask: IP address mask
189 *
190 * Description:
191 * Write the IPv6 address and address mask, if necessary, to @audit_buf.
192 *
193 */
194static void netlbl_unlabel_audit_addr6(struct audit_buffer *audit_buf,
195 const char *dev,
196 const struct in6_addr *addr,
197 const struct in6_addr *mask)
198{
199 if (dev != NULL)
200 audit_log_format(audit_buf, " netif=%s", dev);
201 audit_log_format(audit_buf, " src=" NIP6_FMT, NIP6(*addr));
202 if (ntohl(mask->s6_addr32[3]) != 0xffffffff) {
203 u32 mask_len = 0;
204 u32 mask_val;
205 int iter = -1;
206 while (ntohl(mask->s6_addr32[++iter]) == 0xffffffff)
207 mask_len += 32;
208 mask_val = ntohl(mask->s6_addr32[iter]);
209 while (mask_val > 0) {
210 mask_val <<= 1;
211 mask_len++;
212 }
213 audit_log_format(audit_buf, " src_prefixlen=%d", mask_len);
214 }
215}
216
217/*
150 * Unlabeled Connection Hash Table Functions 218 * Unlabeled Connection Hash Table Functions
151 */ 219 */
152 220
@@ -530,6 +598,7 @@ add_iface_failure:
530 * @mask: address mask in network byte order 598 * @mask: address mask in network byte order
531 * @addr_len: length of address/mask (4 for IPv4, 16 for IPv6) 599 * @addr_len: length of address/mask (4 for IPv4, 16 for IPv6)
532 * @secid: LSM secid value for the entry 600 * @secid: LSM secid value for the entry
601 * @audit_info: NetLabel audit information
533 * 602 *
534 * Description: 603 * Description:
535 * Adds a new entry to the unlabeled connection hash table. Returns zero on 604 * Adds a new entry to the unlabeled connection hash table. Returns zero on
@@ -541,12 +610,18 @@ static int netlbl_unlhsh_add(struct net *net,
541 const void *addr, 610 const void *addr,
542 const void *mask, 611 const void *mask,
543 u32 addr_len, 612 u32 addr_len,
544 u32 secid) 613 u32 secid,
614 struct netlbl_audit *audit_info)
545{ 615{
546 int ret_val; 616 int ret_val;
547 int ifindex; 617 int ifindex;
548 struct net_device *dev; 618 struct net_device *dev;
549 struct netlbl_unlhsh_iface *iface; 619 struct netlbl_unlhsh_iface *iface;
620 struct in_addr *addr4, *mask4;
621 struct in6_addr *addr6, *mask6;
622 struct audit_buffer *audit_buf = NULL;
623 char *secctx = NULL;
624 u32 secctx_len;
550 625
551 if (addr_len != sizeof(struct in_addr) && 626 if (addr_len != sizeof(struct in_addr) &&
552 addr_len != sizeof(struct in6_addr)) 627 addr_len != sizeof(struct in6_addr))
@@ -573,13 +648,28 @@ static int netlbl_unlhsh_add(struct net *net,
573 goto unlhsh_add_return; 648 goto unlhsh_add_return;
574 } 649 }
575 } 650 }
651 audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCADD,
652 audit_info);
576 switch (addr_len) { 653 switch (addr_len) {
577 case sizeof(struct in_addr): 654 case sizeof(struct in_addr):
578 ret_val = netlbl_unlhsh_add_addr4(iface, addr, mask, secid); 655 addr4 = (struct in_addr *)addr;
656 mask4 = (struct in_addr *)mask;
657 ret_val = netlbl_unlhsh_add_addr4(iface, addr4, mask4, secid);
658 if (audit_buf != NULL)
659 netlbl_unlabel_audit_addr4(audit_buf,
660 dev_name,
661 addr4->s_addr,
662 mask4->s_addr);
579 break; 663 break;
580#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 664#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
581 case sizeof(struct in6_addr): 665 case sizeof(struct in6_addr):
582 ret_val = netlbl_unlhsh_add_addr6(iface, addr, mask, secid); 666 addr6 = (struct in6_addr *)addr;
667 mask6 = (struct in6_addr *)mask;
668 ret_val = netlbl_unlhsh_add_addr6(iface, addr6, mask6, secid);
669 if (audit_buf != NULL)
670 netlbl_unlabel_audit_addr6(audit_buf,
671 dev_name,
672 addr6, mask6);
583 break; 673 break;
584#endif /* IPv6 */ 674#endif /* IPv6 */
585 default: 675 default:
@@ -590,14 +680,26 @@ static int netlbl_unlhsh_add(struct net *net,
590 680
591unlhsh_add_return: 681unlhsh_add_return:
592 rcu_read_unlock(); 682 rcu_read_unlock();
683 if (audit_buf != NULL) {
684 if (security_secid_to_secctx(secid,
685 &secctx,
686 &secctx_len) == 0) {
687 audit_log_format(audit_buf, " sec_obj=%s", secctx);
688 security_release_secctx(secctx, secctx_len);
689 }
690 audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0);
691 audit_log_end(audit_buf);
692 }
593 return ret_val; 693 return ret_val;
594} 694}
595 695
596/** 696/**
597 * netlbl_unlhsh_remove_addr4 - Remove an IPv4 address entry 697 * netlbl_unlhsh_remove_addr4 - Remove an IPv4 address entry
698 * @net: network namespace
598 * @iface: interface entry 699 * @iface: interface entry
599 * @addr: IP address 700 * @addr: IP address
600 * @mask: IP address mask 701 * @mask: IP address mask
702 * @audit_info: NetLabel audit information
601 * 703 *
602 * Description: 704 * Description:
603 * Remove an IP address entry from the unlabeled connection hash table. 705 * Remove an IP address entry from the unlabeled connection hash table.
@@ -605,12 +707,18 @@ unlhsh_add_return:
605 * responsible for calling the rcu_read_[un]lock() functions. 707 * responsible for calling the rcu_read_[un]lock() functions.
606 * 708 *
607 */ 709 */
608static int netlbl_unlhsh_remove_addr4(struct netlbl_unlhsh_iface *iface, 710static int netlbl_unlhsh_remove_addr4(struct net *net,
711 struct netlbl_unlhsh_iface *iface,
609 const struct in_addr *addr, 712 const struct in_addr *addr,
610 const struct in_addr *mask) 713 const struct in_addr *mask,
714 struct netlbl_audit *audit_info)
611{ 715{
612 int ret_val = -ENOENT; 716 int ret_val = -ENOENT;
613 struct netlbl_unlhsh_addr4 *entry; 717 struct netlbl_unlhsh_addr4 *entry;
718 struct audit_buffer *audit_buf = NULL;
719 struct net_device *dev;
720 char *secctx = NULL;
721 u32 secctx_len;
614 722
615 spin_lock(&netlbl_unlhsh_lock); 723 spin_lock(&netlbl_unlhsh_lock);
616 entry = netlbl_unlhsh_search_addr4(addr->s_addr, iface); 724 entry = netlbl_unlhsh_search_addr4(addr->s_addr, iface);
@@ -622,6 +730,25 @@ static int netlbl_unlhsh_remove_addr4(struct netlbl_unlhsh_iface *iface,
622 } 730 }
623 spin_unlock(&netlbl_unlhsh_lock); 731 spin_unlock(&netlbl_unlhsh_lock);
624 732
733 audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCDEL,
734 audit_info);
735 if (audit_buf != NULL) {
736 dev = dev_get_by_index(net, iface->ifindex);
737 netlbl_unlabel_audit_addr4(audit_buf,
738 (dev != NULL ? dev->name : NULL),
739 entry->addr, entry->mask);
740 if (dev != NULL)
741 dev_put(dev);
742 if (security_secid_to_secctx(entry->secid,
743 &secctx,
744 &secctx_len) == 0) {
745 audit_log_format(audit_buf, " sec_obj=%s", secctx);
746 security_release_secctx(secctx, secctx_len);
747 }
748 audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0);
749 audit_log_end(audit_buf);
750 }
751
625 if (ret_val == 0) 752 if (ret_val == 0)
626 call_rcu(&entry->rcu, netlbl_unlhsh_free_addr4); 753 call_rcu(&entry->rcu, netlbl_unlhsh_free_addr4);
627 return ret_val; 754 return ret_val;
@@ -630,9 +757,11 @@ static int netlbl_unlhsh_remove_addr4(struct netlbl_unlhsh_iface *iface,
630#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 757#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
631/** 758/**
632 * netlbl_unlhsh_remove_addr6 - Remove an IPv6 address entry 759 * netlbl_unlhsh_remove_addr6 - Remove an IPv6 address entry
760 * @net: network namespace
633 * @iface: interface entry 761 * @iface: interface entry
634 * @addr: IP address 762 * @addr: IP address
635 * @mask: IP address mask 763 * @mask: IP address mask
764 * @audit_info: NetLabel audit information
636 * 765 *
637 * Description: 766 * Description:
638 * Remove an IP address entry from the unlabeled connection hash table. 767 * Remove an IP address entry from the unlabeled connection hash table.
@@ -640,12 +769,18 @@ static int netlbl_unlhsh_remove_addr4(struct netlbl_unlhsh_iface *iface,
640 * responsible for calling the rcu_read_[un]lock() functions. 769 * responsible for calling the rcu_read_[un]lock() functions.
641 * 770 *
642 */ 771 */
643static int netlbl_unlhsh_remove_addr6(struct netlbl_unlhsh_iface *iface, 772static int netlbl_unlhsh_remove_addr6(struct net *net,
773 struct netlbl_unlhsh_iface *iface,
644 const struct in6_addr *addr, 774 const struct in6_addr *addr,
645 const struct in6_addr *mask) 775 const struct in6_addr *mask,
776 struct netlbl_audit *audit_info)
646{ 777{
647 int ret_val = -ENOENT; 778 int ret_val = -ENOENT;
648 struct netlbl_unlhsh_addr6 *entry; 779 struct netlbl_unlhsh_addr6 *entry;
780 struct audit_buffer *audit_buf = NULL;
781 struct net_device *dev;
782 char *secctx = NULL;
783 u32 secctx_len;
649 784
650 spin_lock(&netlbl_unlhsh_lock); 785 spin_lock(&netlbl_unlhsh_lock);
651 entry = netlbl_unlhsh_search_addr6(addr, iface); 786 entry = netlbl_unlhsh_search_addr6(addr, iface);
@@ -658,6 +793,25 @@ static int netlbl_unlhsh_remove_addr6(struct netlbl_unlhsh_iface *iface,
658 } 793 }
659 spin_unlock(&netlbl_unlhsh_lock); 794 spin_unlock(&netlbl_unlhsh_lock);
660 795
796 audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCDEL,
797 audit_info);
798 if (audit_buf != NULL) {
799 dev = dev_get_by_index(net, iface->ifindex);
800 netlbl_unlabel_audit_addr6(audit_buf,
801 (dev != NULL ? dev->name : NULL),
802 addr, mask);
803 if (dev != NULL)
804 dev_put(dev);
805 if (security_secid_to_secctx(entry->secid,
806 &secctx,
807 &secctx_len) == 0) {
808 audit_log_format(audit_buf, " sec_obj=%s", secctx);
809 security_release_secctx(secctx, secctx_len);
810 }
811 audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0);
812 audit_log_end(audit_buf);
813 }
814
661 if (ret_val == 0) 815 if (ret_val == 0)
662 call_rcu(&entry->rcu, netlbl_unlhsh_free_addr6); 816 call_rcu(&entry->rcu, netlbl_unlhsh_free_addr6);
663 return ret_val; 817 return ret_val;
@@ -708,6 +862,7 @@ unlhsh_condremove_failure:
708 * @addr: IP address in network byte order 862 * @addr: IP address in network byte order
709 * @mask: address mask in network byte order 863 * @mask: address mask in network byte order
710 * @addr_len: length of address/mask (4 for IPv4, 16 for IPv6) 864 * @addr_len: length of address/mask (4 for IPv4, 16 for IPv6)
865 * @audit_info: NetLabel audit information
711 * 866 *
712 * Description: 867 * Description:
713 * Removes and existing entry from the unlabeled connection hash table. 868 * Removes and existing entry from the unlabeled connection hash table.
@@ -718,7 +873,8 @@ static int netlbl_unlhsh_remove(struct net *net,
718 const char *dev_name, 873 const char *dev_name,
719 const void *addr, 874 const void *addr,
720 const void *mask, 875 const void *mask,
721 u32 addr_len) 876 u32 addr_len,
877 struct netlbl_audit *audit_info)
722{ 878{
723 int ret_val; 879 int ret_val;
724 struct net_device *dev; 880 struct net_device *dev;
@@ -745,11 +901,15 @@ static int netlbl_unlhsh_remove(struct net *net,
745 } 901 }
746 switch (addr_len) { 902 switch (addr_len) {
747 case sizeof(struct in_addr): 903 case sizeof(struct in_addr):
748 ret_val = netlbl_unlhsh_remove_addr4(iface, addr, mask); 904 ret_val = netlbl_unlhsh_remove_addr4(net,
905 iface, addr, mask,
906 audit_info);
749 break; 907 break;
750#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 908#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
751 case sizeof(struct in6_addr): 909 case sizeof(struct in6_addr):
752 ret_val = netlbl_unlhsh_remove_addr6(iface, addr, mask); 910 ret_val = netlbl_unlhsh_remove_addr6(net,
911 iface, addr, mask,
912 audit_info);
753 break; 913 break;
754#endif /* IPv6 */ 914#endif /* IPv6 */
755 default: 915 default:
@@ -972,6 +1132,7 @@ static int netlbl_unlabel_staticadd(struct sk_buff *skb,
972 void *mask; 1132 void *mask;
973 u32 addr_len; 1133 u32 addr_len;
974 u32 secid; 1134 u32 secid;
1135 struct netlbl_audit audit_info;
975 1136
976 /* Don't allow users to add both IPv4 and IPv6 addresses for a 1137 /* Don't allow users to add both IPv4 and IPv6 addresses for a
977 * single entry. However, allow users to create two entries, one each 1138 * single entry. However, allow users to create two entries, one each
@@ -985,6 +1146,8 @@ static int netlbl_unlabel_staticadd(struct sk_buff *skb,
985 !info->attrs[NLBL_UNLABEL_A_IPV6MASK]))) 1146 !info->attrs[NLBL_UNLABEL_A_IPV6MASK])))
986 return -EINVAL; 1147 return -EINVAL;
987 1148
1149 netlbl_netlink_auditinfo(skb, &audit_info);
1150
988 ret_val = netlbl_unlabel_addrinfo_get(info, &addr, &mask, &addr_len); 1151 ret_val = netlbl_unlabel_addrinfo_get(info, &addr, &mask, &addr_len);
989 if (ret_val != 0) 1152 if (ret_val != 0)
990 return ret_val; 1153 return ret_val;
@@ -997,7 +1160,8 @@ static int netlbl_unlabel_staticadd(struct sk_buff *skb,
997 return ret_val; 1160 return ret_val;
998 1161
999 return netlbl_unlhsh_add(&init_net, 1162 return netlbl_unlhsh_add(&init_net,
1000 dev_name, addr, mask, addr_len, secid); 1163 dev_name, addr, mask, addr_len, secid,
1164 &audit_info);
1001} 1165}
1002 1166
1003/** 1167/**
@@ -1019,6 +1183,7 @@ static int netlbl_unlabel_staticadddef(struct sk_buff *skb,
1019 void *mask; 1183 void *mask;
1020 u32 addr_len; 1184 u32 addr_len;
1021 u32 secid; 1185 u32 secid;
1186 struct netlbl_audit audit_info;
1022 1187
1023 /* Don't allow users to add both IPv4 and IPv6 addresses for a 1188 /* Don't allow users to add both IPv4 and IPv6 addresses for a
1024 * single entry. However, allow users to create two entries, one each 1189 * single entry. However, allow users to create two entries, one each
@@ -1031,6 +1196,8 @@ static int netlbl_unlabel_staticadddef(struct sk_buff *skb,
1031 !info->attrs[NLBL_UNLABEL_A_IPV6MASK]))) 1196 !info->attrs[NLBL_UNLABEL_A_IPV6MASK])))
1032 return -EINVAL; 1197 return -EINVAL;
1033 1198
1199 netlbl_netlink_auditinfo(skb, &audit_info);
1200
1034 ret_val = netlbl_unlabel_addrinfo_get(info, &addr, &mask, &addr_len); 1201 ret_val = netlbl_unlabel_addrinfo_get(info, &addr, &mask, &addr_len);
1035 if (ret_val != 0) 1202 if (ret_val != 0)
1036 return ret_val; 1203 return ret_val;
@@ -1041,7 +1208,9 @@ static int netlbl_unlabel_staticadddef(struct sk_buff *skb,
1041 if (ret_val != 0) 1208 if (ret_val != 0)
1042 return ret_val; 1209 return ret_val;
1043 1210
1044 return netlbl_unlhsh_add(&init_net, NULL, addr, mask, addr_len, secid); 1211 return netlbl_unlhsh_add(&init_net,
1212 NULL, addr, mask, addr_len, secid,
1213 &audit_info);
1045} 1214}
1046 1215
1047/** 1216/**
@@ -1063,6 +1232,7 @@ static int netlbl_unlabel_staticremove(struct sk_buff *skb,
1063 void *addr; 1232 void *addr;
1064 void *mask; 1233 void *mask;
1065 u32 addr_len; 1234 u32 addr_len;
1235 struct netlbl_audit audit_info;
1066 1236
1067 /* See the note in netlbl_unlabel_staticadd() about not allowing both 1237 /* See the note in netlbl_unlabel_staticadd() about not allowing both
1068 * IPv4 and IPv6 in the same entry. */ 1238 * IPv4 and IPv6 in the same entry. */
@@ -1073,12 +1243,16 @@ static int netlbl_unlabel_staticremove(struct sk_buff *skb,
1073 !info->attrs[NLBL_UNLABEL_A_IPV6MASK]))) 1243 !info->attrs[NLBL_UNLABEL_A_IPV6MASK])))
1074 return -EINVAL; 1244 return -EINVAL;
1075 1245
1246 netlbl_netlink_auditinfo(skb, &audit_info);
1247
1076 ret_val = netlbl_unlabel_addrinfo_get(info, &addr, &mask, &addr_len); 1248 ret_val = netlbl_unlabel_addrinfo_get(info, &addr, &mask, &addr_len);
1077 if (ret_val != 0) 1249 if (ret_val != 0)
1078 return ret_val; 1250 return ret_val;
1079 dev_name = nla_data(info->attrs[NLBL_UNLABEL_A_IFACE]); 1251 dev_name = nla_data(info->attrs[NLBL_UNLABEL_A_IFACE]);
1080 1252
1081 return netlbl_unlhsh_remove(&init_net, dev_name, addr, mask, addr_len); 1253 return netlbl_unlhsh_remove(&init_net,
1254 dev_name, addr, mask, addr_len,
1255 &audit_info);
1082} 1256}
1083 1257
1084/** 1258/**
@@ -1099,6 +1273,7 @@ static int netlbl_unlabel_staticremovedef(struct sk_buff *skb,
1099 void *addr; 1273 void *addr;
1100 void *mask; 1274 void *mask;
1101 u32 addr_len; 1275 u32 addr_len;
1276 struct netlbl_audit audit_info;
1102 1277
1103 /* See the note in netlbl_unlabel_staticadd() about not allowing both 1278 /* See the note in netlbl_unlabel_staticadd() about not allowing both
1104 * IPv4 and IPv6 in the same entry. */ 1279 * IPv4 and IPv6 in the same entry. */
@@ -1108,11 +1283,15 @@ static int netlbl_unlabel_staticremovedef(struct sk_buff *skb,
1108 !info->attrs[NLBL_UNLABEL_A_IPV6MASK]))) 1283 !info->attrs[NLBL_UNLABEL_A_IPV6MASK])))
1109 return -EINVAL; 1284 return -EINVAL;
1110 1285
1286 netlbl_netlink_auditinfo(skb, &audit_info);
1287
1111 ret_val = netlbl_unlabel_addrinfo_get(info, &addr, &mask, &addr_len); 1288 ret_val = netlbl_unlabel_addrinfo_get(info, &addr, &mask, &addr_len);
1112 if (ret_val != 0) 1289 if (ret_val != 0)
1113 return ret_val; 1290 return ret_val;
1114 1291
1115 return netlbl_unlhsh_remove(&init_net, NULL, addr, mask, addr_len); 1292 return netlbl_unlhsh_remove(&init_net,
1293 NULL, addr, mask, addr_len,
1294 &audit_info);
1116} 1295}
1117 1296
1118 1297