When a bundle transaction fails with multiple errors,
bundle_print_errors() crashes with SIGSEGV if an error's XID doesn't
match any request in the requests list.
This happens because LIST_FOR_EACH_CONTINUE sets bmsg to NULL when it
exhausts the list without finding a match. On the next error iteration,
the list evaluation crashes with a NULL pointer dereference.
Control message errors (TIMEOUT for OPEN_REQUEST, BAD_ID for COMMIT,
etc...) have XIDs that never match entries in the requests list.
When the bundle times out and a subsequent error is triggered, both
errors are collected, triggering the crash.
Fix by checking if bmsg is NULL before entering the inner loop.
The existing fallback to the truncated payload from the error itself
handles the non-matching case correctly.
Fixes: 506c1ddb3404 ("vconn: Better bundle error management.")
Reported-at: https://redhat.atlassian.net/browse/FDP-4392
Signed-off-by: David Marchand <[email protected]>
---
utilities/ovs-ofctl.c | 27 +++++++++++++++------------
1 file changed, 15 insertions(+), 12 deletions(-)
diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c
index 871d643d98..a38798b068 100644
--- a/utilities/ovs-ofctl.c
+++ b/utilities/ovs-ofctl.c
@@ -762,18 +762,21 @@ bundle_print_errors(struct ovs_list *errors, struct
ovs_list *requests,
const struct ofp_header *ofp_msg = payload.data;
size_t msg_len = payload.size;
- /* Find the failing message from the requests list to be able to
- * dump the whole message. We assume the errors are returned in
- * the same order as in which the messages are sent to get O(n)
- * rather than O(n^2) processing here. If this heuristics fails we
- * may print the truncated hexdumps instead. */
- LIST_FOR_EACH_CONTINUE (bmsg, list_node, requests) {
- const struct ofp_header *oh = bmsg->data;
-
- if (oh->xid == error_xid) {
- ofp_msg = oh;
- msg_len = bmsg->size;
- break;
+ if (bmsg) {
+ /* Find the failing message from the requests list to be able
+ * to dump the whole message. We assume the errors are
+ * returned in the same order as in which the messages are sent
+ * to get O(n) rather than O(n^2) processing here. If this
+ * heuristics fails we may print the truncated hexdumps
+ * instead. */
+ LIST_FOR_EACH_CONTINUE (bmsg, list_node, requests) {
+ const struct ofp_header *oh = bmsg->data;
+
+ if (oh->xid == error_xid) {
+ ofp_msg = oh;
+ msg_len = bmsg->size;
+ break;
+ }
}
}
fprintf(stderr, "Error %s for: ", ofperr_get_name(ofperr));
--
2.54.0
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev