diff options
author | Dumitru Ceara <dceara@redhat.com> | 2022-04-11 13:38:44 +0200 |
---|---|---|
committer | Ilya Maximets <i.maximets@ovn.org> | 2022-05-17 23:10:17 +0200 |
commit | a5cc859a4228a9ce70c40304041ed2b18064ddcc (patch) | |
tree | 20471394a4493f9301f8b4817e9d07d3cd4666da /include | |
parent | 08c3e5e37eeea77f198fdd887f4bbd482bde4621 (diff) | |
download | openvswitch-a5cc859a4228a9ce70c40304041ed2b18064ddcc.tar.gz |
ofp-actions: Use aligned structures when decoding ofp actions.
Some openflow actions can be misaligned, e.g., actions whithin OF 1.0
replies to statistics reply messages which have a header of 12 bytes
and no additional padding.
Also, buggy controllers might incorrectly encode actions.
When decoding multiple actions in ofpacts_decode(), make sure that
when advancing to the next action it will be properly aligned
(multiple of OFPACT_ALIGNTO).
Detected by UB Sanitizer when running one of the fuzz tests:
lib/ofp-actions.c:5347:12:
runtime error: member access within misaligned address 0x0000016ba274
for type 'const struct nx_action_learn', which requires 8 byte alignment
0x0000016ba274: note: pointer points here
20 20 20 20 ff ff 00 38 00 00 23 20 00 10 20 20
^
20 20 20 20 20 20 20 20 20 20 20 20 00 03 20 00
0 0x52cece in decode_LEARN_common lib/ofp-actions.c:5347
1 0x52dcf6 in decode_NXAST_RAW_LEARN lib/ofp-actions.c:5463
2 0x548604 in ofpact_decode lib/ofp-actions.inc2:4723
3 0x53ee43 in ofpacts_decode lib/ofp-actions.c:7781
4 0x53efc1 in ofpacts_pull_openflow_actions__ lib/ofp-actions.c:7820
5 0x5409e1 in ofpacts_pull_openflow_instructions lib/ofp-actions.c:8396
6 0x5608a8 in ofputil_decode_flow_stats_reply lib/ofp-flow.c:1100
Acked-by: Adrian Moreno <amorenoz@redhat.com>
Acked-by: Aaron Conole <aconole@redhat.com>
Signed-off-by: Dumitru Ceara <dceara@redhat.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/openvswitch/ofp-actions.h | 1 | ||||
-rw-r--r-- | include/openvswitch/ofpbuf.h | 2 |
2 files changed, 3 insertions, 0 deletions
diff --git a/include/openvswitch/ofp-actions.h b/include/openvswitch/ofp-actions.h index 711e7c773..7b57e49ad 100644 --- a/include/openvswitch/ofp-actions.h +++ b/include/openvswitch/ofp-actions.h @@ -203,6 +203,7 @@ BUILD_ASSERT_DECL(sizeof(struct ofpact) == 4); /* Alignment. */ #define OFPACT_ALIGNTO 8 #define OFPACT_ALIGN(SIZE) ROUND_UP(SIZE, OFPACT_ALIGNTO) +#define OFPACT_IS_ALIGNED(ADDR) ((uintptr_t) (ADDR) % OFPACT_ALIGNTO == 0) #define OFPACT_PADDED_MEMBERS(MEMBERS) PADDED_MEMBERS(OFPACT_ALIGNTO, MEMBERS) /* Returns the ofpact following 'ofpact'. */ diff --git a/include/openvswitch/ofpbuf.h b/include/openvswitch/ofpbuf.h index 32f03ea83..1fc4a3a7f 100644 --- a/include/openvswitch/ofpbuf.h +++ b/include/openvswitch/ofpbuf.h @@ -111,6 +111,7 @@ void ofpbuf_use_ds(struct ofpbuf *, const struct ds *); void ofpbuf_use_stack(struct ofpbuf *, void *, size_t); void ofpbuf_use_stub(struct ofpbuf *, void *, size_t); void ofpbuf_use_const(struct ofpbuf *, const void *, size_t); +void ofpbuf_use_data(struct ofpbuf *, const void *, size_t); void ofpbuf_init(struct ofpbuf *, size_t); void ofpbuf_uninit(struct ofpbuf *); @@ -149,6 +150,7 @@ static inline size_t ofpbuf_msgsize(const struct ofpbuf *); void ofpbuf_prealloc_headroom(struct ofpbuf *, size_t); void ofpbuf_prealloc_tailroom(struct ofpbuf *, size_t); void ofpbuf_trim(struct ofpbuf *); +void ofpbuf_align(struct ofpbuf *); void ofpbuf_padto(struct ofpbuf *, size_t); void ofpbuf_shift(struct ofpbuf *, int); |