Opened 9 months ago

Closed 2 days ago

#891 closed defect (fixed)

Reading /loc/bd/initrd causes rd to crash

Reported by: Jiri Svoboda Owned by: Jiri Svoboda
Priority: minor Milestone: 0.16.1
Component: helenos/unspecified Version: mainline
Keywords: Cc:
Blocker for: Depends on:
See also:

Description (last modified by Jiri Svoboda)

An attempt to read /loc/bd/initrd as a file causes rd server to stop with an assertion failure:

# cp /loc/bd/initrd /tmp/x
[init:rd(5)] Assertion failed (futex->whandle != CAP_NIL) in task 5,
file "../uspace/lib/c/generic/thread/../private/./futex.h", line 124.
[init:rd(5)] 0x0000000000437ea0: 0x000000000040fca5() stacktrace_kio_print
[init:rd(5)] 0x0000000000437ed0: 0x000000000040c418() __helenos_assert_abort
[init:rd(5)] 0x0000000000437f00: 0x0000000000406083() __futex_lock
[init:rd(5)] 0x0000000000437f10: 0x00000000004057ce() fibril_rmutex_lock
[init:rd(5)] 0x0000000000437f40: 0x00000000004062a9() mpsc_send
[init:rd(5)] 0x0000000000437fe0: 0x000000000040136d() async_manager_fibril
[init:rd(5)] 0x0000000000437ff0: 0x0000000000405122() _fibril_main
[init:rd(5)] -- end of stack trace --
[/srv/taskmon(47)] taskmon: Task 5 fault in thread 0xffffffff81e3a9c0.

Change History (5)

comment:1 by Jiri Svoboda, 9 months ago

Description: modified (diff)

comment:2 by Jiri Svoboda, 6 months ago

Milestone: 0.15.10.16.1

Milestone renamed

comment:3 by Jiri Svoboda, 4 days ago

I root caused the bug. Here's the chain of events:

  1. initrd receives CONNECT_ME_TO
  2. starts connection_fibril() and creates conn
  3. rd_conn calls bd_conn()
  4. bd_conn() fails to receive callback connection request
  5. bd_conn() exits
  6. connection handler terminates
  7. connection_fibril() destroys connection conn/ destroys mpsc and terminates
  8. async receives another call with request_label set to conn
  9. route_call() reads the stale request_label and tries to send the message to the destroyed mpsc channel
  10. fibril_rmutex_lock() trips over the destroyed futex

Root cause: bd_conn() exits without processing all the messages. This causes async server code to trip on a freed connection structure. Async framework does not keep track of this and relies on user connection handler to process all messages before exiting.

comment:4 by Jiri Svoboda, 2 days ago

Owner: set to Jiri Svoboda
Status: newaccepted

comment:5 by Jiri Svoboda, 2 days ago

Resolution: fixed
Status: acceptedclosed
Note: See TracTickets for help on using tickets.