[PATCH] net/tap-linux.c: avoid abort when setting vnet_hdr_len on invalid fd

Houqi (Nick) Zuo posted 1 patch 4 days, 7 hours ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20250924070216.1802043-1-hzuo@redhat.com
Maintainers: Jason Wang <jasowang@redhat.com>
net/tap-linux.c | 1 -
1 file changed, 1 deletion(-)
[PATCH] net/tap-linux.c: avoid abort when setting vnet_hdr_len on invalid fd
Posted by Houqi (Nick) Zuo 4 days, 7 hours ago
When QEMU creates a tap device automatically and the tap device is
manually removed from the host while the guest is running, the tap
device file descriptor becomes invalid. Later, when the guest executes
shutdown, the tap_fd_set_vnet_hdr_len() function may be called and
abort QEMU with a core dump when attempting to use the invalid fd.

This patch removes the abort() call. If the fd is found to be in a
bad state (e.g., EBADFD or ENODEV), the function will print an error message.

The expected behavior for this negative test case is that QEMU should
report an error but continue running rather than aborting.

Testing:
- Start QEMU with automatically created tap device
- Manually remove the tap device on the host
- Execute shutdown in the guest
- Verify QEMU reports an error but does not abort

(gdb) bt full
        tid = <optimized out>
        ret = 0
        pd = <optimized out>
        old_mask = {__val = {10}}
        ret = <optimized out>
        ret = <optimized out>
        save_stage = 1
        act = {__sigaction_handler = {sa_handler = 0x20, sa_sigaction = 0x20}, sa_mask = {__val = {16929458408262392576, 18446744073709550848, 139737042419943, 139737042419943, 0, 94049703655600, 139737042419943, 139737042670528, 18446744073709550328, 77, 139705603579344, 18446744073709551615, 139737041472378, 139705595179568, 16929458408262392576, 94049679794864}}, sa_flags = 281695456, sa_restorer = 0xa}
        s = <optimized out>
        i = 0
        nc = 0x5589a730ab28
        n = 0x5589a72cfa10
        err = 0x0
        i = 0
        k = <optimized out>
        bad = <optimized out>
        vdev = 0x5589a72cfa10
        k = 0x5589a5c162b0
        i = 0
        vdev = <optimized out>
        proxy = 0x5589a72c7470
        i = 0
        bus = 0x5589a72cf990
        tmp = <optimized out>
        print_once_ = false
        access_mask = 255
        access_size = 1
        i = 0
        r = 0
        reentrancy_guard_applied = <optimized out>
        size = <optimized out>
        val = 6
        result = 0
        release_lock = <optimized out>
        result = 0
        buf = 0x7f1711da6028 <error: Cannot access memory at address 0x7f1711da6028>
--Type <RET> for more, q to quit, c to continue without paging--
        l = <optimized out>
        mr_addr = 6
        mr = 0x0
        _rcu_read_auto = 0x1
        result = 0
        fv = 0x2956
        attrs = {secure = 0, space = 0, user = 0, memory = 0, debug = 0, requester_id = 0, pid = 0, address_type = 0, unspecified = false, _reserved1 = 0 '\000', _reserved2 = 0}
        run = 0x7f1711da6000
        ret = <optimized out>
        run_ret = <optimized out>
        r = <optimized out>
        cpu = <optimized out>
        __clframe = {__cancel_routine = <optimized out>, __cancel_arg = 0x0, __do_it = 1, __cancel_type = <optimized out>}
        qemu_thread_args = 0x5589a5d72580
        start_routine = 0x55899a918850 <kvm_vcpu_thread_fn>
        arg = 0x5589a5d68b40
        r = 0x0
        ret = <optimized out>
        pd = <optimized out>
        out = <optimized out>
        unwind_buf = {cancel_jmp_buf = {{jmp_buf = {32, 8894544057743421332, -1288, 0, 140726164742416, 140726164742679, -8831356496486092908, -8844535456800460908}, mask_was_saved = 0}}, priv = {pad = {0x0, 0x0, 0x0, 0x0}, data = {prev = 0x0, cleanup = 0x0, canceltype = 0}}}
        not_first_call = <optimized out>

Signed-off-by: Houqi (Nick) Zuo <hzuo@redhat.com>
---
 net/tap-linux.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/net/tap-linux.c b/net/tap-linux.c
index e832810665..37a53416e8 100644
--- a/net/tap-linux.c
+++ b/net/tap-linux.c
@@ -206,7 +206,6 @@ void tap_fd_set_vnet_hdr_len(int fd, int len)
     if (ioctl(fd, TUNSETVNETHDRSZ, &len) == -1) {
         fprintf(stderr, "TUNSETVNETHDRSZ ioctl() failed: %s. Exiting.\n",
                 strerror(errno));
-        abort();
     }
 }
 
-- 
2.47.3