[dpdk-dev] [PATCH] eal/linux: fix memory allocations in containers+SELinux
Burakov, Anatoly
anatoly.burakov at intel.com
Fri Sep 11 14:46:40 CEST 2020
On 10-Sep-20 5:24 PM, David Marchand wrote:
> 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")
> Cc: stable at dpdk.org
>
> Signed-off-by: David Marchand <david.marchand at redhat.com>
> ---
I believe only the primary will try to allocate new pages, but this only
covers the page-per-file scenario. There's also legacy mem option (which
would attempt to remove files prior to creating new ones - not sure if
it's refused in that case), and single file segments option (which will
mostly fallocate holes rather than delete files, but may still attempt
to delete files - by the way, how does fallocate work with SELinux?).
So, for the contents of the patch in question, it's good, but *might* be
incomplete for the above reasons. I can't test this right this moment so
i'll leave this up to you :P
--
Thanks,
Anatoly
More information about the dev
mailing list