rsync: fix regression with _FORTIFY_SOURCE=2

See https://github.com/WayneD/rsync/issues/511 for details.
Not using fetchpatch, because I didn't found a raw link for opensuse's repository

authored by

Jörg Thalheim and committed by
Jörg Thalheim
54904423 7790e79c

+55
+6
pkgs/applications/networking/sync/rsync/default.nix
··· 30 30 31 31 nativeBuildInputs = [ perl ]; 32 32 33 + patches = [ 34 + # https://github.com/WayneD/rsync/issues/511#issuecomment-1774612577 35 + # original source: https://build.opensuse.org/package/view_file/network/rsync/rsync-fortified-strlcpy-fix.patch?expand=1&rev=3f8dd2f4a404c96c0f69176e60893714 36 + ./rsync-fortified-strlcpy-fix.patch 37 + ]; 38 + 33 39 buildInputs = [ libiconv zlib popt ] 34 40 ++ lib.optional enableACLs acl 35 41 ++ lib.optional enableZstd zstd
+49
pkgs/applications/networking/sync/rsync/rsync-fortified-strlcpy-fix.patch
··· 1 + From 1f83963f59960150e8c46112daa8411324c1f209 Mon Sep 17 00:00:00 2001 2 + From: Jiri Slaby <jslaby@suse.cz> 3 + Date: Fri, 18 Aug 2023 08:26:20 +0200 4 + Subject: [PATCH] exclude: fix crashes with fortified strlcpy() 5 + 6 + Fortified (-D_FORTIFY_SOURCE=2 for gcc) builds make strlcpy() crash when 7 + its third parameter (size) is larger than the buffer: 8 + $ rsync -FFXHav '--filter=merge global-rsync-filter' Align-37-43/ xxx 9 + sending incremental file list 10 + *** buffer overflow detected ***: terminated 11 + 12 + It's in the exclude code in setup_merge_file(): 13 + strlcpy(y, save, MAXPATHLEN); 14 + 15 + Note the 'y' pointer was incremented, so it no longer points to memory 16 + with MAXPATHLEN "owned" bytes. 17 + 18 + Fix it by remembering the number of copied bytes into the 'save' buffer 19 + and use that instead of MAXPATHLEN which is clearly incorrect. 20 + 21 + Fixes #511. 22 + --- 23 + exclude.c | 5 +++-- 24 + 1 file changed, 3 insertions(+), 2 deletions(-) 25 + 26 + diff --git a/exclude.c b/exclude.c 27 + index ffe55b167..1a5de3b9e 100644 28 + --- a/exclude.c 29 + +++ b/exclude.c 30 + @@ -720,7 +720,8 @@ static BOOL setup_merge_file(int mergelist_num, filter_rule *ex, 31 + parent_dirscan = True; 32 + while (*y) { 33 + char save[MAXPATHLEN]; 34 + - strlcpy(save, y, MAXPATHLEN); 35 + + /* copylen is strlen(y) which is < MAXPATHLEN. +1 for \0 */ 36 + + size_t copylen = strlcpy(save, y, MAXPATHLEN) + 1; 37 + *y = '\0'; 38 + dirbuf_len = y - dirbuf; 39 + strlcpy(x, ex->pattern, MAXPATHLEN - (x - buf)); 40 + @@ -734,7 +735,7 @@ static BOOL setup_merge_file(int mergelist_num, filter_rule *ex, 41 + lp->head = NULL; 42 + } 43 + lp->tail = NULL; 44 + - strlcpy(y, save, MAXPATHLEN); 45 + + strlcpy(y, save, copylen); 46 + while ((*x++ = *y++) != '/') {} 47 + } 48 + parent_dirscan = False; 49 +