From 0192864da7e9c5a89439809d518ae17b660b1dab Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 4 Jun 2021 22:16:02 +0900 Subject: [PATCH 1/2] test: add a testcase that demonstrates a conflict of hashed filename The commit e64943363a8dd8bd320c2b633478be8befd1af5c introduces hashed path at the end of the filename. But we can easily generate the path which conflicts another path. The issue will be fixed in later commit. --- src/udev/test-udev-node.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/udev/test-udev-node.c b/src/udev/test-udev-node.c index fe3dd437d5..d2e2285089 100644 --- a/src/udev/test-udev-node.c +++ b/src/udev/test-udev-node.c @@ -33,6 +33,10 @@ static void test_udev_node_escape_path(void) { strcpy(b + sizeof(b) - 12, "N3YhcCqFeID"); test_udev_node_escape_path_one(a, b); + + strcpy(a + sizeof(a) - 12 - 9, "N3YhcCqFeID"); + + test_udev_node_escape_path_one(a, b); /* <-- Ouch. This will pass. Needs to be fixed. */ } int main(int argc, char *argv[]) { From 2bb02271657b44efc7be1ede1ff1eed8408d0229 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 4 Jun 2021 22:28:09 +0900 Subject: [PATCH 2/2] udev: always use last 11 chars for hash string This makes the last 11 chars are always preserved for hashed string. So, it is hard to generate a path which conflicts to another path. Fixes an issue demonstrated in the previous commit. --- src/udev/test-udev-node.c | 10 +++++++++- src/udev/udev-node.c | 9 ++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/udev/test-udev-node.c b/src/udev/test-udev-node.c index d2e2285089..010c19acf5 100644 --- a/src/udev/test-udev-node.c +++ b/src/udev/test-udev-node.c @@ -35,8 +35,16 @@ static void test_udev_node_escape_path(void) { test_udev_node_escape_path_one(a, b); strcpy(a + sizeof(a) - 12 - 9, "N3YhcCqFeID"); + strcpy(b + sizeof(b) - 12, "L1oK9iKWdmi"); + test_udev_node_escape_path_one(a, b); - test_udev_node_escape_path_one(a, b); /* <-- Ouch. This will pass. Needs to be fixed. */ + strcpy(a + sizeof(a) - 12 - 9, "a"); + strcpy(b + sizeof(b) - 12, "A7oaHBRuuZq"); + test_udev_node_escape_path_one(a, b); + + a[sizeof(a) - 12 - 9] = '\0'; + b[sizeof(a) - 12] = '\0'; + test_udev_node_escape_path_one(a, b); } int main(int argc, char *argv[]) { diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c index a56084de7e..9e52906571 100644 --- a/src/udev/udev-node.c +++ b/src/udev/udev-node.c @@ -219,20 +219,21 @@ size_t udev_node_escape_path(const char *src, char *dest, size_t size) { assert(src); assert(dest); + assert(size >= 12); for (i = 0, j = 0; src[i] != '\0'; i++) { if (src[i] == '/') { - if (j+4 >= size) + if (j+4 >= size - 12 + 1) goto toolong; memcpy(&dest[j], "\\x2f", 4); j += 4; } else if (src[i] == '\\') { - if (j+4 >= size) + if (j+4 >= size - 12 + 1) goto toolong; memcpy(&dest[j], "\\x5c", 4); j += 4; } else { - if (j+1 >= size) + if (j+1 >= size - 12 + 1) goto toolong; dest[j] = src[i]; j++; @@ -247,8 +248,6 @@ toolong: h = siphash24_string(src, UDEV_NODE_HASH_KEY.bytes); - assert(size >= 12); - for (unsigned k = 0; k <= 10; k++) dest[size - k - 2] = urlsafe_base64char((h >> (k * 6)) & 63);