Fix two memcpy() bugs in the new injection point code
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Mon, 22 Jan 2024 18:55:45 +0000 (20:55 +0200)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Mon, 22 Jan 2024 18:55:45 +0000 (20:55 +0200)
1. The memcpy()s in InjectionPointAttach() would copy garbage from
beyond the end of input string to the buffer in shared memory. You
won't usually notice, but if there is not enough valid mapped memory
beyond the end of the string, the read of unmapped memory will
segfault. This was flagged by the Cirrus CI build with address
sanitizer enabled.

2. The memcpy() in injection_point_cache_add() failed to copy the NULL
terminator.

Discussion: https://www.postgresql.org/message-id/0615a424-b726-4157-afa7-4245629f9512%40iki.fi

src/backend/utils/misc/injection_point.c

index a4ee00559b361de4e19460964fa743406c308d9a..4f52f198533639c3e14a78006465fae86a6c9d90 100644 (file)
@@ -97,7 +97,7 @@ injection_point_cache_add(const char *name,
        hash_search(InjectionPointCache, name, HASH_ENTER, &found);
 
    Assert(!found);
-   memcpy(entry->name, name, strlen(name));
+   strlcpy(entry->name, name, sizeof(entry->name));
    entry->callback = callback;
 }
 
@@ -217,11 +217,11 @@ InjectionPointAttach(const char *name,
    }
 
    /* Save the entry */
-   memcpy(entry_by_name->name, name, sizeof(entry_by_name->name));
+   strlcpy(entry_by_name->name, name, sizeof(entry_by_name->name));
    entry_by_name->name[INJ_NAME_MAXLEN - 1] = '\0';
-   memcpy(entry_by_name->library, library, sizeof(entry_by_name->library));
+   strlcpy(entry_by_name->library, library, sizeof(entry_by_name->library));
    entry_by_name->library[INJ_LIB_MAXLEN - 1] = '\0';
-   memcpy(entry_by_name->function, function, sizeof(entry_by_name->function));
+   strlcpy(entry_by_name->function, function, sizeof(entry_by_name->function));
    entry_by_name->function[INJ_FUNC_MAXLEN - 1] = '\0';
 
    LWLockRelease(InjectionPointLock);