For '.' and '..' directories (or any short file name),
a out of bound issue occurs.

Caught by UBSan:

EAL: Detected shared linkage of DPDK
../lib/eal/common/eal_common_options.c:420:15: runtime error: index -2
        out of bounds for type 'char[256]'
    #0 0x7f867eedf206 in eal_plugindir_init
        eal_common_options.c
    #1 0x7f867eede58a in eal_plugins_init
        (build/lib/librte_eal.so.25+0xde58a)
        (BuildId: e7e4a1935e4bacb51c82ab1a84098a27decf3b4c)
    #2 0x7f867efb8587 in rte_eal_init
        (build/lib/librte_eal.so.25+0x1b8587)
        (BuildId: e7e4a1935e4bacb51c82ab1a84098a27decf3b4c)
    #3 0x55b62360861e in main
        (/home/runner/work/dpdk/dpdk/build/app/dpdk-testpmd+0x9e061e)
        (BuildId: d821ec918612c83fad8b5ccb6cc518e66bee48cd)
    #4 0x7f8667429d8f in __libc_start_call_main
        csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #5 0x7f8667429e3f in __libc_start_main
        csu/../csu/libc-start.c:392:3
    #6 0x55b622d9d444 in _start
        (/home/runner/work/dpdk/dpdk/build/app/dpdk-testpmd+0x175444)
        (BuildId: d821ec918612c83fad8b5ccb6cc518e66bee48cd)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior
        ../lib/eal/common/eal_common_options.c:420:15 in
        ../lib/eal/common/eal_common_options.c:421:15:
        runtime error: index 18446744073709551609 out of bounds
        for type 'char[256]'

Fixes: c57f6e5c604a ("eal: fix plugin loading")
Cc: sta...@dpdk.org

Signed-off-by: David Marchand <david.march...@redhat.com>
---
 lib/eal/common/eal_common_options.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/lib/eal/common/eal_common_options.c 
b/lib/eal/common/eal_common_options.c
index 83b6fc7e89..153f807e4f 100644
--- a/lib/eal/common/eal_common_options.c
+++ b/lib/eal/common/eal_common_options.c
@@ -399,6 +399,14 @@ eal_plugins_init(void)
 }
 #else
 
+static bool
+ends_with(const char *str, size_t str_len, const char *tail)
+{
+       size_t tail_len = strlen(tail);
+
+       return str_len >= tail_len && strncmp(&str[str_len - tail_len], tail, 
tail_len) == 0;
+}
+
 static int
 eal_plugindir_init(const char *path)
 {
@@ -417,13 +425,12 @@ eal_plugindir_init(const char *path)
        }
 
        while ((dent = readdir(d)) != NULL) {
+               size_t nlen = strnlen(dent->d_name, sizeof(dent->d_name));
                struct stat sb;
-               int nlen = strnlen(dent->d_name, sizeof(dent->d_name));
 
                /* check if name ends in .so or .so.ABI_VERSION */
-               if (strcmp(&dent->d_name[nlen - 3], ".so") != 0 &&
-                   strcmp(&dent->d_name[nlen - 4 - strlen(ABI_VERSION)],
-                          ".so."ABI_VERSION) != 0)
+               if (!ends_with(dent->d_name, nlen, ".so") &&
+                               !ends_with(dent->d_name, nlen, 
".so."ABI_VERSION))
                        continue;
 
                snprintf(sopath, sizeof(sopath), "%s/%s", path, dent->d_name);
-- 
2.49.0

Reply via email to