Skip to content

Commit 6d232e3

Browse files
committed
Fix crash when handling socket closure early
When the MCTP daemon closes the socket, the event loop may still deliver `EPOLLIN` alongside `POLLHUP`. Previously, the callback did not explicitly check for `POLLHUP` before attempting to receive data via `recvMsg()`. This led to a scenario where `recvMsg()` was called on a socket that had already been closed, causing undefined behavior or memory corruption (e.g., during buffer allocation or cleanup). While `recvMsg()` returned a failure code (`PLDM_REQUESTER_RECV_FAIL`), the subsequent call to `io.get_event().exit(0)` would result in a crash due to the corrupted state. This change adds an early check for `POLLHUP` (and `POLLERR`) at the beginning of the IO callback and exits the event loop immediately when detected. This prevents any further I/O operations on a dead socket and ensures a clean shutdown without triggering undefined behavior. Here is the gdb backtrace & its corresponding source code[1]: ``` Core was generated by `/usr/bin/pldmd'. Program terminated with signal SIGABRT, Aborted. #0 __pthread_kill_implementation (threadid=<optimized out>, signo=6, no_tid=<optimized out>) at pthread_kill.c:44 #1 0x763c9344 in __GI_raise (sig=sig@entry=6) at /usr/src/debug/glibc/2.39+git/sysdeps/posix/raise.c:26 #2 0x763b3f80 in __GI_abort () at abort.c:79 openbmc#3 0x764026e4 in __libc_message_impl (fmt=0x764e8050 "%s\n") at /usr/src/debug/glibc/2.39+git/sysdeps/posix/libc_fatal.c:132 openbmc#4 0x76419d8c in malloc_printerr (str=<optimized out>) at malloc.c:5772 openbmc#5 0x7641a950 in _int_free_create_chunk (av=0x20, av@entry=0x764f05fc <main_arena>, p=0x1000, p@entry=0x1c7f898, size=<optimized out>, size@entry=152, nextchunk=nextchunk@entry=0x1c7f930, nextsize=nextsize@entry=32) at malloc.c:4735 openbmc#6 0x7641bf94 in _int_free_merge_chunk (av=0x764f05fc <main_arena>, p=0x1c7f898, size=152) at malloc.c:4700 openbmc#7 0x7641c298 in _int_free (av=<optimized out>, p=<optimized out>, have_lock=<optimized out>, have_lock@entry=0) at malloc.c:4646 openbmc#8 0x7641ec20 in __GI___libc_free (mem=mem@entry=0x1c7f8a0) at malloc.c:3398 openbmc#9 0x7681a3b8 in source_free (s=0x1c7f8a0) at /usr/src/debug/systemd/255.4/src/libsystemd/sd-event/sd-event.c:1125 openbmc#10 0x7681e6d8 in event_source_free (s=<optimized out>) at /usr/src/debug/systemd/255.4/src/libsystemd/sd-event/sd-event.c:2590 openbmc#11 sd_event_source_unref (p=<optimized out>) at /usr/src/debug/systemd/255.4/src/libsystemd/sd-event/sd-event.c:2595 openbmc#12 0x767eb624 in sd_bus_detach_event (bus=<optimized out>) at /usr/src/debug/systemd/255.4/src/libsystemd/sd-bus/sd-bus.c:3887 openbmc#13 0x767e0888 in sd_bus_close (bus=0x1bb4950) at /usr/src/debug/systemd/255.4/src/libsystemd/sd-bus/sd-bus.c:1772 openbmc#14 sd_bus_close (bus=0x1bb4950) at /usr/src/debug/systemd/255.4/src/libsystemd/sd-bus/sd-bus.c:1759 openbmc#15 0x767eea30 in quit_callback (event=<optimized out>, userdata=0x1bb4950) at /usr/src/debug/systemd/255.4/src/libsystemd/sd-bus/sd-bus.c:3726 openbmc#16 0x76826288 in source_dispatch (s=s@entry=0x1c1d718) at /usr/src/debug/systemd/255.4/src/libsystemd/sd-event/sd-event.c:4227 openbmc#17 0x7682697c in dispatch_exit (e=0x1bb42c0) at /usr/src/debug/systemd/255.4/src/libsystemd/sd-event/sd-event.c:4349 openbmc#18 sd_event_dispatch (e=<optimized out>, e@entry=0x1bb42c0) at /usr/src/debug/systemd/255.4/src/libsystemd/sd-event/sd-event.c:4801 openbmc#19 0x768282c8 in sd_event_run (e=<optimized out>, timeout=<optimized out>) at /usr/src/debug/systemd/255.4/src/libsystemd/sd-event/sd-event.c:4869 openbmc#20 0x76828558 in sd_event_loop (e=<optimized out>) at /usr/src/debug/systemd/255.4/src/libsystemd/sd-event/sd-event.c:4891 openbmc#21 0x7678f514 in sdeventplus::internal::SdEventImpl::sd_event_loop (event=<optimized out>, this=<optimized out>) at /usr/src/debug/sdeventplus/0.1+git/src/sdeventplus/internal/sdevent.cpp:86 openbmc#22 sdeventplus::Event::loop (this=this@entry=0x7ed298e0) at /usr/src/debug/sdeventplus/0.1+git/src/sdeventplus/event.cpp:81 openbmc#23 0x004f904c in main (argc=<optimized out>, argv=<optimized out>) at /usr/src/debug/pldm/1.0+git/pldmd/pldmd.cpp:433 ``` [1]: https://github.com/ibm-openbmc/pldm/blob/424d866fe97b20343e7733fcab462e0ea1035379/pldmd/pldmd.cpp#L433 Change-Id: Idc5fb2cb849f2af7c12b67cdd509d81b2587c8ba Signed-off-by: Manojkiran Eda <[email protected]>
1 parent 6f67ca7 commit 6d232e3

File tree

1 file changed

+8
-1
lines changed

1 file changed

+8
-1
lines changed

pldmd/pldmd.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,14 @@ int main(int argc, char** argv)
347347
fwManager.get(), platformManager.get()});
348348
auto callback = [verbose, &invoker, &reqHandler, &fwManager, &pldmTransport,
349349
TID](IO& io, int fd, uint32_t revents) mutable {
350-
if (!(revents & EPOLLIN))
350+
if (revents & (POLLHUP | POLLERR))
351+
{
352+
warning("Transport Socket hang-up or error. IO Exiting.");
353+
io.get_event().exit(0);
354+
return;
355+
}
356+
357+
else if (!(revents & EPOLLIN))
351358
{
352359
return;
353360
}

0 commit comments

Comments
 (0)