diff options
-rw-r--r-- | net/netlabel/netlabel_domainhash.c | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c index d8d424337550..6bb1d42f0fac 100644 --- a/net/netlabel/netlabel_domainhash.c +++ b/net/netlabel/netlabel_domainhash.c | |||
@@ -245,6 +245,71 @@ static void netlbl_domhsh_audit_add(struct netlbl_dom_map *entry, | |||
245 | } | 245 | } |
246 | } | 246 | } |
247 | 247 | ||
248 | /** | ||
249 | * netlbl_domhsh_validate - Validate a new domain mapping entry | ||
250 | * @entry: the entry to validate | ||
251 | * | ||
252 | * This function validates the new domain mapping entry to ensure that it is | ||
253 | * a valid entry. Returns zero on success, negative values on failure. | ||
254 | * | ||
255 | */ | ||
256 | static int netlbl_domhsh_validate(const struct netlbl_dom_map *entry) | ||
257 | { | ||
258 | struct netlbl_af4list *iter4; | ||
259 | struct netlbl_domaddr4_map *map4; | ||
260 | #if IS_ENABLED(CONFIG_IPV6) | ||
261 | struct netlbl_af6list *iter6; | ||
262 | struct netlbl_domaddr6_map *map6; | ||
263 | #endif /* IPv6 */ | ||
264 | |||
265 | if (entry == NULL) | ||
266 | return -EINVAL; | ||
267 | |||
268 | switch (entry->type) { | ||
269 | case NETLBL_NLTYPE_UNLABELED: | ||
270 | if (entry->type_def.cipsov4 != NULL || | ||
271 | entry->type_def.addrsel != NULL) | ||
272 | return -EINVAL; | ||
273 | break; | ||
274 | case NETLBL_NLTYPE_CIPSOV4: | ||
275 | if (entry->type_def.cipsov4 == NULL) | ||
276 | return -EINVAL; | ||
277 | break; | ||
278 | case NETLBL_NLTYPE_ADDRSELECT: | ||
279 | netlbl_af4list_foreach(iter4, &entry->type_def.addrsel->list4) { | ||
280 | map4 = netlbl_domhsh_addr4_entry(iter4); | ||
281 | switch (map4->type) { | ||
282 | case NETLBL_NLTYPE_UNLABELED: | ||
283 | if (map4->type_def.cipsov4 != NULL) | ||
284 | return -EINVAL; | ||
285 | break; | ||
286 | case NETLBL_NLTYPE_CIPSOV4: | ||
287 | if (map4->type_def.cipsov4 == NULL) | ||
288 | return -EINVAL; | ||
289 | break; | ||
290 | default: | ||
291 | return -EINVAL; | ||
292 | } | ||
293 | } | ||
294 | #if IS_ENABLED(CONFIG_IPV6) | ||
295 | netlbl_af6list_foreach(iter6, &entry->type_def.addrsel->list6) { | ||
296 | map6 = netlbl_domhsh_addr6_entry(iter6); | ||
297 | switch (map6->type) { | ||
298 | case NETLBL_NLTYPE_UNLABELED: | ||
299 | break; | ||
300 | default: | ||
301 | return -EINVAL; | ||
302 | } | ||
303 | } | ||
304 | #endif /* IPv6 */ | ||
305 | break; | ||
306 | default: | ||
307 | return -EINVAL; | ||
308 | } | ||
309 | |||
310 | return 0; | ||
311 | } | ||
312 | |||
248 | /* | 313 | /* |
249 | * Domain Hash Table Functions | 314 | * Domain Hash Table Functions |
250 | */ | 315 | */ |
@@ -311,6 +376,10 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry, | |||
311 | struct netlbl_af6list *tmp6; | 376 | struct netlbl_af6list *tmp6; |
312 | #endif /* IPv6 */ | 377 | #endif /* IPv6 */ |
313 | 378 | ||
379 | ret_val = netlbl_domhsh_validate(entry); | ||
380 | if (ret_val != 0) | ||
381 | return ret_val; | ||
382 | |||
314 | /* XXX - we can remove this RCU read lock as the spinlock protects the | 383 | /* XXX - we can remove this RCU read lock as the spinlock protects the |
315 | * entire function, but before we do we need to fixup the | 384 | * entire function, but before we do we need to fixup the |
316 | * netlbl_af[4,6]list RCU functions to do "the right thing" with | 385 | * netlbl_af[4,6]list RCU functions to do "the right thing" with |