[dpdk-stable] patch 'mem: fix allocation in container with SELinux' has been queued to LTS release 18.11.11

Kevin Traynor ktraynor at redhat.com
Thu Nov 5 13:39:50 CET 2020


Hi,

FYI, your patch has been queued to LTS release 18.11.11

Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet.
It will be pushed if I get no objections before 11/10/20. So please
shout if anyone has objections.

Also note that after the patch there's a diff of the upstream commit vs the
patch applied to the branch. This will indicate if there was any rebasing
needed to apply to the stable branch. If there were code changes for rebasing
(ie: not only metadata diffs), please double check that the rebase was
correctly done.

Queued patches are on a temporary branch at:
https://github.com/kevintraynor/dpdk-stable-queue

This queued commit can be viewed at:
https://github.com/kevintraynor/dpdk-stable-queue/commit/2a3e5d6205c2087e1879dceb1bd573bccab4469a

Thanks.

Kevin.

---
>From 2a3e5d6205c2087e1879dceb1bd573bccab4469a Mon Sep 17 00:00:00 2001
From: David Marchand <david.marchand at redhat.com>
Date: Thu, 10 Sep 2020 18:24:07 +0200
Subject: [PATCH] mem: fix allocation in container with SELinux

[ upstream commit aa48ddf4f0d2a9f90cd9247ac779ced55588c27a ]

This is something we encountered while working in an OpenShift
environment with SELinux enabled.
In this environment, a DPDK application could create/write to hugepage
files but removing them was refused.
This resulted in dirty files being reused when starting a new DPDK
application and triggered random crashes / erratic behavior.

Getting a SELinux setup can be a challenge, and even more if you add
containers to the picture :-).
So here is a reproducer for the interested testers:

  # cat >wrap.c <<EOF
  #define _GNU_SOURCE
  #include <dlfcn.h>
  #include <errno.h>
  #include <stdio.h>
  #include <string.h>
  #include <sys/stat.h>
  #include <sys/types.h>
  #include <unistd.h>

  int unlink(const char *pathname)
  {
  	static int (*orig)(const char *pathname) = NULL;
  	struct stat st;

  	if (orig == NULL)
  		orig = dlsym(RTLD_NEXT, "unlink");
  	if (strstr(pathname, "rtemap_") != NULL &&
			stat(pathname, &st) == 0) {
  		fprintf(stderr, "### refused unlink for %s\n",
  			pathname);
  		errno = EACCES;
  		return -1;
  	}
  	fprintf(stderr, "### called unlink for %s\n", pathname);
  	return orig(pathname);
  }

  int unlinkat(int dirfd, const char *pathname, int flags)
  {
  	static int (*orig)(int dirfd, const char *pathname, int flags) =
  		NULL;
  	struct stat st;

  	if (orig == NULL)
  		orig = dlsym(RTLD_NEXT, "unlinkat");
  	if (strstr(pathname, "rtemap_") != NULL &&
  			fstatat(dirfd, pathname, &st, flags) == 0) {
  		fprintf(stderr, "### refused unlinkat for %s\n",
  			pathname);
  		errno = EACCES;
  		return -1;
  	}
  	fprintf(stderr, "### called unlinkat for %s\n", pathname);
  	return orig(dirfd, pathname, flags);
  }
  EOF

  # gcc -fPIC -shared  -o libwrap.so wrap.c -ldl
  # \rm /dev/hugepages/rtemap*

  # # First run is fine
  # LD_PRELOAD=libwrap.so dpdk-testpmd -w 0000:01:00.0 -- -i
  [...]
  Configuring Port 0 (socket 0)
  Port 0: 24:6E:96:3C:52:D8
  Checking link statuses...
  Done
  testpmd>

  # # Second run we have dirty memory
  # LD_PRELOAD=libwrap.so dpdk-testpmd -w 0000:01:00.0 -- -i
  [...]
  ### refused unlinkat for rtemap_0
  [...]
  Port 0 is now not stopped
  Please stop the ports first
  Done
  testpmd>

Removing hugepage files is done in multiple places and the memory
allocation code is complex.
This fix tries to do the minimum and avoids touching other paths.

If trying to remove the hugepage file before allocating a page fails,
the error is reported to the caller and the user will see a memory
allocation error log.

Fixes: 582bed1e1d1d ("mem: support mapping hugepages at runtime")

Signed-off-by: David Marchand <david.marchand at redhat.com>
Acked-by: Anatoly Burakov <anatoly.burakov at intel.com>
---
 lib/librte_eal/linuxapp/eal/eal_memalloc.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/lib/librte_eal/linuxapp/eal/eal_memalloc.c b/lib/librte_eal/linuxapp/eal/eal_memalloc.c
index 518314d89c..dea2b5ec93 100644
--- a/lib/librte_eal/linuxapp/eal/eal_memalloc.c
+++ b/lib/librte_eal/linuxapp/eal/eal_memalloc.c
@@ -420,4 +420,19 @@ get_seg_fd(char *path, int buflen, struct hugepage_info *hi,
 
 		if (fd < 0) {
+			/* A primary process is the only one creating these
+			 * files. If there is a leftover that was not cleaned
+			 * by clear_hugedir(), we must *now* make sure to drop
+			 * the file or we will remap old stuff while the rest
+			 * of the code is built on the assumption that a new
+			 * page is clean.
+			 */
+			if (rte_eal_process_type() == RTE_PROC_PRIMARY &&
+					unlink(path) == -1 &&
+					errno != ENOENT) {
+				RTE_LOG(DEBUG, EAL, "%s(): could not remove '%s': %s\n",
+					__func__, path, strerror(errno));
+				return -1;
+			}
+
 			fd = open(path, O_CREAT | O_RDWR, 0600);
 			if (fd < 0) {
-- 
2.26.2

---
  Diff of the applied patch vs upstream commit (please double-check if non-empty:
---
--- -	2020-11-05 12:38:55.073275999 +0000
+++ 0043-mem-fix-allocation-in-container-with-SELinux.patch	2020-11-05 12:38:54.244896023 +0000
@@ -1 +1 @@
-From aa48ddf4f0d2a9f90cd9247ac779ced55588c27a Mon Sep 17 00:00:00 2001
+From 2a3e5d6205c2087e1879dceb1bd573bccab4469a Mon Sep 17 00:00:00 2001
@@ -5,0 +6,2 @@
+[ upstream commit aa48ddf4f0d2a9f90cd9247ac779ced55588c27a ]
+
@@ -96 +97,0 @@
-Cc: stable at dpdk.org
@@ -101 +102 @@
- lib/librte_eal/linux/eal_memalloc.c | 15 +++++++++++++++
+ lib/librte_eal/linuxapp/eal/eal_memalloc.c | 15 +++++++++++++++
@@ -104,5 +105,5 @@
-diff --git a/lib/librte_eal/linux/eal_memalloc.c b/lib/librte_eal/linux/eal_memalloc.c
-index db60e79975..40a5c4aa1d 100644
---- a/lib/librte_eal/linux/eal_memalloc.c
-+++ b/lib/librte_eal/linux/eal_memalloc.c
-@@ -330,4 +330,19 @@ get_seg_fd(char *path, int buflen, struct hugepage_info *hi,
+diff --git a/lib/librte_eal/linuxapp/eal/eal_memalloc.c b/lib/librte_eal/linuxapp/eal/eal_memalloc.c
+index 518314d89c..dea2b5ec93 100644
+--- a/lib/librte_eal/linuxapp/eal/eal_memalloc.c
++++ b/lib/librte_eal/linuxapp/eal/eal_memalloc.c
+@@ -420,4 +420,19 @@ get_seg_fd(char *path, int buflen, struct hugepage_info *hi,



More information about the stable mailing list