From b70e5bf5bfa5fa2c2fffe08bcf300da1d3583602 Mon Sep 17 00:00:00 2001
From: Lars Ellenberg <lars.ellenberg@linbit.com>
Date: Wed, 9 Nov 2022 11:01:54 +0100
Subject: [PATCH 2/2] drbdadm: drop use of GLOB_MAGCHAR, use strchr heuristic only

Fixup for
2022-09-05 4a1b5900 drbdadm: allow files from an expanded include glob to vanish

When using the `include` statement, if the glob did not match any file,
there is nothing to do, silently ignore.  Unless it was no glob, but a literal,
which we would expect to exist.

Also, there is a race between expanding a glob and accessing the file.
That also should not happen for literals, though.

Since we still had the heuristic anyways, because apparently |GLOB_MAGCHAR
does not happen for GLOB_NOMATCH returns, and there exist non-GNU libc that
don't (and likely won't) implement that extension, just forget about
(gl_flags & GLOB_MAGCHAR) but use the incomplete strchr heuristic only.

Sourced From Alpine: https://git.alpinelinux.org/aports/tree/main/drbd-utils/drop_use_of_GLOB_MAGCHAR.patch

Upstream-Status: Pending
Signed-off-by: Khem Raj <raj.khem@gmail.com>
---
 user/v9/drbdadm_parser.c | 35 ++++++++++++++++++++---------------
 1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/user/v9/drbdadm_parser.c b/user/v9/drbdadm_parser.c
index b2f6ed8a..9a0a775d 100644
--- a/user/v9/drbdadm_parser.c
+++ b/user/v9/drbdadm_parser.c
@@ -1947,14 +1947,29 @@ void include_stmt(char *str)
 	size_t i;
 	int r;
 
-	cwd = pushd_to_current_config_file_unless_stdin();
-
-	/* """
+	/*
+	 * If the glob did not match any file,
+	 * there is nothing to do, silently ignore.
+	 * Unless it was no glob, but a literal,
+	 * which we would expect to exist.
+	 *
+	 * """
 	 * As a GNU extension, pglob->gl_flags is set to the
 	 * flags specified, ored with GLOB_MAGCHAR if any
 	 * metacharacters were found.
 	 * """
+	 *
+	 * But apparently |GLOB_MAGCHAR does not happen for GLOB_NOMATCH returns,
+	 * at least not consistently :-(
+	 * Also, there exist non-GNU libc
+	 * So we have this incomplete strchr heuristic anyways.
 	 */
+	bool contains_glob_magic_char =
+			strchr(str, '*') ||
+			strchr(str, '?') ||
+			strchr(str, '[');
+
+	cwd = pushd_to_current_config_file_unless_stdin();
 	r = glob(str, 0, NULL, &glob_buf);
 	if (r == 0) {
 		for (i=0; i<glob_buf.gl_pathc; i++) {
@@ -1965,7 +1980,7 @@ void include_stmt(char *str)
 			if (f) {
 				include_file(f, strdup(glob_buf.gl_pathv[i]));
 				fclose(f);
-			} else if (errno == ENOENT && glob_buf.gl_flags & GLOB_MAGCHAR) {
+			} else if (errno == ENOENT && contains_glob_magic_char) {
 				/* Noisily ignore race between glob expansion
 				 * and actual open. */
 				err("%s:%d: include file vanished after glob expansion '%s'.\n",
@@ -1979,17 +1994,7 @@ void include_stmt(char *str)
 		}
 		globfree(&glob_buf);
 	} else if (r == GLOB_NOMATCH) {
-		/*
-		 * If the glob did not match any file,
-		 * there is nothing to do, silently ignore.
-		 * Unless it was no glob, but a literal,
-		 * which we would expect to exist.
-		 * Apparently |GLOB_MAGCHAR does not happen for GLOB_NOMATCH returns,
-		 * at least not consistently :-(
-		 * So we have this strchr heuristic anyways.
-		 */
-		/* if (!(glob_buf.gl_flags & GLOB_MAGCHAR)) { */
-		if (!strchr(str, '?') && !strchr(str, '*') && !strchr(str, '[')) {
+		if (!contains_glob_magic_char) {
 			err("%s:%d: Failed to open include file '%s'.\n",
 			    config_save, line, str);
 			config_valid = 0;
-- 
2.39.0

