[ovs-dev] [PATCH] ofproto-dpif-upcall: Fix use of cleared stack memory.
Ethan Jackson
ethan at nicira.com
Fri Aug 15 20:33:55 UTC 2014
Acked-by: Ethan Jackson <ethan at nicira.com>
Thanks for taking care of this.
Ethan
On Fri, Aug 15, 2014 at 1:15 AM, Alex Wang <alexw at nicira.com> wrote:
> Commit cc377352d (ofproto: Reorganize in preparation for direct
> dpdk upcalls.) introduced the bug that uses variable defined on
> the stack inside while loop for reading dpif upcalls and keeps
> reference to attributes of the variable within the same function
> after the stack is cleared. This bug can cause ovs abort.
>
> This commit fixes the above issue by defining an array of the
> variable on the function stack.
>
> Signed-off-by: Alex Wang <alexw at nicira.com>
> ---
> ofproto/ofproto-dpif-upcall.c | 27 ++++++++++++++-------------
> 1 file changed, 14 insertions(+), 13 deletions(-)
>
> diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c
> index 180684c..9f68a7d 100644
> --- a/ofproto/ofproto-dpif-upcall.c
> +++ b/ofproto/ofproto-dpif-upcall.c
> @@ -574,55 +574,56 @@ recv_upcalls(struct handler *handler)
> struct udpif *udpif = handler->udpif;
> uint64_t recv_stubs[UPCALL_MAX_BATCH][512 / 8];
> struct ofpbuf recv_bufs[UPCALL_MAX_BATCH];
> + struct dpif_upcall dupcalls[UPCALL_MAX_BATCH];
> struct upcall upcalls[UPCALL_MAX_BATCH];
> size_t n_upcalls, i;
>
> n_upcalls = 0;
> while (n_upcalls < UPCALL_MAX_BATCH) {
> struct ofpbuf *recv_buf = &recv_bufs[n_upcalls];
> + struct dpif_upcall *dupcall = &dupcalls[n_upcalls];
> struct upcall *upcall = &upcalls[n_upcalls];
> - struct dpif_upcall dupcall;
> struct pkt_metadata md;
> struct flow flow;
> int error;
>
> ofpbuf_use_stub(recv_buf, recv_stubs[n_upcalls],
> sizeof recv_stubs[n_upcalls]);
> - if (dpif_recv(udpif->dpif, handler->handler_id, &dupcall, recv_buf)) {
> + if (dpif_recv(udpif->dpif, handler->handler_id, dupcall, recv_buf)) {
> ofpbuf_uninit(recv_buf);
> 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);
> + error = upcall_receive(upcall, udpif->backer, &dupcall->packet,
> + dupcall->type, dupcall->userdata, &flow);
> if (error) {
> if (error == ENODEV) {
> /* Received packet on datapath port for which we couldn't
> * associate an ofproto. This can happen if a port is removed
> * while traffic is being received. Print a rate-limited
> * message in case it happens frequently. */
> - dpif_flow_put(udpif->dpif, DPIF_FP_CREATE, dupcall.key,
> - dupcall.key_len, NULL, 0, NULL, 0, NULL);
> + 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);
> }
> goto free_dupcall;
> }
>
> - upcall->key = dupcall.key;
> - upcall->key_len = dupcall.key_len;
> + upcall->key = dupcall->key;
> + upcall->key_len = dupcall->key_len;
>
> - 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);
> + flow_extract(&dupcall->packet, &md, &flow);
>
> error = process_upcall(udpif, upcall, NULL);
> if (error) {
> @@ -635,14 +636,14 @@ recv_upcalls(struct handler *handler)
> cleanup:
> upcall_uninit(upcall);
> free_dupcall:
> - ofpbuf_uninit(&dupcall.packet);
> + ofpbuf_uninit(&dupcall->packet);
> ofpbuf_uninit(recv_buf);
> }
>
> if (n_upcalls) {
> handle_upcalls(handler->udpif, upcalls, n_upcalls);
> for (i = 0; i < n_upcalls; i++) {
> - ofpbuf_uninit(CONST_CAST(struct ofpbuf *, upcalls[i].packet));
> + ofpbuf_uninit(&dupcalls[i].packet);
> ofpbuf_uninit(&recv_bufs[i]);
> upcall_uninit(&upcalls[i]);
> }
> --
> 1.7.9.5
>
> _______________________________________________
> dev mailing list
> dev at openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev
More information about the dev
mailing list