Skip to content

Commit 8e73833

Browse files
TomCodeLVblp
authored andcommitted
lib: added check to prevent int overflow
If enough large input is given ofpact_finish will fail. Implemented ofpbuf_oversized function to check for oversized buffer. Checks were added for parse functions and error messages returned. Basic manual testing performed. Reviewed-by: Yifeng Sun <pkusunyifeng@gmail.com> Reported-by: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=12972 Signed-off-by: Toms Atteka <cpp.code.lv@gmail.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
1 parent 723b6ab commit 8e73833

File tree

4 files changed

+45
-0
lines changed

4 files changed

+45
-0
lines changed

include/openvswitch/ofpbuf.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ char *ofpbuf_to_string(const struct ofpbuf *, size_t maxbytes);
162162
static inline struct ofpbuf *ofpbuf_from_list(const struct ovs_list *);
163163
void ofpbuf_list_delete(struct ovs_list *);
164164
static inline bool ofpbuf_equal(const struct ofpbuf *, const struct ofpbuf *);
165+
static inline bool ofpbuf_oversized(const struct ofpbuf *ofpacts);
165166

166167

167168
/* Frees memory that 'b' points to, as well as 'b' itself. */
@@ -272,6 +273,11 @@ static inline bool ofpbuf_equal(const struct ofpbuf *a, const struct ofpbuf *b)
272273
memcmp(a->data, b->data, a->size) == 0;
273274
}
274275

276+
static inline bool ofpbuf_oversized(const struct ofpbuf *ofpacts)
277+
{
278+
return (char *)ofpbuf_tail(ofpacts) - (char *)ofpacts->header > UINT16_MAX;
279+
}
280+
275281
#ifdef __cplusplus
276282
}
277283
#endif

lib/bundle.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,11 @@ bundle_parse__(const char *s, const struct ofputil_port_map *port_map,
183183
bundle = ofpacts->header;
184184
bundle->n_slaves++;
185185
}
186+
187+
if (ofpbuf_oversized(ofpacts)) {
188+
return xasprintf("input too big");
189+
}
190+
186191
ofpact_finish_BUNDLE(ofpacts, &bundle);
187192
bundle->basis = atoi(basis);
188193

lib/learn.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,11 @@ learn_parse__(char *orig, char *arg, const struct ofputil_port_map *port_map,
455455
learn = ofpacts->header;
456456
}
457457
}
458+
459+
if (ofpbuf_oversized(ofpacts)) {
460+
return xasprintf("input too big");
461+
}
462+
458463
ofpact_finish_LEARN(ofpacts, &learn);
459464

460465
return NULL;

lib/ofp-actions.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -989,6 +989,11 @@ parse_CONTROLLER(char *arg, const struct ofpact_parse_params *pp)
989989
controller = pp->ofpacts->header;
990990
controller->userdata_len = userdata_len;
991991
}
992+
993+
if (ofpbuf_oversized(pp->ofpacts)) {
994+
return xasprintf("input too big");
995+
}
996+
992997
ofpact_finish_CONTROLLER(pp->ofpacts, &controller);
993998
}
994999

@@ -3690,6 +3695,11 @@ parse_DEC_TTL(char *arg, const struct ofpact_parse_params *pp)
36903695
return xstrdup("dec_ttl_cnt_ids: expected at least one controller "
36913696
"id.");
36923697
}
3698+
3699+
if (ofpbuf_oversized(pp->ofpacts)) {
3700+
return xasprintf("input too big");
3701+
}
3702+
36933703
ofpact_finish_DEC_TTL(pp->ofpacts, &ids);
36943704
}
36953705
return NULL;
@@ -4443,6 +4453,11 @@ parse_ENCAP(char *arg, const struct ofpact_parse_params *pp)
44434453
/* ofpbuf may have been re-allocated. */
44444454
encap = pp->ofpacts->header;
44454455
encap->n_props = n_props;
4456+
4457+
if (ofpbuf_oversized(pp->ofpacts)) {
4458+
return xasprintf("input too big");
4459+
}
4460+
44464461
ofpact_finish_ENCAP(pp->ofpacts, &encap);
44474462
return NULL;
44484463
}
@@ -5772,6 +5787,11 @@ parse_NOTE(const char *arg, const struct ofpact_parse_params *pp)
57725787
struct ofpact_note *note = ofpbuf_at_assert(pp->ofpacts, start_ofs,
57735788
sizeof *note);
57745789
note->length = pp->ofpacts->size - (start_ofs + sizeof *note);
5790+
5791+
if (ofpbuf_oversized(pp->ofpacts)) {
5792+
return xasprintf("input too big");
5793+
}
5794+
57755795
ofpact_finish_NOTE(pp->ofpacts, &note);
57765796
return NULL;
57775797
}
@@ -5929,6 +5949,10 @@ parse_CLONE(char *arg, const struct ofpact_parse_params *pp)
59295949
pp->ofpacts->header = ofpbuf_push_uninit(pp->ofpacts, sizeof *clone);
59305950
clone = pp->ofpacts->header;
59315951

5952+
if (ofpbuf_oversized(pp->ofpacts)) {
5953+
return xasprintf("input too big");
5954+
}
5955+
59325956
ofpact_finish_CLONE(pp->ofpacts, &clone);
59335957
ofpbuf_push_uninit(pp->ofpacts, clone_offset);
59345958
return error;
@@ -6615,6 +6639,11 @@ parse_CT(char *arg, const struct ofpact_parse_params *pp)
66156639
if (!error && oc->flags & NX_CT_F_FORCE && !(oc->flags & NX_CT_F_COMMIT)) {
66166640
error = xasprintf("\"force\" flag requires \"commit\" flag.");
66176641
}
6642+
6643+
if (ofpbuf_oversized(pp->ofpacts)) {
6644+
return xasprintf("input too big");
6645+
}
6646+
66186647
ofpact_finish_CT(pp->ofpacts, &oc);
66196648
ofpbuf_push_uninit(pp->ofpacts, ct_offset);
66206649
return error;

0 commit comments

Comments
 (0)