2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-22 09:58:01 +00:00

ofproto: Fix crash processing malformed Bundle Add message.

When an OpenFlow Bundle Add message is received, a bundle entry is
created and the OpenFlow message embedded in the bundle add message is
processed.  If any error is encountered while processing the embedded
message, the bundle entry is freed. The bundle entry free function
assumes that the entry has been populated with a properly formatted
OpenFlow message and performs some message specific cleanup actions .
This assumption does not hold true in the error case and OVS crashes
when performing the cleanup.

The fix is in case of errors, simply free the bundle entry without
attempting to perform any embedded message cleanup

Signed-off-by: Anju Thomas <anju.thomas@ericsson.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
This commit is contained in:
Anju Thomas 2018-05-07 22:58:06 +05:30 committed by Ben Pfaff
parent fb8635c538
commit d0485f488f
2 changed files with 13 additions and 21 deletions

View File

@ -58,8 +58,6 @@ struct ofp_bundle {
struct ovs_list msg_list; /* List of 'struct bundle_message's */ struct ovs_list msg_list; /* List of 'struct bundle_message's */
}; };
static inline struct ofp_bundle_entry *ofp_bundle_entry_alloc(
enum ofptype type, const struct ofp_header *oh);
static inline void ofp_bundle_entry_free(struct ofp_bundle_entry *); static inline void ofp_bundle_entry_free(struct ofp_bundle_entry *);
enum ofperr ofp_bundle_open(struct ofconn *, uint32_t id, uint16_t flags, enum ofperr ofp_bundle_open(struct ofconn *, uint32_t id, uint16_t flags,
@ -72,17 +70,6 @@ enum ofperr ofp_bundle_add_message(struct ofconn *, uint32_t id,
void ofp_bundle_remove__(struct ofconn *, struct ofp_bundle *); void ofp_bundle_remove__(struct ofconn *, struct ofp_bundle *);
static inline struct ofp_bundle_entry *
ofp_bundle_entry_alloc(enum ofptype type, const struct ofp_header *oh)
{
struct ofp_bundle_entry *entry = xmalloc(sizeof *entry);
entry->type = type;
entry->msg = xmemdup(oh, ntohs(oh->length));
return entry;
}
static inline void static inline void
ofp_bundle_entry_free(struct ofp_bundle_entry *entry) ofp_bundle_entry_free(struct ofp_bundle_entry *entry)
{ {

View File

@ -7906,7 +7906,6 @@ handle_bundle_add(struct ofconn *ofconn, const struct ofp_header *oh)
struct ofproto *ofproto = ofconn_get_ofproto(ofconn); struct ofproto *ofproto = ofconn_get_ofproto(ofconn);
enum ofperr error; enum ofperr error;
struct ofputil_bundle_add_msg badd; struct ofputil_bundle_add_msg badd;
struct ofp_bundle_entry *bmsg;
enum ofptype type; enum ofptype type;
error = reject_slave_controller(ofconn); error = reject_slave_controller(ofconn);
@ -7919,7 +7918,8 @@ handle_bundle_add(struct ofconn *ofconn, const struct ofp_header *oh)
return error; return error;
} }
bmsg = ofp_bundle_entry_alloc(type, badd.msg); /* Allocate bundle entry and decode the embedded message. */
struct ofp_bundle_entry *bmsg = xmalloc(sizeof *bmsg);
struct ofpbuf ofpacts; struct ofpbuf ofpacts;
uint64_t ofpacts_stub[1024 / 8]; uint64_t ofpacts_stub[1024 / 8];
@ -7958,18 +7958,23 @@ handle_bundle_add(struct ofconn *ofconn, const struct ofp_header *oh)
} else { } else {
OVS_NOT_REACHED(); OVS_NOT_REACHED();
} }
ofpbuf_uninit(&ofpacts); ofpbuf_uninit(&ofpacts);
if (error) {
if (!error) { free(bmsg);
error = ofp_bundle_add_message(ofconn, badd.bundle_id, badd.flags, return error;
bmsg, oh);
} }
/* Now that the embedded message has been successfully decoded, finish up
* initializing the bundle entry. */
bmsg->type = type;
bmsg->msg = xmemdup(oh, ntohs(oh->length));
/* Add bundle entry to bundle. */
error = ofp_bundle_add_message(ofconn, badd.bundle_id, badd.flags,
bmsg, oh);
if (error) { if (error) {
ofp_bundle_entry_free(bmsg); ofp_bundle_entry_free(bmsg);
} }
return error; return error;
} }