summaryrefslogtreecommitdiff
path: root/utilities/ovs-ofctl.c
diff options
context:
space:
mode:
authorBen Pfaff <blp@ovn.org>2017-06-13 16:04:29 -0700
committerBen Pfaff <blp@ovn.org>2017-06-14 08:21:03 -0700
commit209aa4ad1370ed00f054fa832b016b92f250f99b (patch)
tree261b2cc157fd72fa2b8ac6e09b77d3ee3a13e946 /utilities/ovs-ofctl.c
parent53611f7b05460ee60cc94d67e14ac8945de4b4f9 (diff)
downloadopenvswitch-209aa4ad1370ed00f054fa832b016b92f250f99b.tar.gz
ovs-ofctl: Avoid read overrun in ofperr_decode_msg().
vconn_add_bundle_error() was keeping at most 64 bytes of an OpenFlow error message, then it was passing it to ofperr_decode_msg(), which assumed that the full message was available. This led to a buffer overread. There's no good reason why it was only keeping the first 64 bytes, so this commit changes it to keep the whole error message, sidestepping the problem. struct vconn_bundle_error only existed for this special case, so remove it in favor of a chain of ofpbufs. Found via gcc's address sanitizer. Reported-by: Lance Richardson <lrichard@redhat.com> Fixes: 506c1ddb3404 ("vconn: Better bundle error management.") Signed-off-by: Ben Pfaff <blp@ovn.org> Acked-by: Jarno Rajahlame <jarno@ovn.org>
Diffstat (limited to 'utilities/ovs-ofctl.c')
-rw-r--r--utilities/ovs-ofctl.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c
index dca9be3a5..95989eb11 100644
--- a/utilities/ovs-ofctl.c
+++ b/utilities/ovs-ofctl.c
@@ -699,16 +699,18 @@ static void
bundle_print_errors(struct ovs_list *errors, struct ovs_list *requests,
const char *vconn_name)
{
- struct vconn_bundle_error *error, *next;
+ struct ofpbuf *error, *next;
struct ofpbuf *bmsg;
INIT_CONTAINER(bmsg, requests, list_node);
LIST_FOR_EACH_SAFE (error, next, list_node, errors) {
+ const struct ofp_header *error_oh = error->data;
+ ovs_be32 error_xid = error_oh->xid;
enum ofperr ofperr;
struct ofpbuf payload;
- ofperr = ofperr_decode_msg(&error->ofp_msg, &payload);
+ ofperr = ofperr_decode_msg(error_oh, &payload);
if (!ofperr) {
fprintf(stderr, "***decode error***");
} else {
@@ -724,7 +726,7 @@ bundle_print_errors(struct ovs_list *errors, struct ovs_list *requests,
LIST_FOR_EACH_CONTINUE (bmsg, list_node, requests) {
const struct ofp_header *oh = bmsg->data;
- if (oh->xid == error->ofp_msg.xid) {
+ if (oh->xid == error_xid) {
ofp_msg = oh;
msg_len = bmsg->size;
break;
@@ -735,7 +737,7 @@ bundle_print_errors(struct ovs_list *errors, struct ovs_list *requests,
verbosity + 1);
}
ofpbuf_uninit(&payload);
- free(error);
+ ofpbuf_delete(error);
}
fflush(stderr);
}