642} 643 644static int 645mac_biba_parse_element(struct mac_biba_element *element, char *string) 646{ 647 char *compartment, *end, *grade; 648 int value; 649 650 if (strcmp(string, "high") == 0 || 651 strcmp(string, "hi") == 0) { 652 element->mbe_type = MAC_BIBA_TYPE_HIGH; 653 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 654 } else if (strcmp(string, "low") == 0 || 655 strcmp(string, "lo") == 0) { 656 element->mbe_type = MAC_BIBA_TYPE_LOW; 657 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 658 } else if (strcmp(string, "equal") == 0 || 659 strcmp(string, "eq") == 0) { 660 element->mbe_type = MAC_BIBA_TYPE_EQUAL; 661 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 662 } else { 663 element->mbe_type = MAC_BIBA_TYPE_GRADE; 664 665 /* 666 * Numeric grade piece of the element. 667 */ 668 grade = strsep(&string, ":"); 669 value = strtol(grade, &end, 10); 670 if (end == grade || *end != '\0') 671 return (EINVAL); 672 if (value < 0 || value > 65535) 673 return (EINVAL); 674 element->mbe_grade = value; 675 676 /* 677 * Optional compartment piece of the element. If none 678 * are included, we assume that the label has no 679 * compartments. 680 */ 681 if (string == NULL) 682 return (0); 683 if (*string == '\0') 684 return (0); 685 686 while ((compartment = strsep(&string, "+")) != NULL) { 687 value = strtol(compartment, &end, 10); 688 if (compartment == end || *end != '\0') 689 return (EINVAL); 690 if (value < 1 || value > MAC_BIBA_MAX_COMPARTMENTS) 691 return (EINVAL); 692 MAC_BIBA_BIT_SET(value, element->mbe_compartments); 693 } 694 } 695 696 return (0); 697} 698 699/* 700 * Note: destructively consumes the string, make a local copy before 701 * calling if that's a problem. 702 */ 703static int 704mac_biba_parse(struct mac_biba *mac_biba, char *string) 705{ 706 char *rangehigh, *rangelow, *single; 707 int error; 708 709 single = strsep(&string, "("); 710 if (*single == '\0') 711 single = NULL; 712 713 if (string != NULL) { 714 rangelow = strsep(&string, "-"); 715 if (string == NULL) 716 return (EINVAL); 717 rangehigh = strsep(&string, ")"); 718 if (string == NULL) 719 return (EINVAL); 720 if (*string != '\0') 721 return (EINVAL); 722 } else { 723 rangelow = NULL; 724 rangehigh = NULL; 725 } 726 727 KASSERT((rangelow != NULL && rangehigh != NULL) || 728 (rangelow == NULL && rangehigh == NULL), 729 ("mac_biba_parse: range mismatch")); 730 731 bzero(mac_biba, sizeof(*mac_biba)); 732 if (single != NULL) { 733 error = mac_biba_parse_element(&mac_biba->mb_single, single); 734 if (error) 735 return (error); 736 mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE; 737 } 738 739 if (rangelow != NULL) { 740 error = mac_biba_parse_element(&mac_biba->mb_rangelow, 741 rangelow); 742 if (error) 743 return (error); 744 error = mac_biba_parse_element(&mac_biba->mb_rangehigh, 745 rangehigh); 746 if (error) 747 return (error); 748 mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE; 749 } 750 751 error = mac_biba_valid(mac_biba); 752 if (error) 753 return (error); 754 755 return (0); 756} 757 758static int 759mac_biba_internalize_label(struct label *label, char *element_name, 760 char *element_data, int *claimed) 761{ 762 struct mac_biba *mac_biba, mac_biba_temp; 763 int error; 764 765 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 766 return (0); 767 768 (*claimed)++; 769 770 error = mac_biba_parse(&mac_biba_temp, element_data); 771 if (error) 772 return (error); 773 774 mac_biba = SLOT(label); 775 *mac_biba = mac_biba_temp; 776 777 return (0); 778} 779 780static void 781mac_biba_copy_label(struct label *src, struct label *dest) 782{ 783 784 *SLOT(dest) = *SLOT(src); 785} 786 787/* 788 * Labeling event operations: file system objects, and things that look 789 * a lot like file system objects. 790 */ 791static void 792mac_biba_create_devfs_device(struct mount *mp, dev_t dev, 793 struct devfs_dirent *devfs_dirent, struct label *label) 794{ 795 struct mac_biba *mac_biba; 796 int biba_type; 797 798 mac_biba = SLOT(label); 799 if (strcmp(dev->si_name, "null") == 0 || 800 strcmp(dev->si_name, "zero") == 0 || 801 strcmp(dev->si_name, "random") == 0 || 802 strncmp(dev->si_name, "fd/", strlen("fd/")) == 0) 803 biba_type = MAC_BIBA_TYPE_EQUAL; 804 else if (ptys_equal && 805 (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 || 806 strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0)) 807 biba_type = MAC_BIBA_TYPE_EQUAL; 808 else 809 biba_type = MAC_BIBA_TYPE_HIGH; 810 mac_biba_set_single(mac_biba, biba_type, 0, NULL); 811} 812 813static void 814mac_biba_create_devfs_directory(struct mount *mp, char *dirname, 815 int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label) 816{ 817 struct mac_biba *mac_biba; 818 819 mac_biba = SLOT(label); 820 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 821} 822 823static void 824mac_biba_create_devfs_symlink(struct ucred *cred, struct mount *mp, 825 struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de, 826 struct label *delabel) 827{ 828 struct mac_biba *source, *dest; 829 830 source = SLOT(&cred->cr_label); 831 dest = SLOT(delabel); 832 833 mac_biba_copy_single(source, dest); 834} 835 836static void 837mac_biba_create_mount(struct ucred *cred, struct mount *mp, 838 struct label *mntlabel, struct label *fslabel) 839{ 840 struct mac_biba *source, *dest; 841 842 source = SLOT(&cred->cr_label); 843 dest = SLOT(mntlabel); 844 mac_biba_copy_single(source, dest); 845 dest = SLOT(fslabel); 846 mac_biba_copy_single(source, dest); 847} 848 849static void 850mac_biba_create_root_mount(struct ucred *cred, struct mount *mp, 851 struct label *mntlabel, struct label *fslabel) 852{ 853 struct mac_biba *mac_biba; 854 855 /* Always mount root as high integrity. */ 856 mac_biba = SLOT(fslabel); 857 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 858 mac_biba = SLOT(mntlabel); 859 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 860} 861 862static void 863mac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp, 864 struct label *vnodelabel, struct label *label) 865{ 866 struct mac_biba *source, *dest; 867 868 source = SLOT(label); 869 dest = SLOT(vnodelabel); 870 871 mac_biba_copy(source, dest); 872} 873 874static void 875mac_biba_update_devfsdirent(struct mount *mp, 876 struct devfs_dirent *devfs_dirent, struct label *direntlabel, 877 struct vnode *vp, struct label *vnodelabel) 878{ 879 struct mac_biba *source, *dest; 880 881 source = SLOT(vnodelabel); 882 dest = SLOT(direntlabel); 883 884 mac_biba_copy(source, dest); 885} 886 887static void 888mac_biba_associate_vnode_devfs(struct mount *mp, struct label *fslabel, 889 struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 890 struct label *vlabel) 891{ 892 struct mac_biba *source, *dest; 893 894 source = SLOT(delabel); 895 dest = SLOT(vlabel); 896 897 mac_biba_copy_single(source, dest); 898} 899 900static int 901mac_biba_associate_vnode_extattr(struct mount *mp, struct label *fslabel, 902 struct vnode *vp, struct label *vlabel) 903{ 904 struct mac_biba temp, *source, *dest; 905 int buflen, error; 906 907 source = SLOT(fslabel); 908 dest = SLOT(vlabel); 909 910 buflen = sizeof(temp); 911 bzero(&temp, buflen); 912 913 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 914 MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &temp, curthread); 915 if (error == ENOATTR || error == EOPNOTSUPP) { 916 /* Fall back to the fslabel. */ 917 mac_biba_copy_single(source, dest); 918 return (0); 919 } else if (error) 920 return (error); 921 922 if (buflen != sizeof(temp)) { 923 printf("mac_biba_associate_vnode_extattr: bad size %d\n", 924 buflen); 925 return (EPERM); 926 } 927 if (mac_biba_valid(&temp) != 0) { 928 printf("mac_biba_associate_vnode_extattr: invalid\n"); 929 return (EPERM); 930 } 931 if ((temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE) { 932 printf("mac_biba_associate_vnode_extattr: not single\n"); 933 return (EPERM); 934 } 935 936 mac_biba_copy_single(&temp, dest); 937 return (0); 938} 939 940static void 941mac_biba_associate_vnode_singlelabel(struct mount *mp, 942 struct label *fslabel, struct vnode *vp, struct label *vlabel) 943{ 944 struct mac_biba *source, *dest; 945 946 source = SLOT(fslabel); 947 dest = SLOT(vlabel); 948 949 mac_biba_copy_single(source, dest); 950} 951 952static int 953mac_biba_create_vnode_extattr(struct ucred *cred, struct mount *mp, 954 struct label *fslabel, struct vnode *dvp, struct label *dlabel, 955 struct vnode *vp, struct label *vlabel, struct componentname *cnp) 956{ 957 struct mac_biba *source, *dest, temp; 958 size_t buflen; 959 int error; 960 961 buflen = sizeof(temp); 962 bzero(&temp, buflen); 963 964 source = SLOT(&cred->cr_label); 965 dest = SLOT(vlabel); 966 mac_biba_copy_single(source, &temp); 967 968 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 969 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread); 970 if (error == 0) 971 mac_biba_copy_single(source, dest); 972 return (error); 973} 974 975static int 976mac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 977 struct label *vlabel, struct label *intlabel) 978{ 979 struct mac_biba *source, temp; 980 size_t buflen; 981 int error; 982 983 buflen = sizeof(temp); 984 bzero(&temp, buflen); 985 986 source = SLOT(intlabel); 987 if ((source->mb_flags & MAC_BIBA_FLAG_SINGLE) == 0) 988 return (0); 989 990 mac_biba_copy_single(source, &temp); 991 992 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 993 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread); 994 return (error); 995} 996 997/* 998 * Labeling event operations: IPC object. 999 */ 1000static void 1001mac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel, 1002 struct mbuf *m, struct label *mbuflabel) 1003{ 1004 struct mac_biba *source, *dest; 1005 1006 source = SLOT(socketlabel); 1007 dest = SLOT(mbuflabel); 1008 1009 mac_biba_copy_single(source, dest); 1010} 1011 1012static void 1013mac_biba_create_socket(struct ucred *cred, struct socket *socket, 1014 struct label *socketlabel) 1015{ 1016 struct mac_biba *source, *dest; 1017 1018 source = SLOT(&cred->cr_label); 1019 dest = SLOT(socketlabel); 1020 1021 mac_biba_copy_single(source, dest); 1022} 1023 1024static void 1025mac_biba_create_pipe(struct ucred *cred, struct pipe *pipe, 1026 struct label *pipelabel) 1027{ 1028 struct mac_biba *source, *dest; 1029 1030 source = SLOT(&cred->cr_label); 1031 dest = SLOT(pipelabel); 1032 1033 mac_biba_copy_single(source, dest); 1034} 1035 1036static void 1037mac_biba_create_socket_from_socket(struct socket *oldsocket, 1038 struct label *oldsocketlabel, struct socket *newsocket, 1039 struct label *newsocketlabel) 1040{ 1041 struct mac_biba *source, *dest; 1042 1043 source = SLOT(oldsocketlabel); 1044 dest = SLOT(newsocketlabel); 1045 1046 mac_biba_copy_single(source, dest); 1047} 1048 1049static void 1050mac_biba_relabel_socket(struct ucred *cred, struct socket *socket, 1051 struct label *socketlabel, struct label *newlabel) 1052{ 1053 struct mac_biba *source, *dest; 1054 1055 source = SLOT(newlabel); 1056 dest = SLOT(socketlabel); 1057 1058 mac_biba_copy(source, dest); 1059} 1060 1061static void 1062mac_biba_relabel_pipe(struct ucred *cred, struct pipe *pipe, 1063 struct label *pipelabel, struct label *newlabel) 1064{ 1065 struct mac_biba *source, *dest; 1066 1067 source = SLOT(newlabel); 1068 dest = SLOT(pipelabel); 1069 1070 mac_biba_copy(source, dest); 1071} 1072 1073static void 1074mac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel, 1075 struct socket *socket, struct label *socketpeerlabel) 1076{ 1077 struct mac_biba *source, *dest; 1078 1079 source = SLOT(mbuflabel); 1080 dest = SLOT(socketpeerlabel); 1081 1082 mac_biba_copy_single(source, dest); 1083} 1084 1085/* 1086 * Labeling event operations: network objects. 1087 */ 1088static void 1089mac_biba_set_socket_peer_from_socket(struct socket *oldsocket, 1090 struct label *oldsocketlabel, struct socket *newsocket, 1091 struct label *newsocketpeerlabel) 1092{ 1093 struct mac_biba *source, *dest; 1094 1095 source = SLOT(oldsocketlabel); 1096 dest = SLOT(newsocketpeerlabel); 1097 1098 mac_biba_copy_single(source, dest); 1099} 1100 1101static void 1102mac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d, 1103 struct label *bpflabel) 1104{ 1105 struct mac_biba *source, *dest; 1106 1107 source = SLOT(&cred->cr_label); 1108 dest = SLOT(bpflabel); 1109 1110 mac_biba_copy_single(source, dest); 1111} 1112 1113static void 1114mac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel) 1115{ 1116 char tifname[IFNAMSIZ], ifname[IFNAMSIZ], *p, *q; 1117 char tiflist[sizeof(trusted_interfaces)]; 1118 struct mac_biba *dest; 1119 int len, type; 1120 1121 dest = SLOT(ifnetlabel); 1122 1123 if (ifnet->if_type == IFT_LOOP) { 1124 type = MAC_BIBA_TYPE_EQUAL; 1125 goto set; 1126 } 1127 1128 if (trust_all_interfaces) { 1129 type = MAC_BIBA_TYPE_HIGH; 1130 goto set; 1131 } 1132 1133 type = MAC_BIBA_TYPE_LOW; 1134 1135 if (trusted_interfaces[0] == '\0' || 1136 !strvalid(trusted_interfaces, sizeof(trusted_interfaces))) 1137 goto set; 1138 1139 bzero(tiflist, sizeof(tiflist)); 1140 for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++) 1141 if(*p != ' ' && *p != '\t') 1142 *q = *p; 1143 1144 snprintf(ifname, IFNAMSIZ, "%s%d", ifnet->if_name, ifnet->if_unit); 1145 1146 for (p = q = tiflist;; p++) { 1147 if (*p == ',' || *p == '\0') { 1148 len = p - q; 1149 if (len < IFNAMSIZ) { 1150 bzero(tifname, sizeof(tifname)); 1151 bcopy(q, tifname, len); 1152 if (strcmp(tifname, ifname) == 0) { 1153 type = MAC_BIBA_TYPE_HIGH; 1154 break; 1155 } 1156 } else { 1157 *p = '\0'; 1158 printf("mac_biba warning: interface name " 1159 "\"%s\" is too long (must be < %d)\n", 1160 q, IFNAMSIZ); 1161 } 1162 if (*p == '\0') 1163 break; 1164 q = p + 1; 1165 } 1166 } 1167set: 1168 mac_biba_set_single(dest, type, 0, NULL); 1169 mac_biba_set_range(dest, type, 0, NULL, type, 0, NULL); 1170} 1171 1172static void 1173mac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1174 struct ipq *ipq, struct label *ipqlabel) 1175{ 1176 struct mac_biba *source, *dest; 1177 1178 source = SLOT(fragmentlabel); 1179 dest = SLOT(ipqlabel); 1180 1181 mac_biba_copy_single(source, dest); 1182} 1183 1184static void 1185mac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel, 1186 struct mbuf *datagram, struct label *datagramlabel) 1187{ 1188 struct mac_biba *source, *dest; 1189 1190 source = SLOT(ipqlabel); 1191 dest = SLOT(datagramlabel); 1192 1193 /* Just use the head, since we require them all to match. */ 1194 mac_biba_copy_single(source, dest); 1195} 1196 1197static void 1198mac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel, 1199 struct mbuf *fragment, struct label *fragmentlabel) 1200{ 1201 struct mac_biba *source, *dest; 1202 1203 source = SLOT(datagramlabel); 1204 dest = SLOT(fragmentlabel); 1205 1206 mac_biba_copy_single(source, dest); 1207} 1208 1209static void 1210mac_biba_create_mbuf_from_mbuf(struct mbuf *oldmbuf, 1211 struct label *oldmbuflabel, struct mbuf *newmbuf, 1212 struct label *newmbuflabel) 1213{ 1214 struct mac_biba *source, *dest; 1215 1216 source = SLOT(oldmbuflabel); 1217 dest = SLOT(newmbuflabel); 1218 1219 /* 1220 * Because the source mbuf may not yet have been "created", 1221 * just initialized, we do a conditional copy. Since we don't 1222 * allow mbufs to have ranges, do a KASSERT to make sure that 1223 * doesn't happen. 1224 */ 1225 KASSERT((source->mb_flags & MAC_BIBA_FLAG_RANGE) == 0, 1226 ("mac_biba_create_mbuf_from_mbuf: source mbuf has range")); 1227 mac_biba_copy(source, dest); 1228} 1229 1230static void 1231mac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel, 1232 struct mbuf *mbuf, struct label *mbuflabel) 1233{ 1234 struct mac_biba *dest; 1235 1236 dest = SLOT(mbuflabel); 1237 1238 mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1239} 1240 1241static void 1242mac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel, 1243 struct mbuf *mbuf, struct label *mbuflabel) 1244{ 1245 struct mac_biba *source, *dest; 1246 1247 source = SLOT(bpflabel); 1248 dest = SLOT(mbuflabel); 1249 1250 mac_biba_copy_single(source, dest); 1251} 1252 1253static void 1254mac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel, 1255 struct mbuf *m, struct label *mbuflabel) 1256{ 1257 struct mac_biba *source, *dest; 1258 1259 source = SLOT(ifnetlabel); 1260 dest = SLOT(mbuflabel); 1261 1262 mac_biba_copy_single(source, dest); 1263} 1264 1265static void 1266mac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf, 1267 struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel, 1268 struct mbuf *newmbuf, struct label *newmbuflabel) 1269{ 1270 struct mac_biba *source, *dest; 1271 1272 source = SLOT(oldmbuflabel); 1273 dest = SLOT(newmbuflabel); 1274 1275 mac_biba_copy_single(source, dest); 1276} 1277 1278static void 1279mac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel, 1280 struct mbuf *newmbuf, struct label *newmbuflabel) 1281{ 1282 struct mac_biba *source, *dest; 1283 1284 source = SLOT(oldmbuflabel); 1285 dest = SLOT(newmbuflabel); 1286 1287 mac_biba_copy_single(source, dest); 1288} 1289 1290static int 1291mac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel, 1292 struct ipq *ipq, struct label *ipqlabel) 1293{ 1294 struct mac_biba *a, *b; 1295 1296 a = SLOT(ipqlabel); 1297 b = SLOT(fragmentlabel); 1298 1299 return (mac_biba_equal_single(a, b)); 1300} 1301 1302static void 1303mac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet, 1304 struct label *ifnetlabel, struct label *newlabel) 1305{ 1306 struct mac_biba *source, *dest; 1307 1308 source = SLOT(newlabel); 1309 dest = SLOT(ifnetlabel); 1310 1311 mac_biba_copy(source, dest); 1312} 1313 1314static void 1315mac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1316 struct ipq *ipq, struct label *ipqlabel) 1317{ 1318 1319 /* NOOP: we only accept matching labels, so no need to update */ 1320} 1321 1322/* 1323 * Labeling event operations: processes. 1324 */ 1325static void 1326mac_biba_create_cred(struct ucred *cred_parent, struct ucred *cred_child) 1327{ 1328 struct mac_biba *source, *dest; 1329 1330 source = SLOT(&cred_parent->cr_label); 1331 dest = SLOT(&cred_child->cr_label); 1332 1333 mac_biba_copy_single(source, dest); 1334 mac_biba_copy_range(source, dest); 1335} 1336 1337static void 1338mac_biba_create_proc0(struct ucred *cred) 1339{ 1340 struct mac_biba *dest; 1341 1342 dest = SLOT(&cred->cr_label); 1343 1344 mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1345 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1346 MAC_BIBA_TYPE_HIGH, 0, NULL); 1347} 1348 1349static void 1350mac_biba_create_proc1(struct ucred *cred) 1351{ 1352 struct mac_biba *dest; 1353 1354 dest = SLOT(&cred->cr_label); 1355 1356 mac_biba_set_single(dest, MAC_BIBA_TYPE_HIGH, 0, NULL); 1357 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1358 MAC_BIBA_TYPE_HIGH, 0, NULL); 1359} 1360 1361static void 1362mac_biba_relabel_cred(struct ucred *cred, struct label *newlabel) 1363{ 1364 struct mac_biba *source, *dest; 1365 1366 source = SLOT(newlabel); 1367 dest = SLOT(&cred->cr_label); 1368 1369 mac_biba_copy(source, dest); 1370} 1371 1372/* 1373 * Access control checks. 1374 */ 1375static int 1376mac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel, 1377 struct ifnet *ifnet, struct label *ifnetlabel) 1378{ 1379 struct mac_biba *a, *b; 1380 1381 if (!mac_biba_enabled) 1382 return (0); 1383 1384 a = SLOT(bpflabel); 1385 b = SLOT(ifnetlabel); 1386 1387 if (mac_biba_equal_single(a, b)) 1388 return (0); 1389 return (EACCES); 1390} 1391 1392static int 1393mac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel) 1394{ 1395 struct mac_biba *subj, *new; 1396 int error; 1397 1398 subj = SLOT(&cred->cr_label); 1399 new = SLOT(newlabel); 1400 1401 /* 1402 * If there is a Biba label update for the credential, it may 1403 * be an update of the single, range, or both. 1404 */ 1405 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1406 if (error) 1407 return (error); 1408 1409 /* 1410 * If the Biba label is to be changed, authorize as appropriate. 1411 */ 1412 if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1413 /* 1414 * If the change request modifies both the Biba label 1415 * single and range, check that the new single will be 1416 * in the new range. 1417 */ 1418 if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) == 1419 MAC_BIBA_FLAGS_BOTH && 1420 !mac_biba_single_in_range(new, new)) 1421 return (EINVAL); 1422 1423 /* 1424 * To change the Biba single label on a credential, the 1425 * new single label must be in the current range. 1426 */ 1427 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE && 1428 !mac_biba_single_in_range(new, subj)) 1429 return (EPERM); 1430 1431 /* 1432 * To change the Biba range on a credential, the new 1433 * range label must be in the current range. 1434 */ 1435 if (new->mb_flags & MAC_BIBA_FLAG_RANGE && 1436 !mac_biba_range_in_range(new, subj)) 1437 return (EPERM); 1438 1439 /* 1440 * To have EQUAL in any component of the new credential 1441 * Biba label, the subject must already have EQUAL in 1442 * their label. 1443 */ 1444 if (mac_biba_contains_equal(new)) { 1445 error = mac_biba_subject_privileged(subj); 1446 if (error) 1447 return (error); 1448 } 1449 } 1450 1451 return (0); 1452} 1453 1454static int 1455mac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2) 1456{ 1457 struct mac_biba *subj, *obj; 1458 1459 if (!mac_biba_enabled) 1460 return (0); 1461 1462 subj = SLOT(&u1->cr_label); 1463 obj = SLOT(&u2->cr_label); 1464 1465 /* XXX: range */ 1466 if (!mac_biba_dominate_single(obj, subj)) 1467 return (ESRCH); 1468 1469 return (0); 1470} 1471 1472static int 1473mac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet, 1474 struct label *ifnetlabel, struct label *newlabel) 1475{ 1476 struct mac_biba *subj, *new; 1477 int error; 1478 1479 subj = SLOT(&cred->cr_label); 1480 new = SLOT(newlabel); 1481 1482 /* 1483 * If there is a Biba label update for the interface, it may 1484 * be an update of the single, range, or both. 1485 */ 1486 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1487 if (error) 1488 return (error); 1489 1490 /* 1491 * Relabling network interfaces requires Biba privilege. 1492 */ 1493 error = mac_biba_subject_privileged(subj); 1494 if (error) 1495 return (error); 1496 1497 /* 1498 * If the Biba label is to be changed, authorize as appropriate. 1499 */ 1500 if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1501 /* 1502 * Rely on the traditional superuser status for the Biba 1503 * interface relabel requirements. XXXMAC: This will go 1504 * away. 1505 */ 1506 error = suser_cred(cred, 0); 1507 if (error) 1508 return (EPERM); 1509 1510 /* 1511 * XXXMAC: Additional consistency tests regarding the single 1512 * and the range of the new label might be performed here. 1513 */ 1514 } 1515 1516 return (0); 1517} 1518 1519static int 1520mac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, 1521 struct mbuf *m, struct label *mbuflabel) 1522{ 1523 struct mac_biba *p, *i; 1524 1525 if (!mac_biba_enabled) 1526 return (0); 1527 1528 p = SLOT(mbuflabel); 1529 i = SLOT(ifnetlabel); 1530 1531 return (mac_biba_single_in_range(p, i) ? 0 : EACCES); 1532} 1533 1534static int 1535mac_biba_check_kld_load(struct ucred *cred, struct vnode *vp, 1536 struct label *label) 1537{ 1538 struct mac_biba *subj, *obj; 1539 int error; 1540 1541 if (!mac_biba_enabled) 1542 return (0); 1543 1544 subj = SLOT(&cred->cr_label); 1545 1546 error = mac_biba_subject_privileged(subj); 1547 if (error) 1548 return (error); 1549 1550 obj = SLOT(label); 1551 if (!mac_biba_high_single(obj)) 1552 return (EACCES); 1553 1554 return (0); 1555} 1556 1557 1558static int 1559mac_biba_check_kld_unload(struct ucred *cred) 1560{ 1561 struct mac_biba *subj; 1562 1563 if (!mac_biba_enabled) 1564 return (0); 1565 1566 subj = SLOT(&cred->cr_label); 1567 1568 return (mac_biba_subject_privileged(subj)); 1569} 1570 1571static int 1572mac_biba_check_mount_stat(struct ucred *cred, struct mount *mp, 1573 struct label *mntlabel) 1574{ 1575 struct mac_biba *subj, *obj; 1576 1577 if (!mac_biba_enabled) 1578 return (0); 1579 1580 subj = SLOT(&cred->cr_label); 1581 obj = SLOT(mntlabel); 1582 1583 if (!mac_biba_dominate_single(obj, subj)) 1584 return (EACCES); 1585 1586 return (0); 1587} 1588 1589static int 1590mac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, 1591 struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data) 1592{ 1593 1594 if(!mac_biba_enabled) 1595 return (0); 1596 1597 /* XXX: This will be implemented soon... */ 1598 1599 return (0); 1600} 1601 1602static int 1603mac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe, 1604 struct label *pipelabel) 1605{ 1606 struct mac_biba *subj, *obj; 1607 1608 if (!mac_biba_enabled) 1609 return (0); 1610 1611 subj = SLOT(&cred->cr_label); 1612 obj = SLOT((pipelabel)); 1613 1614 if (!mac_biba_dominate_single(obj, subj)) 1615 return (EACCES); 1616 1617 return (0); 1618} 1619 1620static int 1621mac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe, 1622 struct label *pipelabel) 1623{ 1624 struct mac_biba *subj, *obj; 1625 1626 if (!mac_biba_enabled) 1627 return (0); 1628 1629 subj = SLOT(&cred->cr_label); 1630 obj = SLOT((pipelabel)); 1631 1632 if (!mac_biba_dominate_single(obj, subj)) 1633 return (EACCES); 1634 1635 return (0); 1636} 1637 1638static int 1639mac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 1640 struct label *pipelabel, struct label *newlabel) 1641{ 1642 struct mac_biba *subj, *obj, *new; 1643 int error; 1644 1645 new = SLOT(newlabel); 1646 subj = SLOT(&cred->cr_label); 1647 obj = SLOT(pipelabel); 1648 1649 /* 1650 * If there is a Biba label update for a pipe, it must be a 1651 * single update. 1652 */ 1653 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1654 if (error) 1655 return (error); 1656 1657 /* 1658 * To perform a relabel of a pipe (Biba label or not), Biba must 1659 * authorize the relabel. 1660 */ 1661 if (!mac_biba_single_in_range(obj, subj)) 1662 return (EPERM); 1663 1664 /* 1665 * If the Biba label is to be changed, authorize as appropriate. 1666 */ 1667 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1668 /* 1669 * To change the Biba label on a pipe, the new pipe label 1670 * must be in the subject range. 1671 */ 1672 if (!mac_biba_single_in_range(new, subj)) 1673 return (EPERM); 1674 1675 /* 1676 * To change the Biba label on a pipe to be EQUAL, the 1677 * subject must have appropriate privilege. 1678 */ 1679 if (mac_biba_contains_equal(new)) { 1680 error = mac_biba_subject_privileged(subj); 1681 if (error) 1682 return (error); 1683 } 1684 } 1685 1686 return (0); 1687} 1688 1689static int 1690mac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe, 1691 struct label *pipelabel) 1692{ 1693 struct mac_biba *subj, *obj; 1694 1695 if (!mac_biba_enabled) 1696 return (0); 1697 1698 subj = SLOT(&cred->cr_label); 1699 obj = SLOT((pipelabel)); 1700 1701 if (!mac_biba_dominate_single(obj, subj)) 1702 return (EACCES); 1703 1704 return (0); 1705} 1706 1707static int 1708mac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe, 1709 struct label *pipelabel) 1710{ 1711 struct mac_biba *subj, *obj; 1712 1713 if (!mac_biba_enabled) 1714 return (0); 1715 1716 subj = SLOT(&cred->cr_label); 1717 obj = SLOT((pipelabel)); 1718 1719 if (!mac_biba_dominate_single(subj, obj)) 1720 return (EACCES); 1721 1722 return (0); 1723} 1724 1725static int 1726mac_biba_check_proc_debug(struct ucred *cred, struct proc *proc) 1727{ 1728 struct mac_biba *subj, *obj; 1729 1730 if (!mac_biba_enabled) 1731 return (0); 1732 1733 subj = SLOT(&cred->cr_label); 1734 obj = SLOT(&proc->p_ucred->cr_label); 1735 1736 /* XXX: range checks */ 1737 if (!mac_biba_dominate_single(obj, subj)) 1738 return (ESRCH); 1739 if (!mac_biba_dominate_single(subj, obj)) 1740 return (EACCES); 1741 1742 return (0); 1743} 1744 1745static int 1746mac_biba_check_proc_sched(struct ucred *cred, struct proc *proc) 1747{ 1748 struct mac_biba *subj, *obj; 1749 1750 if (!mac_biba_enabled) 1751 return (0); 1752 1753 subj = SLOT(&cred->cr_label); 1754 obj = SLOT(&proc->p_ucred->cr_label); 1755 1756 /* XXX: range checks */ 1757 if (!mac_biba_dominate_single(obj, subj)) 1758 return (ESRCH); 1759 if (!mac_biba_dominate_single(subj, obj)) 1760 return (EACCES); 1761 1762 return (0); 1763} 1764 1765static int 1766mac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 1767{ 1768 struct mac_biba *subj, *obj; 1769 1770 if (!mac_biba_enabled) 1771 return (0); 1772 1773 subj = SLOT(&cred->cr_label); 1774 obj = SLOT(&proc->p_ucred->cr_label); 1775 1776 /* XXX: range checks */ 1777 if (!mac_biba_dominate_single(obj, subj)) 1778 return (ESRCH); 1779 if (!mac_biba_dominate_single(subj, obj)) 1780 return (EACCES); 1781 1782 return (0); 1783} 1784 1785static int 1786mac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel, 1787 struct mbuf *m, struct label *mbuflabel) 1788{ 1789 struct mac_biba *p, *s; 1790 1791 if (!mac_biba_enabled) 1792 return (0); 1793 1794 p = SLOT(mbuflabel); 1795 s = SLOT(socketlabel); 1796 1797 return (mac_biba_equal_single(p, s) ? 0 : EACCES); 1798} 1799 1800static int 1801mac_biba_check_socket_relabel(struct ucred *cred, struct socket *so, 1802 struct label *socketlabel, struct label *newlabel) 1803{ 1804 struct mac_biba *subj, *obj, *new; 1805 int error; 1806 1807 new = SLOT(newlabel); 1808 subj = SLOT(&cred->cr_label); 1809 obj = SLOT(socketlabel); 1810 1811 /* 1812 * If there is a Biba label update for the socket, it may be 1813 * an update of single. 1814 */ 1815 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1816 if (error) 1817 return (error); 1818 1819 /* 1820 * To relabel a socket, the old socket single must be in the subject 1821 * range. 1822 */ 1823 if (!mac_biba_single_in_range(obj, subj)) 1824 return (EPERM); 1825 1826 /* 1827 * If the Biba label is to be changed, authorize as appropriate. 1828 */ 1829 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1830 /* 1831 * To relabel a socket, the new socket single must be in 1832 * the subject range. 1833 */ 1834 if (!mac_biba_single_in_range(new, subj)) 1835 return (EPERM); 1836 1837 /* 1838 * To change the Biba label on the socket to contain EQUAL, 1839 * the subject must have appropriate privilege. 1840 */ 1841 if (mac_biba_contains_equal(new)) { 1842 error = mac_biba_subject_privileged(subj); 1843 if (error) 1844 return (error); 1845 } 1846 } 1847 1848 return (0); 1849} 1850 1851static int 1852mac_biba_check_socket_visible(struct ucred *cred, struct socket *socket, 1853 struct label *socketlabel) 1854{ 1855 struct mac_biba *subj, *obj; 1856 1857 if (!mac_biba_enabled) 1858 return (0); 1859 1860 subj = SLOT(&cred->cr_label); 1861 obj = SLOT(socketlabel); 1862 1863 if (!mac_biba_dominate_single(obj, subj)) 1864 return (ENOENT); 1865 1866 return (0); 1867} 1868 1869static int 1870mac_biba_check_sysarch_ioperm(struct ucred *cred) 1871{ 1872 struct mac_biba *subj; 1873 int error; 1874 1875 if (!mac_biba_enabled) 1876 return (0); 1877 1878 subj = SLOT(&cred->cr_label); 1879 1880 error = mac_biba_subject_privileged(subj); 1881 if (error) 1882 return (error); 1883 1884 return (0); 1885} 1886 1887static int 1888mac_biba_check_system_acct(struct ucred *cred, struct vnode *vp, 1889 struct label *label) 1890{ 1891 struct mac_biba *subj, *obj; 1892 int error; 1893 1894 if (!mac_biba_enabled) 1895 return (0); 1896 1897 subj = SLOT(&cred->cr_label); 1898 1899 error = mac_biba_subject_privileged(subj); 1900 if (error) 1901 return (error); 1902 1903 if (label == NULL) 1904 return (0); 1905 1906 obj = SLOT(label); 1907 if (!mac_biba_high_single(obj)) 1908 return (EACCES); 1909 1910 return (0); 1911} 1912 1913static int 1914mac_biba_check_system_settime(struct ucred *cred) 1915{ 1916 struct mac_biba *subj; 1917 int error; 1918 1919 if (!mac_biba_enabled) 1920 return (0); 1921 1922 subj = SLOT(&cred->cr_label); 1923 1924 error = mac_biba_subject_privileged(subj); 1925 if (error) 1926 return (error); 1927 1928 return (0); 1929} 1930 1931static int 1932mac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp, 1933 struct label *label) 1934{ 1935 struct mac_biba *subj, *obj; 1936 int error; 1937 1938 if (!mac_biba_enabled) 1939 return (0); 1940 1941 subj = SLOT(&cred->cr_label); 1942 obj = SLOT(label); 1943 1944 error = mac_biba_subject_privileged(subj); 1945 if (error) 1946 return (error); 1947 1948 if (!mac_biba_high_single(obj)) 1949 return (EACCES); 1950 1951 return (0); 1952} 1953 1954static int 1955mac_biba_check_system_swapoff(struct ucred *cred, struct vnode *vp, 1956 struct label *label) 1957{ 1958 struct mac_biba *subj, *obj; 1959 int error; 1960 1961 if (!mac_biba_enabled) 1962 return (0); 1963 1964 subj = SLOT(&cred->cr_label); 1965 obj = SLOT(label); 1966 1967 error = mac_biba_subject_privileged(subj); 1968 if (error) 1969 return (error); 1970 1971 return (0); 1972} 1973 1974static int 1975mac_biba_check_system_sysctl(struct ucred *cred, int *name, u_int namelen, 1976 void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen) 1977{ 1978 struct mac_biba *subj; 1979 int error; 1980 1981 if (!mac_biba_enabled) 1982 return (0); 1983 1984 subj = SLOT(&cred->cr_label); 1985 1986 /* 1987 * In general, treat sysctl variables as biba/high, but also 1988 * require privilege to change them, since they are a 1989 * communications channel between grades. Exempt MIB 1990 * queries from this due to undocmented sysctl magic. 1991 * XXXMAC: This probably requires some more review. 1992 */ 1993 if (new != NULL) { 1994 if (namelen > 0 && name[0] == 0) 1995 return (0); 1996 1997 if (!mac_biba_subject_dominate_high(subj)) 1998 return (EACCES); 1999 2000 error = mac_biba_subject_privileged(subj); 2001 if (error) 2002 return (error); 2003 } 2004 2005 return (0); 2006} 2007 2008static int 2009mac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 2010 struct label *dlabel) 2011{ 2012 struct mac_biba *subj, *obj; 2013 2014 if (!mac_biba_enabled) 2015 return (0); 2016 2017 subj = SLOT(&cred->cr_label); 2018 obj = SLOT(dlabel); 2019 2020 if (!mac_biba_dominate_single(obj, subj)) 2021 return (EACCES); 2022 2023 return (0); 2024} 2025 2026static int 2027mac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 2028 struct label *dlabel) 2029{ 2030 struct mac_biba *subj, *obj; 2031 2032 if (!mac_biba_enabled) 2033 return (0); 2034 2035 subj = SLOT(&cred->cr_label); 2036 obj = SLOT(dlabel); 2037 2038 if (!mac_biba_dominate_single(obj, subj)) 2039 return (EACCES); 2040 2041 return (0); 2042} 2043 2044static int 2045mac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp, 2046 struct label *dlabel, struct componentname *cnp, struct vattr *vap) 2047{ 2048 struct mac_biba *subj, *obj; 2049 2050 if (!mac_biba_enabled) 2051 return (0); 2052 2053 subj = SLOT(&cred->cr_label); 2054 obj = SLOT(dlabel); 2055 2056 if (!mac_biba_dominate_single(subj, obj)) 2057 return (EACCES); 2058 2059 return (0); 2060} 2061 2062static int 2063mac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 2064 struct label *dlabel, struct vnode *vp, struct label *label, 2065 struct componentname *cnp) 2066{ 2067 struct mac_biba *subj, *obj; 2068 2069 if (!mac_biba_enabled) 2070 return (0); 2071 2072 subj = SLOT(&cred->cr_label); 2073 obj = SLOT(dlabel); 2074 2075 if (!mac_biba_dominate_single(subj, obj)) 2076 return (EACCES); 2077 2078 obj = SLOT(label); 2079 2080 if (!mac_biba_dominate_single(subj, obj)) 2081 return (EACCES); 2082 2083 return (0); 2084} 2085 2086static int 2087mac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 2088 struct label *label, acl_type_t type) 2089{ 2090 struct mac_biba *subj, *obj; 2091 2092 if (!mac_biba_enabled) 2093 return (0); 2094 2095 subj = SLOT(&cred->cr_label); 2096 obj = SLOT(label); 2097 2098 if (!mac_biba_dominate_single(subj, obj)) 2099 return (EACCES); 2100 2101 return (0); 2102} 2103 2104static int 2105mac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp, 2106 struct label *label, struct image_params *imgp, 2107 struct label *execlabel) 2108{ 2109 struct mac_biba *subj, *obj, *exec; 2110 int error; 2111 2112 if (execlabel != NULL) { 2113 /* 2114 * We currently don't permit labels to be changed at 2115 * exec-time as part of Biba, so disallow non-NULL 2116 * Biba label elements in the execlabel. 2117 */ 2118 exec = SLOT(execlabel); 2119 error = biba_atmostflags(exec, 0); 2120 if (error) 2121 return (error); 2122 } 2123 2124 if (!mac_biba_enabled) 2125 return (0); 2126 2127 subj = SLOT(&cred->cr_label); 2128 obj = SLOT(label); 2129 2130 if (!mac_biba_dominate_single(obj, subj)) 2131 return (EACCES); 2132 2133 return (0); 2134} 2135 2136static int 2137mac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 2138 struct label *label, acl_type_t type) 2139{ 2140 struct mac_biba *subj, *obj; 2141 2142 if (!mac_biba_enabled) 2143 return (0); 2144 2145 subj = SLOT(&cred->cr_label); 2146 obj = SLOT(label); 2147 2148 if (!mac_biba_dominate_single(obj, subj)) 2149 return (EACCES); 2150 2151 return (0); 2152} 2153 2154static int 2155mac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 2156 struct label *label, int attrnamespace, const char *name, struct uio *uio) 2157{ 2158 struct mac_biba *subj, *obj; 2159 2160 if (!mac_biba_enabled) 2161 return (0); 2162 2163 subj = SLOT(&cred->cr_label); 2164 obj = SLOT(label); 2165 2166 if (!mac_biba_dominate_single(obj, subj)) 2167 return (EACCES); 2168 2169 return (0); 2170} 2171 2172static int 2173mac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp, 2174 struct label *dlabel, struct vnode *vp, struct label *label, 2175 struct componentname *cnp) 2176{ 2177 struct mac_biba *subj, *obj; 2178 2179 if (!mac_biba_enabled) 2180 return (0); 2181 2182 subj = SLOT(&cred->cr_label); 2183 obj = SLOT(dlabel); 2184 2185 if (!mac_biba_dominate_single(subj, obj)) 2186 return (EACCES); 2187 2188 obj = SLOT(label); 2189 2190 if (!mac_biba_dominate_single(subj, obj)) 2191 return (EACCES); 2192 2193 return (0); 2194} 2195 2196static int 2197mac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 2198 struct label *dlabel, struct componentname *cnp) 2199{ 2200 struct mac_biba *subj, *obj; 2201 2202 if (!mac_biba_enabled) 2203 return (0); 2204 2205 subj = SLOT(&cred->cr_label); 2206 obj = SLOT(dlabel); 2207 2208 if (!mac_biba_dominate_single(obj, subj)) 2209 return (EACCES); 2210 2211 return (0); 2212} 2213 2214static int 2215mac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp, 2216 struct label *label, int prot) 2217{ 2218 struct mac_biba *subj, *obj; 2219 2220 /* 2221 * Rely on the use of open()-time protections to handle 2222 * non-revocation cases. 2223 */ 2224 if (!mac_biba_enabled || !revocation_enabled) 2225 return (0); 2226 2227 subj = SLOT(&cred->cr_label); 2228 obj = SLOT(label); 2229 2230 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2231 if (!mac_biba_dominate_single(obj, subj)) 2232 return (EACCES); 2233 } 2234 if (prot & VM_PROT_WRITE) { 2235 if (!mac_biba_dominate_single(subj, obj)) 2236 return (EACCES); 2237 } 2238 2239 return (0); 2240} 2241 2242static int 2243mac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp, 2244 struct label *vnodelabel, int acc_mode) 2245{ 2246 struct mac_biba *subj, *obj; 2247 2248 if (!mac_biba_enabled) 2249 return (0); 2250 2251 subj = SLOT(&cred->cr_label); 2252 obj = SLOT(vnodelabel); 2253 2254 /* XXX privilege override for admin? */ 2255 if (acc_mode & (VREAD | VEXEC | VSTAT)) { 2256 if (!mac_biba_dominate_single(obj, subj)) 2257 return (EACCES); 2258 } 2259 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2260 if (!mac_biba_dominate_single(subj, obj)) 2261 return (EACCES); 2262 } 2263 2264 return (0); 2265} 2266 2267static int 2268mac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 2269 struct vnode *vp, struct label *label) 2270{ 2271 struct mac_biba *subj, *obj; 2272 2273 if (!mac_biba_enabled || !revocation_enabled) 2274 return (0); 2275 2276 subj = SLOT(&active_cred->cr_label); 2277 obj = SLOT(label); 2278 2279 if (!mac_biba_dominate_single(obj, subj)) 2280 return (EACCES); 2281 2282 return (0); 2283} 2284 2285static int 2286mac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2287 struct vnode *vp, struct label *label) 2288{ 2289 struct mac_biba *subj, *obj; 2290 2291 if (!mac_biba_enabled || !revocation_enabled) 2292 return (0); 2293 2294 subj = SLOT(&active_cred->cr_label); 2295 obj = SLOT(label); 2296 2297 if (!mac_biba_dominate_single(obj, subj)) 2298 return (EACCES); 2299 2300 return (0); 2301} 2302 2303static int 2304mac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 2305 struct label *dlabel) 2306{ 2307 struct mac_biba *subj, *obj; 2308 2309 if (!mac_biba_enabled) 2310 return (0); 2311 2312 subj = SLOT(&cred->cr_label); 2313 obj = SLOT(dlabel); 2314 2315 if (!mac_biba_dominate_single(obj, subj)) 2316 return (EACCES); 2317 2318 return (0); 2319} 2320 2321static int 2322mac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp, 2323 struct label *label) 2324{ 2325 struct mac_biba *subj, *obj; 2326 2327 if (!mac_biba_enabled) 2328 return (0); 2329 2330 subj = SLOT(&cred->cr_label); 2331 obj = SLOT(label); 2332 2333 if (!mac_biba_dominate_single(obj, subj)) 2334 return (EACCES); 2335 2336 return (0); 2337} 2338 2339static int 2340mac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 2341 struct label *vnodelabel, struct label *newlabel) 2342{ 2343 struct mac_biba *old, *new, *subj; 2344 int error; 2345 2346 old = SLOT(vnodelabel); 2347 new = SLOT(newlabel); 2348 subj = SLOT(&cred->cr_label); 2349 2350 /* 2351 * If there is a Biba label update for the vnode, it must be a 2352 * single label. 2353 */ 2354 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 2355 if (error) 2356 return (error); 2357 2358 /* 2359 * To perform a relabel of the vnode (Biba label or not), Biba must 2360 * authorize the relabel. 2361 */ 2362 if (!mac_biba_single_in_range(old, subj)) 2363 return (EPERM); 2364 2365 /* 2366 * If the Biba label is to be changed, authorize as appropriate. 2367 */ 2368 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 2369 /* 2370 * To change the Biba label on a vnode, the new vnode label 2371 * must be in the subject range. 2372 */ 2373 if (!mac_biba_single_in_range(new, subj)) 2374 return (EPERM); 2375 2376 /* 2377 * To change the Biba label on the vnode to be EQUAL, 2378 * the subject must have appropriate privilege. 2379 */ 2380 if (mac_biba_contains_equal(new)) { 2381 error = mac_biba_subject_privileged(subj); 2382 if (error) 2383 return (error); 2384 } 2385 } 2386 2387 return (0); 2388} 2389 2390static int 2391mac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 2392 struct label *dlabel, struct vnode *vp, struct label *label, 2393 struct componentname *cnp) 2394{ 2395 struct mac_biba *subj, *obj; 2396 2397 if (!mac_biba_enabled) 2398 return (0); 2399 2400 subj = SLOT(&cred->cr_label); 2401 obj = SLOT(dlabel); 2402 2403 if (!mac_biba_dominate_single(subj, obj)) 2404 return (EACCES); 2405 2406 obj = SLOT(label); 2407 2408 if (!mac_biba_dominate_single(subj, obj)) 2409 return (EACCES); 2410 2411 return (0); 2412} 2413 2414static int 2415mac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 2416 struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 2417 struct componentname *cnp) 2418{ 2419 struct mac_biba *subj, *obj; 2420 2421 if (!mac_biba_enabled) 2422 return (0); 2423 2424 subj = SLOT(&cred->cr_label); 2425 obj = SLOT(dlabel); 2426 2427 if (!mac_biba_dominate_single(subj, obj)) 2428 return (EACCES); 2429 2430 if (vp != NULL) { 2431 obj = SLOT(label); 2432 2433 if (!mac_biba_dominate_single(subj, obj)) 2434 return (EACCES); 2435 } 2436 2437 return (0); 2438} 2439 2440static int 2441mac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 2442 struct label *label) 2443{ 2444 struct mac_biba *subj, *obj; 2445 2446 if (!mac_biba_enabled) 2447 return (0); 2448 2449 subj = SLOT(&cred->cr_label); 2450 obj = SLOT(label); 2451 2452 if (!mac_biba_dominate_single(subj, obj)) 2453 return (EACCES); 2454 2455 return (0); 2456} 2457 2458static int 2459mac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 2460 struct label *label, acl_type_t type, struct acl *acl) 2461{ 2462 struct mac_biba *subj, *obj; 2463 2464 if (!mac_biba_enabled) 2465 return (0); 2466 2467 subj = SLOT(&cred->cr_label); 2468 obj = SLOT(label); 2469 2470 if (!mac_biba_dominate_single(subj, obj)) 2471 return (EACCES); 2472 2473 return (0); 2474} 2475 2476static int 2477mac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2478 struct label *vnodelabel, int attrnamespace, const char *name, 2479 struct uio *uio) 2480{ 2481 struct mac_biba *subj, *obj; 2482 2483 if (!mac_biba_enabled) 2484 return (0); 2485 2486 subj = SLOT(&cred->cr_label); 2487 obj = SLOT(vnodelabel); 2488 2489 if (!mac_biba_dominate_single(subj, obj)) 2490 return (EACCES); 2491 2492 /* XXX: protect the MAC EA in a special way? */ 2493 2494 return (0); 2495} 2496 2497static int 2498mac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 2499 struct label *vnodelabel, u_long flags) 2500{ 2501 struct mac_biba *subj, *obj; 2502 2503 if (!mac_biba_enabled) 2504 return (0); 2505 2506 subj = SLOT(&cred->cr_label); 2507 obj = SLOT(vnodelabel); 2508 2509 if (!mac_biba_dominate_single(subj, obj)) 2510 return (EACCES); 2511 2512 return (0); 2513} 2514 2515static int 2516mac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 2517 struct label *vnodelabel, mode_t mode) 2518{ 2519 struct mac_biba *subj, *obj; 2520 2521 if (!mac_biba_enabled) 2522 return (0); 2523 2524 subj = SLOT(&cred->cr_label); 2525 obj = SLOT(vnodelabel); 2526 2527 if (!mac_biba_dominate_single(subj, obj)) 2528 return (EACCES); 2529 2530 return (0); 2531} 2532 2533static int 2534mac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 2535 struct label *vnodelabel, uid_t uid, gid_t gid) 2536{ 2537 struct mac_biba *subj, *obj; 2538 2539 if (!mac_biba_enabled) 2540 return (0); 2541 2542 subj = SLOT(&cred->cr_label); 2543 obj = SLOT(vnodelabel); 2544 2545 if (!mac_biba_dominate_single(subj, obj)) 2546 return (EACCES); 2547 2548 return (0); 2549} 2550 2551static int 2552mac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2553 struct label *vnodelabel, struct timespec atime, struct timespec mtime) 2554{ 2555 struct mac_biba *subj, *obj; 2556 2557 if (!mac_biba_enabled) 2558 return (0); 2559 2560 subj = SLOT(&cred->cr_label); 2561 obj = SLOT(vnodelabel); 2562 2563 if (!mac_biba_dominate_single(subj, obj)) 2564 return (EACCES); 2565 2566 return (0); 2567} 2568 2569static int 2570mac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2571 struct vnode *vp, struct label *vnodelabel) 2572{ 2573 struct mac_biba *subj, *obj; 2574 2575 if (!mac_biba_enabled) 2576 return (0); 2577 2578 subj = SLOT(&active_cred->cr_label); 2579 obj = SLOT(vnodelabel); 2580 2581 if (!mac_biba_dominate_single(obj, subj)) 2582 return (EACCES); 2583 2584 return (0); 2585} 2586 2587static int 2588mac_biba_check_vnode_write(struct ucred *active_cred, 2589 struct ucred *file_cred, struct vnode *vp, struct label *label) 2590{ 2591 struct mac_biba *subj, *obj; 2592 2593 if (!mac_biba_enabled || !revocation_enabled) 2594 return (0); 2595 2596 subj = SLOT(&active_cred->cr_label); 2597 obj = SLOT(label); 2598 2599 if (!mac_biba_dominate_single(subj, obj)) 2600 return (EACCES); 2601 2602 return (0); 2603} 2604 2605static struct mac_policy_ops mac_biba_ops = 2606{ 2607 .mpo_destroy = mac_biba_destroy, 2608 .mpo_init = mac_biba_init, 2609 .mpo_init_bpfdesc_label = mac_biba_init_label, 2610 .mpo_init_cred_label = mac_biba_init_label, 2611 .mpo_init_devfsdirent_label = mac_biba_init_label, 2612 .mpo_init_ifnet_label = mac_biba_init_label, 2613 .mpo_init_ipq_label = mac_biba_init_label_waitcheck, 2614 .mpo_init_mbuf_label = mac_biba_init_label_waitcheck, 2615 .mpo_init_mount_label = mac_biba_init_label, 2616 .mpo_init_mount_fs_label = mac_biba_init_label, 2617 .mpo_init_pipe_label = mac_biba_init_label, 2618 .mpo_init_socket_label = mac_biba_init_label_waitcheck, 2619 .mpo_init_socket_peer_label = mac_biba_init_label_waitcheck, 2620 .mpo_init_vnode_label = mac_biba_init_label, 2621 .mpo_destroy_bpfdesc_label = mac_biba_destroy_label, 2622 .mpo_destroy_cred_label = mac_biba_destroy_label, 2623 .mpo_destroy_devfsdirent_label = mac_biba_destroy_label, 2624 .mpo_destroy_ifnet_label = mac_biba_destroy_label, 2625 .mpo_destroy_ipq_label = mac_biba_destroy_label, 2626 .mpo_destroy_mbuf_label = mac_biba_destroy_label, 2627 .mpo_destroy_mount_label = mac_biba_destroy_label, 2628 .mpo_destroy_mount_fs_label = mac_biba_destroy_label, 2629 .mpo_destroy_pipe_label = mac_biba_destroy_label, 2630 .mpo_destroy_socket_label = mac_biba_destroy_label, 2631 .mpo_destroy_socket_peer_label = mac_biba_destroy_label, 2632 .mpo_destroy_vnode_label = mac_biba_destroy_label, 2633 .mpo_copy_mbuf_label = mac_biba_copy_label, 2634 .mpo_copy_pipe_label = mac_biba_copy_label, 2635 .mpo_copy_vnode_label = mac_biba_copy_label, 2636 .mpo_externalize_cred_label = mac_biba_externalize_label, 2637 .mpo_externalize_ifnet_label = mac_biba_externalize_label, 2638 .mpo_externalize_pipe_label = mac_biba_externalize_label, 2639 .mpo_externalize_socket_label = mac_biba_externalize_label, 2640 .mpo_externalize_socket_peer_label = mac_biba_externalize_label, 2641 .mpo_externalize_vnode_label = mac_biba_externalize_label, 2642 .mpo_internalize_cred_label = mac_biba_internalize_label, 2643 .mpo_internalize_ifnet_label = mac_biba_internalize_label, 2644 .mpo_internalize_pipe_label = mac_biba_internalize_label, 2645 .mpo_internalize_socket_label = mac_biba_internalize_label, 2646 .mpo_internalize_vnode_label = mac_biba_internalize_label, 2647 .mpo_create_devfs_device = mac_biba_create_devfs_device, 2648 .mpo_create_devfs_directory = mac_biba_create_devfs_directory, 2649 .mpo_create_devfs_symlink = mac_biba_create_devfs_symlink, 2650 .mpo_create_mount = mac_biba_create_mount, 2651 .mpo_create_root_mount = mac_biba_create_root_mount, 2652 .mpo_relabel_vnode = mac_biba_relabel_vnode, 2653 .mpo_update_devfsdirent = mac_biba_update_devfsdirent, 2654 .mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs, 2655 .mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr, 2656 .mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel, 2657 .mpo_create_vnode_extattr = mac_biba_create_vnode_extattr, 2658 .mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr, 2659 .mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket, 2660 .mpo_create_pipe = mac_biba_create_pipe, 2661 .mpo_create_socket = mac_biba_create_socket, 2662 .mpo_create_socket_from_socket = mac_biba_create_socket_from_socket, 2663 .mpo_relabel_pipe = mac_biba_relabel_pipe, 2664 .mpo_relabel_socket = mac_biba_relabel_socket, 2665 .mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf, 2666 .mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket, 2667 .mpo_create_bpfdesc = mac_biba_create_bpfdesc, 2668 .mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq, 2669 .mpo_create_fragment = mac_biba_create_fragment, 2670 .mpo_create_ifnet = mac_biba_create_ifnet, 2671 .mpo_create_ipq = mac_biba_create_ipq, 2672 .mpo_create_mbuf_from_mbuf = mac_biba_create_mbuf_from_mbuf, 2673 .mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer, 2674 .mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc, 2675 .mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet, 2676 .mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap, 2677 .mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer, 2678 .mpo_fragment_match = mac_biba_fragment_match, 2679 .mpo_relabel_ifnet = mac_biba_relabel_ifnet, 2680 .mpo_update_ipq = mac_biba_update_ipq, 2681 .mpo_create_cred = mac_biba_create_cred, 2682 .mpo_create_proc0 = mac_biba_create_proc0, 2683 .mpo_create_proc1 = mac_biba_create_proc1, 2684 .mpo_relabel_cred = mac_biba_relabel_cred, 2685 .mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive, 2686 .mpo_check_cred_relabel = mac_biba_check_cred_relabel, 2687 .mpo_check_cred_visible = mac_biba_check_cred_visible, 2688 .mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel, 2689 .mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit, 2690 .mpo_check_kld_load = mac_biba_check_kld_load, 2691 .mpo_check_kld_unload = mac_biba_check_kld_unload, 2692 .mpo_check_mount_stat = mac_biba_check_mount_stat, 2693 .mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl, 2694 .mpo_check_pipe_poll = mac_biba_check_pipe_poll, 2695 .mpo_check_pipe_read = mac_biba_check_pipe_read, 2696 .mpo_check_pipe_relabel = mac_biba_check_pipe_relabel, 2697 .mpo_check_pipe_stat = mac_biba_check_pipe_stat, 2698 .mpo_check_pipe_write = mac_biba_check_pipe_write, 2699 .mpo_check_proc_debug = mac_biba_check_proc_debug, 2700 .mpo_check_proc_sched = mac_biba_check_proc_sched, 2701 .mpo_check_proc_signal = mac_biba_check_proc_signal, 2702 .mpo_check_socket_deliver = mac_biba_check_socket_deliver, 2703 .mpo_check_socket_relabel = mac_biba_check_socket_relabel, 2704 .mpo_check_socket_visible = mac_biba_check_socket_visible, 2705 .mpo_check_sysarch_ioperm = mac_biba_check_sysarch_ioperm, 2706 .mpo_check_system_acct = mac_biba_check_system_acct, 2707 .mpo_check_system_settime = mac_biba_check_system_settime, 2708 .mpo_check_system_swapon = mac_biba_check_system_swapon, 2709 .mpo_check_system_swapoff = mac_biba_check_system_swapoff, 2710 .mpo_check_system_sysctl = mac_biba_check_system_sysctl, 2711 .mpo_check_vnode_access = mac_biba_check_vnode_open, 2712 .mpo_check_vnode_chdir = mac_biba_check_vnode_chdir, 2713 .mpo_check_vnode_chroot = mac_biba_check_vnode_chroot, 2714 .mpo_check_vnode_create = mac_biba_check_vnode_create, 2715 .mpo_check_vnode_delete = mac_biba_check_vnode_delete, 2716 .mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl, 2717 .mpo_check_vnode_exec = mac_biba_check_vnode_exec, 2718 .mpo_check_vnode_getacl = mac_biba_check_vnode_getacl, 2719 .mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr, 2720 .mpo_check_vnode_link = mac_biba_check_vnode_link, 2721 .mpo_check_vnode_lookup = mac_biba_check_vnode_lookup, 2722 .mpo_check_vnode_mmap = mac_biba_check_vnode_mmap, 2723 .mpo_check_vnode_mprotect = mac_biba_check_vnode_mmap, 2724 .mpo_check_vnode_open = mac_biba_check_vnode_open, 2725 .mpo_check_vnode_poll = mac_biba_check_vnode_poll, 2726 .mpo_check_vnode_read = mac_biba_check_vnode_read, 2727 .mpo_check_vnode_readdir = mac_biba_check_vnode_readdir, 2728 .mpo_check_vnode_readlink = mac_biba_check_vnode_readlink, 2729 .mpo_check_vnode_relabel = mac_biba_check_vnode_relabel, 2730 .mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from, 2731 .mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to, 2732 .mpo_check_vnode_revoke = mac_biba_check_vnode_revoke, 2733 .mpo_check_vnode_setacl = mac_biba_check_vnode_setacl, 2734 .mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr, 2735 .mpo_check_vnode_setflags = mac_biba_check_vnode_setflags, 2736 .mpo_check_vnode_setmode = mac_biba_check_vnode_setmode, 2737 .mpo_check_vnode_setowner = mac_biba_check_vnode_setowner, 2738 .mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes, 2739 .mpo_check_vnode_stat = mac_biba_check_vnode_stat, 2740 .mpo_check_vnode_write = mac_biba_check_vnode_write, 2741}; 2742 2743MAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba", 2744 MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mac_biba_slot);
| 630} 631 632static int 633mac_biba_parse_element(struct mac_biba_element *element, char *string) 634{ 635 char *compartment, *end, *grade; 636 int value; 637 638 if (strcmp(string, "high") == 0 || 639 strcmp(string, "hi") == 0) { 640 element->mbe_type = MAC_BIBA_TYPE_HIGH; 641 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 642 } else if (strcmp(string, "low") == 0 || 643 strcmp(string, "lo") == 0) { 644 element->mbe_type = MAC_BIBA_TYPE_LOW; 645 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 646 } else if (strcmp(string, "equal") == 0 || 647 strcmp(string, "eq") == 0) { 648 element->mbe_type = MAC_BIBA_TYPE_EQUAL; 649 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 650 } else { 651 element->mbe_type = MAC_BIBA_TYPE_GRADE; 652 653 /* 654 * Numeric grade piece of the element. 655 */ 656 grade = strsep(&string, ":"); 657 value = strtol(grade, &end, 10); 658 if (end == grade || *end != '\0') 659 return (EINVAL); 660 if (value < 0 || value > 65535) 661 return (EINVAL); 662 element->mbe_grade = value; 663 664 /* 665 * Optional compartment piece of the element. If none 666 * are included, we assume that the label has no 667 * compartments. 668 */ 669 if (string == NULL) 670 return (0); 671 if (*string == '\0') 672 return (0); 673 674 while ((compartment = strsep(&string, "+")) != NULL) { 675 value = strtol(compartment, &end, 10); 676 if (compartment == end || *end != '\0') 677 return (EINVAL); 678 if (value < 1 || value > MAC_BIBA_MAX_COMPARTMENTS) 679 return (EINVAL); 680 MAC_BIBA_BIT_SET(value, element->mbe_compartments); 681 } 682 } 683 684 return (0); 685} 686 687/* 688 * Note: destructively consumes the string, make a local copy before 689 * calling if that's a problem. 690 */ 691static int 692mac_biba_parse(struct mac_biba *mac_biba, char *string) 693{ 694 char *rangehigh, *rangelow, *single; 695 int error; 696 697 single = strsep(&string, "("); 698 if (*single == '\0') 699 single = NULL; 700 701 if (string != NULL) { 702 rangelow = strsep(&string, "-"); 703 if (string == NULL) 704 return (EINVAL); 705 rangehigh = strsep(&string, ")"); 706 if (string == NULL) 707 return (EINVAL); 708 if (*string != '\0') 709 return (EINVAL); 710 } else { 711 rangelow = NULL; 712 rangehigh = NULL; 713 } 714 715 KASSERT((rangelow != NULL && rangehigh != NULL) || 716 (rangelow == NULL && rangehigh == NULL), 717 ("mac_biba_parse: range mismatch")); 718 719 bzero(mac_biba, sizeof(*mac_biba)); 720 if (single != NULL) { 721 error = mac_biba_parse_element(&mac_biba->mb_single, single); 722 if (error) 723 return (error); 724 mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE; 725 } 726 727 if (rangelow != NULL) { 728 error = mac_biba_parse_element(&mac_biba->mb_rangelow, 729 rangelow); 730 if (error) 731 return (error); 732 error = mac_biba_parse_element(&mac_biba->mb_rangehigh, 733 rangehigh); 734 if (error) 735 return (error); 736 mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE; 737 } 738 739 error = mac_biba_valid(mac_biba); 740 if (error) 741 return (error); 742 743 return (0); 744} 745 746static int 747mac_biba_internalize_label(struct label *label, char *element_name, 748 char *element_data, int *claimed) 749{ 750 struct mac_biba *mac_biba, mac_biba_temp; 751 int error; 752 753 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 754 return (0); 755 756 (*claimed)++; 757 758 error = mac_biba_parse(&mac_biba_temp, element_data); 759 if (error) 760 return (error); 761 762 mac_biba = SLOT(label); 763 *mac_biba = mac_biba_temp; 764 765 return (0); 766} 767 768static void 769mac_biba_copy_label(struct label *src, struct label *dest) 770{ 771 772 *SLOT(dest) = *SLOT(src); 773} 774 775/* 776 * Labeling event operations: file system objects, and things that look 777 * a lot like file system objects. 778 */ 779static void 780mac_biba_create_devfs_device(struct mount *mp, dev_t dev, 781 struct devfs_dirent *devfs_dirent, struct label *label) 782{ 783 struct mac_biba *mac_biba; 784 int biba_type; 785 786 mac_biba = SLOT(label); 787 if (strcmp(dev->si_name, "null") == 0 || 788 strcmp(dev->si_name, "zero") == 0 || 789 strcmp(dev->si_name, "random") == 0 || 790 strncmp(dev->si_name, "fd/", strlen("fd/")) == 0) 791 biba_type = MAC_BIBA_TYPE_EQUAL; 792 else if (ptys_equal && 793 (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 || 794 strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0)) 795 biba_type = MAC_BIBA_TYPE_EQUAL; 796 else 797 biba_type = MAC_BIBA_TYPE_HIGH; 798 mac_biba_set_single(mac_biba, biba_type, 0, NULL); 799} 800 801static void 802mac_biba_create_devfs_directory(struct mount *mp, char *dirname, 803 int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label) 804{ 805 struct mac_biba *mac_biba; 806 807 mac_biba = SLOT(label); 808 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 809} 810 811static void 812mac_biba_create_devfs_symlink(struct ucred *cred, struct mount *mp, 813 struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de, 814 struct label *delabel) 815{ 816 struct mac_biba *source, *dest; 817 818 source = SLOT(&cred->cr_label); 819 dest = SLOT(delabel); 820 821 mac_biba_copy_single(source, dest); 822} 823 824static void 825mac_biba_create_mount(struct ucred *cred, struct mount *mp, 826 struct label *mntlabel, struct label *fslabel) 827{ 828 struct mac_biba *source, *dest; 829 830 source = SLOT(&cred->cr_label); 831 dest = SLOT(mntlabel); 832 mac_biba_copy_single(source, dest); 833 dest = SLOT(fslabel); 834 mac_biba_copy_single(source, dest); 835} 836 837static void 838mac_biba_create_root_mount(struct ucred *cred, struct mount *mp, 839 struct label *mntlabel, struct label *fslabel) 840{ 841 struct mac_biba *mac_biba; 842 843 /* Always mount root as high integrity. */ 844 mac_biba = SLOT(fslabel); 845 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 846 mac_biba = SLOT(mntlabel); 847 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 848} 849 850static void 851mac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp, 852 struct label *vnodelabel, struct label *label) 853{ 854 struct mac_biba *source, *dest; 855 856 source = SLOT(label); 857 dest = SLOT(vnodelabel); 858 859 mac_biba_copy(source, dest); 860} 861 862static void 863mac_biba_update_devfsdirent(struct mount *mp, 864 struct devfs_dirent *devfs_dirent, struct label *direntlabel, 865 struct vnode *vp, struct label *vnodelabel) 866{ 867 struct mac_biba *source, *dest; 868 869 source = SLOT(vnodelabel); 870 dest = SLOT(direntlabel); 871 872 mac_biba_copy(source, dest); 873} 874 875static void 876mac_biba_associate_vnode_devfs(struct mount *mp, struct label *fslabel, 877 struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 878 struct label *vlabel) 879{ 880 struct mac_biba *source, *dest; 881 882 source = SLOT(delabel); 883 dest = SLOT(vlabel); 884 885 mac_biba_copy_single(source, dest); 886} 887 888static int 889mac_biba_associate_vnode_extattr(struct mount *mp, struct label *fslabel, 890 struct vnode *vp, struct label *vlabel) 891{ 892 struct mac_biba temp, *source, *dest; 893 int buflen, error; 894 895 source = SLOT(fslabel); 896 dest = SLOT(vlabel); 897 898 buflen = sizeof(temp); 899 bzero(&temp, buflen); 900 901 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 902 MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &temp, curthread); 903 if (error == ENOATTR || error == EOPNOTSUPP) { 904 /* Fall back to the fslabel. */ 905 mac_biba_copy_single(source, dest); 906 return (0); 907 } else if (error) 908 return (error); 909 910 if (buflen != sizeof(temp)) { 911 printf("mac_biba_associate_vnode_extattr: bad size %d\n", 912 buflen); 913 return (EPERM); 914 } 915 if (mac_biba_valid(&temp) != 0) { 916 printf("mac_biba_associate_vnode_extattr: invalid\n"); 917 return (EPERM); 918 } 919 if ((temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE) { 920 printf("mac_biba_associate_vnode_extattr: not single\n"); 921 return (EPERM); 922 } 923 924 mac_biba_copy_single(&temp, dest); 925 return (0); 926} 927 928static void 929mac_biba_associate_vnode_singlelabel(struct mount *mp, 930 struct label *fslabel, struct vnode *vp, struct label *vlabel) 931{ 932 struct mac_biba *source, *dest; 933 934 source = SLOT(fslabel); 935 dest = SLOT(vlabel); 936 937 mac_biba_copy_single(source, dest); 938} 939 940static int 941mac_biba_create_vnode_extattr(struct ucred *cred, struct mount *mp, 942 struct label *fslabel, struct vnode *dvp, struct label *dlabel, 943 struct vnode *vp, struct label *vlabel, struct componentname *cnp) 944{ 945 struct mac_biba *source, *dest, temp; 946 size_t buflen; 947 int error; 948 949 buflen = sizeof(temp); 950 bzero(&temp, buflen); 951 952 source = SLOT(&cred->cr_label); 953 dest = SLOT(vlabel); 954 mac_biba_copy_single(source, &temp); 955 956 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 957 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread); 958 if (error == 0) 959 mac_biba_copy_single(source, dest); 960 return (error); 961} 962 963static int 964mac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 965 struct label *vlabel, struct label *intlabel) 966{ 967 struct mac_biba *source, temp; 968 size_t buflen; 969 int error; 970 971 buflen = sizeof(temp); 972 bzero(&temp, buflen); 973 974 source = SLOT(intlabel); 975 if ((source->mb_flags & MAC_BIBA_FLAG_SINGLE) == 0) 976 return (0); 977 978 mac_biba_copy_single(source, &temp); 979 980 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 981 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread); 982 return (error); 983} 984 985/* 986 * Labeling event operations: IPC object. 987 */ 988static void 989mac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel, 990 struct mbuf *m, struct label *mbuflabel) 991{ 992 struct mac_biba *source, *dest; 993 994 source = SLOT(socketlabel); 995 dest = SLOT(mbuflabel); 996 997 mac_biba_copy_single(source, dest); 998} 999 1000static void 1001mac_biba_create_socket(struct ucred *cred, struct socket *socket, 1002 struct label *socketlabel) 1003{ 1004 struct mac_biba *source, *dest; 1005 1006 source = SLOT(&cred->cr_label); 1007 dest = SLOT(socketlabel); 1008 1009 mac_biba_copy_single(source, dest); 1010} 1011 1012static void 1013mac_biba_create_pipe(struct ucred *cred, struct pipe *pipe, 1014 struct label *pipelabel) 1015{ 1016 struct mac_biba *source, *dest; 1017 1018 source = SLOT(&cred->cr_label); 1019 dest = SLOT(pipelabel); 1020 1021 mac_biba_copy_single(source, dest); 1022} 1023 1024static void 1025mac_biba_create_socket_from_socket(struct socket *oldsocket, 1026 struct label *oldsocketlabel, struct socket *newsocket, 1027 struct label *newsocketlabel) 1028{ 1029 struct mac_biba *source, *dest; 1030 1031 source = SLOT(oldsocketlabel); 1032 dest = SLOT(newsocketlabel); 1033 1034 mac_biba_copy_single(source, dest); 1035} 1036 1037static void 1038mac_biba_relabel_socket(struct ucred *cred, struct socket *socket, 1039 struct label *socketlabel, struct label *newlabel) 1040{ 1041 struct mac_biba *source, *dest; 1042 1043 source = SLOT(newlabel); 1044 dest = SLOT(socketlabel); 1045 1046 mac_biba_copy(source, dest); 1047} 1048 1049static void 1050mac_biba_relabel_pipe(struct ucred *cred, struct pipe *pipe, 1051 struct label *pipelabel, struct label *newlabel) 1052{ 1053 struct mac_biba *source, *dest; 1054 1055 source = SLOT(newlabel); 1056 dest = SLOT(pipelabel); 1057 1058 mac_biba_copy(source, dest); 1059} 1060 1061static void 1062mac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel, 1063 struct socket *socket, struct label *socketpeerlabel) 1064{ 1065 struct mac_biba *source, *dest; 1066 1067 source = SLOT(mbuflabel); 1068 dest = SLOT(socketpeerlabel); 1069 1070 mac_biba_copy_single(source, dest); 1071} 1072 1073/* 1074 * Labeling event operations: network objects. 1075 */ 1076static void 1077mac_biba_set_socket_peer_from_socket(struct socket *oldsocket, 1078 struct label *oldsocketlabel, struct socket *newsocket, 1079 struct label *newsocketpeerlabel) 1080{ 1081 struct mac_biba *source, *dest; 1082 1083 source = SLOT(oldsocketlabel); 1084 dest = SLOT(newsocketpeerlabel); 1085 1086 mac_biba_copy_single(source, dest); 1087} 1088 1089static void 1090mac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d, 1091 struct label *bpflabel) 1092{ 1093 struct mac_biba *source, *dest; 1094 1095 source = SLOT(&cred->cr_label); 1096 dest = SLOT(bpflabel); 1097 1098 mac_biba_copy_single(source, dest); 1099} 1100 1101static void 1102mac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel) 1103{ 1104 char tifname[IFNAMSIZ], ifname[IFNAMSIZ], *p, *q; 1105 char tiflist[sizeof(trusted_interfaces)]; 1106 struct mac_biba *dest; 1107 int len, type; 1108 1109 dest = SLOT(ifnetlabel); 1110 1111 if (ifnet->if_type == IFT_LOOP) { 1112 type = MAC_BIBA_TYPE_EQUAL; 1113 goto set; 1114 } 1115 1116 if (trust_all_interfaces) { 1117 type = MAC_BIBA_TYPE_HIGH; 1118 goto set; 1119 } 1120 1121 type = MAC_BIBA_TYPE_LOW; 1122 1123 if (trusted_interfaces[0] == '\0' || 1124 !strvalid(trusted_interfaces, sizeof(trusted_interfaces))) 1125 goto set; 1126 1127 bzero(tiflist, sizeof(tiflist)); 1128 for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++) 1129 if(*p != ' ' && *p != '\t') 1130 *q = *p; 1131 1132 snprintf(ifname, IFNAMSIZ, "%s%d", ifnet->if_name, ifnet->if_unit); 1133 1134 for (p = q = tiflist;; p++) { 1135 if (*p == ',' || *p == '\0') { 1136 len = p - q; 1137 if (len < IFNAMSIZ) { 1138 bzero(tifname, sizeof(tifname)); 1139 bcopy(q, tifname, len); 1140 if (strcmp(tifname, ifname) == 0) { 1141 type = MAC_BIBA_TYPE_HIGH; 1142 break; 1143 } 1144 } else { 1145 *p = '\0'; 1146 printf("mac_biba warning: interface name " 1147 "\"%s\" is too long (must be < %d)\n", 1148 q, IFNAMSIZ); 1149 } 1150 if (*p == '\0') 1151 break; 1152 q = p + 1; 1153 } 1154 } 1155set: 1156 mac_biba_set_single(dest, type, 0, NULL); 1157 mac_biba_set_range(dest, type, 0, NULL, type, 0, NULL); 1158} 1159 1160static void 1161mac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1162 struct ipq *ipq, struct label *ipqlabel) 1163{ 1164 struct mac_biba *source, *dest; 1165 1166 source = SLOT(fragmentlabel); 1167 dest = SLOT(ipqlabel); 1168 1169 mac_biba_copy_single(source, dest); 1170} 1171 1172static void 1173mac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel, 1174 struct mbuf *datagram, struct label *datagramlabel) 1175{ 1176 struct mac_biba *source, *dest; 1177 1178 source = SLOT(ipqlabel); 1179 dest = SLOT(datagramlabel); 1180 1181 /* Just use the head, since we require them all to match. */ 1182 mac_biba_copy_single(source, dest); 1183} 1184 1185static void 1186mac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel, 1187 struct mbuf *fragment, struct label *fragmentlabel) 1188{ 1189 struct mac_biba *source, *dest; 1190 1191 source = SLOT(datagramlabel); 1192 dest = SLOT(fragmentlabel); 1193 1194 mac_biba_copy_single(source, dest); 1195} 1196 1197static void 1198mac_biba_create_mbuf_from_mbuf(struct mbuf *oldmbuf, 1199 struct label *oldmbuflabel, struct mbuf *newmbuf, 1200 struct label *newmbuflabel) 1201{ 1202 struct mac_biba *source, *dest; 1203 1204 source = SLOT(oldmbuflabel); 1205 dest = SLOT(newmbuflabel); 1206 1207 /* 1208 * Because the source mbuf may not yet have been "created", 1209 * just initialized, we do a conditional copy. Since we don't 1210 * allow mbufs to have ranges, do a KASSERT to make sure that 1211 * doesn't happen. 1212 */ 1213 KASSERT((source->mb_flags & MAC_BIBA_FLAG_RANGE) == 0, 1214 ("mac_biba_create_mbuf_from_mbuf: source mbuf has range")); 1215 mac_biba_copy(source, dest); 1216} 1217 1218static void 1219mac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel, 1220 struct mbuf *mbuf, struct label *mbuflabel) 1221{ 1222 struct mac_biba *dest; 1223 1224 dest = SLOT(mbuflabel); 1225 1226 mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1227} 1228 1229static void 1230mac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel, 1231 struct mbuf *mbuf, struct label *mbuflabel) 1232{ 1233 struct mac_biba *source, *dest; 1234 1235 source = SLOT(bpflabel); 1236 dest = SLOT(mbuflabel); 1237 1238 mac_biba_copy_single(source, dest); 1239} 1240 1241static void 1242mac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel, 1243 struct mbuf *m, struct label *mbuflabel) 1244{ 1245 struct mac_biba *source, *dest; 1246 1247 source = SLOT(ifnetlabel); 1248 dest = SLOT(mbuflabel); 1249 1250 mac_biba_copy_single(source, dest); 1251} 1252 1253static void 1254mac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf, 1255 struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel, 1256 struct mbuf *newmbuf, struct label *newmbuflabel) 1257{ 1258 struct mac_biba *source, *dest; 1259 1260 source = SLOT(oldmbuflabel); 1261 dest = SLOT(newmbuflabel); 1262 1263 mac_biba_copy_single(source, dest); 1264} 1265 1266static void 1267mac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel, 1268 struct mbuf *newmbuf, struct label *newmbuflabel) 1269{ 1270 struct mac_biba *source, *dest; 1271 1272 source = SLOT(oldmbuflabel); 1273 dest = SLOT(newmbuflabel); 1274 1275 mac_biba_copy_single(source, dest); 1276} 1277 1278static int 1279mac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel, 1280 struct ipq *ipq, struct label *ipqlabel) 1281{ 1282 struct mac_biba *a, *b; 1283 1284 a = SLOT(ipqlabel); 1285 b = SLOT(fragmentlabel); 1286 1287 return (mac_biba_equal_single(a, b)); 1288} 1289 1290static void 1291mac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet, 1292 struct label *ifnetlabel, struct label *newlabel) 1293{ 1294 struct mac_biba *source, *dest; 1295 1296 source = SLOT(newlabel); 1297 dest = SLOT(ifnetlabel); 1298 1299 mac_biba_copy(source, dest); 1300} 1301 1302static void 1303mac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1304 struct ipq *ipq, struct label *ipqlabel) 1305{ 1306 1307 /* NOOP: we only accept matching labels, so no need to update */ 1308} 1309 1310/* 1311 * Labeling event operations: processes. 1312 */ 1313static void 1314mac_biba_create_cred(struct ucred *cred_parent, struct ucred *cred_child) 1315{ 1316 struct mac_biba *source, *dest; 1317 1318 source = SLOT(&cred_parent->cr_label); 1319 dest = SLOT(&cred_child->cr_label); 1320 1321 mac_biba_copy_single(source, dest); 1322 mac_biba_copy_range(source, dest); 1323} 1324 1325static void 1326mac_biba_create_proc0(struct ucred *cred) 1327{ 1328 struct mac_biba *dest; 1329 1330 dest = SLOT(&cred->cr_label); 1331 1332 mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1333 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1334 MAC_BIBA_TYPE_HIGH, 0, NULL); 1335} 1336 1337static void 1338mac_biba_create_proc1(struct ucred *cred) 1339{ 1340 struct mac_biba *dest; 1341 1342 dest = SLOT(&cred->cr_label); 1343 1344 mac_biba_set_single(dest, MAC_BIBA_TYPE_HIGH, 0, NULL); 1345 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1346 MAC_BIBA_TYPE_HIGH, 0, NULL); 1347} 1348 1349static void 1350mac_biba_relabel_cred(struct ucred *cred, struct label *newlabel) 1351{ 1352 struct mac_biba *source, *dest; 1353 1354 source = SLOT(newlabel); 1355 dest = SLOT(&cred->cr_label); 1356 1357 mac_biba_copy(source, dest); 1358} 1359 1360/* 1361 * Access control checks. 1362 */ 1363static int 1364mac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel, 1365 struct ifnet *ifnet, struct label *ifnetlabel) 1366{ 1367 struct mac_biba *a, *b; 1368 1369 if (!mac_biba_enabled) 1370 return (0); 1371 1372 a = SLOT(bpflabel); 1373 b = SLOT(ifnetlabel); 1374 1375 if (mac_biba_equal_single(a, b)) 1376 return (0); 1377 return (EACCES); 1378} 1379 1380static int 1381mac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel) 1382{ 1383 struct mac_biba *subj, *new; 1384 int error; 1385 1386 subj = SLOT(&cred->cr_label); 1387 new = SLOT(newlabel); 1388 1389 /* 1390 * If there is a Biba label update for the credential, it may 1391 * be an update of the single, range, or both. 1392 */ 1393 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1394 if (error) 1395 return (error); 1396 1397 /* 1398 * If the Biba label is to be changed, authorize as appropriate. 1399 */ 1400 if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1401 /* 1402 * If the change request modifies both the Biba label 1403 * single and range, check that the new single will be 1404 * in the new range. 1405 */ 1406 if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) == 1407 MAC_BIBA_FLAGS_BOTH && 1408 !mac_biba_single_in_range(new, new)) 1409 return (EINVAL); 1410 1411 /* 1412 * To change the Biba single label on a credential, the 1413 * new single label must be in the current range. 1414 */ 1415 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE && 1416 !mac_biba_single_in_range(new, subj)) 1417 return (EPERM); 1418 1419 /* 1420 * To change the Biba range on a credential, the new 1421 * range label must be in the current range. 1422 */ 1423 if (new->mb_flags & MAC_BIBA_FLAG_RANGE && 1424 !mac_biba_range_in_range(new, subj)) 1425 return (EPERM); 1426 1427 /* 1428 * To have EQUAL in any component of the new credential 1429 * Biba label, the subject must already have EQUAL in 1430 * their label. 1431 */ 1432 if (mac_biba_contains_equal(new)) { 1433 error = mac_biba_subject_privileged(subj); 1434 if (error) 1435 return (error); 1436 } 1437 } 1438 1439 return (0); 1440} 1441 1442static int 1443mac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2) 1444{ 1445 struct mac_biba *subj, *obj; 1446 1447 if (!mac_biba_enabled) 1448 return (0); 1449 1450 subj = SLOT(&u1->cr_label); 1451 obj = SLOT(&u2->cr_label); 1452 1453 /* XXX: range */ 1454 if (!mac_biba_dominate_single(obj, subj)) 1455 return (ESRCH); 1456 1457 return (0); 1458} 1459 1460static int 1461mac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet, 1462 struct label *ifnetlabel, struct label *newlabel) 1463{ 1464 struct mac_biba *subj, *new; 1465 int error; 1466 1467 subj = SLOT(&cred->cr_label); 1468 new = SLOT(newlabel); 1469 1470 /* 1471 * If there is a Biba label update for the interface, it may 1472 * be an update of the single, range, or both. 1473 */ 1474 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1475 if (error) 1476 return (error); 1477 1478 /* 1479 * Relabling network interfaces requires Biba privilege. 1480 */ 1481 error = mac_biba_subject_privileged(subj); 1482 if (error) 1483 return (error); 1484 1485 /* 1486 * If the Biba label is to be changed, authorize as appropriate. 1487 */ 1488 if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1489 /* 1490 * Rely on the traditional superuser status for the Biba 1491 * interface relabel requirements. XXXMAC: This will go 1492 * away. 1493 */ 1494 error = suser_cred(cred, 0); 1495 if (error) 1496 return (EPERM); 1497 1498 /* 1499 * XXXMAC: Additional consistency tests regarding the single 1500 * and the range of the new label might be performed here. 1501 */ 1502 } 1503 1504 return (0); 1505} 1506 1507static int 1508mac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, 1509 struct mbuf *m, struct label *mbuflabel) 1510{ 1511 struct mac_biba *p, *i; 1512 1513 if (!mac_biba_enabled) 1514 return (0); 1515 1516 p = SLOT(mbuflabel); 1517 i = SLOT(ifnetlabel); 1518 1519 return (mac_biba_single_in_range(p, i) ? 0 : EACCES); 1520} 1521 1522static int 1523mac_biba_check_kld_load(struct ucred *cred, struct vnode *vp, 1524 struct label *label) 1525{ 1526 struct mac_biba *subj, *obj; 1527 int error; 1528 1529 if (!mac_biba_enabled) 1530 return (0); 1531 1532 subj = SLOT(&cred->cr_label); 1533 1534 error = mac_biba_subject_privileged(subj); 1535 if (error) 1536 return (error); 1537 1538 obj = SLOT(label); 1539 if (!mac_biba_high_single(obj)) 1540 return (EACCES); 1541 1542 return (0); 1543} 1544 1545 1546static int 1547mac_biba_check_kld_unload(struct ucred *cred) 1548{ 1549 struct mac_biba *subj; 1550 1551 if (!mac_biba_enabled) 1552 return (0); 1553 1554 subj = SLOT(&cred->cr_label); 1555 1556 return (mac_biba_subject_privileged(subj)); 1557} 1558 1559static int 1560mac_biba_check_mount_stat(struct ucred *cred, struct mount *mp, 1561 struct label *mntlabel) 1562{ 1563 struct mac_biba *subj, *obj; 1564 1565 if (!mac_biba_enabled) 1566 return (0); 1567 1568 subj = SLOT(&cred->cr_label); 1569 obj = SLOT(mntlabel); 1570 1571 if (!mac_biba_dominate_single(obj, subj)) 1572 return (EACCES); 1573 1574 return (0); 1575} 1576 1577static int 1578mac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, 1579 struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data) 1580{ 1581 1582 if(!mac_biba_enabled) 1583 return (0); 1584 1585 /* XXX: This will be implemented soon... */ 1586 1587 return (0); 1588} 1589 1590static int 1591mac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe, 1592 struct label *pipelabel) 1593{ 1594 struct mac_biba *subj, *obj; 1595 1596 if (!mac_biba_enabled) 1597 return (0); 1598 1599 subj = SLOT(&cred->cr_label); 1600 obj = SLOT((pipelabel)); 1601 1602 if (!mac_biba_dominate_single(obj, subj)) 1603 return (EACCES); 1604 1605 return (0); 1606} 1607 1608static int 1609mac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe, 1610 struct label *pipelabel) 1611{ 1612 struct mac_biba *subj, *obj; 1613 1614 if (!mac_biba_enabled) 1615 return (0); 1616 1617 subj = SLOT(&cred->cr_label); 1618 obj = SLOT((pipelabel)); 1619 1620 if (!mac_biba_dominate_single(obj, subj)) 1621 return (EACCES); 1622 1623 return (0); 1624} 1625 1626static int 1627mac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 1628 struct label *pipelabel, struct label *newlabel) 1629{ 1630 struct mac_biba *subj, *obj, *new; 1631 int error; 1632 1633 new = SLOT(newlabel); 1634 subj = SLOT(&cred->cr_label); 1635 obj = SLOT(pipelabel); 1636 1637 /* 1638 * If there is a Biba label update for a pipe, it must be a 1639 * single update. 1640 */ 1641 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1642 if (error) 1643 return (error); 1644 1645 /* 1646 * To perform a relabel of a pipe (Biba label or not), Biba must 1647 * authorize the relabel. 1648 */ 1649 if (!mac_biba_single_in_range(obj, subj)) 1650 return (EPERM); 1651 1652 /* 1653 * If the Biba label is to be changed, authorize as appropriate. 1654 */ 1655 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1656 /* 1657 * To change the Biba label on a pipe, the new pipe label 1658 * must be in the subject range. 1659 */ 1660 if (!mac_biba_single_in_range(new, subj)) 1661 return (EPERM); 1662 1663 /* 1664 * To change the Biba label on a pipe to be EQUAL, the 1665 * subject must have appropriate privilege. 1666 */ 1667 if (mac_biba_contains_equal(new)) { 1668 error = mac_biba_subject_privileged(subj); 1669 if (error) 1670 return (error); 1671 } 1672 } 1673 1674 return (0); 1675} 1676 1677static int 1678mac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe, 1679 struct label *pipelabel) 1680{ 1681 struct mac_biba *subj, *obj; 1682 1683 if (!mac_biba_enabled) 1684 return (0); 1685 1686 subj = SLOT(&cred->cr_label); 1687 obj = SLOT((pipelabel)); 1688 1689 if (!mac_biba_dominate_single(obj, subj)) 1690 return (EACCES); 1691 1692 return (0); 1693} 1694 1695static int 1696mac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe, 1697 struct label *pipelabel) 1698{ 1699 struct mac_biba *subj, *obj; 1700 1701 if (!mac_biba_enabled) 1702 return (0); 1703 1704 subj = SLOT(&cred->cr_label); 1705 obj = SLOT((pipelabel)); 1706 1707 if (!mac_biba_dominate_single(subj, obj)) 1708 return (EACCES); 1709 1710 return (0); 1711} 1712 1713static int 1714mac_biba_check_proc_debug(struct ucred *cred, struct proc *proc) 1715{ 1716 struct mac_biba *subj, *obj; 1717 1718 if (!mac_biba_enabled) 1719 return (0); 1720 1721 subj = SLOT(&cred->cr_label); 1722 obj = SLOT(&proc->p_ucred->cr_label); 1723 1724 /* XXX: range checks */ 1725 if (!mac_biba_dominate_single(obj, subj)) 1726 return (ESRCH); 1727 if (!mac_biba_dominate_single(subj, obj)) 1728 return (EACCES); 1729 1730 return (0); 1731} 1732 1733static int 1734mac_biba_check_proc_sched(struct ucred *cred, struct proc *proc) 1735{ 1736 struct mac_biba *subj, *obj; 1737 1738 if (!mac_biba_enabled) 1739 return (0); 1740 1741 subj = SLOT(&cred->cr_label); 1742 obj = SLOT(&proc->p_ucred->cr_label); 1743 1744 /* XXX: range checks */ 1745 if (!mac_biba_dominate_single(obj, subj)) 1746 return (ESRCH); 1747 if (!mac_biba_dominate_single(subj, obj)) 1748 return (EACCES); 1749 1750 return (0); 1751} 1752 1753static int 1754mac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 1755{ 1756 struct mac_biba *subj, *obj; 1757 1758 if (!mac_biba_enabled) 1759 return (0); 1760 1761 subj = SLOT(&cred->cr_label); 1762 obj = SLOT(&proc->p_ucred->cr_label); 1763 1764 /* XXX: range checks */ 1765 if (!mac_biba_dominate_single(obj, subj)) 1766 return (ESRCH); 1767 if (!mac_biba_dominate_single(subj, obj)) 1768 return (EACCES); 1769 1770 return (0); 1771} 1772 1773static int 1774mac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel, 1775 struct mbuf *m, struct label *mbuflabel) 1776{ 1777 struct mac_biba *p, *s; 1778 1779 if (!mac_biba_enabled) 1780 return (0); 1781 1782 p = SLOT(mbuflabel); 1783 s = SLOT(socketlabel); 1784 1785 return (mac_biba_equal_single(p, s) ? 0 : EACCES); 1786} 1787 1788static int 1789mac_biba_check_socket_relabel(struct ucred *cred, struct socket *so, 1790 struct label *socketlabel, struct label *newlabel) 1791{ 1792 struct mac_biba *subj, *obj, *new; 1793 int error; 1794 1795 new = SLOT(newlabel); 1796 subj = SLOT(&cred->cr_label); 1797 obj = SLOT(socketlabel); 1798 1799 /* 1800 * If there is a Biba label update for the socket, it may be 1801 * an update of single. 1802 */ 1803 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1804 if (error) 1805 return (error); 1806 1807 /* 1808 * To relabel a socket, the old socket single must be in the subject 1809 * range. 1810 */ 1811 if (!mac_biba_single_in_range(obj, subj)) 1812 return (EPERM); 1813 1814 /* 1815 * If the Biba label is to be changed, authorize as appropriate. 1816 */ 1817 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1818 /* 1819 * To relabel a socket, the new socket single must be in 1820 * the subject range. 1821 */ 1822 if (!mac_biba_single_in_range(new, subj)) 1823 return (EPERM); 1824 1825 /* 1826 * To change the Biba label on the socket to contain EQUAL, 1827 * the subject must have appropriate privilege. 1828 */ 1829 if (mac_biba_contains_equal(new)) { 1830 error = mac_biba_subject_privileged(subj); 1831 if (error) 1832 return (error); 1833 } 1834 } 1835 1836 return (0); 1837} 1838 1839static int 1840mac_biba_check_socket_visible(struct ucred *cred, struct socket *socket, 1841 struct label *socketlabel) 1842{ 1843 struct mac_biba *subj, *obj; 1844 1845 if (!mac_biba_enabled) 1846 return (0); 1847 1848 subj = SLOT(&cred->cr_label); 1849 obj = SLOT(socketlabel); 1850 1851 if (!mac_biba_dominate_single(obj, subj)) 1852 return (ENOENT); 1853 1854 return (0); 1855} 1856 1857static int 1858mac_biba_check_sysarch_ioperm(struct ucred *cred) 1859{ 1860 struct mac_biba *subj; 1861 int error; 1862 1863 if (!mac_biba_enabled) 1864 return (0); 1865 1866 subj = SLOT(&cred->cr_label); 1867 1868 error = mac_biba_subject_privileged(subj); 1869 if (error) 1870 return (error); 1871 1872 return (0); 1873} 1874 1875static int 1876mac_biba_check_system_acct(struct ucred *cred, struct vnode *vp, 1877 struct label *label) 1878{ 1879 struct mac_biba *subj, *obj; 1880 int error; 1881 1882 if (!mac_biba_enabled) 1883 return (0); 1884 1885 subj = SLOT(&cred->cr_label); 1886 1887 error = mac_biba_subject_privileged(subj); 1888 if (error) 1889 return (error); 1890 1891 if (label == NULL) 1892 return (0); 1893 1894 obj = SLOT(label); 1895 if (!mac_biba_high_single(obj)) 1896 return (EACCES); 1897 1898 return (0); 1899} 1900 1901static int 1902mac_biba_check_system_settime(struct ucred *cred) 1903{ 1904 struct mac_biba *subj; 1905 int error; 1906 1907 if (!mac_biba_enabled) 1908 return (0); 1909 1910 subj = SLOT(&cred->cr_label); 1911 1912 error = mac_biba_subject_privileged(subj); 1913 if (error) 1914 return (error); 1915 1916 return (0); 1917} 1918 1919static int 1920mac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp, 1921 struct label *label) 1922{ 1923 struct mac_biba *subj, *obj; 1924 int error; 1925 1926 if (!mac_biba_enabled) 1927 return (0); 1928 1929 subj = SLOT(&cred->cr_label); 1930 obj = SLOT(label); 1931 1932 error = mac_biba_subject_privileged(subj); 1933 if (error) 1934 return (error); 1935 1936 if (!mac_biba_high_single(obj)) 1937 return (EACCES); 1938 1939 return (0); 1940} 1941 1942static int 1943mac_biba_check_system_swapoff(struct ucred *cred, struct vnode *vp, 1944 struct label *label) 1945{ 1946 struct mac_biba *subj, *obj; 1947 int error; 1948 1949 if (!mac_biba_enabled) 1950 return (0); 1951 1952 subj = SLOT(&cred->cr_label); 1953 obj = SLOT(label); 1954 1955 error = mac_biba_subject_privileged(subj); 1956 if (error) 1957 return (error); 1958 1959 return (0); 1960} 1961 1962static int 1963mac_biba_check_system_sysctl(struct ucred *cred, int *name, u_int namelen, 1964 void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen) 1965{ 1966 struct mac_biba *subj; 1967 int error; 1968 1969 if (!mac_biba_enabled) 1970 return (0); 1971 1972 subj = SLOT(&cred->cr_label); 1973 1974 /* 1975 * In general, treat sysctl variables as biba/high, but also 1976 * require privilege to change them, since they are a 1977 * communications channel between grades. Exempt MIB 1978 * queries from this due to undocmented sysctl magic. 1979 * XXXMAC: This probably requires some more review. 1980 */ 1981 if (new != NULL) { 1982 if (namelen > 0 && name[0] == 0) 1983 return (0); 1984 1985 if (!mac_biba_subject_dominate_high(subj)) 1986 return (EACCES); 1987 1988 error = mac_biba_subject_privileged(subj); 1989 if (error) 1990 return (error); 1991 } 1992 1993 return (0); 1994} 1995 1996static int 1997mac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 1998 struct label *dlabel) 1999{ 2000 struct mac_biba *subj, *obj; 2001 2002 if (!mac_biba_enabled) 2003 return (0); 2004 2005 subj = SLOT(&cred->cr_label); 2006 obj = SLOT(dlabel); 2007 2008 if (!mac_biba_dominate_single(obj, subj)) 2009 return (EACCES); 2010 2011 return (0); 2012} 2013 2014static int 2015mac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 2016 struct label *dlabel) 2017{ 2018 struct mac_biba *subj, *obj; 2019 2020 if (!mac_biba_enabled) 2021 return (0); 2022 2023 subj = SLOT(&cred->cr_label); 2024 obj = SLOT(dlabel); 2025 2026 if (!mac_biba_dominate_single(obj, subj)) 2027 return (EACCES); 2028 2029 return (0); 2030} 2031 2032static int 2033mac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp, 2034 struct label *dlabel, struct componentname *cnp, struct vattr *vap) 2035{ 2036 struct mac_biba *subj, *obj; 2037 2038 if (!mac_biba_enabled) 2039 return (0); 2040 2041 subj = SLOT(&cred->cr_label); 2042 obj = SLOT(dlabel); 2043 2044 if (!mac_biba_dominate_single(subj, obj)) 2045 return (EACCES); 2046 2047 return (0); 2048} 2049 2050static int 2051mac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 2052 struct label *dlabel, struct vnode *vp, struct label *label, 2053 struct componentname *cnp) 2054{ 2055 struct mac_biba *subj, *obj; 2056 2057 if (!mac_biba_enabled) 2058 return (0); 2059 2060 subj = SLOT(&cred->cr_label); 2061 obj = SLOT(dlabel); 2062 2063 if (!mac_biba_dominate_single(subj, obj)) 2064 return (EACCES); 2065 2066 obj = SLOT(label); 2067 2068 if (!mac_biba_dominate_single(subj, obj)) 2069 return (EACCES); 2070 2071 return (0); 2072} 2073 2074static int 2075mac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 2076 struct label *label, acl_type_t type) 2077{ 2078 struct mac_biba *subj, *obj; 2079 2080 if (!mac_biba_enabled) 2081 return (0); 2082 2083 subj = SLOT(&cred->cr_label); 2084 obj = SLOT(label); 2085 2086 if (!mac_biba_dominate_single(subj, obj)) 2087 return (EACCES); 2088 2089 return (0); 2090} 2091 2092static int 2093mac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp, 2094 struct label *label, struct image_params *imgp, 2095 struct label *execlabel) 2096{ 2097 struct mac_biba *subj, *obj, *exec; 2098 int error; 2099 2100 if (execlabel != NULL) { 2101 /* 2102 * We currently don't permit labels to be changed at 2103 * exec-time as part of Biba, so disallow non-NULL 2104 * Biba label elements in the execlabel. 2105 */ 2106 exec = SLOT(execlabel); 2107 error = biba_atmostflags(exec, 0); 2108 if (error) 2109 return (error); 2110 } 2111 2112 if (!mac_biba_enabled) 2113 return (0); 2114 2115 subj = SLOT(&cred->cr_label); 2116 obj = SLOT(label); 2117 2118 if (!mac_biba_dominate_single(obj, subj)) 2119 return (EACCES); 2120 2121 return (0); 2122} 2123 2124static int 2125mac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 2126 struct label *label, acl_type_t type) 2127{ 2128 struct mac_biba *subj, *obj; 2129 2130 if (!mac_biba_enabled) 2131 return (0); 2132 2133 subj = SLOT(&cred->cr_label); 2134 obj = SLOT(label); 2135 2136 if (!mac_biba_dominate_single(obj, subj)) 2137 return (EACCES); 2138 2139 return (0); 2140} 2141 2142static int 2143mac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 2144 struct label *label, int attrnamespace, const char *name, struct uio *uio) 2145{ 2146 struct mac_biba *subj, *obj; 2147 2148 if (!mac_biba_enabled) 2149 return (0); 2150 2151 subj = SLOT(&cred->cr_label); 2152 obj = SLOT(label); 2153 2154 if (!mac_biba_dominate_single(obj, subj)) 2155 return (EACCES); 2156 2157 return (0); 2158} 2159 2160static int 2161mac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp, 2162 struct label *dlabel, struct vnode *vp, struct label *label, 2163 struct componentname *cnp) 2164{ 2165 struct mac_biba *subj, *obj; 2166 2167 if (!mac_biba_enabled) 2168 return (0); 2169 2170 subj = SLOT(&cred->cr_label); 2171 obj = SLOT(dlabel); 2172 2173 if (!mac_biba_dominate_single(subj, obj)) 2174 return (EACCES); 2175 2176 obj = SLOT(label); 2177 2178 if (!mac_biba_dominate_single(subj, obj)) 2179 return (EACCES); 2180 2181 return (0); 2182} 2183 2184static int 2185mac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 2186 struct label *dlabel, struct componentname *cnp) 2187{ 2188 struct mac_biba *subj, *obj; 2189 2190 if (!mac_biba_enabled) 2191 return (0); 2192 2193 subj = SLOT(&cred->cr_label); 2194 obj = SLOT(dlabel); 2195 2196 if (!mac_biba_dominate_single(obj, subj)) 2197 return (EACCES); 2198 2199 return (0); 2200} 2201 2202static int 2203mac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp, 2204 struct label *label, int prot) 2205{ 2206 struct mac_biba *subj, *obj; 2207 2208 /* 2209 * Rely on the use of open()-time protections to handle 2210 * non-revocation cases. 2211 */ 2212 if (!mac_biba_enabled || !revocation_enabled) 2213 return (0); 2214 2215 subj = SLOT(&cred->cr_label); 2216 obj = SLOT(label); 2217 2218 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2219 if (!mac_biba_dominate_single(obj, subj)) 2220 return (EACCES); 2221 } 2222 if (prot & VM_PROT_WRITE) { 2223 if (!mac_biba_dominate_single(subj, obj)) 2224 return (EACCES); 2225 } 2226 2227 return (0); 2228} 2229 2230static int 2231mac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp, 2232 struct label *vnodelabel, int acc_mode) 2233{ 2234 struct mac_biba *subj, *obj; 2235 2236 if (!mac_biba_enabled) 2237 return (0); 2238 2239 subj = SLOT(&cred->cr_label); 2240 obj = SLOT(vnodelabel); 2241 2242 /* XXX privilege override for admin? */ 2243 if (acc_mode & (VREAD | VEXEC | VSTAT)) { 2244 if (!mac_biba_dominate_single(obj, subj)) 2245 return (EACCES); 2246 } 2247 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2248 if (!mac_biba_dominate_single(subj, obj)) 2249 return (EACCES); 2250 } 2251 2252 return (0); 2253} 2254 2255static int 2256mac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 2257 struct vnode *vp, struct label *label) 2258{ 2259 struct mac_biba *subj, *obj; 2260 2261 if (!mac_biba_enabled || !revocation_enabled) 2262 return (0); 2263 2264 subj = SLOT(&active_cred->cr_label); 2265 obj = SLOT(label); 2266 2267 if (!mac_biba_dominate_single(obj, subj)) 2268 return (EACCES); 2269 2270 return (0); 2271} 2272 2273static int 2274mac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2275 struct vnode *vp, struct label *label) 2276{ 2277 struct mac_biba *subj, *obj; 2278 2279 if (!mac_biba_enabled || !revocation_enabled) 2280 return (0); 2281 2282 subj = SLOT(&active_cred->cr_label); 2283 obj = SLOT(label); 2284 2285 if (!mac_biba_dominate_single(obj, subj)) 2286 return (EACCES); 2287 2288 return (0); 2289} 2290 2291static int 2292mac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 2293 struct label *dlabel) 2294{ 2295 struct mac_biba *subj, *obj; 2296 2297 if (!mac_biba_enabled) 2298 return (0); 2299 2300 subj = SLOT(&cred->cr_label); 2301 obj = SLOT(dlabel); 2302 2303 if (!mac_biba_dominate_single(obj, subj)) 2304 return (EACCES); 2305 2306 return (0); 2307} 2308 2309static int 2310mac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp, 2311 struct label *label) 2312{ 2313 struct mac_biba *subj, *obj; 2314 2315 if (!mac_biba_enabled) 2316 return (0); 2317 2318 subj = SLOT(&cred->cr_label); 2319 obj = SLOT(label); 2320 2321 if (!mac_biba_dominate_single(obj, subj)) 2322 return (EACCES); 2323 2324 return (0); 2325} 2326 2327static int 2328mac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 2329 struct label *vnodelabel, struct label *newlabel) 2330{ 2331 struct mac_biba *old, *new, *subj; 2332 int error; 2333 2334 old = SLOT(vnodelabel); 2335 new = SLOT(newlabel); 2336 subj = SLOT(&cred->cr_label); 2337 2338 /* 2339 * If there is a Biba label update for the vnode, it must be a 2340 * single label. 2341 */ 2342 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 2343 if (error) 2344 return (error); 2345 2346 /* 2347 * To perform a relabel of the vnode (Biba label or not), Biba must 2348 * authorize the relabel. 2349 */ 2350 if (!mac_biba_single_in_range(old, subj)) 2351 return (EPERM); 2352 2353 /* 2354 * If the Biba label is to be changed, authorize as appropriate. 2355 */ 2356 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 2357 /* 2358 * To change the Biba label on a vnode, the new vnode label 2359 * must be in the subject range. 2360 */ 2361 if (!mac_biba_single_in_range(new, subj)) 2362 return (EPERM); 2363 2364 /* 2365 * To change the Biba label on the vnode to be EQUAL, 2366 * the subject must have appropriate privilege. 2367 */ 2368 if (mac_biba_contains_equal(new)) { 2369 error = mac_biba_subject_privileged(subj); 2370 if (error) 2371 return (error); 2372 } 2373 } 2374 2375 return (0); 2376} 2377 2378static int 2379mac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 2380 struct label *dlabel, struct vnode *vp, struct label *label, 2381 struct componentname *cnp) 2382{ 2383 struct mac_biba *subj, *obj; 2384 2385 if (!mac_biba_enabled) 2386 return (0); 2387 2388 subj = SLOT(&cred->cr_label); 2389 obj = SLOT(dlabel); 2390 2391 if (!mac_biba_dominate_single(subj, obj)) 2392 return (EACCES); 2393 2394 obj = SLOT(label); 2395 2396 if (!mac_biba_dominate_single(subj, obj)) 2397 return (EACCES); 2398 2399 return (0); 2400} 2401 2402static int 2403mac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 2404 struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 2405 struct componentname *cnp) 2406{ 2407 struct mac_biba *subj, *obj; 2408 2409 if (!mac_biba_enabled) 2410 return (0); 2411 2412 subj = SLOT(&cred->cr_label); 2413 obj = SLOT(dlabel); 2414 2415 if (!mac_biba_dominate_single(subj, obj)) 2416 return (EACCES); 2417 2418 if (vp != NULL) { 2419 obj = SLOT(label); 2420 2421 if (!mac_biba_dominate_single(subj, obj)) 2422 return (EACCES); 2423 } 2424 2425 return (0); 2426} 2427 2428static int 2429mac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 2430 struct label *label) 2431{ 2432 struct mac_biba *subj, *obj; 2433 2434 if (!mac_biba_enabled) 2435 return (0); 2436 2437 subj = SLOT(&cred->cr_label); 2438 obj = SLOT(label); 2439 2440 if (!mac_biba_dominate_single(subj, obj)) 2441 return (EACCES); 2442 2443 return (0); 2444} 2445 2446static int 2447mac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 2448 struct label *label, acl_type_t type, struct acl *acl) 2449{ 2450 struct mac_biba *subj, *obj; 2451 2452 if (!mac_biba_enabled) 2453 return (0); 2454 2455 subj = SLOT(&cred->cr_label); 2456 obj = SLOT(label); 2457 2458 if (!mac_biba_dominate_single(subj, obj)) 2459 return (EACCES); 2460 2461 return (0); 2462} 2463 2464static int 2465mac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2466 struct label *vnodelabel, int attrnamespace, const char *name, 2467 struct uio *uio) 2468{ 2469 struct mac_biba *subj, *obj; 2470 2471 if (!mac_biba_enabled) 2472 return (0); 2473 2474 subj = SLOT(&cred->cr_label); 2475 obj = SLOT(vnodelabel); 2476 2477 if (!mac_biba_dominate_single(subj, obj)) 2478 return (EACCES); 2479 2480 /* XXX: protect the MAC EA in a special way? */ 2481 2482 return (0); 2483} 2484 2485static int 2486mac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 2487 struct label *vnodelabel, u_long flags) 2488{ 2489 struct mac_biba *subj, *obj; 2490 2491 if (!mac_biba_enabled) 2492 return (0); 2493 2494 subj = SLOT(&cred->cr_label); 2495 obj = SLOT(vnodelabel); 2496 2497 if (!mac_biba_dominate_single(subj, obj)) 2498 return (EACCES); 2499 2500 return (0); 2501} 2502 2503static int 2504mac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 2505 struct label *vnodelabel, mode_t mode) 2506{ 2507 struct mac_biba *subj, *obj; 2508 2509 if (!mac_biba_enabled) 2510 return (0); 2511 2512 subj = SLOT(&cred->cr_label); 2513 obj = SLOT(vnodelabel); 2514 2515 if (!mac_biba_dominate_single(subj, obj)) 2516 return (EACCES); 2517 2518 return (0); 2519} 2520 2521static int 2522mac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 2523 struct label *vnodelabel, uid_t uid, gid_t gid) 2524{ 2525 struct mac_biba *subj, *obj; 2526 2527 if (!mac_biba_enabled) 2528 return (0); 2529 2530 subj = SLOT(&cred->cr_label); 2531 obj = SLOT(vnodelabel); 2532 2533 if (!mac_biba_dominate_single(subj, obj)) 2534 return (EACCES); 2535 2536 return (0); 2537} 2538 2539static int 2540mac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2541 struct label *vnodelabel, struct timespec atime, struct timespec mtime) 2542{ 2543 struct mac_biba *subj, *obj; 2544 2545 if (!mac_biba_enabled) 2546 return (0); 2547 2548 subj = SLOT(&cred->cr_label); 2549 obj = SLOT(vnodelabel); 2550 2551 if (!mac_biba_dominate_single(subj, obj)) 2552 return (EACCES); 2553 2554 return (0); 2555} 2556 2557static int 2558mac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2559 struct vnode *vp, struct label *vnodelabel) 2560{ 2561 struct mac_biba *subj, *obj; 2562 2563 if (!mac_biba_enabled) 2564 return (0); 2565 2566 subj = SLOT(&active_cred->cr_label); 2567 obj = SLOT(vnodelabel); 2568 2569 if (!mac_biba_dominate_single(obj, subj)) 2570 return (EACCES); 2571 2572 return (0); 2573} 2574 2575static int 2576mac_biba_check_vnode_write(struct ucred *active_cred, 2577 struct ucred *file_cred, struct vnode *vp, struct label *label) 2578{ 2579 struct mac_biba *subj, *obj; 2580 2581 if (!mac_biba_enabled || !revocation_enabled) 2582 return (0); 2583 2584 subj = SLOT(&active_cred->cr_label); 2585 obj = SLOT(label); 2586 2587 if (!mac_biba_dominate_single(subj, obj)) 2588 return (EACCES); 2589 2590 return (0); 2591} 2592 2593static struct mac_policy_ops mac_biba_ops = 2594{ 2595 .mpo_destroy = mac_biba_destroy, 2596 .mpo_init = mac_biba_init, 2597 .mpo_init_bpfdesc_label = mac_biba_init_label, 2598 .mpo_init_cred_label = mac_biba_init_label, 2599 .mpo_init_devfsdirent_label = mac_biba_init_label, 2600 .mpo_init_ifnet_label = mac_biba_init_label, 2601 .mpo_init_ipq_label = mac_biba_init_label_waitcheck, 2602 .mpo_init_mbuf_label = mac_biba_init_label_waitcheck, 2603 .mpo_init_mount_label = mac_biba_init_label, 2604 .mpo_init_mount_fs_label = mac_biba_init_label, 2605 .mpo_init_pipe_label = mac_biba_init_label, 2606 .mpo_init_socket_label = mac_biba_init_label_waitcheck, 2607 .mpo_init_socket_peer_label = mac_biba_init_label_waitcheck, 2608 .mpo_init_vnode_label = mac_biba_init_label, 2609 .mpo_destroy_bpfdesc_label = mac_biba_destroy_label, 2610 .mpo_destroy_cred_label = mac_biba_destroy_label, 2611 .mpo_destroy_devfsdirent_label = mac_biba_destroy_label, 2612 .mpo_destroy_ifnet_label = mac_biba_destroy_label, 2613 .mpo_destroy_ipq_label = mac_biba_destroy_label, 2614 .mpo_destroy_mbuf_label = mac_biba_destroy_label, 2615 .mpo_destroy_mount_label = mac_biba_destroy_label, 2616 .mpo_destroy_mount_fs_label = mac_biba_destroy_label, 2617 .mpo_destroy_pipe_label = mac_biba_destroy_label, 2618 .mpo_destroy_socket_label = mac_biba_destroy_label, 2619 .mpo_destroy_socket_peer_label = mac_biba_destroy_label, 2620 .mpo_destroy_vnode_label = mac_biba_destroy_label, 2621 .mpo_copy_mbuf_label = mac_biba_copy_label, 2622 .mpo_copy_pipe_label = mac_biba_copy_label, 2623 .mpo_copy_vnode_label = mac_biba_copy_label, 2624 .mpo_externalize_cred_label = mac_biba_externalize_label, 2625 .mpo_externalize_ifnet_label = mac_biba_externalize_label, 2626 .mpo_externalize_pipe_label = mac_biba_externalize_label, 2627 .mpo_externalize_socket_label = mac_biba_externalize_label, 2628 .mpo_externalize_socket_peer_label = mac_biba_externalize_label, 2629 .mpo_externalize_vnode_label = mac_biba_externalize_label, 2630 .mpo_internalize_cred_label = mac_biba_internalize_label, 2631 .mpo_internalize_ifnet_label = mac_biba_internalize_label, 2632 .mpo_internalize_pipe_label = mac_biba_internalize_label, 2633 .mpo_internalize_socket_label = mac_biba_internalize_label, 2634 .mpo_internalize_vnode_label = mac_biba_internalize_label, 2635 .mpo_create_devfs_device = mac_biba_create_devfs_device, 2636 .mpo_create_devfs_directory = mac_biba_create_devfs_directory, 2637 .mpo_create_devfs_symlink = mac_biba_create_devfs_symlink, 2638 .mpo_create_mount = mac_biba_create_mount, 2639 .mpo_create_root_mount = mac_biba_create_root_mount, 2640 .mpo_relabel_vnode = mac_biba_relabel_vnode, 2641 .mpo_update_devfsdirent = mac_biba_update_devfsdirent, 2642 .mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs, 2643 .mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr, 2644 .mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel, 2645 .mpo_create_vnode_extattr = mac_biba_create_vnode_extattr, 2646 .mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr, 2647 .mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket, 2648 .mpo_create_pipe = mac_biba_create_pipe, 2649 .mpo_create_socket = mac_biba_create_socket, 2650 .mpo_create_socket_from_socket = mac_biba_create_socket_from_socket, 2651 .mpo_relabel_pipe = mac_biba_relabel_pipe, 2652 .mpo_relabel_socket = mac_biba_relabel_socket, 2653 .mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf, 2654 .mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket, 2655 .mpo_create_bpfdesc = mac_biba_create_bpfdesc, 2656 .mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq, 2657 .mpo_create_fragment = mac_biba_create_fragment, 2658 .mpo_create_ifnet = mac_biba_create_ifnet, 2659 .mpo_create_ipq = mac_biba_create_ipq, 2660 .mpo_create_mbuf_from_mbuf = mac_biba_create_mbuf_from_mbuf, 2661 .mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer, 2662 .mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc, 2663 .mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet, 2664 .mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap, 2665 .mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer, 2666 .mpo_fragment_match = mac_biba_fragment_match, 2667 .mpo_relabel_ifnet = mac_biba_relabel_ifnet, 2668 .mpo_update_ipq = mac_biba_update_ipq, 2669 .mpo_create_cred = mac_biba_create_cred, 2670 .mpo_create_proc0 = mac_biba_create_proc0, 2671 .mpo_create_proc1 = mac_biba_create_proc1, 2672 .mpo_relabel_cred = mac_biba_relabel_cred, 2673 .mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive, 2674 .mpo_check_cred_relabel = mac_biba_check_cred_relabel, 2675 .mpo_check_cred_visible = mac_biba_check_cred_visible, 2676 .mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel, 2677 .mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit, 2678 .mpo_check_kld_load = mac_biba_check_kld_load, 2679 .mpo_check_kld_unload = mac_biba_check_kld_unload, 2680 .mpo_check_mount_stat = mac_biba_check_mount_stat, 2681 .mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl, 2682 .mpo_check_pipe_poll = mac_biba_check_pipe_poll, 2683 .mpo_check_pipe_read = mac_biba_check_pipe_read, 2684 .mpo_check_pipe_relabel = mac_biba_check_pipe_relabel, 2685 .mpo_check_pipe_stat = mac_biba_check_pipe_stat, 2686 .mpo_check_pipe_write = mac_biba_check_pipe_write, 2687 .mpo_check_proc_debug = mac_biba_check_proc_debug, 2688 .mpo_check_proc_sched = mac_biba_check_proc_sched, 2689 .mpo_check_proc_signal = mac_biba_check_proc_signal, 2690 .mpo_check_socket_deliver = mac_biba_check_socket_deliver, 2691 .mpo_check_socket_relabel = mac_biba_check_socket_relabel, 2692 .mpo_check_socket_visible = mac_biba_check_socket_visible, 2693 .mpo_check_sysarch_ioperm = mac_biba_check_sysarch_ioperm, 2694 .mpo_check_system_acct = mac_biba_check_system_acct, 2695 .mpo_check_system_settime = mac_biba_check_system_settime, 2696 .mpo_check_system_swapon = mac_biba_check_system_swapon, 2697 .mpo_check_system_swapoff = mac_biba_check_system_swapoff, 2698 .mpo_check_system_sysctl = mac_biba_check_system_sysctl, 2699 .mpo_check_vnode_access = mac_biba_check_vnode_open, 2700 .mpo_check_vnode_chdir = mac_biba_check_vnode_chdir, 2701 .mpo_check_vnode_chroot = mac_biba_check_vnode_chroot, 2702 .mpo_check_vnode_create = mac_biba_check_vnode_create, 2703 .mpo_check_vnode_delete = mac_biba_check_vnode_delete, 2704 .mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl, 2705 .mpo_check_vnode_exec = mac_biba_check_vnode_exec, 2706 .mpo_check_vnode_getacl = mac_biba_check_vnode_getacl, 2707 .mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr, 2708 .mpo_check_vnode_link = mac_biba_check_vnode_link, 2709 .mpo_check_vnode_lookup = mac_biba_check_vnode_lookup, 2710 .mpo_check_vnode_mmap = mac_biba_check_vnode_mmap, 2711 .mpo_check_vnode_mprotect = mac_biba_check_vnode_mmap, 2712 .mpo_check_vnode_open = mac_biba_check_vnode_open, 2713 .mpo_check_vnode_poll = mac_biba_check_vnode_poll, 2714 .mpo_check_vnode_read = mac_biba_check_vnode_read, 2715 .mpo_check_vnode_readdir = mac_biba_check_vnode_readdir, 2716 .mpo_check_vnode_readlink = mac_biba_check_vnode_readlink, 2717 .mpo_check_vnode_relabel = mac_biba_check_vnode_relabel, 2718 .mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from, 2719 .mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to, 2720 .mpo_check_vnode_revoke = mac_biba_check_vnode_revoke, 2721 .mpo_check_vnode_setacl = mac_biba_check_vnode_setacl, 2722 .mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr, 2723 .mpo_check_vnode_setflags = mac_biba_check_vnode_setflags, 2724 .mpo_check_vnode_setmode = mac_biba_check_vnode_setmode, 2725 .mpo_check_vnode_setowner = mac_biba_check_vnode_setowner, 2726 .mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes, 2727 .mpo_check_vnode_stat = mac_biba_check_vnode_stat, 2728 .mpo_check_vnode_write = mac_biba_check_vnode_write, 2729}; 2730 2731MAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba", 2732 MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mac_biba_slot);
|