Re: [bug report] libceph: (linger) requests not removed from need_resend/need_resend_linger in error case
Viacheslav Dubeyko <[email protected]>
| Newsgroups | org.kernel.vger.ceph-devel |
|---|---|
| Message-ID | <[email protected]> |
CC: [email protected] On Wed, 2026-06-17 at 15:12 +0200, Raphael Zimmer wrote: > Hi, > I discovered an issue in the libceph module. It may lead to a > stack-use-after-return and, therefore, overwriting stack memory, or > triggering a BUG_ON() assertion. The behavior can be triggered by > messages of type CEPH_MSG_OSD_MAP from a Ceph monitor or OSD. > > The problem is as follows: > When receiving a message of type CEPH_MSG_OSD_MAP, it is handled in > ceph_osdc_handle_map(). This function creates two local stack > variables > that track (linger) requests that need to be resent. For requests, > this > is an rb_root variable named need_resend, and for linger requests, a > list_head named need_resend_linger. Subsequently, handle_one_map() is > called, which calls scan_requests() for each osd. In scan_requests, > the > new target is calculated for each (linger) request, and, in case of > CALC_TARGET_NEED_RESEND, they are inserted into the previously > created > list/rbtree. All requests in these structures are kicked off to their > new target osd after processing all osdmaps. When doing this, they > are > removed again from the list/rbtree. If an error occurs during > processing, e.g., because an osdmap is corrupted, > ceph_osdc_handle_map() > jumps to the bad label and doesn't call kick_requests(). Therefore, > the > (linger) requests are still inserted in the list/rbtree, which now > doesn't have a head/root anymore. This leads to requests having > invalid > pointers to stack memory. Subsequently, this can have multiple > effects. > If the (linger) request should be inserted (for resending) the next > time > a (valid) osdmap arrives, the respective structures still have values > that suggest they are inserted. For a linger request, this results in > not being able to insert it again, and for requests, a BUG_ON() > assertion may be triggered in the rbtree insertion function. > Furthermore, if (during processing a subsequent osdmap) > recalc_linger_target() returns CALC_TARGET_POOL_DNE to > scan_requests() > for the linger request still having a pointer to need_resend_linger, > list_del_init() is called, resulting in accessing the invalid pointer > to > stack memory. > > I suggest fixing this issue by removing all (linger) requests from > the > list/rbtree after jumping to the bad label if an error occurs, > similar > to how it is handled in kick_requests. > I will send a proposed patch in reply to this email. > > Best regards, > Raphael