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> Acked-by: Bruce Richardson <bruce.richard...@intel.com> --- Changes since v2: - removed check on null termination of dirent, --- lib/eal/common/eal_common_options.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/eal/common/eal_common_options.c b/lib/eal/common/eal_common_options.c index f0a9ddeeb7..e6eb04a138 100644 --- a/lib/eal/common/eal_common_options.c +++ b/lib/eal/common/eal_common_options.c @@ -399,12 +399,21 @@ eal_plugins_init(void) } #else +static bool +ends_with(const char *str, const char *tail) +{ + size_t tail_len = strlen(tail); + size_t str_len = strlen(str); + + return str_len >= tail_len && strcmp(&str[str_len - tail_len], tail) == 0; +} + static int eal_plugindir_init(const char *path) { - DIR *d = NULL; struct dirent *dent = NULL; char sopath[PATH_MAX]; + DIR *d = NULL; if (path == NULL || *path == '\0') return 0; @@ -418,12 +427,8 @@ eal_plugindir_init(const char *path) while ((dent = readdir(d)) != NULL) { 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, ".so") && !ends_with(dent->d_name, ".so."ABI_VERSION)) continue; snprintf(sopath, sizeof(sopath), "%s/%s", path, dent->d_name); -- 2.50.0