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