From e1154f713ec8f47ff38979d76e9456b49b0bc264 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Thu, 8 Sep 2011 11:25:29 -0700 Subject: [PATCH] ofproto: Reject invalid input ports in OFPT_PACKET_OUT requests. Some invalid ports (those above the maximum port number supported by the datapath, including OpenFlow reserved ports that are not translated by OVS into some other number) will be rejected by the datapath. It's better to catch these early and send back an appropriate OpenFlow error code, rather than to just get EINVAL from the kernel and have to guess at the problem. Reported-by: Aaron Rosen --- include/openflow/nicira-ext.h | 3 +++ ofproto/ofproto-dpif.c | 4 ++++ ofproto/ofproto.c | 13 ++++++++++++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/include/openflow/nicira-ext.h b/include/openflow/nicira-ext.h index 84060d79..875052a9 100644 --- a/include/openflow/nicira-ext.h +++ b/include/openflow/nicira-ext.h @@ -110,6 +110,9 @@ enum nx_bad_request_code { /* NXT_ROLE_REQUEST specified an invalid role. */ NXBRC_BAD_ROLE = 0x201, + + /* The in_port in an ofp_packet_out request is invalid. */ + NXBRC_BAD_IN_PORT = 0x202 }; /* Additional "code" values for OFPET_FLOW_MOD_FAILED. */ diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 6c303bba..93e79a97 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -5077,6 +5077,10 @@ packet_out(struct ofproto *ofproto_, struct ofpbuf *packet, struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_); int error; + if (flow->in_port >= ofproto->max_ports && flow->in_port < OFPP_MAX) { + return ofp_mkerr_nicira(OFPET_BAD_REQUEST, NXBRC_BAD_IN_PORT); + } + error = validate_actions(ofp_actions, n_ofp_actions, flow, ofproto->max_ports); if (!error) { diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 8a2abdc6..b7b31b02 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -1729,6 +1729,7 @@ handle_packet_out(struct ofconn *ofconn, const struct ofp_header *oh) struct ofpbuf request; struct flow flow; size_t n_ofp_actions; + uint16_t in_port; int error; COVERAGE_INC(ofproto_packet_out); @@ -1762,8 +1763,18 @@ handle_packet_out(struct ofconn *ofconn, const struct ofp_header *oh) buffer = NULL; } + /* Get in_port and partially validate it. + * + * We don't know what range of ports the ofproto actually implements, but + * we do know that only certain reserved ports (numbered OFPP_MAX and + * above) are valid. */ + in_port = ntohs(opo->in_port); + if (in_port >= OFPP_MAX && in_port != OFPP_LOCAL && in_port != OFPP_NONE) { + return ofp_mkerr_nicira(OFPET_BAD_REQUEST, NXBRC_BAD_IN_PORT); + } + /* Send out packet. */ - flow_extract(&payload, 0, 0, ntohs(opo->in_port), &flow); + flow_extract(&payload, 0, 0, in_port, &flow); error = p->ofproto_class->packet_out(p, &payload, &flow, ofp_actions, n_ofp_actions); ofpbuf_delete(buffer); -- 2.30.2