From e6e51ccbf17ff40a899c8859fb4e95abd5cfcd57 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Fri, 7 Aug 2026 15:48:14 +0100 Subject: [PATCH] [build] Move various pointer assignments after their length checks When performing a length check on untrusted received data, it is preferable to assign the corresponding typed pointer only after validating that the length is sufficient to contain the dereferenced pointer type. This allows the compiler to catch any unintended dereferences before the length check has taken place, and so hardens the code against future potential changes. This pattern of assigning the pointer only after the corresponding length check is already fairly widespread, but there are still large swathes of older code that use the less safe idiom of assigning the pointer first (generally as part of the variable declaration). Move an assortment of pointer assignments after their corresponding length checks, and fix the few harmless premature dereferences that were discovered in the process (e.g. using a potentially non-existent IPv4 source address as a debug colour stream identifier). This is not intended to be a comprehensive update of all such pointer assignments, merely an improvement of those sites where assignments are easily identifiable and trivially hardened. Signed-off-by: Michael Brown --- src/drivers/block/srp.c | 9 ++++++--- src/drivers/net/iphone.c | 10 ++++++---- src/drivers/net/netvsc.c | 9 ++++++--- src/net/aoe.c | 6 ++++-- src/net/arp.c | 9 +++++++-- src/net/eth_slow.c | 3 ++- src/net/ethernet.c | 3 ++- src/net/fc.c | 3 ++- src/net/fcels.c | 42 ++++++++++++++++++++++++++-------------- src/net/fcns.c | 3 ++- src/net/fcp.c | 3 ++- src/net/icmp.c | 12 +++++++++--- src/net/icmpv4.c | 3 ++- src/net/icmpv6.c | 3 ++- src/net/ipv4.c | 5 +++-- src/net/ipv6.c | 8 ++++---- src/net/ping.c | 3 ++- src/net/tcp.c | 3 ++- src/net/udp.c | 4 ++-- src/net/udp/dhcpv6.c | 3 ++- src/net/udp/dns.c | 3 ++- src/net/udp/tftp.c | 12 ++++++++---- src/net/vlan.c | 3 ++- 23 files changed, 107 insertions(+), 55 deletions(-) diff --git a/src/drivers/block/srp.c b/src/drivers/block/srp.c index f0ef57474..f552ac8cf 100644 --- a/src/drivers/block/srp.c +++ b/src/drivers/block/srp.c @@ -335,7 +335,7 @@ static int srp_login ( struct srp_device *srpdev, union srp_port_id *initiator, */ static int srp_login_rsp ( struct srp_device *srpdev, const void *data, size_t len ) { - const struct srp_login_rsp *login_rsp = data; + const struct srp_login_rsp *login_rsp; /* Sanity check */ if ( len < sizeof ( *login_rsp ) ) { @@ -343,6 +343,7 @@ static int srp_login_rsp ( struct srp_device *srpdev, srpdev, len ); return -EINVAL; } + login_rsp = data; DBGC ( srpdev, "SRP %p tag %08x LOGIN_RSP:\n", srpdev, ntohl ( login_rsp->tag.dwords[1] ) ); DBGC_HDA ( srpdev, 0, data, len ); @@ -367,7 +368,7 @@ static int srp_login_rsp ( struct srp_device *srpdev, */ static int srp_login_rej ( struct srp_device *srpdev, const void *data, size_t len ) { - const struct srp_login_rej *login_rej = data; + const struct srp_login_rej *login_rej; uint32_t reason; /* Sanity check */ @@ -376,6 +377,7 @@ static int srp_login_rej ( struct srp_device *srpdev, srpdev, len ); return -EINVAL; } + login_rej = data; reason = ntohl ( login_rej->reason ); DBGC ( srpdev, "SRP %p tag %08x LOGIN_REJ reason %08x:\n", srpdev, ntohl ( login_rej->tag.dwords[1] ), reason ); @@ -656,7 +658,7 @@ static int srpdev_scsi_command ( struct srp_device *srpdev, static int srpdev_deliver ( struct srp_device *srpdev, struct io_buffer *iobuf, struct xfer_metadata *meta __unused ) { - struct srp_common *common = iobuf->data; + struct srp_common *common; int ( * type ) ( struct srp_device *srp, const void *data, size_t len ); int rc; @@ -667,6 +669,7 @@ static int srpdev_deliver ( struct srp_device *srpdev, rc = -EINVAL; goto err; } + common = iobuf->data; /* Determine IU type */ switch ( common->type ) { diff --git a/src/drivers/net/iphone.c b/src/drivers/net/iphone.c index d35737c49..661922c15 100644 --- a/src/drivers/net/iphone.c +++ b/src/drivers/net/iphone.c @@ -807,16 +807,17 @@ static void imux_rx_syn ( struct imux *imux ) { * @v iobuf I/O buffer */ static void imux_rx_tcp ( struct imux *imux, struct io_buffer *iobuf ) { - struct imux_header_tcp *tcp = iobuf->data; + struct imux_header_tcp *tcp; size_t len = iob_len ( iobuf ); int rc; /* Sanity check */ if ( len < sizeof ( *tcp ) ) { DBGC ( imux, "IMUX %p malformed TCP message:\n", imux ); - DBGC_HDA ( imux, 0, tcp, len ); + DBGC_HDA ( imux, 0, iobuf->data, len ); goto error; } + tcp = iobuf->data; /* Ignore unexpected packets */ if ( tcp->tcp.dest != htons ( imux->port ) ) { @@ -867,7 +868,7 @@ static void imux_rx_tcp ( struct imux *imux, struct io_buffer *iobuf ) { static void imux_in_complete ( struct usb_endpoint *ep, struct io_buffer *iobuf, int rc ) { struct imux *imux = container_of ( ep, struct imux, usbnet.in ); - struct imux_header *hdr = iobuf->data; + struct imux_header *hdr; size_t len = iob_len ( iobuf ); /* Ignore packets cancelled when the endpoint closes */ @@ -884,9 +885,10 @@ static void imux_in_complete ( struct usb_endpoint *ep, /* Sanity check */ if ( len < sizeof ( *hdr ) ) { DBGC ( imux, "IMUX %p malformed message:\n", imux ); - DBGC_HDA ( imux, 0, hdr, len ); + DBGC_HDA ( imux, 0, iobuf->data, len ); goto drop; } + hdr = iobuf->data; /* Record input sequence */ imux->in_seq = ntohs ( hdr->in_seq ); diff --git a/src/drivers/net/netvsc.c b/src/drivers/net/netvsc.c index 681aa54e7..8726eec94 100644 --- a/src/drivers/net/netvsc.c +++ b/src/drivers/net/netvsc.c @@ -137,7 +137,7 @@ static int netvsc_initialise ( struct netvsc_device *netvsc ) { static int netvsc_initialised ( struct netvsc_device *netvsc, const void *data, size_t len ) { - const struct netvsc_init_completion *cmplt = data; + const struct netvsc_init_completion *cmplt; /* Check completion */ if ( len < sizeof ( *cmplt ) ) { @@ -145,6 +145,7 @@ netvsc_initialised ( struct netvsc_device *netvsc, const void *data, "completion (%zd bytes)\n", netvsc->name, len ); return -EINVAL; } + cmplt = data; if ( cmplt->header.type != cpu_to_le32 ( NETVSC_INIT_CMPLT ) ) { DBGC ( netvsc, "NETVSC %s unexpected initialisation completion " "type %d\n", netvsc->name, @@ -226,7 +227,7 @@ static int netvsc_establish_buffer ( struct netvsc_device *netvsc, */ static int netvsc_rx_established_buffer ( struct netvsc_device *netvsc, const void *data, size_t len ) { - const struct netvsc_rx_establish_buffer_completion *cmplt = data; + const struct netvsc_rx_establish_buffer_completion *cmplt; /* Check completion */ if ( len < sizeof ( *cmplt ) ) { @@ -234,6 +235,7 @@ static int netvsc_rx_established_buffer ( struct netvsc_device *netvsc, "bytes)\n", netvsc->name, len ); return -EINVAL; } + cmplt = data; if ( cmplt->header.type != cpu_to_le32 ( NETVSC_RX_ESTABLISH_CMPLT ) ) { DBGC ( netvsc, "NETVSC %s unexpected buffer completion type " "%d\n", netvsc->name, le32_to_cpu ( cmplt->header.type)); @@ -320,7 +322,7 @@ static int netvsc_recv_data ( struct vmbus_device *vmdev, uint64_t xid, struct list_head *list ) { struct rndis_device *rndis = vmbus_get_drvdata ( vmdev ); struct netvsc_device *netvsc = rndis->priv; - const struct netvsc_rndis_message *msg = data; + const struct netvsc_rndis_message *msg; struct io_buffer *iobuf; struct io_buffer *tmp; int rc; @@ -332,6 +334,7 @@ static int netvsc_recv_data ( struct vmbus_device *vmdev, uint64_t xid, rc = -EINVAL; goto err_sanity; } + msg = data; if ( msg->header.type != cpu_to_le32 ( NETVSC_RNDIS_MSG ) ) { DBGC ( netvsc, "NETVSC %s received unexpected RNDIS packet " "type %d\n", netvsc->name, diff --git a/src/net/aoe.c b/src/net/aoe.c index edeb81867..86911ab67 100644 --- a/src/net/aoe.c +++ b/src/net/aoe.c @@ -285,7 +285,7 @@ static int aoecmd_tx ( struct aoe_command *aoecmd ) { static int aoecmd_rx ( struct aoe_command *aoecmd, struct io_buffer *iobuf, const void *ll_source ) { struct aoe_device *aoedev = aoecmd->aoedev; - struct aoehdr *aoehdr = iobuf->data; + struct aoehdr *aoehdr; int rc; /* Sanity check */ @@ -296,6 +296,7 @@ static int aoecmd_rx ( struct aoe_command *aoecmd, struct io_buffer *iobuf, rc = -EINVAL; goto done; } + aoehdr = iobuf->data; if ( ( ntohs ( aoehdr->major ) != aoedev->major ) || ( aoehdr->minor != aoedev->minor ) ) { DBGC ( aoedev, "AoE %s/%08x received response for incorrect " @@ -876,7 +877,7 @@ static int aoe_rx ( struct io_buffer *iobuf, const void *ll_dest __unused, const void *ll_source, unsigned int flags __unused ) { - struct aoehdr *aoehdr = iobuf->data; + struct aoehdr *aoehdr; struct aoe_command *aoecmd; int rc; @@ -887,6 +888,7 @@ static int aoe_rx ( struct io_buffer *iobuf, rc = -EINVAL; goto err_sanity; } + aoehdr = iobuf->data; if ( ( aoehdr->ver_flags & AOE_VERSION_MASK ) != AOE_VERSION ) { DBG ( "AoE received packet for unsupported protocol version " "%02x\n", ( aoehdr->ver_flags & AOE_VERSION_MASK ) ); diff --git a/src/net/arp.c b/src/net/arp.c index 2bf3c12ec..243f86217 100644 --- a/src/net/arp.c +++ b/src/net/arp.c @@ -136,7 +136,7 @@ static int arp_rx ( struct io_buffer *iobuf, struct net_device *netdev, const void *ll_dest __unused, const void *ll_source __unused, unsigned int flags __unused ) { - struct arphdr *arphdr = iobuf->data; + struct arphdr *arphdr; struct arp_net_protocol *arp_net_protocol; struct net_protocol *net_protocol; struct ll_protocol *ll_protocol; @@ -144,7 +144,12 @@ static int arp_rx ( struct io_buffer *iobuf, struct net_device *netdev, int rc; /* Sanity check */ - if ( ( len < sizeof ( *arphdr ) ) || ( len < arp_len ( arphdr ) ) ) { + if ( len < sizeof ( *arphdr ) ) { + rc = -EINVAL; + goto done; + } + arphdr = iobuf->data; + if ( len < arp_len ( arphdr ) ) { rc = -EINVAL; goto done; } diff --git a/src/net/eth_slow.c b/src/net/eth_slow.c index e4c78acd1..21d621993 100644 --- a/src/net/eth_slow.c +++ b/src/net/eth_slow.c @@ -284,13 +284,14 @@ static int eth_slow_rx ( struct io_buffer *iobuf, const void *ll_dest __unused, const void *ll_source __unused, unsigned int flags __unused ) { - union eth_slow_packet *eth_slow = iobuf->data; + union eth_slow_packet *eth_slow; /* Sanity checks */ if ( iob_len ( iobuf ) < sizeof ( *eth_slow ) ) { free_iob ( iobuf ); return -EINVAL; } + eth_slow = iobuf->data; /* Strip any trailing padding */ iob_unput ( iobuf, ( iob_len ( iobuf ) - sizeof ( *eth_slow ) ) ); diff --git a/src/net/ethernet.c b/src/net/ethernet.c index 60219b98f..069adb3fe 100644 --- a/src/net/ethernet.c +++ b/src/net/ethernet.c @@ -102,7 +102,7 @@ int eth_push ( struct net_device *netdev __unused, struct io_buffer *iobuf, int eth_pull ( struct net_device *netdev __unused, struct io_buffer *iobuf, const void **ll_dest, const void **ll_source, uint16_t *net_proto, unsigned int *flags ) { - struct ethhdr *ethhdr = iobuf->data; + struct ethhdr *ethhdr; uint16_t *llc_proto; /* Sanity check. While in theory we could receive a one-byte @@ -115,6 +115,7 @@ int eth_pull ( struct net_device *netdev __unused, struct io_buffer *iobuf, iob_len ( iobuf ) ); return -EINVAL; } + ethhdr = iobuf->data; /* Strip off Ethernet header */ iob_pull ( iobuf, sizeof ( *ethhdr ) ); diff --git a/src/net/fc.c b/src/net/fc.c index 2e8070272..a6c7fd14c 100644 --- a/src/net/fc.c +++ b/src/net/fc.c @@ -858,7 +858,7 @@ static struct fc_exchange * fc_port_demux ( struct fc_port *port, */ static int fc_port_deliver ( struct fc_port *port, struct io_buffer *iobuf, struct xfer_metadata *meta ) { - struct fc_frame_header *fchdr = iobuf->data; + struct fc_frame_header *fchdr; unsigned int xchg_id; struct fc_exchange *xchg; int rc; @@ -870,6 +870,7 @@ static int fc_port_deliver ( struct fc_port *port, struct io_buffer *iobuf, rc = -EINVAL; goto err_sanity; } + fchdr = iobuf->data; /* Verify local port ID */ if ( ( memcmp ( &fchdr->d_id, &port->port_id, diff --git a/src/net/fcels.c b/src/net/fcels.c index 5fc27cef4..d97d2560d 100644 --- a/src/net/fcels.c +++ b/src/net/fcels.c @@ -159,9 +159,9 @@ int fc_els_tx ( struct fc_els *els, const void *data, size_t len ) { static int fc_els_rx ( struct fc_els *els, struct io_buffer *iobuf, struct xfer_metadata *meta ) { - struct fc_els_frame_common *frame = iobuf->data; struct sockaddr_fc *src = ( ( struct sockaddr_fc * ) meta->src ); struct sockaddr_fc *dest = ( ( struct sockaddr_fc * ) meta->dest ); + struct fc_els_frame_common *frame; size_t len = iob_len ( iobuf ); int rc; @@ -169,10 +169,11 @@ static int fc_els_rx ( struct fc_els *els, if ( len < sizeof ( *frame ) ) { DBGC ( els, FCELS_FMT " received underlength frame:\n", FCELS_ARGS ( els ) ); - DBGC_HDA ( els, 0, frame, len ); + DBGC_HDA ( els, 0, iobuf->data, len ); rc = -EINVAL; goto done; } + frame = iobuf->data; if ( ! src ) { DBGC ( els, FCELS_FMT " received frame missing source " "address:\n", FCELS_ARGS ( els ) ); @@ -493,7 +494,7 @@ static int fc_els_flogi_tx ( struct fc_els *els ) { * @ret rc Return status code */ static int fc_els_flogi_rx ( struct fc_els *els, void *data, size_t len ) { - struct fc_login_frame *flogi = data; + struct fc_login_frame *flogi; int has_fabric; int rc; @@ -504,6 +505,7 @@ static int fc_els_flogi_rx ( struct fc_els *els, void *data, size_t len ) { DBGC_HDA ( els, 0, data, len ); return -EINVAL; } + flogi = data; /* Extract parameters */ has_fabric = ( flogi->common.flags & htons ( FC_LOGIN_F_PORT ) ); @@ -633,7 +635,7 @@ static int fc_els_plogi_tx ( struct fc_els *els ) { * @ret rc Return status code */ static int fc_els_plogi_rx ( struct fc_els *els, void *data, size_t len ) { - struct fc_login_frame *plogi = data; + struct fc_login_frame *plogi; struct fc_peer *peer; int rc; @@ -645,6 +647,7 @@ static int fc_els_plogi_rx ( struct fc_els *els, void *data, size_t len ) { rc = -EINVAL; goto err_sanity; } + plogi = data; if ( ! fc_link_ok ( &els->port->link ) ) { DBGC ( els, FCELS_FMT " received while port link is down\n", FCELS_ARGS ( els ) ); @@ -815,7 +818,7 @@ static void fc_els_logo_logout ( struct fc_els *els, */ static int fc_els_logo_rx_request ( struct fc_els *els, void *data, size_t len ) { - struct fc_logout_request_frame *logo = data; + struct fc_logout_request_frame *logo; int rc; /* Sanity check */ @@ -825,6 +828,7 @@ static int fc_els_logo_rx_request ( struct fc_els *els, void *data, DBGC_HDA ( els, 0, data, len ); return -EINVAL; } + logo = data; DBGC ( els, FCELS_FMT " has port %s as %s\n", FCELS_ARGS ( els ), fc_ntoa ( &logo->port_wwn ), fc_id_ntoa ( &logo->port_id ) ); @@ -1009,7 +1013,7 @@ int fc_els_prli_rx ( struct fc_els *els, struct { struct fc_prli_frame frame; uint8_t param[descriptor->param_len]; - } __attribute__ (( packed )) *prli = data; + } __attribute__ (( packed )) *prli; struct fc_ulp *ulp; int rc; @@ -1021,6 +1025,7 @@ int fc_els_prli_rx ( struct fc_els *els, rc = -EINVAL; goto err_sanity; } + prli = data; DBGC ( els, FCELS_FMT " has parameters:\n", FCELS_ARGS ( els ) ); DBGC_HDA ( els, 0, prli->param, sizeof ( prli->param ) ); @@ -1095,15 +1100,16 @@ int fc_els_prli_detect ( struct fc_els *els __unused, const struct { struct fc_prli_frame frame; uint8_t param[descriptor->param_len]; - } __attribute__ (( packed )) *prli = data; - - /* Check for PRLI */ - if ( prli->frame.command != FC_ELS_PRLI ) - return -EINVAL; + } __attribute__ (( packed )) *prli; /* Check for sufficient length to contain service parameter page */ if ( len < sizeof ( *prli ) ) return -EINVAL; + prli = data; + + /* Check for PRLI */ + if ( prli->frame.command != FC_ELS_PRLI ) + return -EINVAL; /* Check for upper-layer protocol type */ if ( prli->frame.page.type != descriptor->type ) @@ -1282,13 +1288,21 @@ static int fc_els_echo_rx_request ( struct fc_els *els, void *data, */ static int fc_els_echo_rx_response ( struct fc_els *els, void *data, size_t len ) { - struct fc_echo_request_frame *echo = data; + struct fc_echo_request_frame *echo; DBGC ( els, FCELS_FMT "\n", FCELS_ARGS ( els ) ); + /* Sanity check */ + if ( len != sizeof ( *echo ) ) { + DBGC ( els, FCELS_FMT " received underlength echo response\n", + FCELS_ARGS ( els ) ); + DBGC_HDA ( els, 0, data, len ); + return -EIO; + } + echo = data; + /* Check response is correct */ - if ( ( len != sizeof ( *echo ) ) || - ( echo->magic != htonl ( FC_ECHO_MAGIC ) ) ) { + if ( echo->magic != htonl ( FC_ECHO_MAGIC ) ) { DBGC ( els, FCELS_FMT " received bad echo response\n", FCELS_ARGS ( els ) ); DBGC_HDA ( els, 0, data, len ); diff --git a/src/net/fcns.c b/src/net/fcns.c index be4dfea24..2b966d528 100644 --- a/src/net/fcns.c +++ b/src/net/fcns.c @@ -106,7 +106,7 @@ static void fc_ns_query_close ( struct fc_ns_query *query, int rc ) { static int fc_ns_query_deliver ( struct fc_ns_query *query, struct io_buffer *iobuf, struct xfer_metadata *meta __unused ) { - union fc_ns_response *resp = iobuf->data; + union fc_ns_response *resp; struct fc_port_id *peer_port_id; int rc; @@ -117,6 +117,7 @@ static int fc_ns_query_deliver ( struct fc_ns_query *query, rc = -EINVAL; goto done; } + resp = iobuf->data; /* Handle response */ switch ( ntohs ( resp->ct.code ) ) { diff --git a/src/net/fcp.c b/src/net/fcp.c index 5bb6ebff2..333272028 100644 --- a/src/net/fcp.c +++ b/src/net/fcp.c @@ -508,7 +508,7 @@ static int fcpcmd_recv_xfer_rdy ( struct fcp_command *fcpcmd, struct io_buffer *iobuf, struct xfer_metadata *meta __unused ) { struct fcp_device *fcpdev = fcpcmd->fcpdev; - struct fcp_xfer_rdy *xfer_rdy = iobuf->data; + struct fcp_xfer_rdy *xfer_rdy; int rc; /* Sanity checks */ @@ -519,6 +519,7 @@ static int fcpcmd_recv_xfer_rdy ( struct fcp_command *fcpcmd, rc = -EPROTO; goto done; } + xfer_rdy = iobuf->data; if ( ntohl ( xfer_rdy->offset ) != fcpcmd->offset ) { /* We do not advertise out-of-order delivery */ DBGC ( fcpdev, "FCP %p xchg %04x cannot support out-of-order " diff --git a/src/net/icmp.c b/src/net/icmp.c index 740b42440..19d282ecd 100644 --- a/src/net/icmp.c +++ b/src/net/icmp.c @@ -140,9 +140,13 @@ int icmp_tx_echo_request ( struct io_buffer *iobuf, static int icmp_tx_echo_reply ( struct io_buffer *iobuf, struct sockaddr_tcpip *st_dest, struct icmp_echo_protocol *echo_protocol ) { - struct icmp_echo *echo = iobuf->data; + struct icmp_echo *echo; int rc; + /* Sanity check: should have already been checked by receiver */ + assert ( iob_len ( iobuf ) >= sizeof ( *echo ) ); + echo = iobuf->data; + /* Set type */ echo->icmp.type = echo_protocol->reply; @@ -166,7 +170,7 @@ static int icmp_tx_echo_reply ( struct io_buffer *iobuf, int icmp_rx_echo_request ( struct io_buffer *iobuf, struct sockaddr_tcpip *st_src, struct icmp_echo_protocol *echo_protocol ) { - struct icmp_echo *echo = iobuf->data; + struct icmp_echo *echo; int rc; /* Sanity check */ @@ -177,6 +181,7 @@ int icmp_rx_echo_request ( struct io_buffer *iobuf, free_iob ( iobuf ); return -EINVAL; } + echo = iobuf->data; DBGC ( icmpcol ( st_src ), "ICMP RX echo request id %04x seq %04x\n", ntohs ( echo->ident ), ntohs ( echo->sequence ) ); @@ -196,7 +201,7 @@ int icmp_rx_echo_request ( struct io_buffer *iobuf, */ int icmp_rx_echo_reply ( struct io_buffer *iobuf, struct sockaddr_tcpip *st_src ) { - struct icmp_echo *echo = iobuf->data; + struct icmp_echo *echo; int rc; /* Sanity check */ @@ -207,6 +212,7 @@ int icmp_rx_echo_reply ( struct io_buffer *iobuf, free_iob ( iobuf ); return -EINVAL; } + echo = iobuf->data; DBGC ( icmpcol ( st_src ), "ICMP RX echo reply id %04x seq %04x\n", ntohs ( echo->ident ), ntohs ( echo->sequence ) ); diff --git a/src/net/icmpv4.c b/src/net/icmpv4.c index ffcc4b375..96980289c 100644 --- a/src/net/icmpv4.c +++ b/src/net/icmpv4.c @@ -54,7 +54,7 @@ static int icmpv4_rx ( struct io_buffer *iobuf, struct sockaddr_tcpip *st_src, struct sockaddr_tcpip *st_dest __unused, uint16_t pshdr_csum __unused ) { - struct icmp_header *icmp = iobuf->data; + struct icmp_header *icmp; size_t len = iob_len ( iobuf ); unsigned int csum; unsigned int type; @@ -67,6 +67,7 @@ static int icmpv4_rx ( struct io_buffer *iobuf, rc = -EINVAL; goto discard; } + icmp = iobuf->data; /* Verify checksum */ csum = tcpip_chksum ( icmp, len ); diff --git a/src/net/icmpv6.c b/src/net/icmpv6.c index 5331b81e8..20bf5ff93 100644 --- a/src/net/icmpv6.c +++ b/src/net/icmpv6.c @@ -181,7 +181,7 @@ static int icmpv6_rx ( struct io_buffer *iobuf, struct net_device *netdev, struct sockaddr_tcpip *st_dest, uint16_t pshdr_csum ) { struct sockaddr_in6 *sin6_src = ( ( struct sockaddr_in6 * ) st_src ); struct sockaddr_in6 *sin6_dest = ( ( struct sockaddr_in6 * ) st_dest ); - struct icmp_header *icmp = iobuf->data; + struct icmp_header *icmp; size_t len = iob_len ( iobuf ); struct icmpv6_handler *handler; unsigned int csum; @@ -194,6 +194,7 @@ static int icmpv6_rx ( struct io_buffer *iobuf, struct net_device *netdev, rc = -EINVAL; goto done; } + icmp = iobuf->data; /* Verify checksum */ csum = tcpip_continue_chksum ( pshdr_csum, icmp, len ); diff --git a/src/net/ipv4.c b/src/net/ipv4.c index bda8bae05..75ea0087c 100644 --- a/src/net/ipv4.c +++ b/src/net/ipv4.c @@ -635,7 +635,7 @@ static int ipv4_rx ( struct io_buffer *iobuf, const void *ll_dest __unused, const void *ll_source __unused, unsigned int flags ) { - struct iphdr *iphdr = iobuf->data; + struct iphdr *iphdr; size_t hdrlen; size_t len; union { @@ -660,10 +660,11 @@ static int ipv4_rx ( struct io_buffer *iobuf, /* Sanity check the IPv4 header */ if ( iob_len ( iobuf ) < sizeof ( *iphdr ) ) { - DBGC ( iphdr->src, "IPv4 packet too short at %zd bytes (min " + DBGC ( netdev, "IPv4 packet too short at %zd bytes (min " "%zd bytes)\n", iob_len ( iobuf ), sizeof ( *iphdr ) ); goto err_header; } + iphdr = iobuf->data; if ( ( iphdr->verhdrlen & IP_MASK_VER ) != IP_VER ) { DBGC ( iphdr->src, "IPv4 version %#02x not supported\n", iphdr->verhdrlen ); diff --git a/src/net/ipv6.c b/src/net/ipv6.c index 6d7695853..7a96cbb55 100644 --- a/src/net/ipv6.c +++ b/src/net/ipv6.c @@ -651,7 +651,7 @@ static int ipv6_rx ( struct io_buffer *iobuf, struct net_device *netdev, const void *ll_dest __unused, const void *ll_source __unused, unsigned int flags __unused ) { - struct ipv6_header *iphdr = iobuf->data; + struct ipv6_header *iphdr; union ipv6_extension_header *ext; union { struct sockaddr_in6 sin6; @@ -676,12 +676,12 @@ static int ipv6_rx ( struct io_buffer *iobuf, struct net_device *netdev, /* Sanity check the IPv6 header */ if ( iob_len ( iobuf ) < sizeof ( *iphdr ) ) { - DBGC ( ipv6col ( &iphdr->src ), "IPv6 packet too short at %zd " - "bytes (min %zd bytes)\n", iob_len ( iobuf ), - sizeof ( *iphdr ) ); + DBGC ( netdev, "IPv6 packet too short at %zd bytes (min %zd " + "bytes)\n", iob_len ( iobuf ), sizeof ( *iphdr ) ); rc = -EINVAL_LEN; goto err_header; } + iphdr = iobuf->data; if ( ( iphdr->ver_tc_label & htonl ( IPV6_MASK_VER ) ) != htonl ( IPV6_VER ) ) { DBGC ( ipv6col ( &iphdr->src ), "IPv6 version %#08x not " diff --git a/src/net/ping.c b/src/net/ping.c index 5782813e1..7d7c87436 100644 --- a/src/net/ping.c +++ b/src/net/ping.c @@ -102,13 +102,14 @@ static int ping_port_available ( int port ) { * @ret rc Return status code */ int ping_rx ( struct io_buffer *iobuf, struct sockaddr_tcpip *st_src ) { - struct icmp_echo *echo = iobuf->data; + struct icmp_echo *echo; struct ping_connection *ping; struct xfer_metadata meta; int rc; /* Sanity check: should already have been checked by ICMP layer */ assert ( iob_len ( iobuf ) >= sizeof ( *echo ) ); + echo = iobuf->data; /* Identify connection */ ping = ping_demux ( ntohs ( echo->ident ) ); diff --git a/src/net/tcp.c b/src/net/tcp.c index f08db5250..85e1ceb57 100644 --- a/src/net/tcp.c +++ b/src/net/tcp.c @@ -1411,7 +1411,7 @@ static int tcp_rx ( struct io_buffer *iobuf, struct sockaddr_tcpip *st_src, struct sockaddr_tcpip *st_dest __unused, uint16_t pshdr_csum ) { - struct tcp_header *tcphdr = iobuf->data; + struct tcp_header *tcphdr; struct tcp_connection *tcp; struct tcp_options options; size_t hlen; @@ -1436,6 +1436,7 @@ static int tcp_rx ( struct io_buffer *iobuf, rc = -EINVAL; goto discard; } + tcphdr = iobuf->data; hlen = ( ( tcphdr->hlen & TCP_MASK_HLEN ) / 16 ) * 4; if ( hlen < sizeof ( *tcphdr ) ) { DBG ( "TCP header too short at %zd bytes (min %zd bytes)\n", diff --git a/src/net/udp.c b/src/net/udp.c index 41aba2fca..161938179 100644 --- a/src/net/udp.c +++ b/src/net/udp.c @@ -258,7 +258,7 @@ static int udp_rx ( struct io_buffer *iobuf, struct net_device *netdev __unused, struct sockaddr_tcpip *st_src, struct sockaddr_tcpip *st_dest, uint16_t pshdr_csum ) { - struct udp_header *udphdr = iobuf->data; + struct udp_header *udphdr; struct udp_connection *udp; struct xfer_metadata meta; size_t ulen; @@ -269,10 +269,10 @@ static int udp_rx ( struct io_buffer *iobuf, if ( iob_len ( iobuf ) < sizeof ( *udphdr ) ) { DBG ( "UDP packet too short at %zd bytes (min %zd bytes)\n", iob_len ( iobuf ), sizeof ( *udphdr ) ); - rc = -EINVAL; goto done; } + udphdr = iobuf->data; ulen = ntohs ( udphdr->len ); if ( ulen < sizeof ( *udphdr ) ) { DBG ( "UDP length too short at %zd bytes " diff --git a/src/net/udp/dhcpv6.c b/src/net/udp/dhcpv6.c index 43a569d6e..8e007240d 100644 --- a/src/net/udp/dhcpv6.c +++ b/src/net/udp/dhcpv6.c @@ -844,7 +844,7 @@ static int dhcpv6_rx ( struct dhcpv6_session *dhcpv6, struct xfer_metadata *meta ) { struct settings *parent = netdev_settings ( dhcpv6->netdev ); struct sockaddr_in6 *src = ( ( struct sockaddr_in6 * ) meta->src ); - struct dhcpv6_header *dhcphdr = iobuf->data; + struct dhcpv6_header *dhcphdr; struct dhcpv6_option_list options; const union dhcpv6_any_option *option; int rc; @@ -857,6 +857,7 @@ static int dhcpv6_rx ( struct dhcpv6_session *dhcpv6, rc = -EINVAL; goto done; } + dhcphdr = iobuf->data; assert ( src != NULL ); assert ( src->sin6_family == AF_INET6 ); DBGC ( dhcpv6, "DHCPv6 %s received %s from %s\n", diff --git a/src/net/udp/dns.c b/src/net/udp/dns.c index 3f53675f9..589161114 100644 --- a/src/net/udp/dns.c +++ b/src/net/udp/dns.c @@ -669,9 +669,9 @@ static void dns_timer_expired ( struct retry_timer *timer, int fail ) { static int dns_xfer_deliver ( struct dns_request *dns, struct io_buffer *iobuf, struct xfer_metadata *meta __unused ) { - struct dns_header *response = iobuf->data; struct dns_header *query = &dns->buf.query; unsigned int qtype = dns->question->qtype; + struct dns_header *response; struct dns_name buf; union dns_rr *rr; int offset; @@ -688,6 +688,7 @@ static int dns_xfer_deliver ( struct dns_request *dns, rc = -EINVAL; goto done; } + response = iobuf->data; /* Check response ID matches query ID */ if ( response->id != query->id ) { diff --git a/src/net/udp/tftp.c b/src/net/udp/tftp.c index d25c0653b..7cc720fe5 100644 --- a/src/net/udp/tftp.c +++ b/src/net/udp/tftp.c @@ -720,7 +720,7 @@ static int tftp_process_option ( struct tftp_request *tftp, * @ret rc Return status code */ static int tftp_rx_oack ( struct tftp_request *tftp, void *buf, size_t len ) { - struct tftp_oack *oack = buf; + struct tftp_oack *oack; char *end = buf + len; char *name; char *value; @@ -734,6 +734,7 @@ static int tftp_rx_oack ( struct tftp_request *tftp, void *buf, size_t len ) { rc = -EINVAL; goto done; } + oack = buf; /* Process each option in turn */ for ( name = oack->data ; name < end ; name = next ) { @@ -797,7 +798,7 @@ static int tftp_rx_oack ( struct tftp_request *tftp, void *buf, size_t len ) { */ static int tftp_rx_data ( struct tftp_request *tftp, struct io_buffer *iobuf ) { - struct tftp_data *data = iobuf->data; + struct tftp_data *data; struct xfer_metadata meta; unsigned int block; off_t offset; @@ -811,6 +812,7 @@ static int tftp_rx_data ( struct tftp_request *tftp, rc = -EINVAL; goto done; } + data = iobuf->data; /* Calculate block number */ block = ( ( bitmap_first_gap ( &tftp->bitmap ) + 1 ) & ~0xffff ); @@ -899,7 +901,7 @@ static int tftp_errcode_to_rc ( unsigned int errcode ) { * @ret rc Return status code */ static int tftp_rx_error ( struct tftp_request *tftp, void *buf, size_t len ) { - struct tftp_error *error = buf; + struct tftp_error *error; int rc; /* Sanity check */ @@ -908,6 +910,7 @@ static int tftp_rx_error ( struct tftp_request *tftp, void *buf, size_t len ) { "length %zd\n", tftp, len ); return -EINVAL; } + error = buf; DBGC ( tftp, "TFTP %p received ERROR packet with code %d, message " "\"%s\"\n", tftp, ntohs ( error->errcode ), error->errmsg ); @@ -933,7 +936,7 @@ static int tftp_rx ( struct tftp_request *tftp, struct io_buffer *iobuf, struct xfer_metadata *meta ) { struct sockaddr_tcpip *st_src; - struct tftp_common *common = iobuf->data; + struct tftp_common *common; size_t len = iob_len ( iobuf ); int rc = -EINVAL; @@ -946,6 +949,7 @@ static int tftp_rx ( struct tftp_request *tftp, "%zd\n", tftp, len ); goto done; } + common = iobuf->data; if ( ! meta->src ) { DBGC ( tftp, "TFTP %p received packet without source port\n", tftp ); diff --git a/src/net/vlan.c b/src/net/vlan.c index f7697a9be..47e869bea 100644 --- a/src/net/vlan.c +++ b/src/net/vlan.c @@ -233,7 +233,7 @@ struct net_device * vlan_find ( struct net_device *trunk, unsigned int tag ) { static int vlan_rx ( struct io_buffer *iobuf, struct net_device *trunk, const void *ll_dest, const void *ll_source, unsigned int flags __unused ) { - struct vlan_header *vlanhdr = iobuf->data; + struct vlan_header *vlanhdr; struct net_device *netdev; struct ll_protocol *ll_protocol; uint8_t ll_dest_copy[ETH_ALEN]; @@ -248,6 +248,7 @@ static int vlan_rx ( struct io_buffer *iobuf, struct net_device *trunk, rc = -EINVAL; goto err_sanity; } + vlanhdr = iobuf->data; /* Identify VLAN device */ tag = VLAN_TAG ( ntohs ( vlanhdr->tci ) ); -- 2.47.3