[Libguestfs] [libnbd PATCH 3/4] examples: glib-main-loop: Fix error handling
Laszlo Ersek
lersek at redhat.com
Wed Feb 2 08:32:24 UTC 2022
On 02/01/22 20:44, Eric Blake wrote:
> This example failed to check the *error parameter to the read and
> write completion callbacks. What's more, the buffers start life
> uninitialized, so a failed read can end up leaking heap contents to
> the corresponding write.
>
> Fortunately, the example program is hard-coded to two particular
> nbdkit invocations, and not usable to corrupt a user's data. However,
> as this example is likely to be copied elsewhere, we should at least
> perform rudimentary error checking to avoid bad copy-and-paste that
> could turn into a more severe problem in code derived from this.
> Easiest for the example is to just punt and exit the process on any
> detected errors from either the source or destination.
>
> Since the nbdkit invocations are hard-coded, testing that this patch
> works involves using a temporary patch, such as:
>
> | diff --git i/examples/glib-main-loop.c w/examples/glib-main-loop.c
> | index 1982f941..f60a4a38 100644
> | --- i/examples/glib-main-loop.c
> | +++ w/examples/glib-main-loop.c
> | @@ -232,7 +232,8 @@ static struct NBDSource *gssrc, *gsdest;
> | #define SIZE (1024*1024*1024)
> |
> | static const char *src_args[] = {
> | - "nbdkit", "-s", "--exit-with-parent", "-r", "pattern", "size=1G", NULL
> | + "nbdkit", "-s", "--exit-with-parent", "-r", "--filter=error",
> | + "pattern", "size=1G", "error-pread-rate=0.1", NULL
> | };
> |
> | static const char *dest_args[] = {
>
> Fixes: bc3b4230 ("examples: Include an example of integrating with the glib main loop", v0.1.9)
> ---
> examples/glib-main-loop.c | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/examples/glib-main-loop.c b/examples/glib-main-loop.c
> index 2df27878..1982f941 100644
> --- a/examples/glib-main-loop.c
> +++ b/examples/glib-main-loop.c
> @@ -402,6 +402,11 @@ finished_read (void *vp, int *error)
> if (gssrc == NULL)
> return 1; /* Nothing we can do, auto-retire the callback */
>
> + if (*error) {
> + fprintf (stderr, "finished_read: read failed: %s\n", strerror (*error));
> + exit (EXIT_FAILURE);
> + }
> +
> DEBUG (gssrc, "finished_read: read completed");
>
> assert (buffer->state == BUFFER_READING);
> @@ -448,6 +453,11 @@ finished_write (void *vp, int *error)
> if (gsdest == NULL)
> return 1; /* Nothing we can do, auto-retire the callback */
>
> + if (*error) {
> + fprintf (stderr, "finished_write: write failed: %s\n", strerror (*error));
> + exit (EXIT_FAILURE);
> + }
> +
> DEBUG (gsdest, "finished_write: write completed");
>
> assert (buffer->state == BUFFER_WRITING);
>
Slightly inconsistent with
+ errno = *error;
+ perror ("failed to read");
+ exit (EXIT_FAILURE);
from the first patch, but does effectively the same thing.
Thanks,
Laszlo
More information about the Libguestfs
mailing list