@@ -388,6 +388,15 @@ static int netvsc_init_buf(struct hv_device *device,
388388 net_device -> recv_section_size = resp -> sections [0 ].sub_alloc_size ;
389389 net_device -> recv_section_cnt = resp -> sections [0 ].num_sub_allocs ;
390390
391+ /* Ensure buffer will not overflow */
392+ if (net_device -> recv_section_size < NETVSC_MTU_MIN || (u64 )net_device -> recv_section_size *
393+ (u64 )net_device -> recv_section_cnt > (u64 )buf_size ) {
394+ netdev_err (ndev , "invalid recv_section_size %u\n" ,
395+ net_device -> recv_section_size );
396+ ret = - EINVAL ;
397+ goto cleanup ;
398+ }
399+
391400 /* Setup receive completion ring.
392401 * Add 1 to the recv_section_cnt because at least one entry in a
393402 * ring buffer has to be empty.
@@ -460,6 +469,12 @@ static int netvsc_init_buf(struct hv_device *device,
460469 /* Parse the response */
461470 net_device -> send_section_size = init_packet -> msg .
462471 v1_msg .send_send_buf_complete .section_size ;
472+ if (net_device -> send_section_size < NETVSC_MTU_MIN ) {
473+ netdev_err (ndev , "invalid send_section_size %u\n" ,
474+ net_device -> send_section_size );
475+ ret = - EINVAL ;
476+ goto cleanup ;
477+ }
463478
464479 /* Section count is simply the size divided by the section size. */
465480 net_device -> send_section_cnt = buf_size / net_device -> send_section_size ;
@@ -731,12 +746,49 @@ static void netvsc_send_completion(struct net_device *ndev,
731746 int budget )
732747{
733748 const struct nvsp_message * nvsp_packet = hv_pkt_data (desc );
749+ u32 msglen = hv_pkt_datalen (desc );
750+
751+ /* Ensure packet is big enough to read header fields */
752+ if (msglen < sizeof (struct nvsp_message_header )) {
753+ netdev_err (ndev , "nvsp_message length too small: %u\n" , msglen );
754+ return ;
755+ }
734756
735757 switch (nvsp_packet -> hdr .msg_type ) {
736758 case NVSP_MSG_TYPE_INIT_COMPLETE :
759+ if (msglen < sizeof (struct nvsp_message_header ) +
760+ sizeof (struct nvsp_message_init_complete )) {
761+ netdev_err (ndev , "nvsp_msg length too small: %u\n" ,
762+ msglen );
763+ return ;
764+ }
765+ fallthrough ;
766+
737767 case NVSP_MSG1_TYPE_SEND_RECV_BUF_COMPLETE :
768+ if (msglen < sizeof (struct nvsp_message_header ) +
769+ sizeof (struct nvsp_1_message_send_receive_buffer_complete )) {
770+ netdev_err (ndev , "nvsp_msg1 length too small: %u\n" ,
771+ msglen );
772+ return ;
773+ }
774+ fallthrough ;
775+
738776 case NVSP_MSG1_TYPE_SEND_SEND_BUF_COMPLETE :
777+ if (msglen < sizeof (struct nvsp_message_header ) +
778+ sizeof (struct nvsp_1_message_send_send_buffer_complete )) {
779+ netdev_err (ndev , "nvsp_msg1 length too small: %u\n" ,
780+ msglen );
781+ return ;
782+ }
783+ fallthrough ;
784+
739785 case NVSP_MSG5_TYPE_SUBCHANNEL :
786+ if (msglen < sizeof (struct nvsp_message_header ) +
787+ sizeof (struct nvsp_5_subchannel_complete )) {
788+ netdev_err (ndev , "nvsp_msg5 length too small: %u\n" ,
789+ msglen );
790+ return ;
791+ }
740792 /* Copy the response back */
741793 memcpy (& net_device -> channel_init_pkt , nvsp_packet ,
742794 sizeof (struct nvsp_message ));
@@ -1117,19 +1169,28 @@ static void enq_receive_complete(struct net_device *ndev,
11171169static int netvsc_receive (struct net_device * ndev ,
11181170 struct netvsc_device * net_device ,
11191171 struct netvsc_channel * nvchan ,
1120- const struct vmpacket_descriptor * desc ,
1121- const struct nvsp_message * nvsp )
1172+ const struct vmpacket_descriptor * desc )
11221173{
11231174 struct net_device_context * net_device_ctx = netdev_priv (ndev );
11241175 struct vmbus_channel * channel = nvchan -> channel ;
11251176 const struct vmtransfer_page_packet_header * vmxferpage_packet
11261177 = container_of (desc , const struct vmtransfer_page_packet_header , d );
1178+ const struct nvsp_message * nvsp = hv_pkt_data (desc );
1179+ u32 msglen = hv_pkt_datalen (desc );
11271180 u16 q_idx = channel -> offermsg .offer .sub_channel_index ;
11281181 char * recv_buf = net_device -> recv_buf ;
11291182 u32 status = NVSP_STAT_SUCCESS ;
11301183 int i ;
11311184 int count = 0 ;
11321185
1186+ /* Ensure packet is big enough to read header fields */
1187+ if (msglen < sizeof (struct nvsp_message_header )) {
1188+ netif_err (net_device_ctx , rx_err , ndev ,
1189+ "invalid nvsp header, length too small: %u\n" ,
1190+ msglen );
1191+ return 0 ;
1192+ }
1193+
11331194 /* Make sure this is a valid nvsp packet */
11341195 if (unlikely (nvsp -> hdr .msg_type != NVSP_MSG1_TYPE_SEND_RNDIS_PKT )) {
11351196 netif_err (net_device_ctx , rx_err , ndev ,
@@ -1138,6 +1199,14 @@ static int netvsc_receive(struct net_device *ndev,
11381199 return 0 ;
11391200 }
11401201
1202+ /* Validate xfer page pkt header */
1203+ if ((desc -> offset8 << 3 ) < sizeof (struct vmtransfer_page_packet_header )) {
1204+ netif_err (net_device_ctx , rx_err , ndev ,
1205+ "Invalid xfer page pkt, offset too small: %u\n" ,
1206+ desc -> offset8 << 3 );
1207+ return 0 ;
1208+ }
1209+
11411210 if (unlikely (vmxferpage_packet -> xfer_pageset_id != NETVSC_RECEIVE_BUFFER_ID )) {
11421211 netif_err (net_device_ctx , rx_err , ndev ,
11431212 "Invalid xfer page set id - expecting %x got %x\n" ,
@@ -1148,14 +1217,23 @@ static int netvsc_receive(struct net_device *ndev,
11481217
11491218 count = vmxferpage_packet -> range_cnt ;
11501219
1220+ /* Check count for a valid value */
1221+ if (NETVSC_XFER_HEADER_SIZE (count ) > desc -> offset8 << 3 ) {
1222+ netif_err (net_device_ctx , rx_err , ndev ,
1223+ "Range count is not valid: %d\n" ,
1224+ count );
1225+ return 0 ;
1226+ }
1227+
11511228 /* Each range represents 1 RNDIS pkt that contains 1 ethernet frame */
11521229 for (i = 0 ; i < count ; i ++ ) {
11531230 u32 offset = vmxferpage_packet -> ranges [i ].byte_offset ;
11541231 u32 buflen = vmxferpage_packet -> ranges [i ].byte_count ;
11551232 void * data ;
11561233 int ret ;
11571234
1158- if (unlikely (offset + buflen > net_device -> recv_buf_size )) {
1235+ if (unlikely (offset > net_device -> recv_buf_size ||
1236+ buflen > net_device -> recv_buf_size - offset )) {
11591237 nvchan -> rsc .cnt = 0 ;
11601238 status = NVSP_STAT_FAIL ;
11611239 netif_err (net_device_ctx , rx_err , ndev ,
@@ -1194,6 +1272,13 @@ static void netvsc_send_table(struct net_device *ndev,
11941272 u32 count , offset , * tab ;
11951273 int i ;
11961274
1275+ /* Ensure packet is big enough to read send_table fields */
1276+ if (msglen < sizeof (struct nvsp_message_header ) +
1277+ sizeof (struct nvsp_5_send_indirect_table )) {
1278+ netdev_err (ndev , "nvsp_v5_msg length too small: %u\n" , msglen );
1279+ return ;
1280+ }
1281+
11971282 count = nvmsg -> msg .v5_msg .send_table .count ;
11981283 offset = nvmsg -> msg .v5_msg .send_table .offset ;
11991284
@@ -1225,10 +1310,18 @@ static void netvsc_send_table(struct net_device *ndev,
12251310}
12261311
12271312static void netvsc_send_vf (struct net_device * ndev ,
1228- const struct nvsp_message * nvmsg )
1313+ const struct nvsp_message * nvmsg ,
1314+ u32 msglen )
12291315{
12301316 struct net_device_context * net_device_ctx = netdev_priv (ndev );
12311317
1318+ /* Ensure packet is big enough to read its fields */
1319+ if (msglen < sizeof (struct nvsp_message_header ) +
1320+ sizeof (struct nvsp_4_send_vf_association )) {
1321+ netdev_err (ndev , "nvsp_v4_msg length too small: %u\n" , msglen );
1322+ return ;
1323+ }
1324+
12321325 net_device_ctx -> vf_alloc = nvmsg -> msg .v4_msg .vf_assoc .allocated ;
12331326 net_device_ctx -> vf_serial = nvmsg -> msg .v4_msg .vf_assoc .serial ;
12341327 netdev_info (ndev , "VF slot %u %s\n" ,
@@ -1238,16 +1331,24 @@ static void netvsc_send_vf(struct net_device *ndev,
12381331
12391332static void netvsc_receive_inband (struct net_device * ndev ,
12401333 struct netvsc_device * nvscdev ,
1241- const struct nvsp_message * nvmsg ,
1242- u32 msglen )
1334+ const struct vmpacket_descriptor * desc )
12431335{
1336+ const struct nvsp_message * nvmsg = hv_pkt_data (desc );
1337+ u32 msglen = hv_pkt_datalen (desc );
1338+
1339+ /* Ensure packet is big enough to read header fields */
1340+ if (msglen < sizeof (struct nvsp_message_header )) {
1341+ netdev_err (ndev , "inband nvsp_message length too small: %u\n" , msglen );
1342+ return ;
1343+ }
1344+
12441345 switch (nvmsg -> hdr .msg_type ) {
12451346 case NVSP_MSG5_TYPE_SEND_INDIRECTION_TABLE :
12461347 netvsc_send_table (ndev , nvscdev , nvmsg , msglen );
12471348 break ;
12481349
12491350 case NVSP_MSG4_TYPE_SEND_VF_ASSOCIATION :
1250- netvsc_send_vf (ndev , nvmsg );
1351+ netvsc_send_vf (ndev , nvmsg , msglen );
12511352 break ;
12521353 }
12531354}
@@ -1261,23 +1362,20 @@ static int netvsc_process_raw_pkt(struct hv_device *device,
12611362{
12621363 struct vmbus_channel * channel = nvchan -> channel ;
12631364 const struct nvsp_message * nvmsg = hv_pkt_data (desc );
1264- u32 msglen = hv_pkt_datalen (desc );
12651365
12661366 trace_nvsp_recv (ndev , channel , nvmsg );
12671367
12681368 switch (desc -> type ) {
12691369 case VM_PKT_COMP :
1270- netvsc_send_completion (ndev , net_device , channel ,
1271- desc , budget );
1370+ netvsc_send_completion (ndev , net_device , channel , desc , budget );
12721371 break ;
12731372
12741373 case VM_PKT_DATA_USING_XFER_PAGES :
1275- return netvsc_receive (ndev , net_device , nvchan ,
1276- desc , nvmsg );
1374+ return netvsc_receive (ndev , net_device , nvchan , desc );
12771375 break ;
12781376
12791377 case VM_PKT_DATA_INBAND :
1280- netvsc_receive_inband (ndev , net_device , nvmsg , msglen );
1378+ netvsc_receive_inband (ndev , net_device , desc );
12811379 break ;
12821380
12831381 default :
0 commit comments