All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] mcstrans: port to new PCRE2 from end-of-life PCRE
@ 2021-11-23 18:32 Christian Göttsche
  2021-11-23 18:32 ` [PATCH 2/3] libselinux: use PCRE2 by default Christian Göttsche
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Christian Göttsche @ 2021-11-23 18:32 UTC (permalink / raw)
  To: selinux

Quoting pcre.org:

    There are two major versions of the PCRE library. The current
    version, PCRE2, released in 2015, is now at version 10.39.

    The older, but still widely deployed PCRE library, originally
    released in 1997, is at version 8.45. This version of PCRE is now at
    end of life, and is no longer being actively maintained. Version
    8.45 is expected to be the final release of the older PCRE library,
    and new projects should use PCRE2 instead.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
 mcstrans/Makefile       |   6 ++
 mcstrans/src/Makefile   |   4 +-
 mcstrans/src/mcstrans.c | 119 +++++++++++++++++++++++++++-------------
 mcstrans/utils/Makefile |   6 +-
 4 files changed, 93 insertions(+), 42 deletions(-)

diff --git a/mcstrans/Makefile b/mcstrans/Makefile
index c993a9f5..b20279ab 100644
--- a/mcstrans/Makefile
+++ b/mcstrans/Makefile
@@ -1,3 +1,9 @@
+PKG_CONFIG ?= pkg-config
+PCRE_MODULE := libpcre2-8
+PCRE_CFLAGS := $(shell $(PKG_CONFIG) --cflags $(PCRE_MODULE)) -DPCRE2_CODE_UNIT_WIDTH=8
+PCRE_LDLIBS := $(shell $(PKG_CONFIG) --libs $(PCRE_MODULE))
+export PCRE_MODULE PCRE_CFLAGS PCRE_LDLIBS
+
 all: 
 	$(MAKE) -C src 
 	$(MAKE) -C utils
diff --git a/mcstrans/src/Makefile b/mcstrans/src/Makefile
index 76ef0557..ef518625 100644
--- a/mcstrans/src/Makefile
+++ b/mcstrans/src/Makefile
@@ -20,10 +20,10 @@ CFLAGS ?= -Wall -W -Wundef -Wmissing-noreturn -Wmissing-format-attribute
 all: $(PROG)
 
 $(PROG): $(PROG_OBJS) $(LIBSEPOLA)
-	$(CC) $(LDFLAGS) -pie -o $@ $^ -lselinux -lcap -lpcre $(LDLIBS_LIBSEPOLA)
+	$(CC) $(LDFLAGS) -pie -o $@ $^ -lselinux -lcap $(PCRE_LDLIBS) $(LDLIBS_LIBSEPOLA)
 
 %.o:  %.c 
-	$(CC) $(CFLAGS) -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -fPIE -c -o $@ $<
+	$(CC) $(CFLAGS) $(PCRE_CFLAGS) -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -fPIE -c -o $@ $<
 
 install: all
 	test -d $(DESTDIR)$(SBINDIR) || install -m 755 -d $(DESTDIR)$(SBINDIR)
diff --git a/mcstrans/src/mcstrans.c b/mcstrans/src/mcstrans.c
index 09577ea0..60b9291b 100644
--- a/mcstrans/src/mcstrans.c
+++ b/mcstrans/src/mcstrans.c
@@ -26,7 +26,7 @@
 #include <selinux/context.h>
 #include <syslog.h>
 #include <errno.h>
-#include <pcre.h>
+#include <pcre2.h>
 #include <ctype.h>
 #include <time.h>
 #include <sys/time.h>
@@ -36,7 +36,6 @@
 #include "mcstrans.h"
 
 #define N_BUCKETS 1453
-#define OVECCOUNT (512*3)
 
 #define log_error(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__)
 
@@ -82,9 +81,9 @@ typedef struct word_group {
 	affix_t *suffixes;
 	word_t *words;
 
-	pcre *prefix_regexp;
-	pcre *word_regexp;
-	pcre *suffix_regexp;
+	pcre2_code *prefix_regexp;
+	pcre2_code *word_regexp;
+	pcre2_code *suffix_regexp;
 
 	ebitmap_t def;
 
@@ -109,7 +108,7 @@ typedef struct domain {
 	base_classification_t *base_classifications;
 	word_group_t *groups;
 
-	pcre *base_classification_regexp;
+	pcre2_code *base_classification_regexp;
 	struct domain *next;
 } domain_t;
 
@@ -317,9 +316,9 @@ destroy_group(word_group_t **list, word_group_t *group) {
 	free(group->name);
 	free(group->sword);
 	free(group->join);
-	pcre_free(group->prefix_regexp);
-	pcre_free(group->word_regexp);
-	pcre_free(group->suffix_regexp);
+	pcre2_code_free(group->prefix_regexp);
+	pcre2_code_free(group->word_regexp);
+	pcre2_code_free(group->suffix_regexp);
 	ebitmap_destroy(&group->def);
 	free(group);
 }
@@ -392,7 +391,7 @@ destroy_domain(domain_t *domain) {
 		free(domain->base_classifications);
 		domain->base_classifications = next;
 	}
-	pcre_free(domain->base_classification_regexp);
+	pcre2_code_free(domain->base_classification_regexp);
 	while (domain->groups)
 		destroy_group(&domain->groups, domain->groups);
 	free(domain->name);
@@ -963,14 +962,16 @@ word_size(const void *p1, const void *p2) {
 }
 
 static void
-build_regexp(pcre **r, char *buffer) {
-	const char *error;
-	int error_offset;
+build_regexp(pcre2_code **r, char *buffer) {
+	int error;
+	PCRE2_SIZE error_offset;
 	if (*r)
-		pcre_free(*r);
-	*r = pcre_compile(buffer, PCRE_CASELESS, &error, &error_offset, NULL);
-	if (error) {
-		log_error("pcre=%s, error=%s\n", buffer, error ? error: "none");
+		pcre2_code_free(*r);
+	*r = pcre2_compile((PCRE2_SPTR8) buffer, PCRE2_ZERO_TERMINATED, PCRE2_CASELESS, &error, &error_offset, NULL);
+	if (!*r) {
+		PCRE2_UCHAR errbuf[256];
+  		pcre2_get_error_message(error, errbuf, sizeof(errbuf));
+		log_error("pcre compilation of '%s' failed at offset %zu: %s\n", buffer, error_offset, errbuf);
 	}
 	buffer[0] = '\0';
 }
@@ -1088,14 +1089,14 @@ compute_raw_from_trans(const char *level, domain_t *domain) {
 #endif
 
 	int rc = 0;
-	int ovector[OVECCOUNT];
 	word_group_t *g = NULL;
 	char *work = NULL;
 	char *r = NULL;
-	const char * match = NULL;
-	int work_len;
+	size_t work_len;
 	mls_level_t *mraw = NULL;
 	ebitmap_t set, clear, tmp;
+	PCRE2_UCHAR *match = NULL;
+	pcre2_match_data *match_data = NULL;
 
 	ebitmap_init(&set);
 	ebitmap_init(&clear);
@@ -1114,14 +1115,21 @@ compute_raw_from_trans(const char *level, domain_t *domain) {
 	if (!domain->base_classification_regexp)
 		goto err;
 	log_debug(" compute_raw_from_trans work = %s\n", work);
-	rc = pcre_exec(domain->base_classification_regexp, 0, work, work_len, 0, PCRE_ANCHORED, ovector, OVECCOUNT);
+	match_data = pcre2_match_data_create_from_pattern(domain->base_classification_regexp, NULL);
+	if (!match_data) {
+		log_error("allocation error %s", strerror(errno));
+		goto err;
+	}
+	rc = pcre2_match(domain->base_classification_regexp, (PCRE2_SPTR8)work, work_len, 0, PCRE2_ANCHORED, match_data, NULL);
 	if (rc > 0) {
-		match = NULL;
-		pcre_get_substring(work, ovector, rc, 0, &match);
-		log_debug(" compute_raw_from_trans match = %s len = %u\n", match, strlen(match));
+		PCRE2_SIZE match_size;
+		const PCRE2_SIZE *ovector;
+		if (!pcre2_substring_get_bynumber(match_data, 0, &match, &match_size))
+			goto err;
+		log_debug(" compute_raw_from_trans match = %s len = %zu\n", match, strlen((const char *)match));
 		base_classification_t *bc;
 		for (bc = domain->base_classifications; bc; bc = bc->next) {
-			if (!strcmp(bc->trans, match)) {
+			if (!strcmp(bc->trans, (const char *)match)) {
 				log_debug(" compute_raw_from_trans base classification %s matched %s\n", level, bc->trans);
 				mraw = malloc(sizeof(mls_level_t));
 				if (!mraw) {
@@ -1134,16 +1142,27 @@ compute_raw_from_trans(const char *level, domain_t *domain) {
 			}
 		}
 
+		ovector = pcre2_get_ovector_pointer(match_data);
 		memset(work + ovector[0], '#', ovector[1] - ovector[0]);
 		char *p=work + ovector[0] + ovector[1];
 		while (*p && (strchr(" 	", *p) != NULL))
 			*p++ = '#';
-		pcre_free((char *)match);
+		pcre2_substring_free(match);
 		match = NULL;
 	} else {
-		log_debug(" compute_raw_from_trans no base classification matched %s\n", level);
+		switch (rc) {
+		case PCRE2_ERROR_NOMATCH:
+			log_debug(" compute_raw_from_trans no base classification matched %s\n", level);
+			break;
+		default:
+			log_error("compute_raw_from_trans: matching error for input '%s': %d\n", level, rc);
+			break;
+		}		
 	}
 
+	pcre2_match_data_free(match_data);
+	match_data = NULL;
+
 	if (mraw == NULL) {
 		goto err;
 	}
@@ -1154,23 +1173,39 @@ compute_raw_from_trans(const char *level, domain_t *domain) {
 		change = 0;
 		for (g = domain->groups; g && !change && !complete; g = g->next) {
 			int prefix = 0, suffix = 0;
-			int prefix_offset = 0, prefix_len = 0;
-			int suffix_offset = 0, suffix_len = 0;
+			PCRE2_SIZE prefix_offset = 0, prefix_len = 0;
+			PCRE2_SIZE suffix_offset = 0, suffix_len = 0;
 			if (g->prefix_regexp) {
-				rc = pcre_exec(g->prefix_regexp, 0, work, work_len, 0, 0, ovector, OVECCOUNT);
+				match_data = pcre2_match_data_create_from_pattern(g->prefix_regexp, NULL);
+				if (!match_data) {
+					log_error("allocation error %s", strerror(errno));
+					goto err;
+				}
+				rc = pcre2_match(g->prefix_regexp, (PCRE2_SPTR8)work, work_len, 0, 0, match_data, NULL);
 				if (rc > 0) {
+					const PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);
 					prefix = 1;
 					prefix_offset = ovector[0];
 					prefix_len = ovector[1] - ovector[0];
 				}
+				pcre2_match_data_free(match_data);
+				match_data = NULL;
 			}
 			if (g->suffix_regexp) {
-				rc = pcre_exec(g->suffix_regexp, 0, work, work_len, 0, 0, ovector, OVECCOUNT);
+				match_data = pcre2_match_data_create_from_pattern(g->suffix_regexp, NULL);
+				if (!match_data) {
+					log_error("allocation error %s", strerror(errno));
+					goto err;
+				}
+				rc = pcre2_match(g->suffix_regexp, (PCRE2_SPTR8)work, work_len, 0, 0, match_data, NULL);
 				if (rc > 0) {
+					const PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);
 					suffix = 1;
 					suffix_offset = ovector[0];
 					suffix_len = ovector[1] - ovector[0];
 				}
+				pcre2_match_data_free(match_data);
+				match_data = NULL;
 			}
 
 /* anchors prefix ^, suffix $ */
@@ -1179,11 +1214,18 @@ compute_raw_from_trans(const char *level, domain_t *domain) {
 			     (g->suffixes && suffix)) &&
 			     g->word_regexp) {
 				char *s = work + prefix_offset + prefix_len;
-				int l = (suffix_len ? suffix_offset : work_len) - prefix_len - prefix_offset;
-				rc = pcre_exec(g->word_regexp, 0, s, l, 0, 0, ovector, OVECCOUNT);
+				PCRE2_SIZE len = (suffix_len ? suffix_offset : work_len) - prefix_len - prefix_offset;
+				match_data = pcre2_match_data_create_from_pattern(g->word_regexp, NULL);
+				if (!match_data) {
+					log_error("allocation error %s", strerror(errno));
+					goto err;
+				}
+				rc = pcre2_match(g->word_regexp, (PCRE2_SPTR8)s, len, 0, 0, match_data, NULL);
 				if (rc > 0) {
-					match = NULL;
-					pcre_get_substring(s, ovector, rc, 0, &match);
+					PCRE2_SIZE match_size;
+					const PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);
+					if (!pcre2_substring_get_bynumber(match_data, 0, &match, &match_size))
+						goto err;
 					trim((char *)match, g->whitespace);
 					if (*match) {
 						char *p = triml((char *)match, g->whitespace);
@@ -1223,9 +1265,11 @@ compute_raw_from_trans(const char *level, domain_t *domain) {
 						memset(work + suffix_offset, '#', suffix_len);
 						memset(s + ovector[0], '#', ovector[1] - ovector[0]);
 					}
-					pcre_free((void *)match);
+					pcre2_substring_free(match);
 					match = NULL;
 				}
+				pcre2_match_data_free(match_data);
+				match_data = NULL;
 			}
 /* YYY */
 			complete=1;
@@ -1264,10 +1308,11 @@ err:
 	mls_level_destroy(mraw);
 	free(mraw);
 	free(work);
-	pcre_free((void *)match);
 	ebitmap_destroy(&tmp);
 	ebitmap_destroy(&set);
 	ebitmap_destroy(&clear);
+	pcre2_substring_free(match);
+	pcre2_match_data_free(match_data);
 	return NULL;
 }
 
diff --git a/mcstrans/utils/Makefile b/mcstrans/utils/Makefile
index 9dfe7723..a48f4e72 100644
--- a/mcstrans/utils/Makefile
+++ b/mcstrans/utils/Makefile
@@ -14,13 +14,13 @@ endif
 all: $(TARGETS)
 
 transcon: transcon.o ../src/mcstrans.o ../src/mls_level.o $(LIBSEPOLA)
-	$(CC) $(LDFLAGS) -o $@ $^ -lpcre -lselinux $(LDLIBS_LIBSEPOLA)
+	$(CC) $(LDFLAGS) -o $@ $^ $(PCRE_LDLIBS) -lselinux $(LDLIBS_LIBSEPOLA)
 
 untranscon: untranscon.o ../src/mcstrans.o ../src/mls_level.o $(LIBSEPOLA)
-	$(CC) $(LDFLAGS) -o $@ $^ -lpcre -lselinux $(LDLIBS_LIBSEPOLA)
+	$(CC) $(LDFLAGS) -o $@ $^ $(PCRE_LDLIBS) -lselinux $(LDLIBS_LIBSEPOLA)
 
 %.o:  %.c 
-	$(CC) $(CFLAGS) -D_GNU_SOURCE -I../src -fPIE -c -o $@ $<
+	$(CC) $(CFLAGS) $(PCRE_CFLAGS) -D_GNU_SOURCE -I../src -fPIE -c -o $@ $<
 
 install: all
 	-mkdir -p $(DESTDIR)$(SBINDIR)
-- 
2.34.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/3] libselinux: use PCRE2 by default
  2021-11-23 18:32 [PATCH 1/3] mcstrans: port to new PCRE2 from end-of-life PCRE Christian Göttsche
@ 2021-11-23 18:32 ` Christian Göttsche
  2021-11-24 17:06   ` Petr Lautrbach
  2021-12-01 15:56   ` Petr Lautrbach
  2021-11-23 18:32 ` [PATCH 3/3] Replace PCRE with PCRE2 build dependencies Christian Göttsche
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 10+ messages in thread
From: Christian Göttsche @ 2021-11-23 18:32 UTC (permalink / raw)
  To: selinux

Quoting pcre.org:

    There are two major versions of the PCRE library. The current
    version, PCRE2, released in 2015, is now at version 10.39.

    The older, but still widely deployed PCRE library, originally
    released in 1997, is at version 8.45. This version of PCRE is now at
    end of life, and is no longer being actively maintained. Version
    8.45 is expected to be the final release of the older PCRE library,
    and new projects should use PCRE2 instead.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
 libselinux/Makefile       | 2 +-
 libselinux/src/Makefile   | 1 -
 libselinux/utils/Makefile | 1 -
 3 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/libselinux/Makefile b/libselinux/Makefile
index 439bc6a9..6d9e2736 100644
--- a/libselinux/Makefile
+++ b/libselinux/Makefile
@@ -23,7 +23,7 @@ ifeq ($(DISABLE_X11),y)
 endif
 export DISABLE_SETRANS DISABLE_RPM DISABLE_FLAGS ANDROID_HOST DISABLE_X11 LABEL_BACKEND_ANDROID
 
-USE_PCRE2 ?= n
+USE_PCRE2 ?= y
 ifeq ($(USE_PCRE2),y)
 	PCRE_MODULE := libpcre2-8
 	PCRE_CFLAGS := -DUSE_PCRE2 -DPCRE2_CODE_UNIT_WIDTH=8
diff --git a/libselinux/src/Makefile b/libselinux/src/Makefile
index 52c40f01..04bf4f24 100644
--- a/libselinux/src/Makefile
+++ b/libselinux/src/Makefile
@@ -98,7 +98,6 @@ override LDFLAGS += -L/opt/local/lib -undefined dynamic_lookup
 LD_SONAME_FLAGS=-install_name,$(LIBSO)
 endif
 
-PCRE_LDLIBS ?= -lpcre
 # override with -lfts when building on Musl libc to use fts-standalone
 FTS_LDLIBS ?=
 
diff --git a/libselinux/utils/Makefile b/libselinux/utils/Makefile
index 36816155..801066cb 100644
--- a/libselinux/utils/Makefile
+++ b/libselinux/utils/Makefile
@@ -44,7 +44,6 @@ endif
 override CFLAGS += -I../include -D_GNU_SOURCE $(DISABLE_FLAGS) $(PCRE_CFLAGS)
 override LDFLAGS += -L../src
 override LDLIBS += -lselinux $(FTS_LDLIBS)
-PCRE_LDLIBS ?= -lpcre
 
 ifeq ($(ANDROID_HOST),y)
 TARGETS=sefcontext_compile
-- 
2.34.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/3] Replace PCRE with PCRE2 build dependencies
  2021-11-23 18:32 [PATCH 1/3] mcstrans: port to new PCRE2 from end-of-life PCRE Christian Göttsche
  2021-11-23 18:32 ` [PATCH 2/3] libselinux: use PCRE2 by default Christian Göttsche
@ 2021-11-23 18:32 ` Christian Göttsche
  2021-12-01 15:57   ` Petr Lautrbach
  2021-11-29 10:05 ` [PATCH 1/3] mcstrans: port to new PCRE2 from end-of-life PCRE Petr Lautrbach
  2021-11-30 11:04 ` [PATCH v2 " Christian Göttsche
  3 siblings, 1 reply; 10+ messages in thread
From: Christian Göttsche @ 2021-11-23 18:32 UTC (permalink / raw)
  To: selinux

Now that libselinux defaults to PCRE2 and mcstrans has been ported,
update all documentation and scripts.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
 .circleci/config.yml             | 2 +-
 .github/workflows/run_tests.yml  | 2 +-
 CONTRIBUTING.md                  | 2 +-
 README.md                        | 4 ++--
 scripts/ci/fedora-test-runner.sh | 2 +-
 5 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/.circleci/config.yml b/.circleci/config.yml
index 5d3177da..af20484b 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -13,7 +13,7 @@ jobs:
 
     # Install dependencies
     - run: sudo apt-get update -qq
-    - run: sudo apt-get install -qq bison clang clang-tools flex gawk gettext libaudit-dev libcap-dev libcap-ng-dev libcunit1-dev libdbus-glib-1-dev libpcre3-dev python3-dev python-dev ruby-dev swig xmlto
+    - run: sudo apt-get install -qq bison clang clang-tools flex gawk gettext libaudit-dev libcap-dev libcap-ng-dev libcunit1-dev libdbus-glib-1-dev libpcre2-dev python3-dev python-dev ruby-dev swig xmlto
 
     - run:
         name: Setup environment variables
diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml
index ef4be8af..01fbbbe5 100644
--- a/.github/workflows/run_tests.yml
+++ b/.github/workflows/run_tests.yml
@@ -57,7 +57,7 @@ jobs:
             libcap-ng-dev \
             libcunit1-dev \
             libdbus-glib-1-dev \
-            libpcre3-dev \
+            libpcre2-dev \
             python3-dev \
             python-dev \
             ruby-dev \
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index a3517cb8..7c548e58 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -26,7 +26,7 @@ using a custom policy please include it as well.
 There are a number of dependencies required to build the userspace
 tools/libraries. On a Fedora system you can install them with yum:
 
-    # yum install audit-libs-devel bison bzip2-devel dbus-devel dbus-glib-devel flex flex-devel flex-static glib2-devel libcap-devel libcap-ng-devel pam-devel pcre-devel python-devel setools-devel swig ustr-devel
+    # yum install audit-libs-devel bison bzip2-devel dbus-devel dbus-glib-devel flex flex-devel flex-static glib2-devel libcap-devel libcap-ng-devel pam-devel pcre2-devel python-devel setools-devel swig ustr-devel
 
 The tools and libraries can be built and installed under a private directory from the top level with make, e.g.
 
diff --git a/README.md b/README.md
index e1c2fe64..74b0a0c3 100644
--- a/README.md
+++ b/README.md
@@ -51,7 +51,7 @@ dnf install \
     libcap-devel \
     libcap-ng-devel \
     pam-devel \
-    pcre-devel \
+    pcre2-devel \
     xmlto
 
 # For Python and Ruby bindings
@@ -78,7 +78,7 @@ apt-get install --no-install-recommends --no-install-suggests \
     libcap-ng-dev \
     libcunit1-dev \
     libglib2.0-dev \
-    libpcre3-dev \
+    libpcre2-dev \
     pkgconf \
     python3 \
     python3-distutils \
diff --git a/scripts/ci/fedora-test-runner.sh b/scripts/ci/fedora-test-runner.sh
index f817499b..3ce2c3a6 100755
--- a/scripts/ci/fedora-test-runner.sh
+++ b/scripts/ci/fedora-test-runner.sh
@@ -36,7 +36,7 @@ dnf install -y \
     libcap-devel \
     libcap-ng-devel \
     pam-devel \
-    pcre-devel \
+    pcre2-devel \
     xmlto \
     python3-devel \
     ruby-devel \
-- 
2.34.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/3] libselinux: use PCRE2 by default
  2021-11-23 18:32 ` [PATCH 2/3] libselinux: use PCRE2 by default Christian Göttsche
@ 2021-11-24 17:06   ` Petr Lautrbach
  2021-12-01 15:56   ` Petr Lautrbach
  1 sibling, 0 replies; 10+ messages in thread
From: Petr Lautrbach @ 2021-11-24 17:06 UTC (permalink / raw)
  To: Christian Göttsche, selinux

Christian Göttsche <cgzones@googlemail.com> writes:

> Quoting pcre.org:
>
>     There are two major versions of the PCRE library. The current
>     version, PCRE2, released in 2015, is now at version 10.39.
>
>     The older, but still widely deployed PCRE library, originally
>     released in 1997, is at version 8.45. This version of PCRE is now at
>     end of life, and is no longer being actively maintained. Version
>     8.45 is expected to be the final release of the older PCRE library,
>     and new projects should use PCRE2 instead.
>
> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>

Thanks for this patchset!

Would it make sense to drop the pcre code completely?

It could be a problem for RHEL 6 where pcre2 is not available. But given
that RHEL 6 uses gcc 4.7 by default and libsepol uses __builtin_add_overflow
(introduced in gcc 7) libsepol can't be built on RHEL 6 anyway.


Petr


> ---
>  libselinux/Makefile       | 2 +-
>  libselinux/src/Makefile   | 1 -
>  libselinux/utils/Makefile | 1 -
>  3 files changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/libselinux/Makefile b/libselinux/Makefile
> index 439bc6a9..6d9e2736 100644
> --- a/libselinux/Makefile
> +++ b/libselinux/Makefile
> @@ -23,7 +23,7 @@ ifeq ($(DISABLE_X11),y)
>  endif
>  export DISABLE_SETRANS DISABLE_RPM DISABLE_FLAGS ANDROID_HOST DISABLE_X11 LABEL_BACKEND_ANDROID
>  
> -USE_PCRE2 ?= n
> +USE_PCRE2 ?= y
>  ifeq ($(USE_PCRE2),y)
>  	PCRE_MODULE := libpcre2-8
>  	PCRE_CFLAGS := -DUSE_PCRE2 -DPCRE2_CODE_UNIT_WIDTH=8
> diff --git a/libselinux/src/Makefile b/libselinux/src/Makefile
> index 52c40f01..04bf4f24 100644
> --- a/libselinux/src/Makefile
> +++ b/libselinux/src/Makefile
> @@ -98,7 +98,6 @@ override LDFLAGS += -L/opt/local/lib -undefined dynamic_lookup
>  LD_SONAME_FLAGS=-install_name,$(LIBSO)
>  endif
>  
> -PCRE_LDLIBS ?= -lpcre
>  # override with -lfts when building on Musl libc to use fts-standalone
>  FTS_LDLIBS ?=
>  
> diff --git a/libselinux/utils/Makefile b/libselinux/utils/Makefile
> index 36816155..801066cb 100644
> --- a/libselinux/utils/Makefile
> +++ b/libselinux/utils/Makefile
> @@ -44,7 +44,6 @@ endif
>  override CFLAGS += -I../include -D_GNU_SOURCE $(DISABLE_FLAGS) $(PCRE_CFLAGS)
>  override LDFLAGS += -L../src
>  override LDLIBS += -lselinux $(FTS_LDLIBS)
> -PCRE_LDLIBS ?= -lpcre
>  
>  ifeq ($(ANDROID_HOST),y)
>  TARGETS=sefcontext_compile
> -- 
> 2.34.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/3] mcstrans: port to new PCRE2 from end-of-life PCRE
  2021-11-23 18:32 [PATCH 1/3] mcstrans: port to new PCRE2 from end-of-life PCRE Christian Göttsche
  2021-11-23 18:32 ` [PATCH 2/3] libselinux: use PCRE2 by default Christian Göttsche
  2021-11-23 18:32 ` [PATCH 3/3] Replace PCRE with PCRE2 build dependencies Christian Göttsche
@ 2021-11-29 10:05 ` Petr Lautrbach
  2021-11-30 11:04 ` [PATCH v2 " Christian Göttsche
  3 siblings, 0 replies; 10+ messages in thread
From: Petr Lautrbach @ 2021-11-29 10:05 UTC (permalink / raw)
  To: Christian Göttsche, selinux

Christian Göttsche <cgzones@googlemail.com> writes:

> Quoting pcre.org:
>
>     There are two major versions of the PCRE library. The current
>     version, PCRE2, released in 2015, is now at version 10.39.
>
>     The older, but still widely deployed PCRE library, originally
>     released in 1997, is at version 8.45. This version of PCRE is now at
>     end of life, and is no longer being actively maintained. Version
>     8.45 is expected to be the final release of the older PCRE library,
>     and new projects should use PCRE2 instead.
>
> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>


I see failures in the internal testsuite

e.g for mcstrans/share/examples/nato

$ python3 /usr/share/mcstrans/util/mlstrans-test nato.test
...
untrans: 'a:b:c:CONFIDENTIAL-NATO SECRET!' -> 'a:b:c:s4:c0,c2,c11,c200.c511-NATO SECRET!' != 'a:b:c:s4:c0,c2,c11,c200.c511-s5:c1,c200.c511' FAILED
...
mlstrans-test done with 1 error


or examples/pipes

$ python3 /usr/share/mcstrans/util/mlstrans-test pipes.test
...
untrans: 'a:b:c:Restricted Handle Via Iron,Plastic,Copper Pipes Only' -> 'a:b:c:Restricted Handle Via Iron,Plastic,Copper Pipes Only' != 'a:b:c:s2:c101.c103,c200.c511' FAILED
mlstrans-test done with 1 error



Thanks!


> ---
>  mcstrans/Makefile       |   6 ++
>  mcstrans/src/Makefile   |   4 +-
>  mcstrans/src/mcstrans.c | 119 +++++++++++++++++++++++++++-------------
>  mcstrans/utils/Makefile |   6 +-
>  4 files changed, 93 insertions(+), 42 deletions(-)
>
> diff --git a/mcstrans/Makefile b/mcstrans/Makefile
> index c993a9f5..b20279ab 100644
> --- a/mcstrans/Makefile
> +++ b/mcstrans/Makefile
> @@ -1,3 +1,9 @@
> +PKG_CONFIG ?= pkg-config
> +PCRE_MODULE := libpcre2-8
> +PCRE_CFLAGS := $(shell $(PKG_CONFIG) --cflags $(PCRE_MODULE)) -DPCRE2_CODE_UNIT_WIDTH=8
> +PCRE_LDLIBS := $(shell $(PKG_CONFIG) --libs $(PCRE_MODULE))
> +export PCRE_MODULE PCRE_CFLAGS PCRE_LDLIBS
> +
>  all: 
>  	$(MAKE) -C src 
>  	$(MAKE) -C utils
> diff --git a/mcstrans/src/Makefile b/mcstrans/src/Makefile
> index 76ef0557..ef518625 100644
> --- a/mcstrans/src/Makefile
> +++ b/mcstrans/src/Makefile
> @@ -20,10 +20,10 @@ CFLAGS ?= -Wall -W -Wundef -Wmissing-noreturn -Wmissing-format-attribute
>  all: $(PROG)
>  
>  $(PROG): $(PROG_OBJS) $(LIBSEPOLA)
> -	$(CC) $(LDFLAGS) -pie -o $@ $^ -lselinux -lcap -lpcre $(LDLIBS_LIBSEPOLA)
> +	$(CC) $(LDFLAGS) -pie -o $@ $^ -lselinux -lcap $(PCRE_LDLIBS) $(LDLIBS_LIBSEPOLA)
>  
>  %.o:  %.c 
> -	$(CC) $(CFLAGS) -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -fPIE -c -o $@ $<
> +	$(CC) $(CFLAGS) $(PCRE_CFLAGS) -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -fPIE -c -o $@ $<
>  
>  install: all
>  	test -d $(DESTDIR)$(SBINDIR) || install -m 755 -d $(DESTDIR)$(SBINDIR)
> diff --git a/mcstrans/src/mcstrans.c b/mcstrans/src/mcstrans.c
> index 09577ea0..60b9291b 100644
> --- a/mcstrans/src/mcstrans.c
> +++ b/mcstrans/src/mcstrans.c
> @@ -26,7 +26,7 @@
>  #include <selinux/context.h>
>  #include <syslog.h>
>  #include <errno.h>
> -#include <pcre.h>
> +#include <pcre2.h>
>  #include <ctype.h>
>  #include <time.h>
>  #include <sys/time.h>
> @@ -36,7 +36,6 @@
>  #include "mcstrans.h"
>  
>  #define N_BUCKETS 1453
> -#define OVECCOUNT (512*3)
>  
>  #define log_error(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__)
>  
> @@ -82,9 +81,9 @@ typedef struct word_group {
>  	affix_t *suffixes;
>  	word_t *words;
>  
> -	pcre *prefix_regexp;
> -	pcre *word_regexp;
> -	pcre *suffix_regexp;
> +	pcre2_code *prefix_regexp;
> +	pcre2_code *word_regexp;
> +	pcre2_code *suffix_regexp;
>  
>  	ebitmap_t def;
>  
> @@ -109,7 +108,7 @@ typedef struct domain {
>  	base_classification_t *base_classifications;
>  	word_group_t *groups;
>  
> -	pcre *base_classification_regexp;
> +	pcre2_code *base_classification_regexp;
>  	struct domain *next;
>  } domain_t;
>  
> @@ -317,9 +316,9 @@ destroy_group(word_group_t **list, word_group_t *group) {
>  	free(group->name);
>  	free(group->sword);
>  	free(group->join);
> -	pcre_free(group->prefix_regexp);
> -	pcre_free(group->word_regexp);
> -	pcre_free(group->suffix_regexp);
> +	pcre2_code_free(group->prefix_regexp);
> +	pcre2_code_free(group->word_regexp);
> +	pcre2_code_free(group->suffix_regexp);
>  	ebitmap_destroy(&group->def);
>  	free(group);
>  }
> @@ -392,7 +391,7 @@ destroy_domain(domain_t *domain) {
>  		free(domain->base_classifications);
>  		domain->base_classifications = next;
>  	}
> -	pcre_free(domain->base_classification_regexp);
> +	pcre2_code_free(domain->base_classification_regexp);
>  	while (domain->groups)
>  		destroy_group(&domain->groups, domain->groups);
>  	free(domain->name);
> @@ -963,14 +962,16 @@ word_size(const void *p1, const void *p2) {
>  }
>  
>  static void
> -build_regexp(pcre **r, char *buffer) {
> -	const char *error;
> -	int error_offset;
> +build_regexp(pcre2_code **r, char *buffer) {
> +	int error;
> +	PCRE2_SIZE error_offset;
>  	if (*r)
> -		pcre_free(*r);
> -	*r = pcre_compile(buffer, PCRE_CASELESS, &error, &error_offset, NULL);
> -	if (error) {
> -		log_error("pcre=%s, error=%s\n", buffer, error ? error: "none");
> +		pcre2_code_free(*r);
> +	*r = pcre2_compile((PCRE2_SPTR8) buffer, PCRE2_ZERO_TERMINATED, PCRE2_CASELESS, &error, &error_offset, NULL);
> +	if (!*r) {
> +		PCRE2_UCHAR errbuf[256];
> +  		pcre2_get_error_message(error, errbuf, sizeof(errbuf));
> +		log_error("pcre compilation of '%s' failed at offset %zu: %s\n", buffer, error_offset, errbuf);
>  	}
>  	buffer[0] = '\0';
>  }
> @@ -1088,14 +1089,14 @@ compute_raw_from_trans(const char *level, domain_t *domain) {
>  #endif
>  
>  	int rc = 0;
> -	int ovector[OVECCOUNT];
>  	word_group_t *g = NULL;
>  	char *work = NULL;
>  	char *r = NULL;
> -	const char * match = NULL;
> -	int work_len;
> +	size_t work_len;
>  	mls_level_t *mraw = NULL;
>  	ebitmap_t set, clear, tmp;
> +	PCRE2_UCHAR *match = NULL;
> +	pcre2_match_data *match_data = NULL;
>  
>  	ebitmap_init(&set);
>  	ebitmap_init(&clear);
> @@ -1114,14 +1115,21 @@ compute_raw_from_trans(const char *level, domain_t *domain) {
>  	if (!domain->base_classification_regexp)
>  		goto err;
>  	log_debug(" compute_raw_from_trans work = %s\n", work);
> -	rc = pcre_exec(domain->base_classification_regexp, 0, work, work_len, 0, PCRE_ANCHORED, ovector, OVECCOUNT);
> +	match_data = pcre2_match_data_create_from_pattern(domain->base_classification_regexp, NULL);
> +	if (!match_data) {
> +		log_error("allocation error %s", strerror(errno));
> +		goto err;
> +	}
> +	rc = pcre2_match(domain->base_classification_regexp, (PCRE2_SPTR8)work, work_len, 0, PCRE2_ANCHORED, match_data, NULL);
>  	if (rc > 0) {
> -		match = NULL;
> -		pcre_get_substring(work, ovector, rc, 0, &match);
> -		log_debug(" compute_raw_from_trans match = %s len = %u\n", match, strlen(match));
> +		PCRE2_SIZE match_size;
> +		const PCRE2_SIZE *ovector;
> +		if (!pcre2_substring_get_bynumber(match_data, 0, &match, &match_size))
> +			goto err;
> +		log_debug(" compute_raw_from_trans match = %s len = %zu\n", match, strlen((const char *)match));
>  		base_classification_t *bc;
>  		for (bc = domain->base_classifications; bc; bc = bc->next) {
> -			if (!strcmp(bc->trans, match)) {
> +			if (!strcmp(bc->trans, (const char *)match)) {
>  				log_debug(" compute_raw_from_trans base classification %s matched %s\n", level, bc->trans);
>  				mraw = malloc(sizeof(mls_level_t));
>  				if (!mraw) {
> @@ -1134,16 +1142,27 @@ compute_raw_from_trans(const char *level, domain_t *domain) {
>  			}
>  		}
>  
> +		ovector = pcre2_get_ovector_pointer(match_data);
>  		memset(work + ovector[0], '#', ovector[1] - ovector[0]);
>  		char *p=work + ovector[0] + ovector[1];
>  		while (*p && (strchr(" 	", *p) != NULL))
>  			*p++ = '#';
> -		pcre_free((char *)match);
> +		pcre2_substring_free(match);
>  		match = NULL;
>  	} else {
> -		log_debug(" compute_raw_from_trans no base classification matched %s\n", level);
> +		switch (rc) {
> +		case PCRE2_ERROR_NOMATCH:
> +			log_debug(" compute_raw_from_trans no base classification matched %s\n", level);
> +			break;
> +		default:
> +			log_error("compute_raw_from_trans: matching error for input '%s': %d\n", level, rc);
> +			break;
> +		}		
>  	}
>  
> +	pcre2_match_data_free(match_data);
> +	match_data = NULL;
> +
>  	if (mraw == NULL) {
>  		goto err;
>  	}
> @@ -1154,23 +1173,39 @@ compute_raw_from_trans(const char *level, domain_t *domain) {
>  		change = 0;
>  		for (g = domain->groups; g && !change && !complete; g = g->next) {
>  			int prefix = 0, suffix = 0;
> -			int prefix_offset = 0, prefix_len = 0;
> -			int suffix_offset = 0, suffix_len = 0;
> +			PCRE2_SIZE prefix_offset = 0, prefix_len = 0;
> +			PCRE2_SIZE suffix_offset = 0, suffix_len = 0;
>  			if (g->prefix_regexp) {
> -				rc = pcre_exec(g->prefix_regexp, 0, work, work_len, 0, 0, ovector, OVECCOUNT);
> +				match_data = pcre2_match_data_create_from_pattern(g->prefix_regexp, NULL);
> +				if (!match_data) {
> +					log_error("allocation error %s", strerror(errno));
> +					goto err;
> +				}
> +				rc = pcre2_match(g->prefix_regexp, (PCRE2_SPTR8)work, work_len, 0, 0, match_data, NULL);
>  				if (rc > 0) {
> +					const PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);
>  					prefix = 1;
>  					prefix_offset = ovector[0];
>  					prefix_len = ovector[1] - ovector[0];
>  				}
> +				pcre2_match_data_free(match_data);
> +				match_data = NULL;
>  			}
>  			if (g->suffix_regexp) {
> -				rc = pcre_exec(g->suffix_regexp, 0, work, work_len, 0, 0, ovector, OVECCOUNT);
> +				match_data = pcre2_match_data_create_from_pattern(g->suffix_regexp, NULL);
> +				if (!match_data) {
> +					log_error("allocation error %s", strerror(errno));
> +					goto err;
> +				}
> +				rc = pcre2_match(g->suffix_regexp, (PCRE2_SPTR8)work, work_len, 0, 0, match_data, NULL);
>  				if (rc > 0) {
> +					const PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);
>  					suffix = 1;
>  					suffix_offset = ovector[0];
>  					suffix_len = ovector[1] - ovector[0];
>  				}
> +				pcre2_match_data_free(match_data);
> +				match_data = NULL;
>  			}
>  
>  /* anchors prefix ^, suffix $ */
> @@ -1179,11 +1214,18 @@ compute_raw_from_trans(const char *level, domain_t *domain) {
>  			     (g->suffixes && suffix)) &&
>  			     g->word_regexp) {
>  				char *s = work + prefix_offset + prefix_len;
> -				int l = (suffix_len ? suffix_offset : work_len) - prefix_len - prefix_offset;
> -				rc = pcre_exec(g->word_regexp, 0, s, l, 0, 0, ovector, OVECCOUNT);
> +				PCRE2_SIZE len = (suffix_len ? suffix_offset : work_len) - prefix_len - prefix_offset;
> +				match_data = pcre2_match_data_create_from_pattern(g->word_regexp, NULL);
> +				if (!match_data) {
> +					log_error("allocation error %s", strerror(errno));
> +					goto err;
> +				}
> +				rc = pcre2_match(g->word_regexp, (PCRE2_SPTR8)s, len, 0, 0, match_data, NULL);
>  				if (rc > 0) {
> -					match = NULL;
> -					pcre_get_substring(s, ovector, rc, 0, &match);
> +					PCRE2_SIZE match_size;
> +					const PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);
> +					if (!pcre2_substring_get_bynumber(match_data, 0, &match, &match_size))
> +						goto err;
>  					trim((char *)match, g->whitespace);
>  					if (*match) {
>  						char *p = triml((char *)match, g->whitespace);
> @@ -1223,9 +1265,11 @@ compute_raw_from_trans(const char *level, domain_t *domain) {
>  						memset(work + suffix_offset, '#', suffix_len);
>  						memset(s + ovector[0], '#', ovector[1] - ovector[0]);
>  					}
> -					pcre_free((void *)match);
> +					pcre2_substring_free(match);
>  					match = NULL;
>  				}
> +				pcre2_match_data_free(match_data);
> +				match_data = NULL;
>  			}
>  /* YYY */
>  			complete=1;
> @@ -1264,10 +1308,11 @@ err:
>  	mls_level_destroy(mraw);
>  	free(mraw);
>  	free(work);
> -	pcre_free((void *)match);
>  	ebitmap_destroy(&tmp);
>  	ebitmap_destroy(&set);
>  	ebitmap_destroy(&clear);
> +	pcre2_substring_free(match);
> +	pcre2_match_data_free(match_data);
>  	return NULL;
>  }
>  
> diff --git a/mcstrans/utils/Makefile b/mcstrans/utils/Makefile
> index 9dfe7723..a48f4e72 100644
> --- a/mcstrans/utils/Makefile
> +++ b/mcstrans/utils/Makefile
> @@ -14,13 +14,13 @@ endif
>  all: $(TARGETS)
>  
>  transcon: transcon.o ../src/mcstrans.o ../src/mls_level.o $(LIBSEPOLA)
> -	$(CC) $(LDFLAGS) -o $@ $^ -lpcre -lselinux $(LDLIBS_LIBSEPOLA)
> +	$(CC) $(LDFLAGS) -o $@ $^ $(PCRE_LDLIBS) -lselinux $(LDLIBS_LIBSEPOLA)
>  
>  untranscon: untranscon.o ../src/mcstrans.o ../src/mls_level.o $(LIBSEPOLA)
> -	$(CC) $(LDFLAGS) -o $@ $^ -lpcre -lselinux $(LDLIBS_LIBSEPOLA)
> +	$(CC) $(LDFLAGS) -o $@ $^ $(PCRE_LDLIBS) -lselinux $(LDLIBS_LIBSEPOLA)
>  
>  %.o:  %.c 
> -	$(CC) $(CFLAGS) -D_GNU_SOURCE -I../src -fPIE -c -o $@ $<
> +	$(CC) $(CFLAGS) $(PCRE_CFLAGS) -D_GNU_SOURCE -I../src -fPIE -c -o $@ $<
>  
>  install: all
>  	-mkdir -p $(DESTDIR)$(SBINDIR)
> -- 
> 2.34.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v2 1/3] mcstrans: port to new PCRE2 from end-of-life PCRE
  2021-11-23 18:32 [PATCH 1/3] mcstrans: port to new PCRE2 from end-of-life PCRE Christian Göttsche
                   ` (2 preceding siblings ...)
  2021-11-29 10:05 ` [PATCH 1/3] mcstrans: port to new PCRE2 from end-of-life PCRE Petr Lautrbach
@ 2021-11-30 11:04 ` Christian Göttsche
  2021-12-01 15:36   ` Petr Lautrbach
  3 siblings, 1 reply; 10+ messages in thread
From: Christian Göttsche @ 2021-11-30 11:04 UTC (permalink / raw)
  To: selinux

Quoting pcre.org:

    There are two major versions of the PCRE library. The current
    version, PCRE2, released in 2015, is now at version 10.39.

    The older, but still widely deployed PCRE library, originally
    released in 1997, is at version 8.45. This version of PCRE is now at
    end of life, and is no longer being actively maintained. Version
    8.45 is expected to be the final release of the older PCRE library,
    and new projects should use PCRE2 instead.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>

---
v2:
   - do not use pcre2_substring_get_bynumber(), fixes NATO mcstrans
     tests (spotted by Petr Lautrbach)
---
 mcstrans/Makefile       |   6 ++
 mcstrans/src/Makefile   |   4 +-
 mcstrans/src/mcstrans.c | 131 ++++++++++++++++++++++++++++------------
 mcstrans/utils/Makefile |   6 +-
 4 files changed, 104 insertions(+), 43 deletions(-)

diff --git a/mcstrans/Makefile b/mcstrans/Makefile
index c993a9f5..b20279ab 100644
--- a/mcstrans/Makefile
+++ b/mcstrans/Makefile
@@ -1,3 +1,9 @@
+PKG_CONFIG ?= pkg-config
+PCRE_MODULE := libpcre2-8
+PCRE_CFLAGS := $(shell $(PKG_CONFIG) --cflags $(PCRE_MODULE)) -DPCRE2_CODE_UNIT_WIDTH=8
+PCRE_LDLIBS := $(shell $(PKG_CONFIG) --libs $(PCRE_MODULE))
+export PCRE_MODULE PCRE_CFLAGS PCRE_LDLIBS
+
 all: 
 	$(MAKE) -C src 
 	$(MAKE) -C utils
diff --git a/mcstrans/src/Makefile b/mcstrans/src/Makefile
index 76ef0557..ef518625 100644
--- a/mcstrans/src/Makefile
+++ b/mcstrans/src/Makefile
@@ -20,10 +20,10 @@ CFLAGS ?= -Wall -W -Wundef -Wmissing-noreturn -Wmissing-format-attribute
 all: $(PROG)
 
 $(PROG): $(PROG_OBJS) $(LIBSEPOLA)
-	$(CC) $(LDFLAGS) -pie -o $@ $^ -lselinux -lcap -lpcre $(LDLIBS_LIBSEPOLA)
+	$(CC) $(LDFLAGS) -pie -o $@ $^ -lselinux -lcap $(PCRE_LDLIBS) $(LDLIBS_LIBSEPOLA)
 
 %.o:  %.c 
-	$(CC) $(CFLAGS) -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -fPIE -c -o $@ $<
+	$(CC) $(CFLAGS) $(PCRE_CFLAGS) -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -fPIE -c -o $@ $<
 
 install: all
 	test -d $(DESTDIR)$(SBINDIR) || install -m 755 -d $(DESTDIR)$(SBINDIR)
diff --git a/mcstrans/src/mcstrans.c b/mcstrans/src/mcstrans.c
index 09577ea0..6e4bfd3b 100644
--- a/mcstrans/src/mcstrans.c
+++ b/mcstrans/src/mcstrans.c
@@ -26,7 +26,7 @@
 #include <selinux/context.h>
 #include <syslog.h>
 #include <errno.h>
-#include <pcre.h>
+#include <pcre2.h>
 #include <ctype.h>
 #include <time.h>
 #include <sys/time.h>
@@ -36,7 +36,6 @@
 #include "mcstrans.h"
 
 #define N_BUCKETS 1453
-#define OVECCOUNT (512*3)
 
 #define log_error(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__)
 
@@ -82,9 +81,9 @@ typedef struct word_group {
 	affix_t *suffixes;
 	word_t *words;
 
-	pcre *prefix_regexp;
-	pcre *word_regexp;
-	pcre *suffix_regexp;
+	pcre2_code *prefix_regexp;
+	pcre2_code *word_regexp;
+	pcre2_code *suffix_regexp;
 
 	ebitmap_t def;
 
@@ -109,7 +108,7 @@ typedef struct domain {
 	base_classification_t *base_classifications;
 	word_group_t *groups;
 
-	pcre *base_classification_regexp;
+	pcre2_code *base_classification_regexp;
 	struct domain *next;
 } domain_t;
 
@@ -317,9 +316,9 @@ destroy_group(word_group_t **list, word_group_t *group) {
 	free(group->name);
 	free(group->sword);
 	free(group->join);
-	pcre_free(group->prefix_regexp);
-	pcre_free(group->word_regexp);
-	pcre_free(group->suffix_regexp);
+	pcre2_code_free(group->prefix_regexp);
+	pcre2_code_free(group->word_regexp);
+	pcre2_code_free(group->suffix_regexp);
 	ebitmap_destroy(&group->def);
 	free(group);
 }
@@ -392,7 +391,7 @@ destroy_domain(domain_t *domain) {
 		free(domain->base_classifications);
 		domain->base_classifications = next;
 	}
-	pcre_free(domain->base_classification_regexp);
+	pcre2_code_free(domain->base_classification_regexp);
 	while (domain->groups)
 		destroy_group(&domain->groups, domain->groups);
 	free(domain->name);
@@ -963,14 +962,16 @@ word_size(const void *p1, const void *p2) {
 }
 
 static void
-build_regexp(pcre **r, char *buffer) {
-	const char *error;
-	int error_offset;
+build_regexp(pcre2_code **r, char *buffer) {
+	int error;
+	PCRE2_SIZE error_offset;
 	if (*r)
-		pcre_free(*r);
-	*r = pcre_compile(buffer, PCRE_CASELESS, &error, &error_offset, NULL);
-	if (error) {
-		log_error("pcre=%s, error=%s\n", buffer, error ? error: "none");
+		pcre2_code_free(*r);
+	*r = pcre2_compile((PCRE2_SPTR8) buffer, PCRE2_ZERO_TERMINATED, PCRE2_CASELESS, &error, &error_offset, NULL);
+	if (!*r) {
+		PCRE2_UCHAR errbuf[256];
+  		pcre2_get_error_message(error, errbuf, sizeof(errbuf));
+		log_error("pcre compilation of '%s' failed at offset %zu: %s\n", buffer, error_offset, errbuf);
 	}
 	buffer[0] = '\0';
 }
@@ -1088,12 +1089,12 @@ compute_raw_from_trans(const char *level, domain_t *domain) {
 #endif
 
 	int rc = 0;
-	int ovector[OVECCOUNT];
+	pcre2_match_data *match_data = NULL;
 	word_group_t *g = NULL;
 	char *work = NULL;
 	char *r = NULL;
-	const char * match = NULL;
-	int work_len;
+	char *match = NULL;
+	size_t work_len;
 	mls_level_t *mraw = NULL;
 	ebitmap_t set, clear, tmp;
 
@@ -1114,11 +1115,20 @@ compute_raw_from_trans(const char *level, domain_t *domain) {
 	if (!domain->base_classification_regexp)
 		goto err;
 	log_debug(" compute_raw_from_trans work = %s\n", work);
-	rc = pcre_exec(domain->base_classification_regexp, 0, work, work_len, 0, PCRE_ANCHORED, ovector, OVECCOUNT);
+	match_data = pcre2_match_data_create_from_pattern(domain->base_classification_regexp, NULL);
+	if (!match_data) {
+		log_error("allocation error %s", strerror(errno));
+		goto err;
+	}
+	rc = pcre2_match(domain->base_classification_regexp, (PCRE2_SPTR8)work, work_len, 0, PCRE2_ANCHORED, match_data, NULL);
 	if (rc > 0) {
-		match = NULL;
-		pcre_get_substring(work, ovector, rc, 0, &match);
-		log_debug(" compute_raw_from_trans match = %s len = %u\n", match, strlen(match));
+		const PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);
+		match = strndup(work + ovector[0], ovector[1] - ovector[0]);
+		if (!match) {
+			log_error("allocation error %s", strerror(errno));
+			goto err;
+		}
+		log_debug(" compute_raw_from_trans match = %s len = %zu\n", match, strlen(match));
 		base_classification_t *bc;
 		for (bc = domain->base_classifications; bc; bc = bc->next) {
 			if (!strcmp(bc->trans, match)) {
@@ -1138,12 +1148,23 @@ compute_raw_from_trans(const char *level, domain_t *domain) {
 		char *p=work + ovector[0] + ovector[1];
 		while (*p && (strchr(" 	", *p) != NULL))
 			*p++ = '#';
-		pcre_free((char *)match);
+
+		free(match);
 		match = NULL;
 	} else {
-		log_debug(" compute_raw_from_trans no base classification matched %s\n", level);
+		switch (rc) {
+		case PCRE2_ERROR_NOMATCH:
+			log_debug(" compute_raw_from_trans no base classification matched %s\n", level);
+			break;
+		default:
+			log_error("compute_raw_from_trans: base matching error for input '%s': %d\n", level, rc);
+			break;
+		}		
 	}
 
+	pcre2_match_data_free(match_data);
+	match_data = NULL;
+
 	if (mraw == NULL) {
 		goto err;
 	}
@@ -1154,23 +1175,43 @@ compute_raw_from_trans(const char *level, domain_t *domain) {
 		change = 0;
 		for (g = domain->groups; g && !change && !complete; g = g->next) {
 			int prefix = 0, suffix = 0;
-			int prefix_offset = 0, prefix_len = 0;
-			int suffix_offset = 0, suffix_len = 0;
+			PCRE2_SIZE prefix_offset = 0, prefix_len = 0;
+			PCRE2_SIZE suffix_offset = 0, suffix_len = 0;
 			if (g->prefix_regexp) {
-				rc = pcre_exec(g->prefix_regexp, 0, work, work_len, 0, 0, ovector, OVECCOUNT);
+				match_data = pcre2_match_data_create_from_pattern(g->prefix_regexp, NULL);
+				if (!match_data) {
+					log_error("allocation error %s", strerror(errno));
+					goto err;
+				}
+				rc = pcre2_match(g->prefix_regexp, (PCRE2_SPTR8)work, work_len, 0, 0, match_data, NULL);
 				if (rc > 0) {
+					const PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);
 					prefix = 1;
 					prefix_offset = ovector[0];
 					prefix_len = ovector[1] - ovector[0];
+				} else if (rc != PCRE2_ERROR_NOMATCH) {
+					log_error("compute_raw_from_trans: prefix matching error for input '%s': %d\n", level, rc);
 				}
+				pcre2_match_data_free(match_data);
+				match_data = NULL;
 			}
 			if (g->suffix_regexp) {
-				rc = pcre_exec(g->suffix_regexp, 0, work, work_len, 0, 0, ovector, OVECCOUNT);
+				match_data = pcre2_match_data_create_from_pattern(g->suffix_regexp, NULL);
+				if (!match_data) {
+					log_error("allocation error %s", strerror(errno));
+					goto err;
+				}
+				rc = pcre2_match(g->suffix_regexp, (PCRE2_SPTR8)work, work_len, 0, 0, match_data, NULL);
 				if (rc > 0) {
+					const PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);
 					suffix = 1;
 					suffix_offset = ovector[0];
 					suffix_len = ovector[1] - ovector[0];
+				} else if (rc != PCRE2_ERROR_NOMATCH) {
+					log_error("compute_raw_from_trans: suffix matching error for input '%s': %d\n", level, rc);
 				}
+				pcre2_match_data_free(match_data);
+				match_data = NULL;
 			}
 
 /* anchors prefix ^, suffix $ */
@@ -1179,14 +1220,23 @@ compute_raw_from_trans(const char *level, domain_t *domain) {
 			     (g->suffixes && suffix)) &&
 			     g->word_regexp) {
 				char *s = work + prefix_offset + prefix_len;
-				int l = (suffix_len ? suffix_offset : work_len) - prefix_len - prefix_offset;
-				rc = pcre_exec(g->word_regexp, 0, s, l, 0, 0, ovector, OVECCOUNT);
+				PCRE2_SIZE len = (suffix_len ? suffix_offset : work_len) - prefix_len - prefix_offset;
+				match_data = pcre2_match_data_create_from_pattern(g->word_regexp, NULL);
+				if (!match_data) {
+					log_error("allocation error %s", strerror(errno));
+					goto err;
+				}
+				rc = pcre2_match(g->word_regexp, (PCRE2_SPTR8)s, len, 0, 0, match_data, NULL);
 				if (rc > 0) {
-					match = NULL;
-					pcre_get_substring(s, ovector, rc, 0, &match);
-					trim((char *)match, g->whitespace);
+					const PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);
+					match = strndup(s + ovector[0], ovector[1] - ovector[0]);
+					if (!match) {
+						log_error("allocation error %s", strerror(errno));
+						goto err;
+					}
+					trim(match, g->whitespace);
 					if (*match) {
-						char *p = triml((char *)match, g->whitespace);
+						char *p = triml(match, g->whitespace);
 						while (p && *p) {
 							int plen = strlen(p);
 							unsigned int i;
@@ -1223,9 +1273,13 @@ compute_raw_from_trans(const char *level, domain_t *domain) {
 						memset(work + suffix_offset, '#', suffix_len);
 						memset(s + ovector[0], '#', ovector[1] - ovector[0]);
 					}
-					pcre_free((void *)match);
+					free(match);
 					match = NULL;
+				} else if (rc != PCRE2_ERROR_NOMATCH) {
+					log_error("compute_raw_from_trans: word matching error for input '%s' for substring '%s': %d\n", level, s, rc);
 				}
+				pcre2_match_data_free(match_data);
+				match_data = NULL;
 			}
 /* YYY */
 			complete=1;
@@ -1264,10 +1318,11 @@ err:
 	mls_level_destroy(mraw);
 	free(mraw);
 	free(work);
-	pcre_free((void *)match);
+	free(match);
 	ebitmap_destroy(&tmp);
 	ebitmap_destroy(&set);
 	ebitmap_destroy(&clear);
+	pcre2_match_data_free(match_data);
 	return NULL;
 }
 
diff --git a/mcstrans/utils/Makefile b/mcstrans/utils/Makefile
index 9dfe7723..a48f4e72 100644
--- a/mcstrans/utils/Makefile
+++ b/mcstrans/utils/Makefile
@@ -14,13 +14,13 @@ endif
 all: $(TARGETS)
 
 transcon: transcon.o ../src/mcstrans.o ../src/mls_level.o $(LIBSEPOLA)
-	$(CC) $(LDFLAGS) -o $@ $^ -lpcre -lselinux $(LDLIBS_LIBSEPOLA)
+	$(CC) $(LDFLAGS) -o $@ $^ $(PCRE_LDLIBS) -lselinux $(LDLIBS_LIBSEPOLA)
 
 untranscon: untranscon.o ../src/mcstrans.o ../src/mls_level.o $(LIBSEPOLA)
-	$(CC) $(LDFLAGS) -o $@ $^ -lpcre -lselinux $(LDLIBS_LIBSEPOLA)
+	$(CC) $(LDFLAGS) -o $@ $^ $(PCRE_LDLIBS) -lselinux $(LDLIBS_LIBSEPOLA)
 
 %.o:  %.c 
-	$(CC) $(CFLAGS) -D_GNU_SOURCE -I../src -fPIE -c -o $@ $<
+	$(CC) $(CFLAGS) $(PCRE_CFLAGS) -D_GNU_SOURCE -I../src -fPIE -c -o $@ $<
 
 install: all
 	-mkdir -p $(DESTDIR)$(SBINDIR)
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 1/3] mcstrans: port to new PCRE2 from end-of-life PCRE
  2021-11-30 11:04 ` [PATCH v2 " Christian Göttsche
@ 2021-12-01 15:36   ` Petr Lautrbach
  2021-12-09 17:33     ` James Carter
  0 siblings, 1 reply; 10+ messages in thread
From: Petr Lautrbach @ 2021-12-01 15:36 UTC (permalink / raw)
  To: Christian Göttsche, selinux

Christian Göttsche <cgzones@googlemail.com> writes:

> Quoting pcre.org:
>
>     There are two major versions of the PCRE library. The current
>     version, PCRE2, released in 2015, is now at version 10.39.
>
>     The older, but still widely deployed PCRE library, originally
>     released in 1997, is at version 8.45. This version of PCRE is now at
>     end of life, and is no longer being actively maintained. Version
>     8.45 is expected to be the final release of the older PCRE library,
>     and new projects should use PCRE2 instead.
>
> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>

There's few minor whitespace issues, see inline.

Other than that

Acked-by: Petr Lautrbach <plautrba@redhat.com>

Thanks!


> ---
> v2:
>    - do not use pcre2_substring_get_bynumber(), fixes NATO mcstrans
>      tests (spotted by Petr Lautrbach)
> ---
>  mcstrans/Makefile       |   6 ++
>  mcstrans/src/Makefile   |   4 +-
>  mcstrans/src/mcstrans.c | 131 ++++++++++++++++++++++++++++------------
>  mcstrans/utils/Makefile |   6 +-
>  4 files changed, 104 insertions(+), 43 deletions(-)
>
> diff --git a/mcstrans/Makefile b/mcstrans/Makefile
> index c993a9f5..b20279ab 100644
> --- a/mcstrans/Makefile
> +++ b/mcstrans/Makefile
> @@ -1,3 +1,9 @@
> +PKG_CONFIG ?= pkg-config
> +PCRE_MODULE := libpcre2-8
> +PCRE_CFLAGS := $(shell $(PKG_CONFIG) --cflags $(PCRE_MODULE)) -DPCRE2_CODE_UNIT_WIDTH=8
> +PCRE_LDLIBS := $(shell $(PKG_CONFIG) --libs $(PCRE_MODULE))
> +export PCRE_MODULE PCRE_CFLAGS PCRE_LDLIBS
> +
>  all: 
>  	$(MAKE) -C src 
>  	$(MAKE) -C utils
> diff --git a/mcstrans/src/Makefile b/mcstrans/src/Makefile
> index 76ef0557..ef518625 100644
> --- a/mcstrans/src/Makefile
> +++ b/mcstrans/src/Makefile
> @@ -20,10 +20,10 @@ CFLAGS ?= -Wall -W -Wundef -Wmissing-noreturn -Wmissing-format-attribute
>  all: $(PROG)
>  
>  $(PROG): $(PROG_OBJS) $(LIBSEPOLA)
> -	$(CC) $(LDFLAGS) -pie -o $@ $^ -lselinux -lcap -lpcre $(LDLIBS_LIBSEPOLA)
> +	$(CC) $(LDFLAGS) -pie -o $@ $^ -lselinux -lcap $(PCRE_LDLIBS) $(LDLIBS_LIBSEPOLA)
>  
>  %.o:  %.c 
> -	$(CC) $(CFLAGS) -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -fPIE -c -o $@ $<
> +	$(CC) $(CFLAGS) $(PCRE_CFLAGS) -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -fPIE -c -o $@ $<
>  
>  install: all
>  	test -d $(DESTDIR)$(SBINDIR) || install -m 755 -d $(DESTDIR)$(SBINDIR)
> diff --git a/mcstrans/src/mcstrans.c b/mcstrans/src/mcstrans.c
> index 09577ea0..6e4bfd3b 100644
> --- a/mcstrans/src/mcstrans.c
> +++ b/mcstrans/src/mcstrans.c
> @@ -26,7 +26,7 @@
>  #include <selinux/context.h>
>  #include <syslog.h>
>  #include <errno.h>
> -#include <pcre.h>
> +#include <pcre2.h>
>  #include <ctype.h>
>  #include <time.h>
>  #include <sys/time.h>
> @@ -36,7 +36,6 @@
>  #include "mcstrans.h"
>  
>  #define N_BUCKETS 1453
> -#define OVECCOUNT (512*3)
>  
>  #define log_error(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__)
>  
> @@ -82,9 +81,9 @@ typedef struct word_group {
>  	affix_t *suffixes;
>  	word_t *words;
>  
> -	pcre *prefix_regexp;
> -	pcre *word_regexp;
> -	pcre *suffix_regexp;
> +	pcre2_code *prefix_regexp;
> +	pcre2_code *word_regexp;
> +	pcre2_code *suffix_regexp;
>  
>  	ebitmap_t def;
>  
> @@ -109,7 +108,7 @@ typedef struct domain {
>  	base_classification_t *base_classifications;
>  	word_group_t *groups;
>  
> -	pcre *base_classification_regexp;
> +	pcre2_code *base_classification_regexp;
>  	struct domain *next;
>  } domain_t;
>  
> @@ -317,9 +316,9 @@ destroy_group(word_group_t **list, word_group_t *group) {
>  	free(group->name);
>  	free(group->sword);
>  	free(group->join);
> -	pcre_free(group->prefix_regexp);
> -	pcre_free(group->word_regexp);
> -	pcre_free(group->suffix_regexp);
> +	pcre2_code_free(group->prefix_regexp);
> +	pcre2_code_free(group->word_regexp);
> +	pcre2_code_free(group->suffix_regexp);
>  	ebitmap_destroy(&group->def);
>  	free(group);
>  }
> @@ -392,7 +391,7 @@ destroy_domain(domain_t *domain) {
>  		free(domain->base_classifications);
>  		domain->base_classifications = next;
>  	}
> -	pcre_free(domain->base_classification_regexp);
> +	pcre2_code_free(domain->base_classification_regexp);
>  	while (domain->groups)
>  		destroy_group(&domain->groups, domain->groups);
>  	free(domain->name);
> @@ -963,14 +962,16 @@ word_size(const void *p1, const void *p2) {
>  }
>  
>  static void
> -build_regexp(pcre **r, char *buffer) {
> -	const char *error;
> -	int error_offset;
> +build_regexp(pcre2_code **r, char *buffer) {
> +	int error;
> +	PCRE2_SIZE error_offset;
>  	if (*r)
> -		pcre_free(*r);
> -	*r = pcre_compile(buffer, PCRE_CASELESS, &error, &error_offset, NULL);
> -	if (error) {
> -		log_error("pcre=%s, error=%s\n", buffer, error ? error: "none");
> +		pcre2_code_free(*r);
> +	*r = pcre2_compile((PCRE2_SPTR8) buffer, PCRE2_ZERO_TERMINATED, PCRE2_CASELESS, &error, &error_offset, NULL);
> +	if (!*r) {
> +		PCRE2_UCHAR errbuf[256];
> +  		pcre2_get_error_message(error, errbuf, sizeof(errbuf));

  SELinuxProject/selinux/master/.git/worktrees/patchwork/rebase-apply/patch:127: space before tab in indent.
                  pcre2_get_error_message(error, errbuf, sizeof(errbuf));


> +		log_error("pcre compilation of '%s' failed at offset %zu: %s\n", buffer, error_offset, errbuf);
>  	}
>  	buffer[0] = '\0';
>  }
> @@ -1088,12 +1089,12 @@ compute_raw_from_trans(const char *level, domain_t *domain) {
>  #endif
>  
>  	int rc = 0;
> -	int ovector[OVECCOUNT];
> +	pcre2_match_data *match_data = NULL;
>  	word_group_t *g = NULL;
>  	char *work = NULL;
>  	char *r = NULL;
> -	const char * match = NULL;
> -	int work_len;
> +	char *match = NULL;
> +	size_t work_len;
>  	mls_level_t *mraw = NULL;
>  	ebitmap_t set, clear, tmp;
>  
> @@ -1114,11 +1115,20 @@ compute_raw_from_trans(const char *level, domain_t *domain) {
>  	if (!domain->base_classification_regexp)
>  		goto err;
>  	log_debug(" compute_raw_from_trans work = %s\n", work);
> -	rc = pcre_exec(domain->base_classification_regexp, 0, work, work_len, 0, PCRE_ANCHORED, ovector, OVECCOUNT);
> +	match_data = pcre2_match_data_create_from_pattern(domain->base_classification_regexp, NULL);
> +	if (!match_data) {
> +		log_error("allocation error %s", strerror(errno));
> +		goto err;
> +	}
> +	rc = pcre2_match(domain->base_classification_regexp, (PCRE2_SPTR8)work, work_len, 0, PCRE2_ANCHORED, match_data, NULL);
>  	if (rc > 0) {
> -		match = NULL;
> -		pcre_get_substring(work, ovector, rc, 0, &match);
> -		log_debug(" compute_raw_from_trans match = %s len = %u\n", match, strlen(match));
> +		const PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);
> +		match = strndup(work + ovector[0], ovector[1] - ovector[0]);
> +		if (!match) {
> +			log_error("allocation error %s", strerror(errno));
> +			goto err;
> +		}
> +		log_debug(" compute_raw_from_trans match = %s len = %zu\n", match, strlen(match));
>  		base_classification_t *bc;
>  		for (bc = domain->base_classifications; bc; bc = bc->next) {
>  			if (!strcmp(bc->trans, match)) {
> @@ -1138,12 +1148,23 @@ compute_raw_from_trans(const char *level, domain_t *domain) {
>  		char *p=work + ovector[0] + ovector[1];
>  		while (*p && (strchr(" 	", *p) != NULL))
>  			*p++ = '#';
> -		pcre_free((char *)match);
> +
> +		free(match);
>  		match = NULL;
>  	} else {
> -		log_debug(" compute_raw_from_trans no base classification matched %s\n", level);
> +		switch (rc) {
> +		case PCRE2_ERROR_NOMATCH:
> +			log_debug(" compute_raw_from_trans no base classification matched %s\n", level);
> +			break;
> +		default:
> +			log_error("compute_raw_from_trans: base matching error for input '%s': %d\n", level, rc);
> +			break;
> +		}		
>  	}
>

  SELinuxProject/selinux/master/.git/worktrees/patchwork/rebase-apply/patch:190: trailing whitespace.



>  
> +	pcre2_match_data_free(match_data);
> +	match_data = NULL;
> +
>  	if (mraw == NULL) {
>  		goto err;
>  	}
> @@ -1154,23 +1175,43 @@ compute_raw_from_trans(const char *level, domain_t *domain) {
>  		change = 0;
>  		for (g = domain->groups; g && !change && !complete; g = g->next) {
>  			int prefix = 0, suffix = 0;
> -			int prefix_offset = 0, prefix_len = 0;
> -			int suffix_offset = 0, suffix_len = 0;
> +			PCRE2_SIZE prefix_offset = 0, prefix_len = 0;
> +			PCRE2_SIZE suffix_offset = 0, suffix_len = 0;
>  			if (g->prefix_regexp) {
> -				rc = pcre_exec(g->prefix_regexp, 0, work, work_len, 0, 0, ovector, OVECCOUNT);
> +				match_data = pcre2_match_data_create_from_pattern(g->prefix_regexp, NULL);
> +				if (!match_data) {
> +					log_error("allocation error %s", strerror(errno));
> +					goto err;
> +				}
> +				rc = pcre2_match(g->prefix_regexp, (PCRE2_SPTR8)work, work_len, 0, 0, match_data, NULL);
>  				if (rc > 0) {
> +					const PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);
>  					prefix = 1;
>  					prefix_offset = ovector[0];
>  					prefix_len = ovector[1] - ovector[0];
> +				} else if (rc != PCRE2_ERROR_NOMATCH) {
> +					log_error("compute_raw_from_trans: prefix matching error for input '%s': %d\n", level, rc);
>  				}
> +				pcre2_match_data_free(match_data);
> +				match_data = NULL;
>  			}
>  			if (g->suffix_regexp) {
> -				rc = pcre_exec(g->suffix_regexp, 0, work, work_len, 0, 0, ovector, OVECCOUNT);
> +				match_data = pcre2_match_data_create_from_pattern(g->suffix_regexp, NULL);
> +				if (!match_data) {
> +					log_error("allocation error %s", strerror(errno));
> +					goto err;
> +				}
> +				rc = pcre2_match(g->suffix_regexp, (PCRE2_SPTR8)work, work_len, 0, 0, match_data, NULL);
>  				if (rc > 0) {
> +					const PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);
>  					suffix = 1;
>  					suffix_offset = ovector[0];
>  					suffix_len = ovector[1] - ovector[0];
> +				} else if (rc != PCRE2_ERROR_NOMATCH) {
> +					log_error("compute_raw_from_trans: suffix matching error for input '%s': %d\n", level, rc);
>  				}
> +				pcre2_match_data_free(match_data);
> +				match_data = NULL;
>  			}
>  
>  /* anchors prefix ^, suffix $ */
> @@ -1179,14 +1220,23 @@ compute_raw_from_trans(const char *level, domain_t *domain) {
>  			     (g->suffixes && suffix)) &&
>  			     g->word_regexp) {
>  				char *s = work + prefix_offset + prefix_len;
> -				int l = (suffix_len ? suffix_offset : work_len) - prefix_len - prefix_offset;
> -				rc = pcre_exec(g->word_regexp, 0, s, l, 0, 0, ovector, OVECCOUNT);
> +				PCRE2_SIZE len = (suffix_len ? suffix_offset : work_len) - prefix_len - prefix_offset;
> +				match_data = pcre2_match_data_create_from_pattern(g->word_regexp, NULL);
> +				if (!match_data) {
> +					log_error("allocation error %s", strerror(errno));
> +					goto err;
> +				}
> +				rc = pcre2_match(g->word_regexp, (PCRE2_SPTR8)s, len, 0, 0, match_data, NULL);
>  				if (rc > 0) {
> -					match = NULL;
> -					pcre_get_substring(s, ovector, rc, 0, &match);
> -					trim((char *)match, g->whitespace);
> +					const PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);
> +					match = strndup(s + ovector[0], ovector[1] - ovector[0]);
> +					if (!match) {
> +						log_error("allocation error %s", strerror(errno));
> +						goto err;
> +					}
> +					trim(match, g->whitespace);
>  					if (*match) {
> -						char *p = triml((char *)match, g->whitespace);
> +						char *p = triml(match, g->whitespace);
>  						while (p && *p) {
>  							int plen = strlen(p);
>  							unsigned int i;
> @@ -1223,9 +1273,13 @@ compute_raw_from_trans(const char *level, domain_t *domain) {
>  						memset(work + suffix_offset, '#', suffix_len);
>  						memset(s + ovector[0], '#', ovector[1] - ovector[0]);
>  					}
> -					pcre_free((void *)match);
> +					free(match);
>  					match = NULL;
> +				} else if (rc != PCRE2_ERROR_NOMATCH) {
> +					log_error("compute_raw_from_trans: word matching error for input '%s' for substring '%s': %d\n", level, s, rc);
>  				}
> +				pcre2_match_data_free(match_data);
> +				match_data = NULL;
>  			}
>  /* YYY */
>  			complete=1;
> @@ -1264,10 +1318,11 @@ err:
>  	mls_level_destroy(mraw);
>  	free(mraw);
>  	free(work);
> -	pcre_free((void *)match);
> +	free(match);
>  	ebitmap_destroy(&tmp);
>  	ebitmap_destroy(&set);
>  	ebitmap_destroy(&clear);
> +	pcre2_match_data_free(match_data);
>  	return NULL;
>  }
>  
> diff --git a/mcstrans/utils/Makefile b/mcstrans/utils/Makefile
> index 9dfe7723..a48f4e72 100644
> --- a/mcstrans/utils/Makefile
> +++ b/mcstrans/utils/Makefile
> @@ -14,13 +14,13 @@ endif
>  all: $(TARGETS)
>  
>  transcon: transcon.o ../src/mcstrans.o ../src/mls_level.o $(LIBSEPOLA)
> -	$(CC) $(LDFLAGS) -o $@ $^ -lpcre -lselinux $(LDLIBS_LIBSEPOLA)
> +	$(CC) $(LDFLAGS) -o $@ $^ $(PCRE_LDLIBS) -lselinux $(LDLIBS_LIBSEPOLA)
>  
>  untranscon: untranscon.o ../src/mcstrans.o ../src/mls_level.o $(LIBSEPOLA)
> -	$(CC) $(LDFLAGS) -o $@ $^ -lpcre -lselinux $(LDLIBS_LIBSEPOLA)
> +	$(CC) $(LDFLAGS) -o $@ $^ $(PCRE_LDLIBS) -lselinux $(LDLIBS_LIBSEPOLA)
>  
>  %.o:  %.c 
> -	$(CC) $(CFLAGS) -D_GNU_SOURCE -I../src -fPIE -c -o $@ $<
> +	$(CC) $(CFLAGS) $(PCRE_CFLAGS) -D_GNU_SOURCE -I../src -fPIE -c -o $@ $<
>  
>  install: all
>  	-mkdir -p $(DESTDIR)$(SBINDIR)
> -- 
> 2.34.1


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/3] libselinux: use PCRE2 by default
  2021-11-23 18:32 ` [PATCH 2/3] libselinux: use PCRE2 by default Christian Göttsche
  2021-11-24 17:06   ` Petr Lautrbach
@ 2021-12-01 15:56   ` Petr Lautrbach
  1 sibling, 0 replies; 10+ messages in thread
From: Petr Lautrbach @ 2021-12-01 15:56 UTC (permalink / raw)
  To: Christian Göttsche, selinux

Christian Göttsche <cgzones@googlemail.com> writes:

> Quoting pcre.org:
>
>     There are two major versions of the PCRE library. The current
>     version, PCRE2, released in 2015, is now at version 10.39.
>
>     The older, but still widely deployed PCRE library, originally
>     released in 1997, is at version 8.45. This version of PCRE is now at
>     end of life, and is no longer being actively maintained. Version
>     8.45 is expected to be the final release of the older PCRE library,
>     and new projects should use PCRE2 instead.
>
> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>

Acked-by: Petr Lautrbach <plautrba@redhat.com>



> ---
>  libselinux/Makefile       | 2 +-
>  libselinux/src/Makefile   | 1 -
>  libselinux/utils/Makefile | 1 -
>  3 files changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/libselinux/Makefile b/libselinux/Makefile
> index 439bc6a9..6d9e2736 100644
> --- a/libselinux/Makefile
> +++ b/libselinux/Makefile
> @@ -23,7 +23,7 @@ ifeq ($(DISABLE_X11),y)
>  endif
>  export DISABLE_SETRANS DISABLE_RPM DISABLE_FLAGS ANDROID_HOST DISABLE_X11 LABEL_BACKEND_ANDROID
>  
> -USE_PCRE2 ?= n
> +USE_PCRE2 ?= y
>  ifeq ($(USE_PCRE2),y)
>  	PCRE_MODULE := libpcre2-8
>  	PCRE_CFLAGS := -DUSE_PCRE2 -DPCRE2_CODE_UNIT_WIDTH=8
> diff --git a/libselinux/src/Makefile b/libselinux/src/Makefile
> index 52c40f01..04bf4f24 100644
> --- a/libselinux/src/Makefile
> +++ b/libselinux/src/Makefile
> @@ -98,7 +98,6 @@ override LDFLAGS += -L/opt/local/lib -undefined dynamic_lookup
>  LD_SONAME_FLAGS=-install_name,$(LIBSO)
>  endif
>  
> -PCRE_LDLIBS ?= -lpcre
>  # override with -lfts when building on Musl libc to use fts-standalone
>  FTS_LDLIBS ?=
>  
> diff --git a/libselinux/utils/Makefile b/libselinux/utils/Makefile
> index 36816155..801066cb 100644
> --- a/libselinux/utils/Makefile
> +++ b/libselinux/utils/Makefile
> @@ -44,7 +44,6 @@ endif
>  override CFLAGS += -I../include -D_GNU_SOURCE $(DISABLE_FLAGS) $(PCRE_CFLAGS)
>  override LDFLAGS += -L../src
>  override LDLIBS += -lselinux $(FTS_LDLIBS)
> -PCRE_LDLIBS ?= -lpcre
>  
>  ifeq ($(ANDROID_HOST),y)
>  TARGETS=sefcontext_compile
> -- 
> 2.34.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 3/3] Replace PCRE with PCRE2 build dependencies
  2021-11-23 18:32 ` [PATCH 3/3] Replace PCRE with PCRE2 build dependencies Christian Göttsche
@ 2021-12-01 15:57   ` Petr Lautrbach
  0 siblings, 0 replies; 10+ messages in thread
From: Petr Lautrbach @ 2021-12-01 15:57 UTC (permalink / raw)
  To: Christian Göttsche, selinux

Christian Göttsche <cgzones@googlemail.com> writes:

> Now that libselinux defaults to PCRE2 and mcstrans has been ported,
> update all documentation and scripts.
>
> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>

Acked-by: Petr Lautrbach <plautrba@redhat.com>



> ---
>  .circleci/config.yml             | 2 +-
>  .github/workflows/run_tests.yml  | 2 +-
>  CONTRIBUTING.md                  | 2 +-
>  README.md                        | 4 ++--
>  scripts/ci/fedora-test-runner.sh | 2 +-
>  5 files changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/.circleci/config.yml b/.circleci/config.yml
> index 5d3177da..af20484b 100644
> --- a/.circleci/config.yml
> +++ b/.circleci/config.yml
> @@ -13,7 +13,7 @@ jobs:
>  
>      # Install dependencies
>      - run: sudo apt-get update -qq
> -    - run: sudo apt-get install -qq bison clang clang-tools flex gawk gettext libaudit-dev libcap-dev libcap-ng-dev libcunit1-dev libdbus-glib-1-dev libpcre3-dev python3-dev python-dev ruby-dev swig xmlto
> +    - run: sudo apt-get install -qq bison clang clang-tools flex gawk gettext libaudit-dev libcap-dev libcap-ng-dev libcunit1-dev libdbus-glib-1-dev libpcre2-dev python3-dev python-dev ruby-dev swig xmlto
>  
>      - run:
>          name: Setup environment variables
> diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml
> index ef4be8af..01fbbbe5 100644
> --- a/.github/workflows/run_tests.yml
> +++ b/.github/workflows/run_tests.yml
> @@ -57,7 +57,7 @@ jobs:
>              libcap-ng-dev \
>              libcunit1-dev \
>              libdbus-glib-1-dev \
> -            libpcre3-dev \
> +            libpcre2-dev \
>              python3-dev \
>              python-dev \
>              ruby-dev \
> diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
> index a3517cb8..7c548e58 100644
> --- a/CONTRIBUTING.md
> +++ b/CONTRIBUTING.md
> @@ -26,7 +26,7 @@ using a custom policy please include it as well.
>  There are a number of dependencies required to build the userspace
>  tools/libraries. On a Fedora system you can install them with yum:
>  
> -    # yum install audit-libs-devel bison bzip2-devel dbus-devel dbus-glib-devel flex flex-devel flex-static glib2-devel libcap-devel libcap-ng-devel pam-devel pcre-devel python-devel setools-devel swig ustr-devel
> +    # yum install audit-libs-devel bison bzip2-devel dbus-devel dbus-glib-devel flex flex-devel flex-static glib2-devel libcap-devel libcap-ng-devel pam-devel pcre2-devel python-devel setools-devel swig ustr-devel
>  
>  The tools and libraries can be built and installed under a private directory from the top level with make, e.g.
>  
> diff --git a/README.md b/README.md
> index e1c2fe64..74b0a0c3 100644
> --- a/README.md
> +++ b/README.md
> @@ -51,7 +51,7 @@ dnf install \
>      libcap-devel \
>      libcap-ng-devel \
>      pam-devel \
> -    pcre-devel \
> +    pcre2-devel \
>      xmlto
>  
>  # For Python and Ruby bindings
> @@ -78,7 +78,7 @@ apt-get install --no-install-recommends --no-install-suggests \
>      libcap-ng-dev \
>      libcunit1-dev \
>      libglib2.0-dev \
> -    libpcre3-dev \
> +    libpcre2-dev \
>      pkgconf \
>      python3 \
>      python3-distutils \
> diff --git a/scripts/ci/fedora-test-runner.sh b/scripts/ci/fedora-test-runner.sh
> index f817499b..3ce2c3a6 100755
> --- a/scripts/ci/fedora-test-runner.sh
> +++ b/scripts/ci/fedora-test-runner.sh
> @@ -36,7 +36,7 @@ dnf install -y \
>      libcap-devel \
>      libcap-ng-devel \
>      pam-devel \
> -    pcre-devel \
> +    pcre2-devel \
>      xmlto \
>      python3-devel \
>      ruby-devel \
> -- 
> 2.34.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 1/3] mcstrans: port to new PCRE2 from end-of-life PCRE
  2021-12-01 15:36   ` Petr Lautrbach
@ 2021-12-09 17:33     ` James Carter
  0 siblings, 0 replies; 10+ messages in thread
From: James Carter @ 2021-12-09 17:33 UTC (permalink / raw)
  To: Petr Lautrbach; +Cc: Christian Göttsche, SElinux list

On Fri, Dec 3, 2021 at 2:43 AM Petr Lautrbach <plautrba@redhat.com> wrote:
>
> Christian Göttsche <cgzones@googlemail.com> writes:
>
> > Quoting pcre.org:
> >
> >     There are two major versions of the PCRE library. The current
> >     version, PCRE2, released in 2015, is now at version 10.39.
> >
> >     The older, but still widely deployed PCRE library, originally
> >     released in 1997, is at version 8.45. This version of PCRE is now at
> >     end of life, and is no longer being actively maintained. Version
> >     8.45 is expected to be the final release of the older PCRE library,
> >     and new projects should use PCRE2 instead.
> >
> > Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
>
> There's few minor whitespace issues, see inline.
>
> Other than that
>
> Acked-by: Petr Lautrbach <plautrba@redhat.com>
>

I fixed the whitespace issues and merged this series.
Thanks,
Jim

> Thanks!
>
>
> > ---
> > v2:
> >    - do not use pcre2_substring_get_bynumber(), fixes NATO mcstrans
> >      tests (spotted by Petr Lautrbach)
> > ---
> >  mcstrans/Makefile       |   6 ++
> >  mcstrans/src/Makefile   |   4 +-
> >  mcstrans/src/mcstrans.c | 131 ++++++++++++++++++++++++++++------------
> >  mcstrans/utils/Makefile |   6 +-
> >  4 files changed, 104 insertions(+), 43 deletions(-)
> >
> > diff --git a/mcstrans/Makefile b/mcstrans/Makefile
> > index c993a9f5..b20279ab 100644
> > --- a/mcstrans/Makefile
> > +++ b/mcstrans/Makefile
> > @@ -1,3 +1,9 @@
> > +PKG_CONFIG ?= pkg-config
> > +PCRE_MODULE := libpcre2-8
> > +PCRE_CFLAGS := $(shell $(PKG_CONFIG) --cflags $(PCRE_MODULE)) -DPCRE2_CODE_UNIT_WIDTH=8
> > +PCRE_LDLIBS := $(shell $(PKG_CONFIG) --libs $(PCRE_MODULE))
> > +export PCRE_MODULE PCRE_CFLAGS PCRE_LDLIBS
> > +
> >  all:
> >       $(MAKE) -C src
> >       $(MAKE) -C utils
> > diff --git a/mcstrans/src/Makefile b/mcstrans/src/Makefile
> > index 76ef0557..ef518625 100644
> > --- a/mcstrans/src/Makefile
> > +++ b/mcstrans/src/Makefile
> > @@ -20,10 +20,10 @@ CFLAGS ?= -Wall -W -Wundef -Wmissing-noreturn -Wmissing-format-attribute
> >  all: $(PROG)
> >
> >  $(PROG): $(PROG_OBJS) $(LIBSEPOLA)
> > -     $(CC) $(LDFLAGS) -pie -o $@ $^ -lselinux -lcap -lpcre $(LDLIBS_LIBSEPOLA)
> > +     $(CC) $(LDFLAGS) -pie -o $@ $^ -lselinux -lcap $(PCRE_LDLIBS) $(LDLIBS_LIBSEPOLA)
> >
> >  %.o:  %.c
> > -     $(CC) $(CFLAGS) -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -fPIE -c -o $@ $<
> > +     $(CC) $(CFLAGS) $(PCRE_CFLAGS) -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -fPIE -c -o $@ $<
> >
> >  install: all
> >       test -d $(DESTDIR)$(SBINDIR) || install -m 755 -d $(DESTDIR)$(SBINDIR)
> > diff --git a/mcstrans/src/mcstrans.c b/mcstrans/src/mcstrans.c
> > index 09577ea0..6e4bfd3b 100644
> > --- a/mcstrans/src/mcstrans.c
> > +++ b/mcstrans/src/mcstrans.c
> > @@ -26,7 +26,7 @@
> >  #include <selinux/context.h>
> >  #include <syslog.h>
> >  #include <errno.h>
> > -#include <pcre.h>
> > +#include <pcre2.h>
> >  #include <ctype.h>
> >  #include <time.h>
> >  #include <sys/time.h>
> > @@ -36,7 +36,6 @@
> >  #include "mcstrans.h"
> >
> >  #define N_BUCKETS 1453
> > -#define OVECCOUNT (512*3)
> >
> >  #define log_error(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__)
> >
> > @@ -82,9 +81,9 @@ typedef struct word_group {
> >       affix_t *suffixes;
> >       word_t *words;
> >
> > -     pcre *prefix_regexp;
> > -     pcre *word_regexp;
> > -     pcre *suffix_regexp;
> > +     pcre2_code *prefix_regexp;
> > +     pcre2_code *word_regexp;
> > +     pcre2_code *suffix_regexp;
> >
> >       ebitmap_t def;
> >
> > @@ -109,7 +108,7 @@ typedef struct domain {
> >       base_classification_t *base_classifications;
> >       word_group_t *groups;
> >
> > -     pcre *base_classification_regexp;
> > +     pcre2_code *base_classification_regexp;
> >       struct domain *next;
> >  } domain_t;
> >
> > @@ -317,9 +316,9 @@ destroy_group(word_group_t **list, word_group_t *group) {
> >       free(group->name);
> >       free(group->sword);
> >       free(group->join);
> > -     pcre_free(group->prefix_regexp);
> > -     pcre_free(group->word_regexp);
> > -     pcre_free(group->suffix_regexp);
> > +     pcre2_code_free(group->prefix_regexp);
> > +     pcre2_code_free(group->word_regexp);
> > +     pcre2_code_free(group->suffix_regexp);
> >       ebitmap_destroy(&group->def);
> >       free(group);
> >  }
> > @@ -392,7 +391,7 @@ destroy_domain(domain_t *domain) {
> >               free(domain->base_classifications);
> >               domain->base_classifications = next;
> >       }
> > -     pcre_free(domain->base_classification_regexp);
> > +     pcre2_code_free(domain->base_classification_regexp);
> >       while (domain->groups)
> >               destroy_group(&domain->groups, domain->groups);
> >       free(domain->name);
> > @@ -963,14 +962,16 @@ word_size(const void *p1, const void *p2) {
> >  }
> >
> >  static void
> > -build_regexp(pcre **r, char *buffer) {
> > -     const char *error;
> > -     int error_offset;
> > +build_regexp(pcre2_code **r, char *buffer) {
> > +     int error;
> > +     PCRE2_SIZE error_offset;
> >       if (*r)
> > -             pcre_free(*r);
> > -     *r = pcre_compile(buffer, PCRE_CASELESS, &error, &error_offset, NULL);
> > -     if (error) {
> > -             log_error("pcre=%s, error=%s\n", buffer, error ? error: "none");
> > +             pcre2_code_free(*r);
> > +     *r = pcre2_compile((PCRE2_SPTR8) buffer, PCRE2_ZERO_TERMINATED, PCRE2_CASELESS, &error, &error_offset, NULL);
> > +     if (!*r) {
> > +             PCRE2_UCHAR errbuf[256];
> > +             pcre2_get_error_message(error, errbuf, sizeof(errbuf));
>
>   SELinuxProject/selinux/master/.git/worktrees/patchwork/rebase-apply/patch:127: space before tab in indent.
>                   pcre2_get_error_message(error, errbuf, sizeof(errbuf));
>
>
> > +             log_error("pcre compilation of '%s' failed at offset %zu: %s\n", buffer, error_offset, errbuf);
> >       }
> >       buffer[0] = '\0';
> >  }
> > @@ -1088,12 +1089,12 @@ compute_raw_from_trans(const char *level, domain_t *domain) {
> >  #endif
> >
> >       int rc = 0;
> > -     int ovector[OVECCOUNT];
> > +     pcre2_match_data *match_data = NULL;
> >       word_group_t *g = NULL;
> >       char *work = NULL;
> >       char *r = NULL;
> > -     const char * match = NULL;
> > -     int work_len;
> > +     char *match = NULL;
> > +     size_t work_len;
> >       mls_level_t *mraw = NULL;
> >       ebitmap_t set, clear, tmp;
> >
> > @@ -1114,11 +1115,20 @@ compute_raw_from_trans(const char *level, domain_t *domain) {
> >       if (!domain->base_classification_regexp)
> >               goto err;
> >       log_debug(" compute_raw_from_trans work = %s\n", work);
> > -     rc = pcre_exec(domain->base_classification_regexp, 0, work, work_len, 0, PCRE_ANCHORED, ovector, OVECCOUNT);
> > +     match_data = pcre2_match_data_create_from_pattern(domain->base_classification_regexp, NULL);
> > +     if (!match_data) {
> > +             log_error("allocation error %s", strerror(errno));
> > +             goto err;
> > +     }
> > +     rc = pcre2_match(domain->base_classification_regexp, (PCRE2_SPTR8)work, work_len, 0, PCRE2_ANCHORED, match_data, NULL);
> >       if (rc > 0) {
> > -             match = NULL;
> > -             pcre_get_substring(work, ovector, rc, 0, &match);
> > -             log_debug(" compute_raw_from_trans match = %s len = %u\n", match, strlen(match));
> > +             const PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);
> > +             match = strndup(work + ovector[0], ovector[1] - ovector[0]);
> > +             if (!match) {
> > +                     log_error("allocation error %s", strerror(errno));
> > +                     goto err;
> > +             }
> > +             log_debug(" compute_raw_from_trans match = %s len = %zu\n", match, strlen(match));
> >               base_classification_t *bc;
> >               for (bc = domain->base_classifications; bc; bc = bc->next) {
> >                       if (!strcmp(bc->trans, match)) {
> > @@ -1138,12 +1148,23 @@ compute_raw_from_trans(const char *level, domain_t *domain) {
> >               char *p=work + ovector[0] + ovector[1];
> >               while (*p && (strchr("  ", *p) != NULL))
> >                       *p++ = '#';
> > -             pcre_free((char *)match);
> > +
> > +             free(match);
> >               match = NULL;
> >       } else {
> > -             log_debug(" compute_raw_from_trans no base classification matched %s\n", level);
> > +             switch (rc) {
> > +             case PCRE2_ERROR_NOMATCH:
> > +                     log_debug(" compute_raw_from_trans no base classification matched %s\n", level);
> > +                     break;
> > +             default:
> > +                     log_error("compute_raw_from_trans: base matching error for input '%s': %d\n", level, rc);
> > +                     break;
> > +             }
> >       }
> >
>
>   SELinuxProject/selinux/master/.git/worktrees/patchwork/rebase-apply/patch:190: trailing whitespace.
>
>
>
> >
> > +     pcre2_match_data_free(match_data);
> > +     match_data = NULL;
> > +
> >       if (mraw == NULL) {
> >               goto err;
> >       }
> > @@ -1154,23 +1175,43 @@ compute_raw_from_trans(const char *level, domain_t *domain) {
> >               change = 0;
> >               for (g = domain->groups; g && !change && !complete; g = g->next) {
> >                       int prefix = 0, suffix = 0;
> > -                     int prefix_offset = 0, prefix_len = 0;
> > -                     int suffix_offset = 0, suffix_len = 0;
> > +                     PCRE2_SIZE prefix_offset = 0, prefix_len = 0;
> > +                     PCRE2_SIZE suffix_offset = 0, suffix_len = 0;
> >                       if (g->prefix_regexp) {
> > -                             rc = pcre_exec(g->prefix_regexp, 0, work, work_len, 0, 0, ovector, OVECCOUNT);
> > +                             match_data = pcre2_match_data_create_from_pattern(g->prefix_regexp, NULL);
> > +                             if (!match_data) {
> > +                                     log_error("allocation error %s", strerror(errno));
> > +                                     goto err;
> > +                             }
> > +                             rc = pcre2_match(g->prefix_regexp, (PCRE2_SPTR8)work, work_len, 0, 0, match_data, NULL);
> >                               if (rc > 0) {
> > +                                     const PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);
> >                                       prefix = 1;
> >                                       prefix_offset = ovector[0];
> >                                       prefix_len = ovector[1] - ovector[0];
> > +                             } else if (rc != PCRE2_ERROR_NOMATCH) {
> > +                                     log_error("compute_raw_from_trans: prefix matching error for input '%s': %d\n", level, rc);
> >                               }
> > +                             pcre2_match_data_free(match_data);
> > +                             match_data = NULL;
> >                       }
> >                       if (g->suffix_regexp) {
> > -                             rc = pcre_exec(g->suffix_regexp, 0, work, work_len, 0, 0, ovector, OVECCOUNT);
> > +                             match_data = pcre2_match_data_create_from_pattern(g->suffix_regexp, NULL);
> > +                             if (!match_data) {
> > +                                     log_error("allocation error %s", strerror(errno));
> > +                                     goto err;
> > +                             }
> > +                             rc = pcre2_match(g->suffix_regexp, (PCRE2_SPTR8)work, work_len, 0, 0, match_data, NULL);
> >                               if (rc > 0) {
> > +                                     const PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);
> >                                       suffix = 1;
> >                                       suffix_offset = ovector[0];
> >                                       suffix_len = ovector[1] - ovector[0];
> > +                             } else if (rc != PCRE2_ERROR_NOMATCH) {
> > +                                     log_error("compute_raw_from_trans: suffix matching error for input '%s': %d\n", level, rc);
> >                               }
> > +                             pcre2_match_data_free(match_data);
> > +                             match_data = NULL;
> >                       }
> >
> >  /* anchors prefix ^, suffix $ */
> > @@ -1179,14 +1220,23 @@ compute_raw_from_trans(const char *level, domain_t *domain) {
> >                            (g->suffixes && suffix)) &&
> >                            g->word_regexp) {
> >                               char *s = work + prefix_offset + prefix_len;
> > -                             int l = (suffix_len ? suffix_offset : work_len) - prefix_len - prefix_offset;
> > -                             rc = pcre_exec(g->word_regexp, 0, s, l, 0, 0, ovector, OVECCOUNT);
> > +                             PCRE2_SIZE len = (suffix_len ? suffix_offset : work_len) - prefix_len - prefix_offset;
> > +                             match_data = pcre2_match_data_create_from_pattern(g->word_regexp, NULL);
> > +                             if (!match_data) {
> > +                                     log_error("allocation error %s", strerror(errno));
> > +                                     goto err;
> > +                             }
> > +                             rc = pcre2_match(g->word_regexp, (PCRE2_SPTR8)s, len, 0, 0, match_data, NULL);
> >                               if (rc > 0) {
> > -                                     match = NULL;
> > -                                     pcre_get_substring(s, ovector, rc, 0, &match);
> > -                                     trim((char *)match, g->whitespace);
> > +                                     const PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);
> > +                                     match = strndup(s + ovector[0], ovector[1] - ovector[0]);
> > +                                     if (!match) {
> > +                                             log_error("allocation error %s", strerror(errno));
> > +                                             goto err;
> > +                                     }
> > +                                     trim(match, g->whitespace);
> >                                       if (*match) {
> > -                                             char *p = triml((char *)match, g->whitespace);
> > +                                             char *p = triml(match, g->whitespace);
> >                                               while (p && *p) {
> >                                                       int plen = strlen(p);
> >                                                       unsigned int i;
> > @@ -1223,9 +1273,13 @@ compute_raw_from_trans(const char *level, domain_t *domain) {
> >                                               memset(work + suffix_offset, '#', suffix_len);
> >                                               memset(s + ovector[0], '#', ovector[1] - ovector[0]);
> >                                       }
> > -                                     pcre_free((void *)match);
> > +                                     free(match);
> >                                       match = NULL;
> > +                             } else if (rc != PCRE2_ERROR_NOMATCH) {
> > +                                     log_error("compute_raw_from_trans: word matching error for input '%s' for substring '%s': %d\n", level, s, rc);
> >                               }
> > +                             pcre2_match_data_free(match_data);
> > +                             match_data = NULL;
> >                       }
> >  /* YYY */
> >                       complete=1;
> > @@ -1264,10 +1318,11 @@ err:
> >       mls_level_destroy(mraw);
> >       free(mraw);
> >       free(work);
> > -     pcre_free((void *)match);
> > +     free(match);
> >       ebitmap_destroy(&tmp);
> >       ebitmap_destroy(&set);
> >       ebitmap_destroy(&clear);
> > +     pcre2_match_data_free(match_data);
> >       return NULL;
> >  }
> >
> > diff --git a/mcstrans/utils/Makefile b/mcstrans/utils/Makefile
> > index 9dfe7723..a48f4e72 100644
> > --- a/mcstrans/utils/Makefile
> > +++ b/mcstrans/utils/Makefile
> > @@ -14,13 +14,13 @@ endif
> >  all: $(TARGETS)
> >
> >  transcon: transcon.o ../src/mcstrans.o ../src/mls_level.o $(LIBSEPOLA)
> > -     $(CC) $(LDFLAGS) -o $@ $^ -lpcre -lselinux $(LDLIBS_LIBSEPOLA)
> > +     $(CC) $(LDFLAGS) -o $@ $^ $(PCRE_LDLIBS) -lselinux $(LDLIBS_LIBSEPOLA)
> >
> >  untranscon: untranscon.o ../src/mcstrans.o ../src/mls_level.o $(LIBSEPOLA)
> > -     $(CC) $(LDFLAGS) -o $@ $^ -lpcre -lselinux $(LDLIBS_LIBSEPOLA)
> > +     $(CC) $(LDFLAGS) -o $@ $^ $(PCRE_LDLIBS) -lselinux $(LDLIBS_LIBSEPOLA)
> >
> >  %.o:  %.c
> > -     $(CC) $(CFLAGS) -D_GNU_SOURCE -I../src -fPIE -c -o $@ $<
> > +     $(CC) $(CFLAGS) $(PCRE_CFLAGS) -D_GNU_SOURCE -I../src -fPIE -c -o $@ $<
> >
> >  install: all
> >       -mkdir -p $(DESTDIR)$(SBINDIR)
> > --
> > 2.34.1
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2021-12-09 17:33 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-23 18:32 [PATCH 1/3] mcstrans: port to new PCRE2 from end-of-life PCRE Christian Göttsche
2021-11-23 18:32 ` [PATCH 2/3] libselinux: use PCRE2 by default Christian Göttsche
2021-11-24 17:06   ` Petr Lautrbach
2021-12-01 15:56   ` Petr Lautrbach
2021-11-23 18:32 ` [PATCH 3/3] Replace PCRE with PCRE2 build dependencies Christian Göttsche
2021-12-01 15:57   ` Petr Lautrbach
2021-11-29 10:05 ` [PATCH 1/3] mcstrans: port to new PCRE2 from end-of-life PCRE Petr Lautrbach
2021-11-30 11:04 ` [PATCH v2 " Christian Göttsche
2021-12-01 15:36   ` Petr Lautrbach
2021-12-09 17:33     ` James Carter

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.