<feed xmlns='http://www.w3.org/2005/Atom'>
<title>kernel/git/stable/linux.git/drivers/char/virtio_console.c, branch master</title>
<subtitle>Linux kernel stable tree</subtitle>
<id>https://git.landau.one/pub/scm/linux/kernel/git/stable/linux.git/atom?h=master</id>
<link rel='self' href='https://git.landau.one/pub/scm/linux/kernel/git/stable/linux.git/atom?h=master'/>
<link rel='alternate' type='text/html' href='https://git.landau.one/pub/scm/linux/kernel/git/stable/linux.git/'/>
<updated>2026-09-05T17:28:39+00:00</updated>
<entry>
<title>virtio_console: allocate the port_buffer with the caller's gfp</title>
<updated>2026-09-05T17:28:39+00:00</updated>
<author>
<name>Breno Leitao</name>
<email>leitao@debian.org</email>
</author>
<published>2026-08-10T16:40:00+00:00</published>
<link rel='alternate' type='text/html' href='https://git.landau.one/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=b144dc5a24149ba9a0cb2197001973a74b8c93b2'/>
<id>urn:sha1:b144dc5a24149ba9a0cb2197001973a74b8c93b2</id>
<content type='text'>
put_chars() runs from the hvc console write path with preemption
disabled, so it asks alloc_buf() for GFP_ATOMIC. Only the data buffer
gets it: the struct port_buffer itself keeps the GFP_KERNEL default, so
the allocation can enter direct reclaim and sleep. A write to /dev/kmsg
on a CONFIG_DEBUG_ATOMIC_SLEEP kernel splats:

  BUG: sleeping function called from invalid context at ./include/linux/sched/mm.h:320
  in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 1, name: virtme-ng-init
  preempt_count: 1, expected: 0
  Preemption disabled at:
  [&lt;ffffffff813fd90d&gt;] vprintk_emit+0x17d/0x510
  Call Trace:
   &lt;TASK&gt;
   dump_stack_lvl+0x69/0xa0
   __might_resched+0x37a/0x4d0
   __kmalloc_cache_noprof+0x94/0x5f0
   put_chars+0x209/0x3e0
   hvc_console_print+0x234/0x640
   console_flush_all+0x4fc/0x950
   console_unlock+0xbf/0x1b0
   vprintk_emit+0x312/0x510
   devkmsg_emit+0xba/0x110
   devkmsg_write+0x21b/0x2e0
   vfs_write+0x4dc/0x9d0
   ksys_write+0x108/0x1e0
   do_syscall_64+0xfa/0x460
   &lt;/TASK&gt;

Pass gfp on to that allocation too.

Fixes: fc220d6be3c7 ("virtio_console: refactor __send_to_port() buffer ownership")
Signed-off-by: Breno Leitao &lt;leitao@debian.org&gt;
Acked-by: Sungho Bae &lt;baver.bae@lge.com&gt;
Tested-by: Florian Westphal &lt;fw@strlen.de&gt;
Link: https://patch.msgid.link/20260810-serial-v1-1-abbe51602c13@debian.org
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>virtio_console: fix race between hvc put_chars and virtqueue teardown on freeze</title>
<updated>2026-07-31T12:20:02+00:00</updated>
<author>
<name>Sungho Bae</name>
<email>baver.bae@lge.com</email>
</author>
<published>2026-06-03T18:37:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.landau.one/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=b187532ac6dba56df9367ae7698001b4623d4cba'/>
<id>urn:sha1:b187532ac6dba56df9367ae7698001b4623d4cba</id>
<content type='text'>
With no_console_suspend enabled, hvc console output can continue while
virtio_console is freezing. In that window, put_chars can still enqueue
buffers to the output virtqueue while virtcons_freeze is tearing queues
down, triggering a BUG_ON in virtqueue_detach_unused_buf_split:

  BUG_ON(vq-&gt;vq.num_free != vq-&gt;split.vring.num)

Add a pm_freezing flag to ports_device. Set it via smp_store_release()
at the start of virtcons_freeze(); put_chars() and __send_to_port() drop
output while the flag is set, checked via smp_load_acquire().

The check in __send_to_port() is placed under outvq_lock, making it
atomic with remove_port_data() which also acquires outvq_lock. Once
remove_port_data() returns for a given port, no concurrent
__send_to_port() can add buffers before remove_vqs() tears down the vq.

After setting pm_freezing, acquire and release outvq_lock for each port
(protected by ports_lock to prevent list manipulation races) before
calling virtio_reset_device(). A TX thread that already passed the
pm_freezing check may still hold outvq_lock while spinning for host
acknowledgment; the drain loop ensures all such threads have completed
before the device is reset.

Clear pm_freezing in virtcons_restore() only after all port-&gt;out_vq
pointers have been reassigned to the newly allocated virtqueues,
preventing TX paths from dereferencing freed vqs during restore.

Link: https://sashiko.dev/#/patchset/20260519162242.7324-1-baver.bae%40gmail.com
Signed-off-by: Sungho Bae &lt;baver.bae@lge.com&gt;
Link: https://patch.msgid.link/20260603183757.21587-5-baver.bae@gmail.com
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>virtio_console: fix control queue race during restore</title>
<updated>2026-07-31T12:20:02+00:00</updated>
<author>
<name>Sungho Bae</name>
<email>baver.bae@lge.com</email>
</author>
<published>2026-06-03T18:37:56+00:00</published>
<link rel='alternate' type='text/html' href='https://git.landau.one/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=952261953cf79820aa4350679882db0d4f71f493'/>
<id>urn:sha1:952261953cf79820aa4350679882db0d4f71f493</id>
<content type='text'>
In virtcons_restore(), after virtio_device_ready() sets DRIVER_OK, the
device becomes active. If the control receive queue (c_ivq) is populated
immediately, the host can instantly deliver pending control messages
(e.g., VIRTIO_CONSOLE_PORT_REMOVE).

This triggers the control_work_handler(), which can modify the
portdev-&gt;ports list concurrently with the unprotected list_for_each_entry
loop in virtcons_restore(), leading to list corruption or Use-After-Free.

Fix this by deferring the population of the control receive queue
(fill_queue for c_ivq) until after the list iteration is complete. This
ensures the host cannot inject control messages during the vulnerable
window.

Signed-off-by: Sungho Bae &lt;baver.bae@lge.com&gt;
Link: https://patch.msgid.link/20260603183757.21587-4-baver.bae@gmail.com
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>virtio_console: fix hot-unplug races in TX paths</title>
<updated>2026-07-31T12:20:02+00:00</updated>
<author>
<name>Sungho Bae</name>
<email>baver.bae@lge.com</email>
</author>
<published>2026-06-03T18:37:55+00:00</published>
<link rel='alternate' type='text/html' href='https://git.landau.one/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=a616ad344d9f7fe6abc17aa0a43bba93fb077384'/>
<id>urn:sha1:a616ad344d9f7fe6abc17aa0a43bba93fb077384</id>
<content type='text'>
When a port is hot-unplugged, unplug_port() nullifies port-&gt;portdev.
However, concurrent TX paths (__send_to_port, put_chars) could read a
stale pointer or encounter a NULL pointer dereference.

Add READ_ONCE(port-&gt;portdev) and NULL checks in the TX paths. In
__send_to_port(), move the out_vq assignment inside the outvq_lock and
check portdev under the lock. Correspondingly, update unplug_port() to
NULL out port-&gt;portdev while holding the outvq_lock to serialize with
__send_to_port().

In put_chars(), return count instead of 0 on unplug to prevent the hvc
layer from spinning in an infinite retry loop.

Signed-off-by: Sungho Bae &lt;baver.bae@lge.com&gt;
Link: https://patch.msgid.link/20260603183757.21587-3-baver.bae@gmail.com
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>virtio_console: refactor __send_to_port() buffer ownership</title>
<updated>2026-07-31T12:20:02+00:00</updated>
<author>
<name>Sungho Bae</name>
<email>baver.bae@lge.com</email>
</author>
<published>2026-06-03T18:37:54+00:00</published>
<link rel='alternate' type='text/html' href='https://git.landau.one/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=fc220d6be3c7e484b83f92bf6327e17c1ab1d962'/>
<id>urn:sha1:fc220d6be3c7e484b83f92bf6327e17c1ab1d962</id>
<content type='text'>
Modify __send_to_port() to take ownership of a struct port_buffer *
instead of a void * raw buffer.

Previously, put_chars() would pass a raw kmemdup'd buffer and free it
immediately after __send_to_port() returned. This caused a potential
Use-After-Free and data corruption if the virtqueue was shared with
nonblocking writers, as virtqueue_get_buf() might return an older
completed buffer, causing the newly added buffer to be kfree'd while the
host is still DMAing from it.

By transferring ownership of the allocated port_buffer to __send_to_port(),
we ensure that the exact buffer returned by the host is the one that gets
freed, resolving the memory lifecycle mismatch.

Signed-off-by: Sungho Bae &lt;baver.bae@lge.com&gt;
Link: https://patch.msgid.link/20260603183757.21587-2-baver.bae@gmail.com
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>virtio_console: take a kref in find_port_by_vq() to fix port UAF</title>
<updated>2026-07-31T12:18:50+00:00</updated>
<author>
<name>Hari Mishal</name>
<email>harimishal1@gmail.com</email>
</author>
<published>2026-07-17T15:06:22+00:00</published>
<link rel='alternate' type='text/html' href='https://git.landau.one/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=18dd0b4e489e4f0e3b748cf36ccb909c75a3efab'/>
<id>urn:sha1:18dd0b4e489e4f0e3b748cf36ccb909c75a3efab</id>
<content type='text'>
find_port_by_vq() returns a raw struct port pointer without taking a
reference on it, unlike find_port_by_devt_in_portdev() which does.
find_port_by_vq()'s only two callers, in_intr() and out_intr(), run as
virtqueue interrupt callbacks, entirely independent of and possibly
concurrently with unplug_port(), which itself runs from a workqueue when
the host sends a VIRTIO_CONSOLE_PORT_REMOVE control message.

unplug_port() removes the port from portdev-&gt;ports under ports_lock,
then later drops its last reference with kref_put(), freeing it via
remove_port(). find_port_by_vq() also walks portdev-&gt;ports under
ports_lock, so if it finds the port still on the list, the list removal,
and therefore the eventual kref_put(), has not happened yet, and taking
a reference at that point is always safe. Without doing so,
in_intr()/out_intr() can be left holding a pointer to a port that
unplug_port() frees on another core before they are done using it.

Both triggers are host-controlled as the host decides when to send the
PORT_REMOVE control message and when to kick the port's data vq. So a
malicious backend could race the two on purpose, without any guest side
cooperation. The freed object is a generic kmalloc allocation containing
a wait_queue_head_t, which in_intr()/out_intr() pass to
wake_up_interruptible() after touching the stale pointer.
wake_up_interruptible() invokes a function pointer read out of the wait
queue's entries. If the freed slab slot is reclaimed with attacker
influenced content before that call, then this is an arbitrary function
call primitive rather than just undefined behaviour.

Take a reference in find_port_by_vq() while still holding ports_lock,
matching find_port_by_devt_in_portdev(), and release it in in_intr() and
out_intr() once they are done with the port.

Signed-off-by: Hari Mishal &lt;harimishal1@gmail.com&gt;
Link: https://patch.msgid.link/20260717150622.23636-1-harimishal1@gmail.com
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>virtio_console: fix endian conversion in handle_control_message()</title>
<updated>2026-07-17T14:22:40+00:00</updated>
<author>
<name>Ben Dooks</name>
<email>ben.dooks@codethink.co.uk</email>
</author>
<published>2026-06-23T09:21:41+00:00</published>
<link rel='alternate' type='text/html' href='https://git.landau.one/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=f5af7132db239c5d13f20b7ac01db62b62830fb1'/>
<id>urn:sha1:f5af7132db239c5d13f20b7ac01db62b62830fb1</id>
<content type='text'>
There are a couple of prints in handle_control_message() which should
have converted cpkt-&gt;id through virtio32_to_cpu() before passing to
a print.

This fixes the following (prototype) sparse warnings:
drivers/char/virtio_console.c:1538:17: warning: incorrect type in argument 4 (different base types)
drivers/char/virtio_console.c:1538:17:    expected unsigned int
drivers/char/virtio_console.c:1538:17:    got restricted __virtio32 [usertype] id
drivers/char/virtio_console.c:1553:25: warning: incorrect type in argument 3 (different base types)
drivers/char/virtio_console.c:1553:25:    expected unsigned int
drivers/char/virtio_console.c:1553:25:    got restricted __virtio32 [usertype] id

Signed-off-by: Ben Dooks &lt;ben.dooks@codethink.co.uk&gt;
Acked-by: Arnd Bergmann &lt;arnd@arndb.de&gt;
Reviewed-by: Amit Shah &lt;amit@kernel.org&gt;
Link: https://patch.msgid.link/20260623092141.631355-1-ben.dooks@codethink.co.uk
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>virtio_console: read size from config space during device init</title>
<updated>2026-06-10T06:14:02+00:00</updated>
<author>
<name>Filip Hejsek</name>
<email>filip.hejsek@gmail.com</email>
</author>
<published>2026-02-23T17:37:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.landau.one/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=b3592a32b34f37874dc94aa1a0d15c4334ed86ca'/>
<id>urn:sha1:b3592a32b34f37874dc94aa1a0d15c4334ed86ca</id>
<content type='text'>
Previously, the size was only read upon receiving the config interrupt.
This interrupt is sent when the size changes. However, we also need to
read the initial size.

Also make sure to only read the size from config if F_SIZE is enabled.

Fixes: 9778829cffd4 ("virtio: console: Store each console's size in the console structure")
Signed-off-by: Filip Hejsek &lt;filip.hejsek@gmail.com&gt;
Signed-off-by: Michael S. Tsirkin &lt;mst@redhat.com&gt;
Message-ID: &lt;20260223-virtio-console-fix-v1-1-0cf08303b428@gmail.com&gt;
</content>
</entry>
<entry>
<title>Convert more 'alloc_obj' cases to default GFP_KERNEL arguments</title>
<updated>2026-02-22T04:03:00+00:00</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2026-02-22T04:03:00+00:00</published>
<link rel='alternate' type='text/html' href='https://git.landau.one/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=32a92f8c89326985e05dce8b22d3f0aa07a3e1bd'/>
<id>urn:sha1:32a92f8c89326985e05dce8b22d3f0aa07a3e1bd</id>
<content type='text'>
This converts some of the visually simpler cases that have been split
over multiple lines.  I only did the ones that are easy to verify the
resulting diff by having just that final GFP_KERNEL argument on the next
line.

Somebody should probably do a proper coccinelle script for this, but for
me the trivial script actually resulted in an assertion failure in the
middle of the script.  I probably had made it a bit _too_ trivial.

So after fighting that far a while I decided to just do some of the
syntactically simpler cases with variations of the previous 'sed'
scripts.

The more syntactically complex multi-line cases would mostly really want
whitespace cleanup anyway.

Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
<entry>
<title>Convert 'alloc_flex' family to use the new default GFP_KERNEL argument</title>
<updated>2026-02-22T01:09:51+00:00</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2026-02-22T01:06:51+00:00</published>
<link rel='alternate' type='text/html' href='https://git.landau.one/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=323bbfcf1ef8836d0d2ad9e2c1f1c684f0e3b5b3'/>
<id>urn:sha1:323bbfcf1ef8836d0d2ad9e2c1f1c684f0e3b5b3</id>
<content type='text'>
This is the exact same thing as the 'alloc_obj()' version, only much
smaller because there are a lot fewer users of the *alloc_flex()
interface.

As with alloc_obj() version, this was done entirely with mindless brute
force, using the same script, except using 'flex' in the pattern rather
than 'objs*'.

Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
</feed>
