]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Switch to memmove() for truncate_dll_name() (CID #1504298) (#4495)
authorJames Jones <jejones3141@gmail.com>
Thu, 12 May 2022 02:47:55 +0000 (21:47 -0500)
committerGitHub <noreply@github.com>
Thu, 12 May 2022 02:47:55 +0000 (22:47 -0400)
with overlapping src/dest, strcpy() gives undefined behavior

scripts/jlibtool.c

index cf0784f34fcc0577026bc9a230d991781f0e9021..04e849f85fb2e65c09a0066018bb58821bbc3b11 100644 (file)
@@ -1233,21 +1233,27 @@ static char *truncate_dll_name(char const *path)
        char *tmppath = strdup(path);
        char *newname = strrchr(tmppath, '/') + 1;
        char *ext = strrchr(newname, '.');
-       int len;
+       int len, ext_len;
 
-       if (ext == NULL) {
-               return tmppath;
-       }
+       if (ext == NULL) return tmppath;
+
+       /*
+        *      About the removals: they can't be done with strcpy() because
+        *      there is necessarily overlap, which for strcpy() is undefined
+        *      behavior. Only memmove() is guaranteed to work in the presence
+        *      of overlap.
+        */
 
        len = ext - newname;
+       ext_len = strlen(ext);
 
        if (strncmp(newname, "mod_", 4) == 0) {
-               strcpy(newname, newname + 4);
+               memmove(newname, newname + 4, len + ext_len - 4 + 1);
                len -= 4;
        }
 
        if (len > 8) {
-               strcpy(newname + 8, strchr(newname, '.'));
+               memmove(newname + 8, strchr(newname, '.'), ext_len + 1);
        }
 
        return tmppath;