From 56bc3ebcbc72706ad3d6ce92f9e4afd012cbe4e8 Mon Sep 17 00:00:00 2001 From: xfan1024 Date: Sun, 15 Aug 2021 04:54:48 +0800 Subject: [PATCH] src/libudev/conf-files.c: fix bug of using basename BASENAME(3) Linux Programmer's Manual say: > These functions may return pointers to statically allocated memory > which may be overwritten by subsequent calls. Using basename return value as key of hashmap is not safe, it may cause that hashmap_put always return -EEXIST if hash collision happen. Using basename return value as strcmp first and second parameters may always return 0. Signed-off-by: xiaofan --- src/shared/conf-files.c | 4 ++-- src/shared/util.c | 10 +++++++++- src/shared/util.h | 1 + 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/shared/conf-files.c b/src/shared/conf-files.c index b4c2f7154..c8549ab29 100644 --- a/src/shared/conf-files.c +++ b/src/shared/conf-files.c @@ -71,7 +71,7 @@ static int files_add(Hashmap *h, const char *root, const char *path, const char if (!p) return -ENOMEM; - r = hashmap_put(h, basename(p), p); + r = hashmap_put(h, eudev_basename(p), p); if (r == -EEXIST) { log_debug("Skipping overridden file: %s.", p); free(p); @@ -92,7 +92,7 @@ static int base_cmp(const void *a, const void *b) { s1 = *(char * const *)a; s2 = *(char * const *)b; - return strcmp(basename(s1), basename(s2)); + return strcmp(eudev_basename(s1), eudev_basename(s2)); } static int conf_files_list_strv_internal(char ***strv, const char *suffix, const char *root, char **dirs) { diff --git a/src/shared/util.c b/src/shared/util.c index 0779476cd..64598c1d4 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -1725,7 +1725,7 @@ int tempfn_xxxxxx(const char *p, char **ret) { * /foo/bar/.#waldoXXXXXX */ - fn = basename((char*)p); + fn = eudev_basename(p); if (!filename_is_valid(fn)) return -EINVAL; @@ -1967,3 +1967,11 @@ void cmsg_close_all(struct msghdr *mh) { if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) close_many((int*) CMSG_DATA(cmsg), (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int)); } + +const char *eudev_basename(const char *filename) { + const char *p = strrchr(filename, '/'); + + if (p) + return p + 1; + return filename; +} diff --git a/src/shared/util.h b/src/shared/util.h index 5c1dc4801..43feec4f7 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -433,3 +433,4 @@ union inotify_event_buffer { }; void cmsg_close_all(struct msghdr *mh); +const char *eudev_basename(const char *filename);