aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Wang <alexw@nicira.com>2014-10-10 14:41:10 -0700
committerAlex Wang <alexw@nicira.com>2014-10-10 16:07:32 -0700
commitff601a08a44c37fa8a6e0e569dc00d6731f55555 (patch)
tree1df8f7d007cdc5bc61fcc01e3d8701b968a20ba0
parentd9723d892b590d7bd57fe549216be2edd0dad5cb (diff)
ofproto-dpif-upcall: Fix out-of-scope use of stack memory.
Commit cc377352d (ofproto: Reorganize in preparation for direct dpdk upcalls.) introduced the bug that keeps reference to 'struct flow' defined on the stack inside while loop when running out of the scope. This causes strange bug like wrong mask extraction when the part of memory is corrupted, and could lead to even more serious bug/crash. This commit fixes the above issue by defining an array of the 'struct flow's on the function stack. Found by running ovs on RHEL7. Signed-off-by: Alex Wang <alexw@nicira.com> Acked-by: Ben Pfaff <blp@nicira.com>
-rw-r--r--ofproto/ofproto-dpif-upcall.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c
index 882c067bc..1f9c484e5 100644
--- a/ofproto/ofproto-dpif-upcall.c
+++ b/ofproto/ofproto-dpif-upcall.c
@@ -577,6 +577,7 @@ recv_upcalls(struct handler *handler)
struct ofpbuf recv_bufs[UPCALL_MAX_BATCH];
struct dpif_upcall dupcalls[UPCALL_MAX_BATCH];
struct upcall upcalls[UPCALL_MAX_BATCH];
+ struct flow flows[UPCALL_MAX_BATCH];
size_t n_upcalls, i;
n_upcalls = 0;
@@ -584,8 +585,8 @@ recv_upcalls(struct handler *handler)
struct ofpbuf *recv_buf = &recv_bufs[n_upcalls];
struct dpif_upcall *dupcall = &dupcalls[n_upcalls];
struct upcall *upcall = &upcalls[n_upcalls];
+ struct flow *flow = &flows[n_upcalls];
struct pkt_metadata md;
- struct flow flow;
int error;
ofpbuf_use_stub(recv_buf, recv_stubs[n_upcalls],
@@ -595,13 +596,13 @@ recv_upcalls(struct handler *handler)
break;
}
- if (odp_flow_key_to_flow(dupcall->key, dupcall->key_len, &flow)
+ if (odp_flow_key_to_flow(dupcall->key, dupcall->key_len, flow)
== ODP_FIT_ERROR) {
goto free_dupcall;
}
error = upcall_receive(upcall, udpif->backer, &dupcall->packet,
- dupcall->type, dupcall->userdata, &flow);
+ dupcall->type, dupcall->userdata, flow);
if (error) {
if (error == ENODEV) {
/* Received packet on datapath port for which we couldn't
@@ -611,7 +612,7 @@ recv_upcalls(struct handler *handler)
dpif_flow_put(udpif->dpif, DPIF_FP_CREATE, dupcall->key,
dupcall->key_len, NULL, 0, NULL, 0, NULL);
VLOG_INFO_RL(&rl, "received packet on unassociated datapath "
- "port %"PRIu32, flow.in_port.odp_port);
+ "port %"PRIu32, flow->in_port.odp_port);
}
goto free_dupcall;
}
@@ -621,12 +622,12 @@ recv_upcalls(struct handler *handler)
upcall->out_tun_key = dupcall->out_tun_key;
- if (vsp_adjust_flow(upcall->ofproto, &flow, &dupcall->packet)) {
+ if (vsp_adjust_flow(upcall->ofproto, flow, &dupcall->packet)) {
upcall->vsp_adjusted = true;
}
- md = pkt_metadata_from_flow(&flow);
- flow_extract(&dupcall->packet, &md, &flow);
+ md = pkt_metadata_from_flow(flow);
+ flow_extract(&dupcall->packet, &md, flow);
error = process_upcall(udpif, upcall, NULL);
if (error) {