All of lore.kernel.org
 help / color / mirror / Atom feed
From: Markus Armbruster <armbru@redhat.com>
To: qemu-devel@nongnu.org
Cc: marcandre.lureau@redhat.com,  pbonzini@redhat.com,
	devel@lists.libvirt.org,  eblake@redhat.com
Subject: Re: [PATCH 1/4] chardev/parallel: Don't close stdin on inappropriate device
Date: Tue, 13 Feb 2024 14:58:47 +0100	[thread overview]
Message-ID: <87mss479ew.fsf@pond.sub.org> (raw)
In-Reply-To: <20240203080228.2766159-2-armbru@redhat.com> (Markus Armbruster's message of "Sat, 3 Feb 2024 09:02:25 +0100")

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?

> +
> +    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);
 }



  parent reply	other threads:[~2024-02-13 13:59 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-03  8:02 [PATCH 0/4] char: Minor fixes, and a tighter QAPI schema Markus Armbruster
2024-02-03  8:02 ` [PATCH 1/4] chardev/parallel: Don't close stdin on inappropriate device Markus Armbruster
2024-02-07 19:15   ` Eric Blake
2024-02-08  6:52     ` Markus Armbruster
2024-02-13 13:58   ` Markus Armbruster [this message]
2024-02-13 18:25     ` Marc-André Lureau
2024-02-03  8:02 ` [PATCH 2/4] tests/unit/test-char: Fix qemu_socket(), make_udp_socket() check Markus Armbruster
2024-02-07 19:45   ` Eric Blake
2024-02-08  6:52     ` Markus Armbruster
2024-02-03  8:02 ` [PATCH 3/4] qapi/char: Make backend types properly conditional Markus Armbruster
2024-02-07 19:47   ` Eric Blake
2024-02-03  8:02 ` [PATCH 4/4] qapi/char: Deprecate backend type "memory" Markus Armbruster
2024-02-05  9:37   ` Ján Tomko
2024-02-07 19:48   ` Eric Blake
2024-02-03 11:07 ` [PATCH 0/4] char: Minor fixes, and a tighter QAPI schema Marc-André Lureau

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87mss479ew.fsf@pond.sub.org \
    --to=armbru@redhat.com \
    --cc=devel@lists.libvirt.org \
    --cc=eblake@redhat.com \
    --cc=marcandre.lureau@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.