summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Pfaff <blp@ovn.org>2018-08-15 14:57:13 -0700
committerBen Pfaff <blp@ovn.org>2018-08-17 16:39:50 -0700
commit7574f6b8749afcb8ecdb77ef4d89b99668ba9d9c (patch)
treebcd9efa285dd3f8837f5e544227568e10382c664
parent4115e28cb4f0b1bcf573339ce5efd5a094a9b977 (diff)
downloadopenvswitch-7574f6b8749afcb8ecdb77ef4d89b99668ba9d9c.tar.gz
ofp-actions: Avoid assertion failure for clone(ct(...bad actions...)).
decode_NXAST_RAW_CT() temporarily pulls data off the beginning of its ofpacts output ofpbuf and, on its error path, fails to push it back on. At a higher layer, decode_NXAST_RAW_CLONE() asserts, via ofpact_finish_CLONE(), that the ofpact_clone that it put is still in the place where it put it, which causes an assertion failure. The root cause here is the failure to re-push the clone header. One could fix that, but it would be pretty easy for that to go wrong again on some other obscure error path. Instead, this commit just makes the problem go away by always saving and restoring 'ofpact->data' if a decode fails. Reported-at: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9862 Signed-off-by: Ben Pfaff <blp@ovn.org> Acked-by: Justin Pettit <jpettit@ovn.org>
-rw-r--r--lib/ofp-actions.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
index 5aacff62a..6bc52f3f3 100644
--- a/lib/ofp-actions.c
+++ b/lib/ofp-actions.c
@@ -6910,6 +6910,7 @@ ofpacts_pull_openflow_actions__(struct ofpbuf *openflow,
uint64_t *ofpacts_tlv_bitmap)
{
const struct ofp_action_header *actions;
+ void *orig_data = ofpacts->data;
size_t orig_size = ofpacts->size;
enum ofperr error;
@@ -6929,14 +6930,17 @@ ofpacts_pull_openflow_actions__(struct ofpbuf *openflow,
error = ofpacts_decode(actions, actions_len, version, vl_mff_map,
ofpacts_tlv_bitmap, ofpacts);
- if (error) {
- ofpacts->size = orig_size;
- return error;
+ if (!error) {
+ error = ofpacts_verify(ofpacts->data, ofpacts->size, allowed_ovsinsts,
+ outer_action);
}
-
- error = ofpacts_verify(ofpacts->data, ofpacts->size, allowed_ovsinsts,
- outer_action);
if (error) {
+ /* Back out changes to 'ofpacts'. (Normally, decoding would only
+ * append to 'ofpacts', so that one would expect only to need to
+ * restore 'ofpacts->size', but some action parsing temporarily pulls
+ * off data from the start of 'ofpacts' and may not properly re-push it
+ * on error paths.) */
+ ofpacts->data = orig_data;
ofpacts->size = orig_size;
}
return error;