exclude: fix crashes with fortified strlcpy()
authorJiri Slaby <jslaby@suse.cz>
Fri, 18 Aug 2023 06:26:20 +0000 (08:26 +0200)
committerWayne Davison <wayne@opencoder.net>
Sat, 6 Apr 2024 15:41:41 +0000 (08:41 -0700)
Fortified (-D_FORTIFY_SOURCE=2 for gcc) builds make strlcpy() crash when
its third parameter (size) is larger than the buffer:
  $ rsync -FFXHav '--filter=merge global-rsync-filter' Align-37-43/ xxx
  sending incremental file list
  *** buffer overflow detected ***: terminated

It's in the exclude code in setup_merge_file():
  strlcpy(y, save, MAXPATHLEN);

Note the 'y' pointer was incremented, so it no longer points to memory
with MAXPATHLEN "owned" bytes.

Fix it by remembering the number of copied bytes into the 'save' buffer
and use that instead of MAXPATHLEN which is clearly incorrect.

Fixes #511.

exclude.c

index ffe55b167edfdbe1325bcfdbe178f8b7b7017504..1a5de3b9e6a012c06e817b758d98d6aa6848f1e0 100644 (file)
--- a/exclude.c
+++ b/exclude.c
@@ -720,7 +720,8 @@ static BOOL setup_merge_file(int mergelist_num, filter_rule *ex,
        parent_dirscan = True;
        while (*y) {
                char save[MAXPATHLEN];
-               strlcpy(save, y, MAXPATHLEN);
+               /* copylen is strlen(y) which is < MAXPATHLEN. +1 for \0 */
+               size_t copylen = strlcpy(save, y, MAXPATHLEN) + 1;
                *y = '\0';
                dirbuf_len = y - dirbuf;
                strlcpy(x, ex->pattern, MAXPATHLEN - (x - buf));
@@ -734,7 +735,7 @@ static BOOL setup_merge_file(int mergelist_num, filter_rule *ex,
                        lp->head = NULL;
                }
                lp->tail = NULL;
-               strlcpy(y, save, MAXPATHLEN);
+               strlcpy(y, save, copylen);
                while ((*x++ = *y++) != '/') {}
        }
        parent_dirscan = False;