Message ID | 20200705142058.28305-1-trix@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | btfrs: initialize return of btrfs_extent_same | expand |
On 5.07.20 г. 17:20 ч., trix@redhat.com wrote: > From: Tom Rix <trix@redhat.com> > > clang static analysis flags a garbage return > > fs/btrfs/reflink.c:611:2: warning: Undefined or garbage value returned to caller [core.uninitialized.UndefReturn] > return ret; > ^~~~~~~~~~ > ret will not be set when olen is 0 > When olen is 0, this function does no work. > > So initialize ret to 0 > > Signed-off-by: Tom Rix <trix@redhat.com> Patch itself is good however, the bug cannot currently be triggered, due to the following code in the sole caller (btrfs_remap_file_range): 15 if (ret < 0 || len == 0) 14 goto out_unlock; 13 12 if (remap_flags & REMAP_FILE_DEDUP) 11 ret = btrfs_extent_same(src_inode, off, len, dst_inode, destoff); 10 else 9 ret = btrfs_clone_files(dst_file, src_file, off, len, destoff); i.e len is guaranteed to be non-zero > --- > fs/btrfs/reflink.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/fs/btrfs/reflink.c b/fs/btrfs/reflink.c > index 040009d1cc31..200a80fcbecb 100644 > --- a/fs/btrfs/reflink.c > +++ b/fs/btrfs/reflink.c > @@ -572,7 +572,7 @@ static int btrfs_extent_same_range(struct inode *src, u64 loff, u64 len, > static int btrfs_extent_same(struct inode *src, u64 loff, u64 olen, > struct inode *dst, u64 dst_loff) > { > - int ret; > + int ret = 0; > u64 i, tail_len, chunk_count; > struct btrfs_root *root_dst = BTRFS_I(dst)->root; > >
On 5.07.20 г. 17:20 ч., trix@redhat.com wrote: > From: Tom Rix <trix@redhat.com> > > clang static analysis flags a garbage return > > fs/btrfs/reflink.c:611:2: warning: Undefined or garbage value returned to caller [core.uninitialized.UndefReturn] > return ret; > ^~~~~~~~~~ > ret will not be set when olen is 0 > When olen is 0, this function does no work. > > So initialize ret to 0 > > Signed-off-by: Tom Rix <trix@redhat.com> And I forgot: Reviewed-by: Nikolay Borisov <nborisov@suse.com> > --- > fs/btrfs/reflink.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/fs/btrfs/reflink.c b/fs/btrfs/reflink.c > index 040009d1cc31..200a80fcbecb 100644 > --- a/fs/btrfs/reflink.c > +++ b/fs/btrfs/reflink.c > @@ -572,7 +572,7 @@ static int btrfs_extent_same_range(struct inode *src, u64 loff, u64 len, > static int btrfs_extent_same(struct inode *src, u64 loff, u64 olen, > struct inode *dst, u64 dst_loff) > { > - int ret; > + int ret = 0; > u64 i, tail_len, chunk_count; > struct btrfs_root *root_dst = BTRFS_I(dst)->root; > >
On Sun, Jul 05, 2020 at 05:48:17PM +0300, Nikolay Borisov wrote: > On 5.07.20 г. 17:20 ч., trix@redhat.com wrote: > > From: Tom Rix <trix@redhat.com> > > > > clang static analysis flags a garbage return > > > > fs/btrfs/reflink.c:611:2: warning: Undefined or garbage value returned to caller [core.uninitialized.UndefReturn] > > return ret; > > ^~~~~~~~~~ > > ret will not be set when olen is 0 > > When olen is 0, this function does no work. > > > > So initialize ret to 0 > > > > Signed-off-by: Tom Rix <trix@redhat.com> > > Patch itself is good however, the bug cannot currently be triggered, due > to the following code in the sole caller (btrfs_remap_file_range): > > > > 15 if (ret < 0 || len == 0) > 14 goto out_unlock; > 13 > 12 if (remap_flags & REMAP_FILE_DEDUP) > 11 ret = btrfs_extent_same(src_inode, off, len, dst_inode, destoff); > 10 else > 9 ret = btrfs_clone_files(dst_file, src_file, off, > len, destoff); > > i.e len is guaranteed to be non-zero Yeah, for that reason I don't think we need to set the value inside btrfs_extent_same because the caller(s) do the sanity checks. There are VFS-level checks of the length wrt zero, eg. it won't even call to copy_file_range from vfs_copy_file_range. The user supplied length = 0 is interpreted as 'until the end of file' and is properly reclaculated in generic_remap_file_range_prep. This looks like clang checker is not able to follow the values accross function calls, even if the functions are static.
diff --git a/fs/btrfs/reflink.c b/fs/btrfs/reflink.c index 040009d1cc31..200a80fcbecb 100644 --- a/fs/btrfs/reflink.c +++ b/fs/btrfs/reflink.c @@ -572,7 +572,7 @@ static int btrfs_extent_same_range(struct inode *src, u64 loff, u64 len, static int btrfs_extent_same(struct inode *src, u64 loff, u64 olen, struct inode *dst, u64 dst_loff) { - int ret; + int ret = 0; u64 i, tail_len, chunk_count; struct btrfs_root *root_dst = BTRFS_I(dst)->root;