Hi, Glenn,

On Tue, Oct 10, 2023 at 2:23 PM Glenn Washburn
<developm...@efficientek.com> wrote:
>
> On Tue, 10 Oct 2023 12:24:24 -0400
> Jason Andryuk <jandr...@gmail.com> wrote:
>
> > grub_gzio_read_real() uses grub_errno to identify decompression failures
> > when the function completes.  Its callees in gzio.c are void-returning
> > functions that set grub_errno on their exit paths.
> >
> > A Fedora 38 machine was observed to fail `multiboot2 /xen.gz` with
> > "premature end of file".  xen.gz was well formed and could be
> > successfully gunzip-ed in Linux.
> >
> > The TPM is flaky and produces errors when the verifier tries to extend
> > PCRs with measurements.  Logs show "Unkown TPM error" and grub_errno is
> > set to GRUB_ERR_UNKNOWN_DEVICE.  This pre-existing grub_errno causes an
> > otherwise successful grub_gzio_read_real() call to return error.
> >
> > Clear grub_errno at the start of the function to avoid such errors.
>
> This seems to be a somewhat common theme. This is similar to the issue
> that I have seen in grub_disk_read() (see the first patch in the "More
> ls improvements" series). I think GRUB should have an explicit policy
> about grub_errno usage. Vladimir has stated "We generally prefer to have
> grub_print_error() (better) or resetting grib_errno after the error is
> produced rather than blanketly reset grub_errno at the beginning". That
> then suggests that its the callers responsibility to ensure that
> grub_errno is cleared before the call. I don't particularly like that,
> as it seems more economical for grub_errno to be cleared in the callee.
> Since GRUB seems to try to abide by some POSIX/GNU libc semantics, it
> seems reasonable to me to try to offer the same behavior as libc's
> errno. So caller's can not expect grub_errno to be preserved across
> library calls (ie all exported functions). And the callee is free to
> modify grub_errno at will. If the caller wants to preserve grub_errno
> across exported function calls, then the caller should save grub_errno
> in a local.
>
> So I'm for this approach in principle.
>
> > Signed-off-by: Jason Andryuk <jandr...@gmail.com>
> > ---
> >  grub-core/io/gzio.c | 8 ++++++++
> >  1 file changed, 8 insertions(+)
> >
> > diff --git a/grub-core/io/gzio.c b/grub-core/io/gzio.c
> > index ca9355751..1e31a8255 100644
> > --- a/grub-core/io/gzio.c
> > +++ b/grub-core/io/gzio.c
> > @@ -1294,6 +1294,14 @@ grub_gzio_read_real (grub_gzio_t gzio, grub_off_t 
> > offset,
> >  {
> >    grub_ssize_t ret = 0;
> >
> > +  /* Avoid spurious failures on exit when grub_errno is already set. */
> > +  if (grub_errno != GRUB_ERR_NONE)
> > +    {
> > +      grub_dprintf ("gzio", "%s: clearing pre-exising errmsg %s\n",
> > +                  __func__, grub_errmsg);
> > +      grub_errno = GRUB_ERR_NONE;
> > +    }
>
> I think it makes sense to make this an inline called
> "grub_print_uncleared_error" or something of the like to be used in
> other places where this is appropriate. And the debug conditional
> should be "errno" so we can see where this is happening in other areas
> like grub_disk_read() to help in debugging. I suspect this type of
> issue has caused some strange behavior I've seen in the past. Also
> using a different debug conditional allows that type of issue to be
> ignored without ignoring other debug messages from, in this case, gzio.
>
> And, I would have the "grub_errno = GRUB_ERR_NONE;" outside the if
> block, which signals the expectation that grub_errno is cleared
> unconditionally more clearly (if only slightly). I'm kinda ambivalent
> about this though.

I think this all sounds good.  However, I think `grub_clear_errno` is
a better name since that is the main purpose of the function.  Maybe
`grub_reset_errno`.  The dprintf call I mainly added as a debugging
aid and isn't the purpose of the function.  In the (hopefully small)
chance that there was a stale, unprinted value in grub_errno, it seems
better to print it out before clearing.

Regards,
Jason

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to