summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Michelson <mmichels@redhat.com>2019-03-25 17:29:54 -0400
committerBen Pfaff <blp@ovn.org>2019-03-25 14:53:38 -0700
commitdc2d6552cd2370a342ff00ba02894a332c4f19cf (patch)
treefc9302c2bcfe730da623feb87a0b28298cf01974
parent115e8d9a1eafa06f5a7171a2bbbfa38d61bfa4cd (diff)
downloadopenvswitch-dc2d6552cd2370a342ff00ba02894a332c4f19cf.tar.gz
OVN: Use offset instead of pointer into ofpbuf
In general, maintaining a pointer into an ofpbuf is risky. As the ofpbuf grows, it can reallocate its data. If this happens, then pointers into the data will become invalid. A safer practice is to track an offset into the ofpbuf's data where a structure you are interested in is kept. This way, if the ofpbuf data is reallocated, you can find your structure again by using the offset. In practice, this patch is not fixing any issues with OVN. Even though the ra pointer is pointing to ofpbuf data that can be reallocated, it will never actually happen. ovn-northd and all test cases always encode the address mode first, meaning we will only ever read from the ra pointer before the ofpbuf has a chance to expand. However, this base work is essential for an upcoming patch in this series. Signed-off-by: Mark Michelson <mmichels@redhat.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
-rw-r--r--ovn/lib/actions.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/ovn/lib/actions.c b/ovn/lib/actions.c
index 7b7a89478..56e1ab2ae 100644
--- a/ovn/lib/actions.c
+++ b/ovn/lib/actions.c
@@ -1978,18 +1978,21 @@ format_PUT_ND_RA_OPTS(const struct ovnact_put_opts *po,
static void
encode_put_nd_ra_option(const struct ovnact_gen_option *o,
- struct ofpbuf *ofpacts, struct ovs_ra_msg *ra)
+ struct ofpbuf *ofpacts, ptrdiff_t ra_offset)
{
const union expr_constant *c = o->value.values;
switch (o->option->code) {
case ND_RA_FLAG_ADDR_MODE:
+ {
+ struct ovs_ra_msg *ra = ofpbuf_at(ofpacts, ra_offset, sizeof *ra);
if (!strcmp(c->string, "dhcpv6_stateful")) {
ra->mo_flags = IPV6_ND_RA_FLAG_MANAGED_ADDR_CONFIG;
} else if (!strcmp(c->string, "dhcpv6_stateless")) {
ra->mo_flags = IPV6_ND_RA_FLAG_OTHER_ADDR_CONFIG;
}
break;
+ }
case ND_OPT_SOURCE_LINKADDR:
{
@@ -2051,6 +2054,7 @@ encode_PUT_ND_RA_OPTS(const struct ovnact_put_opts *po,
* pinctrl module receives the ICMPv6 Router Solicitation packet
* it can copy the userdata field AS IS and resume the packet.
*/
+ size_t ra_offset = ofpacts->size;
struct ovs_ra_msg *ra = ofpbuf_put_zeros(ofpacts, sizeof *ra);
ra->icmph.icmp6_type = ND_ROUTER_ADVERT;
ra->cur_hop_limit = IPV6_ND_RA_CUR_HOP_LIMIT;
@@ -2059,7 +2063,7 @@ encode_PUT_ND_RA_OPTS(const struct ovnact_put_opts *po,
for (const struct ovnact_gen_option *o = po->options;
o < &po->options[po->n_options]; o++) {
- encode_put_nd_ra_option(o, ofpacts, ra);
+ encode_put_nd_ra_option(o, ofpacts, ra_offset);
}
encode_finish_controller_op(oc_offset, ofpacts);