From 5f5c497c8b556712c10975070a8d234ab19e64a2 Mon Sep 17 00:00:00 2001 From: David Sterba Date: Tue, 2 Jul 2019 12:50:14 +0200 Subject: [PATCH] btrfs-progs: send: add gcc9 workaround for root item reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Gcc version 9.1.1 reports: In file included from /usr/include/string.h:494, from kerncompat.h:25, from ctree.h:26, from send-utils.c:26: In function ‘memset’, inlined from ‘btrfs_read_root_item’ at send-utils.c:165:3, inlined from ‘subvol_uuid_search2’ at send-utils.c:494:8: /usr/include/bits/string_fortified.h:71:10: warning: ‘__builtin_memset’ offset [248, 439] from the object at ‘root_item’ is out of the bounds of referenced subobject ‘generation_v2’ with type ‘long long unsigned int’ at offset 239 [-Warray-bounds] 71 | return __builtin___memset_chk (__dest, __ch, __len, __bos0 (__dest)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ That's correct in case the intent is to overwrite just the generation_v2 member, but we want to zero the rest of the root item structure starting from the generation_v2. No typecasts can obscure that from gcc so the starting address is calculated as base pointer + member offset. Signed-off-by: David Sterba --- send-utils.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/send-utils.c b/send-utils.c index 31ac9a7a..29ff8366 100644 --- a/send-utils.c +++ b/send-utils.c @@ -151,10 +151,21 @@ static int btrfs_read_root_item(int mnt_fd, u64 root_id, return ret; if (read_len < sizeof(*item) || - btrfs_root_generation(item) != btrfs_root_generation_v2(item)) - memset(&item->generation_v2, 0, + btrfs_root_generation(item) != btrfs_root_generation_v2(item)) { + /* + * Workaround for gcc9 that warns that memset over + * generation_v2 overflows, which is what we want but would + * be otherwise a bug + * + * The below is &item->generation_v2 + */ + char *start = (char *)item + offsetof(struct btrfs_root_item, + generation_v2); + + memset(start, 0, sizeof(*item) - offsetof(struct btrfs_root_item, generation_v2)); + } return 0; }