Re: [PATCH] btrfs: fix stale errno check in btrfs_encoded_read/write helpers
Mark Harmstone <[email protected]>
| Newsgroups | org.kernel.vger.fstests,org.kernel.vger.linux-btrfs |
|---|---|
| Message-ID | <[email protected]> |
On 24/03/2026 7.09 pm, Leo Martins wrote: > The atoll() error check `if (offset == 0 && errno != 0)` can falsely > trigger because errno is not cleared before the call. Library > initialization code (e.g. libcap calling prctl(PR_CAPBSET_READ) which > fails with EINVAL) can leave errno set to a non-zero value. When the > caller passes offset=0 (a valid value), atoll() returns 0 without > modifying errno, and the stale errno causes the helper to print usage > and exit. Thanks Leo. From https://pubs.opengroup.org/onlinepubs/9699919799/functions/errno.html: > The following sentence is deleted from the DESCRIPTION: "The value of errno is 0 at program start-up, but is never set to 0 by any XSI function". So yes, apparently you can no longer rely on errno being 0 at the beginning of main. TIL. Reviewed-by: Mark Harmstone <[email protected]> > This caused btrfs/333 to fail consistently on systems where libcap is > linked, since every call with offset 0 would bail out. > > Fix by clearing errno before the atoll() calls in both > btrfs_encoded_read and btrfs_encoded_write helpers. > > Signed-off-by: Leo Martins <[email protected]> > --- > src/btrfs_encoded_read.c | 1 + > src/btrfs_encoded_write.c | 1 + > 2 files changed, 2 insertions(+) > > diff --git a/src/btrfs_encoded_read.c b/src/btrfs_encoded_read.c > index 3ee0d8b0..c7c25b74 100644 > --- a/src/btrfs_encoded_read.c > +++ b/src/btrfs_encoded_read.c > @@ -178,6 +178,7 @@ int main(int argc, char *argv[]) > > filename = argv[2]; > > + errno = 0; > offset = atoll(argv[3]); > if (offset == 0 && errno != 0) { > usage(); > diff --git a/src/btrfs_encoded_write.c b/src/btrfs_encoded_write.c > index 7e46d9fe..bc05cc3b 100644 > --- a/src/btrfs_encoded_write.c > +++ b/src/btrfs_encoded_write.c > @@ -179,6 +179,7 @@ int main(int argc, char *argv[]) > > filename = argv[2]; > > + errno = 0; > offset = atoll(argv[3]); > if (offset == 0 && errno != 0) { > usage();