psss / rpms / libsepol

Forked from rpms/libsepol 5 years ago
Clone
Blob Blame History Raw
diff --git libsepol-2.5/Android.mk libsepol-2.5/Android.mk
index a43b343..5d2c96b 100644
--- libsepol-2.5/Android.mk
+++ libsepol-2.5/Android.mk
@@ -64,6 +64,7 @@ cil_src_files := \
 	cil/src/cil_verify.c
 
 common_cflags := \
+	-D_GNU_SOURCE \
 	-Wall -W -Wundef \
 	-Wshadow -Wmissing-noreturn \
 	-Wmissing-format-attribute
diff --git libsepol-2.5/ChangeLog libsepol-2.5/ChangeLog
index ace3d54..9348d70 100644
--- libsepol-2.5/ChangeLog
+++ libsepol-2.5/ChangeLog
@@ -1,3 +1,10 @@
+	* Build policy on systems not supporting DCCP protocol, from Richard Haines.
+	* Fix extended permissions neverallow checking, from Jeff Vander Stoep.
+	* Fix CIL neverallow and bounds checking, from James Carter
+	* Android.mk: Add -D_GNU_SOURCE to common_cflags, from Nick Kralevich.
+	* Add support for portcon dccp protocol, from Richard Haines
+	* Fix bug in CIL when resetting classes, from Steve Lawrence
+
 2.5 2016-02-23
 	* Fix unused variable annotations, from Nicolas Iooss.
 	* Fix uninitialized variable in CIL, from Nicolas Iooss.
diff --git libsepol-2.5/cil/src/cil.c libsepol-2.5/cil/src/cil.c
index afdc240..de7033a 100644
--- libsepol-2.5/cil/src/cil.c
+++ libsepol-2.5/cil/src/cil.c
@@ -108,6 +108,7 @@ static void cil_init_keys(void)
 	CIL_KEY_STAR = cil_strpool_add("*");
 	CIL_KEY_UDP = cil_strpool_add("udp");
 	CIL_KEY_TCP = cil_strpool_add("tcp");
+	CIL_KEY_DCCP = cil_strpool_add("dccp");
 	CIL_KEY_AUDITALLOW = cil_strpool_add("auditallow");
 	CIL_KEY_TUNABLEIF = cil_strpool_add("tunableif");
 	CIL_KEY_ALLOW = cil_strpool_add("allow");
diff --git libsepol-2.5/cil/src/cil_binary.c libsepol-2.5/cil/src/cil_binary.c
index f749e53..b8437c9 100644
--- libsepol-2.5/cil/src/cil_binary.c
+++ libsepol-2.5/cil/src/cil_binary.c
@@ -31,6 +31,9 @@
 #include <stdio.h>
 #include <assert.h>
 #include <netinet/in.h>
+#ifndef IPPROTO_DCCP
+#define IPPROTO_DCCP 33
+#endif
 
 #include <sepol/policydb/policydb.h>
 #include <sepol/policydb/polcaps.h>
@@ -3035,6 +3038,9 @@ int cil_portcon_to_policydb(policydb_t *pdb, struct cil_sort *portcons)
 		case CIL_PROTOCOL_TCP:
 			new_ocon->u.port.protocol = IPPROTO_TCP;
 			break;
+		case CIL_PROTOCOL_DCCP:
+			new_ocon->u.port.protocol = IPPROTO_DCCP;
+			break;
 		default:
 			/* should not get here */
 			rc = SEPOL_ERR;
@@ -4380,10 +4386,9 @@ exit:
 	return rc;
 }
 
-static int cil_check_neverallow(const struct cil_db *db, policydb_t *pdb, struct cil_tree_node *node)
+static int cil_check_neverallow(const struct cil_db *db, policydb_t *pdb, struct cil_tree_node *node, int *violation)
 {
-	int rc = SEPOL_ERR;
-	int ret = CIL_FALSE;
+	int rc = SEPOL_OK;
 	struct cil_avrule *cil_rule = node->data;
 	struct cil_symtab_datum *tgt = cil_rule->tgt;
 	uint32_t kind;
@@ -4422,11 +4427,11 @@ static int cil_check_neverallow(const struct cil_db *db, policydb_t *pdb, struct
 
 		rc = check_assertion(pdb, rule);
 		if (rc == CIL_TRUE) {
+			*violation = CIL_TRUE;
 			rc = __cil_print_neverallow_failure(db, node);
 			if (rc != SEPOL_OK) {
 				goto exit;
 			}
-			ret = CIL_TRUE;
 		}
 
 	} else {
@@ -4444,12 +4449,11 @@ static int cil_check_neverallow(const struct cil_db *db, policydb_t *pdb, struct
 			rule->xperms = item->data;
 			rc = check_assertion(pdb, rule);
 			if (rc == CIL_TRUE) {
+				*violation = CIL_TRUE;
 				rc = __cil_print_neverallow_failure(db, node);
 				if (rc != SEPOL_OK) {
 					goto exit;
 				}
-				ret = CIL_TRUE;
-				goto exit;
 			}
 		}
 	}
@@ -4466,34 +4470,23 @@ exit:
 	rule->xperms = NULL;
 	__cil_destroy_sepol_avrules(rule);
 
-	if (rc) {
-		return rc;
-	} else {
-		return ret;
-	}
+	return rc;
 }
 
-static int cil_check_neverallows(const struct cil_db *db, policydb_t *pdb, struct cil_list *neverallows)
+static int cil_check_neverallows(const struct cil_db *db, policydb_t *pdb, struct cil_list *neverallows, int *violation)
 {
 	int rc = SEPOL_OK;
-	int ret = CIL_FALSE;
 	struct cil_list_item *item;
 
 	cil_list_for_each(item, neverallows) {
-		rc = cil_check_neverallow(db, pdb, item->data);
-		if (rc < 0) {
+		rc = cil_check_neverallow(db, pdb, item->data, violation);
+		if (rc != SEPOL_OK) {
 			goto exit;
-		} else if (rc > 0) {
-			ret = CIL_TRUE;
 		}
 	}
 
 exit:
-	if (rc || ret) {
-		return SEPOL_ERR;
-	} else {
-		return SEPOL_OK;
-	}
+	return rc;
 }
 
 static struct cil_list *cil_classperms_from_sepol(policydb_t *pdb, uint16_t class, uint32_t data, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[])
@@ -4548,7 +4541,7 @@ exit:
 	return rc;
 }
 
-static int cil_check_type_bounds(const struct cil_db *db, policydb_t *pdb, void *type_value_to_cil, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[])
+static int cil_check_type_bounds(const struct cil_db *db, policydb_t *pdb, void *type_value_to_cil, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[], int *violation)
 {
 	int rc = SEPOL_OK;
 	int i;
@@ -4574,6 +4567,9 @@ static int cil_check_type_bounds(const struct cil_db *db, policydb_t *pdb, void
 		if (bad) {
 			avtab_ptr_t cur;
 			struct cil_avrule target;
+			struct cil_tree_node *n1 = NULL;
+
+			*violation = CIL_TRUE;
 
                         target.is_extended = 0;
 			target.rule_kind = CIL_AVRULE_ALLOWED;
@@ -4585,7 +4581,6 @@ static int cil_check_type_bounds(const struct cil_db *db, policydb_t *pdb, void
 			for (cur = bad; cur; cur = cur->next) {
 				struct cil_list_item *i2;
 				struct cil_list *matching;
-				struct cil_tree_node *n;
 
 				rc = cil_avrule_from_sepol(pdb, cur, &target, type_value_to_cil, class_value_to_cil, perm_value_to_cil);
 				if (rc != SEPOL_OK) {
@@ -4594,7 +4589,7 @@ static int cil_check_type_bounds(const struct cil_db *db, policydb_t *pdb, void
 				}
 				__cil_print_rule("  ", "allow", &target);
 				cil_list_init(&matching, CIL_NODE);
-				rc = cil_find_matching_avrule_in_ast(db->ast->root, CIL_AVRULE, &target, matching, CIL_FALSE);
+				rc = cil_find_matching_avrule_in_ast(db->ast->root, CIL_AVRULE, &target, matching, CIL_TRUE);
 				if (rc) {
 					cil_log(CIL_ERR, "Error occurred while checking type bounds\n");
 					cil_list_destroy(&matching, CIL_FALSE);
@@ -4602,14 +4597,17 @@ static int cil_check_type_bounds(const struct cil_db *db, policydb_t *pdb, void
 					bounds_destroy_bad(bad);
 					goto exit;
 				}
-
 				cil_list_for_each(i2, matching) {
-					__cil_print_parents("    ", (struct cil_tree_node *)i2->data);
+					struct cil_tree_node *n2 = i2->data;
+					struct cil_avrule *r2 = n2->data;
+					if (n1 == n2) {
+						cil_log(CIL_ERR, "    <See previous>\n");
+					} else {
+						n1 = n2;
+						__cil_print_parents("    ", n2);
+						__cil_print_rule("      ", "allow", r2);
+					}
 				}
-				i2 = matching->tail;
-				n = i2->data;
-				__cil_print_rule("      ", "allow", n->data);
-				cil_log(CIL_ERR,"\n");
 				cil_list_destroy(&matching, CIL_FALSE);
 				cil_list_destroy(&target.perms.classperms, CIL_TRUE);
 			}
@@ -4753,20 +4751,32 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p
 	__cil_set_conditional_state_and_flags(pdb);
 
 	if (db->disable_neverallow != CIL_TRUE) {
+		int violation = CIL_FALSE;
 		cil_log(CIL_INFO, "Checking Neverallows\n");
-		rc = cil_check_neverallows(db, pdb, neverallows);
+		rc = cil_check_neverallows(db, pdb, neverallows, &violation);
 		if (rc != SEPOL_OK) goto exit;
 
 		cil_log(CIL_INFO, "Checking User Bounds\n");
-		bounds_check_users(NULL, pdb);
+		rc = bounds_check_users(NULL, pdb);
+		if (rc) {
+			violation = CIL_TRUE;
+		}
 
 		cil_log(CIL_INFO, "Checking Role Bounds\n");
-		bounds_check_roles(NULL, pdb);
+		rc = bounds_check_roles(NULL, pdb);
+		if (rc) {
+			violation = CIL_TRUE;
+		}
 
 		cil_log(CIL_INFO, "Checking Type Bounds\n");
-		rc = cil_check_type_bounds(db, pdb, type_value_to_cil, class_value_to_cil, perm_value_to_cil);
+		rc = cil_check_type_bounds(db, pdb, type_value_to_cil, class_value_to_cil, perm_value_to_cil, &violation);
 		if (rc != SEPOL_OK) goto exit;
 
+		if (violation == CIL_TRUE) {
+			rc = SEPOL_ERR;
+			goto exit;
+		}
+
 	}
 
 	rc = SEPOL_OK;
diff --git libsepol-2.5/cil/src/cil_build_ast.c libsepol-2.5/cil/src/cil_build_ast.c
index 1135e06..90fee8e 100644
--- libsepol-2.5/cil/src/cil_build_ast.c
+++ libsepol-2.5/cil/src/cil_build_ast.c
@@ -4261,6 +4261,8 @@ int cil_gen_portcon(struct cil_db *db, struct cil_tree_node *parse_current, stru
 		portcon->proto = CIL_PROTOCOL_UDP;
 	} else if (proto == CIL_KEY_TCP) {
 		portcon->proto = CIL_PROTOCOL_TCP;
+	} else if (proto == CIL_KEY_DCCP) {
+		portcon->proto = CIL_PROTOCOL_DCCP;
 	} else {
 		cil_log(CIL_ERR, "Invalid protocol\n");
 		rc = SEPOL_ERR;
diff --git libsepol-2.5/cil/src/cil_find.c libsepol-2.5/cil/src/cil_find.c
index 75de886..8e0688c 100644
--- libsepol-2.5/cil/src/cil_find.c
+++ libsepol-2.5/cil/src/cil_find.c
@@ -69,7 +69,11 @@ static int cil_type_match_any(struct cil_symtab_datum *d1, struct cil_symtab_dat
 		/* Both are attributes */
 		struct cil_typeattribute *a1 = (struct cil_typeattribute *)d1;
 		struct cil_typeattribute *a2 = (struct cil_typeattribute *)d2;
-		return ebitmap_match_any(a1->types, a2->types);
+		if (d1 == d2) {
+			return CIL_TRUE;
+		} else if (ebitmap_match_any(a1->types, a2->types)) {
+			return CIL_TRUE;
+		}
 	}
 	return CIL_FALSE;
 }
diff --git libsepol-2.5/cil/src/cil_internal.h libsepol-2.5/cil/src/cil_internal.h
index a0a5480..a75ddf8 100644
--- libsepol-2.5/cil/src/cil_internal.h
+++ libsepol-2.5/cil/src/cil_internal.h
@@ -101,6 +101,7 @@ char *CIL_KEY_OBJECT_R;
 char *CIL_KEY_STAR;
 char *CIL_KEY_TCP;
 char *CIL_KEY_UDP;
+char *CIL_KEY_DCCP;
 char *CIL_KEY_AUDITALLOW;
 char *CIL_KEY_TUNABLEIF;
 char *CIL_KEY_ALLOW;
@@ -713,7 +714,8 @@ struct cil_filecon {
 
 enum cil_protocol {
 	CIL_PROTOCOL_UDP = 1,
-	CIL_PROTOCOL_TCP	
+	CIL_PROTOCOL_TCP,
+	CIL_PROTOCOL_DCCP
 };
 
 struct cil_portcon {
diff --git libsepol-2.5/cil/src/cil_policy.c libsepol-2.5/cil/src/cil_policy.c
index 2c9b158..382129b 100644
--- libsepol-2.5/cil/src/cil_policy.c
+++ libsepol-2.5/cil/src/cil_policy.c
@@ -123,6 +123,8 @@ int cil_portcon_to_policy(FILE **file_arr, struct cil_sort *sort)
 			fprintf(file_arr[NETIFCONS], "udp ");
 		} else if (portcon->proto == CIL_PROTOCOL_TCP) {
 			fprintf(file_arr[NETIFCONS], "tcp ");
+		} else if (portcon->proto == CIL_PROTOCOL_DCCP) {
+			fprintf(file_arr[NETIFCONS], "dccp ");
 		}
 		fprintf(file_arr[NETIFCONS], "%d ", portcon->port_low);
 		fprintf(file_arr[NETIFCONS], "%d ", portcon->port_high);
diff --git libsepol-2.5/cil/src/cil_reset_ast.c libsepol-2.5/cil/src/cil_reset_ast.c
index 06146ca..de00679 100644
--- libsepol-2.5/cil/src/cil_reset_ast.c
+++ libsepol-2.5/cil/src/cil_reset_ast.c
@@ -23,7 +23,7 @@ static void cil_reset_class(struct cil_class *class)
 {
 	if (class->common != NULL) {
 		struct cil_class *common = class->common;
-		cil_symtab_map(&common->perms, __class_reset_perm_values, &common->num_perms);
+		cil_symtab_map(&class->perms, __class_reset_perm_values, &common->num_perms);
 		/* during a re-resolve, we need to reset the common, so a classcommon
 		 * statement isn't seen as a duplicate */
 		class->num_perms -= common->num_perms;
diff --git libsepol-2.5/cil/src/cil_tree.c libsepol-2.5/cil/src/cil_tree.c
index 1c23efc..563b817 100644
--- libsepol-2.5/cil/src/cil_tree.c
+++ libsepol-2.5/cil/src/cil_tree.c
@@ -1319,6 +1319,8 @@ void cil_tree_print_node(struct cil_tree_node *node)
 				cil_log(CIL_INFO, " udp");
 			} else if (portcon->proto == CIL_PROTOCOL_TCP) {
 				cil_log(CIL_INFO, " tcp");
+			} else if (portcon->proto == CIL_PROTOCOL_DCCP) {
+				cil_log(CIL_INFO, " dccp");
 			}
 			cil_log(CIL_INFO, " (%d %d)", portcon->port_low, portcon->port_high);
 
diff --git libsepol-2.5/include/sepol/port_record.h libsepol-2.5/include/sepol/port_record.h
index 697cea4..c07d1fa 100644
--- libsepol-2.5/include/sepol/port_record.h
+++ libsepol-2.5/include/sepol/port_record.h
@@ -14,6 +14,7 @@ typedef struct sepol_port_key sepol_port_key_t;
 
 #define SEPOL_PROTO_UDP 0
 #define SEPOL_PROTO_TCP 1
+#define SEPOL_PROTO_DCCP 2
 
 /* Key */
 extern int sepol_port_compare(const sepol_port_t * port,
diff --git libsepol-2.5/src/assertion.c libsepol-2.5/src/assertion.c
index fbf397f..f4429ad 100644
--- libsepol-2.5/src/assertion.c
+++ libsepol-2.5/src/assertion.c
@@ -147,36 +147,49 @@ static int report_assertion_extended_permissions(sepol_handle_t *handle,
 	avtab_key_t tmp_key;
 	avtab_extended_perms_t *xperms;
 	avtab_extended_perms_t error;
+	ebitmap_t *sattr = &p->type_attr_map[k->source_type - 1];
+	ebitmap_t *tattr = &p->type_attr_map[k->target_type - 1];
+	ebitmap_node_t *snode, *tnode;
+	unsigned int i, j;
 	int rc = 1;
 	int ret = 0;
 
 	memcpy(&tmp_key, k, sizeof(avtab_key_t));
 	tmp_key.specified = AVTAB_XPERMS_ALLOWED;
 
-	for (node = avtab_search_node(avtab, &tmp_key);
-	     node;
-	     node = avtab_search_node_next(node, tmp_key.specified)) {
-		xperms = node->datum.xperms;
-		if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
-				&& (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER))
+	ebitmap_for_each_bit(sattr, snode, i) {
+		if (!ebitmap_node_get_bit(snode, i))
 			continue;
+		ebitmap_for_each_bit(tattr, tnode, j) {
+			if (!ebitmap_node_get_bit(tnode, j))
+				continue;
+			tmp_key.source_type = i + 1;
+			tmp_key.target_type = j + 1;
+			for (node = avtab_search_node(avtab, &tmp_key);
+			     node;
+			     node = avtab_search_node_next(node, tmp_key.specified)) {
+				xperms = node->datum.xperms;
+				if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
+						&& (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER))
+					continue;
 
-		rc = check_extended_permissions(avrule->xperms, xperms);
-		/* failure on the extended permission check_extended_permissionss */
-		if (rc) {
-			extended_permissions_violated(&error, avrule->xperms, xperms);
-			ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of policy.conf) violated by\n"
-					"allowxperm %s %s:%s %s;",
-					avrule->source_line, avrule->source_filename, avrule->line,
-					p->p_type_val_to_name[stype],
-					p->p_type_val_to_name[ttype],
-					p->p_class_val_to_name[curperm->tclass - 1],
-					sepol_extended_perms_to_string(&error));
-
-			rc = 0;
-			ret++;
+				rc = check_extended_permissions(avrule->xperms, xperms);
+				/* failure on the extended permission check_extended_permissionss */
+				if (rc) {
+					extended_permissions_violated(&error, avrule->xperms, xperms);
+					ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of policy.conf) violated by\n"
+							"allowxperm %s %s:%s %s;",
+							avrule->source_line, avrule->source_filename, avrule->line,
+							p->p_type_val_to_name[stype],
+							p->p_type_val_to_name[ttype],
+							p->p_class_val_to_name[curperm->tclass - 1],
+							sepol_extended_perms_to_string(&error));
+
+					rc = 0;
+					ret++;
+				}
+			}
 		}
-
 	}
 
 	/* failure on the regular permissions */
@@ -319,28 +332,42 @@ oom:
  *    granted
  */
 static int check_assertion_extended_permissions(avrule_t *avrule, avtab_t *avtab,
-						avtab_key_t *k)
+						avtab_key_t *k, policydb_t *p)
 {
 	avtab_ptr_t node;
 	avtab_key_t tmp_key;
 	avtab_extended_perms_t *xperms;
 	av_extended_perms_t *neverallow_xperms = avrule->xperms;
+	ebitmap_t *sattr = &p->type_attr_map[k->source_type - 1];
+	ebitmap_t *tattr = &p->type_attr_map[k->target_type - 1];
+	ebitmap_node_t *snode, *tnode;
+	unsigned int i, j;
 	int rc = 1;
 
 	memcpy(&tmp_key, k, sizeof(avtab_key_t));
 	tmp_key.specified = AVTAB_XPERMS_ALLOWED;
 
-	for (node = avtab_search_node(avtab, &tmp_key);
-	     node;
-	     node = avtab_search_node_next(node, tmp_key.specified)) {
-		xperms = node->datum.xperms;
-		if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
-				&& (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER))
+	ebitmap_for_each_bit(sattr, snode, i) {
+		if (!ebitmap_node_get_bit(snode, i))
 			continue;
-
-		rc = check_extended_permissions(neverallow_xperms, xperms);
-		if (rc)
-			break;
+		ebitmap_for_each_bit(tattr, tnode, j) {
+			if (!ebitmap_node_get_bit(tnode, j))
+				continue;
+			tmp_key.source_type = i + 1;
+			tmp_key.target_type = j + 1;
+			for (node = avtab_search_node(avtab, &tmp_key);
+			     node;
+			     node = avtab_search_node_next(node, tmp_key.specified)) {
+				xperms = node->datum.xperms;
+
+				if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
+						&& (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER))
+					continue;
+				rc = check_extended_permissions(neverallow_xperms, xperms);
+				if (rc)
+					break;
+			}
+		}
 	}
 
 	return rc;
@@ -386,7 +413,7 @@ static int check_assertion_avtab_match(avtab_key_t *k, avtab_datum_t *d, void *a
 		goto exit;
 
 	if (avrule->specified == AVRULE_XPERMS_NEVERALLOW) {
-		rc = check_assertion_extended_permissions(avrule, avtab, k);
+		rc = check_assertion_extended_permissions(avrule, avtab, k, p);
 		if (rc == 0)
 			goto exit;
 	}
diff --git libsepol-2.5/src/module_to_cil.c libsepol-2.5/src/module_to_cil.c
index 18ec6b9..38f0dc3 100644
--- libsepol-2.5/src/module_to_cil.c
+++ libsepol-2.5/src/module_to_cil.c
@@ -26,6 +26,9 @@
 #include <getopt.h>
 #include <libgen.h>
 #include <netinet/in.h>
+#ifndef IPPROTO_DCCP
+#define IPPROTO_DCCP 33
+#endif
 #include <signal.h>
 #include <stdarg.h>
 #include <stdio.h>
@@ -2537,6 +2540,7 @@ static int ocontext_selinux_port_to_cil(struct policydb *pdb, struct ocontext *p
 		switch (portcon->u.port.protocol) {
 		case IPPROTO_TCP: protocol = "tcp"; break;
 		case IPPROTO_UDP: protocol = "udp"; break;
+		case IPPROTO_DCCP: protocol = "dccp"; break;
 		default:
 			log_err("Unknown portcon protocol: %i", portcon->u.port.protocol);
 			rc = -1;
diff --git libsepol-2.5/src/port_record.c libsepol-2.5/src/port_record.c
index 6a33d93..ed9093b 100644
--- libsepol-2.5/src/port_record.c
+++ libsepol-2.5/src/port_record.c
@@ -184,6 +184,8 @@ const char *sepol_port_get_proto_str(int proto)
 		return "udp";
 	case SEPOL_PROTO_TCP:
 		return "tcp";
+	case SEPOL_PROTO_DCCP:
+		return "dccp";
 	default:
 		return "???";
 	}
diff --git libsepol-2.5/src/ports.c libsepol-2.5/src/ports.c
index 607a629..62ec602 100644
--- libsepol-2.5/src/ports.c
+++ libsepol-2.5/src/ports.c
@@ -1,4 +1,7 @@
 #include <netinet/in.h>
+#ifndef IPPROTO_DCCP
+#define IPPROTO_DCCP 33
+#endif
 #include <stdlib.h>
 
 #include "debug.h"
@@ -16,6 +19,8 @@ static inline int sepol2ipproto(sepol_handle_t * handle, int proto)
 		return IPPROTO_TCP;
 	case SEPOL_PROTO_UDP:
 		return IPPROTO_UDP;
+	case SEPOL_PROTO_DCCP:
+		return IPPROTO_DCCP;
 	default:
 		ERR(handle, "unsupported protocol %u", proto);
 		return STATUS_ERR;
@@ -30,6 +35,8 @@ static inline int ipproto2sepol(sepol_handle_t * handle, int proto)
 		return SEPOL_PROTO_TCP;
 	case IPPROTO_UDP:
 		return SEPOL_PROTO_UDP;
+	case IPPROTO_DCCP:
+		return SEPOL_PROTO_DCCP;
 	default:
 		ERR(handle, "invalid protocol %u " "found in policy", proto);
 		return STATUS_ERR;