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 <[email protected]>
---
 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


Reply via email to