Fix 2 heap buffer overwrites. Fix use-after-free. Fix abort() in librthread. Index: lib/clip/clip_x11.cpp --- lib/clip/clip_x11.cpp.orig +++ lib/clip/clip_x11.cpp @@ -188,7 +188,7 @@ class Manager { (public) if (f == text_format()) { // Add an extra null char if (n < len) - (*it->second)[n++] = 0; + buf[n] = 0; } return true; @@ -440,14 +440,15 @@ class Manager { (public) event->property, m_target_atom); if (reply) { + xcb_atom_t reply_type = reply->type; // In this case, We're going to receive the clipboard content in // chunks of data with several PropertyNotify events. - if (reply->type == get_atom(INCR)) { + if (reply_type == get_atom(INCR)) { free(reply); reply = get_and_delete_property(event->requestor, event->property, - reply->type); + reply_type); if (reply) { if (xcb_get_property_value_length(reply) == 4) { uint32_t n = *(uint32_t*)xcb_get_property_value(reply); @@ -526,7 +527,6 @@ class Manager { (public) void copy_reply_data(xcb_get_property_reply_t* reply) { const uint8_t* src = (const uint8_t*)xcb_get_property_value(reply); size_t n = xcb_get_property_value_length(reply); - n = n * (reply->format/8); size_t req = m_reply_offset+n; if (!m_reply_data) { @@ -588,6 +588,7 @@ class Manager { (public) if (status == std::cv_status::no_timeout) { // If the condition variable was notified, it means that the // callback was called correctly. + lock.release(); return m_callback_result; } } while (m_incr_received); @@ -595,6 +596,7 @@ class Manager { (public) // Reset callback m_callback = notify_callback(); + lock.release(); return false; }