diff mbox series

[v2,3/3] libselinux: move functions out of header file

Message ID 20241120115951.42445-3-cgoettsche@seltendoof.de (mailing list archive)
State New
Headers show
Series [v2,1/3] libselinux: make use of calloc(3) | expand

Commit Message

Christian Göttsche Nov. 20, 2024, 11:59 a.m. UTC
From: Christian Göttsche <cgzones@googlemail.com>

When building libselinux from its own directory GCC complains about the
two functions free_spec_node() and sort_spec_node(), which are not tiny
and also recursive.

    In file included from label_file.c:27:
    In function ‘load_mmap’,
       inlined from ‘process_file’ at label_file.c:1106:9:
    label_file.h:816:20: error: inlining failed in call to ‘free_spec_node’: --param max-inline-insns-single limit reached [-Werror=inline]
      816 | static inline void free_spec_node(struct spec_node *node)
          |                    ^~~~~~~~~~~~~~
    label_file.c:899:17: note: called from here
      899 |                 free_spec_node(data->root);
          |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~
    label_file.h:816:20: error: inlining failed in call to ‘free_spec_node’: --param max-inline-insns-single limit reached [-Werror=inline]
      816 | static inline void free_spec_node(struct spec_node *node)
          |                    ^~~~~~~~~~~~~~
    label_file.c:908:17: note: called from here
      908 |                 free_spec_node(root);
          |                 ^~~~~~~~~~~~~~~~~~~~
  In function ‘sort_specs’,
      inlined from ‘init’ at label_file.c:1350:3:
    label_file.h:404:20: error: inlining failed in call to ‘sort_spec_node’: --param max-inline-insns-single limit reached [-Werror=inline]
      404 | static inline void sort_spec_node(struct spec_node *node, struct spec_node *parent)
          |                    ^~~~~~~~~~~~~~
    label_file.h:433:9: note: called from here
      433 |         sort_spec_node(data->root, NULL);
          |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    In function ‘sort_specs’,
        inlined from ‘init’ at label_file.c:1370:3:
    label_file.h:404:20: error: inlining failed in call to ‘sort_spec_node’: --param max-inline-insns-single limit reached [-Werror=inline]
      404 | static inline void sort_spec_node(struct spec_node *node, struct spec_node *parent)
          |                    ^~~~~~~~~~~~~~
    label_file.h:433:9: note: called from here
      433 |         sort_spec_node(data->root, NULL);
          |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Fixes: 92306daf ("libselinux: rework selabel_file(5) database")
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
v2:
  - add patch
---
 libselinux/src/label_file.c | 68 +++++++++++++++++++++++++++++++++++
 libselinux/src/label_file.h | 71 ++-----------------------------------
 2 files changed, 71 insertions(+), 68 deletions(-)
diff mbox series

Patch

diff --git a/libselinux/src/label_file.c b/libselinux/src/label_file.c
index 189a5ed2..40bcb9ee 100644
--- a/libselinux/src/label_file.c
+++ b/libselinux/src/label_file.c
@@ -34,6 +34,74 @@ 
 #endif  /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
 
 
+void free_spec_node(struct spec_node *node)
+{
+	for (uint32_t i = 0; i < node->literal_specs_num; i++) {
+		struct literal_spec *lspec = &node->literal_specs[i];
+
+		free(lspec->lr.ctx_raw);
+		free(lspec->lr.ctx_trans);
+		__pthread_mutex_destroy(&lspec->lr.lock);
+
+		if (lspec->from_mmap)
+			continue;
+
+		free(lspec->literal_match);
+		free(lspec->regex_str);
+	}
+	free(node->literal_specs);
+
+	for (uint32_t i = 0; i < node->regex_specs_num; i++) {
+		struct regex_spec *rspec = &node->regex_specs[i];
+
+		free(rspec->lr.ctx_raw);
+		free(rspec->lr.ctx_trans);
+		__pthread_mutex_destroy(&rspec->lr.lock);
+		regex_data_free(rspec->regex);
+		__pthread_mutex_destroy(&rspec->regex_lock);
+
+		if (rspec->from_mmap)
+			continue;
+
+		free(rspec->regex_str);
+	}
+	free(node->regex_specs);
+
+	for (uint32_t i = 0; i < node->children_num; i++)
+		free_spec_node(&node->children[i]);
+	free(node->children);
+
+	if (!node->from_mmap)
+		free(node->stem);
+}
+
+void sort_spec_node(struct spec_node *node, struct spec_node *parent)
+{
+	/* A node should not be its own parent */
+	assert(node != parent);
+	/* Only root node has NULL stem */
+	assert((!parent && !node->stem) || (parent && node->stem && node->stem[0] != '\0'));
+	/* A non-root node should not be empty */
+	assert(!parent || (node->literal_specs_num || node->regex_specs_num || node->children_num));
+
+
+	node->parent = parent;
+
+	/* Sort for comparison support and binary search lookup */
+
+	if (node->literal_specs_num > 1)
+		qsort(node->literal_specs, node->literal_specs_num, sizeof(struct literal_spec), compare_literal_spec);
+
+	if (node->regex_specs_num > 1)
+		qsort(node->regex_specs, node->regex_specs_num, sizeof(struct regex_spec), compare_regex_spec);
+
+	if (node->children_num > 1)
+		qsort(node->children, node->children_num, sizeof(struct spec_node), compare_spec_node);
+
+	for (uint32_t i = 0; i < node->children_num; i++)
+		sort_spec_node(&node->children[i], node);
+}
+
 /*
  * Warn about duplicate specifications.
  */
diff --git a/libselinux/src/label_file.h b/libselinux/src/label_file.h
index de8190f9..b59db003 100644
--- a/libselinux/src/label_file.h
+++ b/libselinux/src/label_file.h
@@ -164,6 +164,9 @@  struct saved_data {
 	struct selabel_sub *subs;
 };
 
+void free_spec_node(struct spec_node *node);
+void sort_spec_node(struct spec_node *node, struct spec_node *parent);
+
 static inline mode_t string_to_file_kind(const char *mode)
 {
 	if (mode[0] != '-' || mode[1] == '\0' || mode[2] != '\0')
@@ -401,33 +404,6 @@  static inline int compare_spec_node(const void *p1, const void *p2)
 	return rc;
 }
 
-static inline void sort_spec_node(struct spec_node *node, struct spec_node *parent)
-{
-	/* A node should not be its own parent */
-	assert(node != parent);
-	/* Only root node has NULL stem */
-	assert((!parent && !node->stem) || (parent && node->stem && node->stem[0] != '\0'));
-	/* A non-root node should not be empty */
-	assert(!parent || (node->literal_specs_num || node->regex_specs_num || node->children_num));
-
-
-	node->parent = parent;
-
-	/* Sort for comparison support and binary search lookup */
-
-	if (node->literal_specs_num > 1)
-		qsort(node->literal_specs, node->literal_specs_num, sizeof(struct literal_spec), compare_literal_spec);
-
-	if (node->regex_specs_num > 1)
-		qsort(node->regex_specs, node->regex_specs_num, sizeof(struct regex_spec), compare_regex_spec);
-
-	if (node->children_num > 1)
-		qsort(node->children, node->children_num, sizeof(struct spec_node), compare_spec_node);
-
-	for (uint32_t i = 0; i < node->children_num; i++)
-		sort_spec_node(&node->children[i], node);
-}
-
 static inline void sort_specs(struct saved_data *data)
 {
 	sort_spec_node(data->root, NULL);
@@ -813,47 +789,6 @@  static int insert_spec(const struct selabel_handle *rec, struct saved_data *data
 
 #undef GROW_ARRAY
 
-static inline void free_spec_node(struct spec_node *node)
-{
-	for (uint32_t i = 0; i < node->literal_specs_num; i++) {
-		struct literal_spec *lspec = &node->literal_specs[i];
-
-		free(lspec->lr.ctx_raw);
-		free(lspec->lr.ctx_trans);
-		__pthread_mutex_destroy(&lspec->lr.lock);
-
-		if (lspec->from_mmap)
-			continue;
-
-		free(lspec->literal_match);
-		free(lspec->regex_str);
-	}
-	free(node->literal_specs);
-
-	for (uint32_t i = 0; i < node->regex_specs_num; i++) {
-		struct regex_spec *rspec = &node->regex_specs[i];
-
-		free(rspec->lr.ctx_raw);
-		free(rspec->lr.ctx_trans);
-		__pthread_mutex_destroy(&rspec->lr.lock);
-		regex_data_free(rspec->regex);
-		__pthread_mutex_destroy(&rspec->regex_lock);
-
-		if (rspec->from_mmap)
-			continue;
-
-		free(rspec->regex_str);
-	}
-	free(node->regex_specs);
-
-	for (uint32_t i = 0; i < node->children_num; i++)
-		free_spec_node(&node->children[i]);
-	free(node->children);
-
-	if (!node->from_mmap)
-		free(node->stem);
-}
-
 /* This will always check for buffer over-runs and either read the next entry
  * if buf != NULL or skip over the entry (as these areas are mapped in the
  * current buffer). */