xref: /aosp_15_r20/external/selinux/libsemanage/src/ibpkeys_local.c (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1 /* Copyright (C) 2017 Mellanox Technologies Inc. */
2 
3 struct semanage_ibpkey;
4 struct semanage_ibpkey_key;
5 typedef struct semanage_ibpkey_key record_key_t;
6 typedef struct semanage_ibpkey record_t;
7 #define DBASE_RECORD_DEFINED
8 
9 #include <stdlib.h>
10 #include <string.h>
11 #include <netinet/in.h>
12 #include "ibpkey_internal.h"
13 #include "debug.h"
14 #include "handle.h"
15 #include "database.h"
16 
semanage_ibpkey_modify_local(semanage_handle_t * handle,const semanage_ibpkey_key_t * key,const semanage_ibpkey_t * data)17 int semanage_ibpkey_modify_local(semanage_handle_t *handle,
18 				 const semanage_ibpkey_key_t *key,
19 				 const semanage_ibpkey_t *data)
20 {
21 	dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle);
22 
23 	return dbase_modify(handle, dconfig, key, data);
24 }
25 
semanage_ibpkey_del_local(semanage_handle_t * handle,const semanage_ibpkey_key_t * key)26 int semanage_ibpkey_del_local(semanage_handle_t *handle,
27 			      const semanage_ibpkey_key_t *key)
28 {
29 	dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle);
30 
31 	return dbase_del(handle, dconfig, key);
32 }
33 
semanage_ibpkey_query_local(semanage_handle_t * handle,const semanage_ibpkey_key_t * key,semanage_ibpkey_t ** response)34 int semanage_ibpkey_query_local(semanage_handle_t *handle,
35 				const semanage_ibpkey_key_t *key,
36 				semanage_ibpkey_t **response)
37 {
38 	dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle);
39 
40 	return dbase_query(handle, dconfig, key, response);
41 }
42 
semanage_ibpkey_exists_local(semanage_handle_t * handle,const semanage_ibpkey_key_t * key,int * response)43 int semanage_ibpkey_exists_local(semanage_handle_t *handle,
44 				 const semanage_ibpkey_key_t *key,
45 				 int *response)
46 {
47 	dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle);
48 
49 	return dbase_exists(handle, dconfig, key, response);
50 }
51 
semanage_ibpkey_count_local(semanage_handle_t * handle,unsigned int * response)52 int semanage_ibpkey_count_local(semanage_handle_t *handle,
53 				unsigned int *response)
54 {
55 	dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle);
56 
57 	return dbase_count(handle, dconfig, response);
58 }
59 
semanage_ibpkey_iterate_local(semanage_handle_t * handle,int (* handler)(const semanage_ibpkey_t * record,void * varg),void * handler_arg)60 int semanage_ibpkey_iterate_local(semanage_handle_t *handle,
61 				  int (*handler)(const semanage_ibpkey_t *record,
62 						 void *varg), void *handler_arg)
63 {
64 	dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle);
65 
66 	return dbase_iterate(handle, dconfig, handler, handler_arg);
67 }
68 
semanage_ibpkey_list_local(semanage_handle_t * handle,semanage_ibpkey_t *** records,unsigned int * count)69 int semanage_ibpkey_list_local(semanage_handle_t *handle,
70 			       semanage_ibpkey_t ***records, unsigned int *count)
71 {
72 	dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle);
73 
74 	return dbase_list(handle, dconfig, records, count);
75 }
76 
77 
semanage_ibpkey_validate_local(semanage_handle_t * handle)78 int semanage_ibpkey_validate_local(semanage_handle_t *handle)
79 {
80 	semanage_ibpkey_t **ibpkeys = NULL;
81 	unsigned int nibpkeys = 0;
82 	unsigned int i = 0, j = 0;
83 	uint64_t subnet_prefix;
84 	uint64_t subnet_prefix2;
85 	char *subnet_prefix_str;
86 	char *subnet_prefix_str2;
87 	int low, high;
88 	int low2, high2;
89 
90 	/* List and sort the ibpkeys */
91 	if (semanage_ibpkey_list_local(handle, &ibpkeys, &nibpkeys) < 0)
92 		goto err;
93 
94 	qsort(ibpkeys, nibpkeys, sizeof(semanage_ibpkey_t *),
95 	      (int (*)(const void *, const void *))
96 	      &semanage_ibpkey_compare2_qsort);
97 
98 	/* Test each ibpkey for overlap */
99 	while (i < nibpkeys) {
100 		if (STATUS_SUCCESS != semanage_ibpkey_get_subnet_prefix(handle,
101 									ibpkeys[i],
102 									&subnet_prefix_str)) {
103 			ERR(handle, "Couldn't get subnet prefix string");
104 			goto err;
105 		}
106 
107 		subnet_prefix = semanage_ibpkey_get_subnet_prefix_bytes(ibpkeys[i]);
108 		low = semanage_ibpkey_get_low(ibpkeys[i]);
109 		high = semanage_ibpkey_get_high(ibpkeys[i]);
110 
111 		/* Find the first ibpkey with matching
112 		 * subnet_prefix to compare against
113 		 */
114 		do {
115 			if (j == nibpkeys - 1)
116 				goto next;
117 			j++;
118 
119 			if (STATUS_SUCCESS !=
120 				semanage_ibpkey_get_subnet_prefix(handle,
121 								  ibpkeys[j],
122 								  &subnet_prefix_str2)) {
123 				ERR(handle, "Couldn't get subnet prefix string");
124 				goto err;
125 			}
126 			subnet_prefix2 = semanage_ibpkey_get_subnet_prefix_bytes(ibpkeys[j]);
127 			low2 = semanage_ibpkey_get_low(ibpkeys[j]);
128 			high2 = semanage_ibpkey_get_high(ibpkeys[j]);
129 		} while (subnet_prefix != subnet_prefix2);
130 
131 		/* Overlap detected */
132 		if (low2 <= high) {
133 			ERR(handle, "ibpkey overlap between ranges "
134 			    "(%s) %u - %u <--> (%s) %u - %u.",
135 			    subnet_prefix_str, low, high,
136 			    subnet_prefix_str2, low2, high2);
137 			goto invalid;
138 		}
139 
140 		/* If closest ibpkey of matching subnet prefix doesn't overlap
141 		 * with test ibpkey, neither do the rest of them, because that's
142 		 * how the sort function works on ibpkeys - lower bound
143 		 * ibpkeys come first
144 		 */
145 next:
146 		i++;
147 		j = i;
148 	}
149 
150 	for (i = 0; i < nibpkeys; i++)
151 		semanage_ibpkey_free(ibpkeys[i]);
152 	free(ibpkeys);
153 	return STATUS_SUCCESS;
154 
155 err:
156 	ERR(handle, "could not complete ibpkeys validity check");
157 
158 invalid:
159 	for (i = 0; i < nibpkeys; i++)
160 		semanage_ibpkey_free(ibpkeys[i]);
161 	free(ibpkeys);
162 	return STATUS_ERR;
163 }
164