[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH 1/4] chardev/parallel: Don't close stdin on inappropriate dev
From: |
Marc-André Lureau |
Subject: |
Re: [PATCH 1/4] chardev/parallel: Don't close stdin on inappropriate device |
Date: |
Tue, 13 Feb 2024 22:25:52 +0400 |
Hi
On Tue, Feb 13, 2024 at 5:58 PM Markus Armbruster <armbru@redhat.com> wrote:
>
> Markus Armbruster <armbru@redhat.com> writes:
>
> > The __linux__ version of qemu_chr_open_pp_fd() tries to claim the
> > parport device with a PPCLAIM ioctl(). On success, it stores the file
> > descriptor in the chardev object, and returns success. On failure, it
> > closes the file descriptor, and returns failure.
> >
> > chardev_new() then passes the Chardev to object_unref(). This duly
> > calls char_parallel_finalize(), which closes the file descriptor
> > stored in the chardev object. Since qemu_chr_open_pp_fd() didn't
> > store it, it's still zero, so this closes standard input. Ooopsie.
> >
> > To demonstate, add a unit test. With the bug above unfixed, running
> > this test closes standard input. char_hotswap_test() happens to run
> > next. It opens a socket, duly gets file descriptor 0, and since it
> > tests for success with > 0 instead of >= 0, it fails.
> >
> > The test needs to be conditional exactly like the chardev it tests.
> > Since the condition is rather complicated, steal the solution from the
> > serial chardev: define HAVE_CHARDEV_PARALLEL in qemu/osdep.h. This
> > also permits simplifying chardev/meson.build a bit.
> >
> > The bug fix is easy enough: store the file descriptor, and leave
> > closing it to char_parallel_finalize().
> >
> > Signed-off-by: Markus Armbruster <armbru@redhat.com>
>
> [...]
>
> > diff --git a/chardev/char-parallel.c b/chardev/char-parallel.c
> > index a5164f975a..78697d7522 100644
> > --- a/chardev/char-parallel.c
> > +++ b/chardev/char-parallel.c
> > @@ -164,13 +164,13 @@ static void qemu_chr_open_pp_fd(Chardev *chr,
> > {
> > ParallelChardev *drv = PARALLEL_CHARDEV(chr);
> >
> > + drv->fd = fd;
> > +
> > if (ioctl(fd, PPCLAIM) < 0) {
> > error_setg_errno(errp, errno, "not a parallel port");
> > - close(fd);
> > return;
> > }
> >
> > - drv->fd = fd;
> > drv->mode = IEEE1284_MODE_COMPAT;
> > }
> > #endif /* __linux__ */
> > @@ -238,6 +238,7 @@ static void qemu_chr_open_pp_fd(Chardev *chr,
> > }
> > #endif
> >
> > +#ifdef HAVE_CHARDEV_PARALLEL
> > static void qmp_chardev_open_parallel(Chardev *chr,
> > ChardevBackend *backend,
> > bool *be_opened,
> > @@ -306,3 +307,5 @@ static void register_types(void)
> > }
> >
> > type_init(register_types);
> > +
> > +#endif /* HAVE_CHARDEV_PARALLEL */
> > diff --git a/tests/unit/test-char.c b/tests/unit/test-char.c
> > index 649fdf64e1..76946e6f90 100644
> > --- a/tests/unit/test-char.c
> > +++ b/tests/unit/test-char.c
> > @@ -1203,6 +1203,24 @@ static void char_serial_test(void)
> > }
> > #endif
> >
> > +#if defined(HAVE_CHARDEV_PARALLEL) && !defined(WIN32)
> > +static void char_parallel_test(void)
> > +{
> > + QemuOpts *opts;
> > + Chardev *chr;
> > +
> > + opts = qemu_opts_create(qemu_find_opts("chardev"), "parallel-id",
> > + 1, &error_abort);
> > + qemu_opt_set(opts, "backend", "parallel", &error_abort);
> > + qemu_opt_set(opts, "path", "/dev/null", &error_abort);
> > +
> > + chr = qemu_chr_new_from_opts(opts, NULL, NULL);
> > + g_assert_null(chr);
>
> This is wrong.
>
> On a Linux host, qemu_chr_new_from_opts() fails, because
> qemu_chr_open_pp_fd()'s attempt to PPCLAIM fails.
>
> On a BSD host, it succeeds.
>
> Proposed fixup appended. Marc-André, is respinning the PR with the
> fixup okay, or would you prefer a v2?
I am okay with a new PR.
thanks
>
> > +
> > + qemu_opts_del(opts);
> > +}
> > +#endif
> > +
> > #ifndef _WIN32
> > static void char_file_fifo_test(void)
> > {
> > @@ -1544,6 +1562,9 @@ int main(int argc, char **argv)
> > g_test_add_func("/char/udp", char_udp_test);
> > #if defined(HAVE_CHARDEV_SERIAL) && !defined(WIN32)
> > g_test_add_func("/char/serial", char_serial_test);
> > +#endif
> > +#if defined(HAVE_CHARDEV_PARALLEL) && !defined(WIN32)
> > + g_test_add_func("/char/parallel", char_parallel_test);
> > #endif
> > g_test_add_func("/char/hotswap", char_hotswap_test);
> > g_test_add_func("/char/websocket", char_websock_test);
>
> [...]
>
> diff --git a/tests/unit/test-char.c b/tests/unit/test-char.c
> index e3b783c06b..f273ce5226 100644
> --- a/tests/unit/test-char.c
> +++ b/tests/unit/test-char.c
> @@ -1215,7 +1215,13 @@ static void char_parallel_test(void)
> qemu_opt_set(opts, "path", "/dev/null", &error_abort);
>
> chr = qemu_chr_new_from_opts(opts, NULL, NULL);
> +#ifdef __linux__
> + /* fails to PPCLAIM, see qemu_chr_open_pp_fd() */
> g_assert_null(chr);
> +#else
> + g_assert_nonnull(chr);
> + object_unparent(OBJECT(chr));
> +#endif
>
> qemu_opts_del(opts);
> }
>
- [PATCH 2/4] tests/unit/test-char: Fix qemu_socket(), make_udp_socket() check, (continued)
- [PATCH 2/4] tests/unit/test-char: Fix qemu_socket(), make_udp_socket() check, Markus Armbruster, 2024/02/03
- [PATCH 4/4] qapi/char: Deprecate backend type "memory", Markus Armbruster, 2024/02/03
- [PATCH 1/4] chardev/parallel: Don't close stdin on inappropriate device, Markus Armbruster, 2024/02/03
- [PATCH 3/4] qapi/char: Make backend types properly conditional, Markus Armbruster, 2024/02/03
- Re: [PATCH 0/4] char: Minor fixes, and a tighter QAPI schema, Marc-André Lureau, 2024/02/03