Skip to content

Commit d814b67

Browse files
committed
Merge branch 'hv_netvsc-Fix-send-indirection-table-offset'
Haiyang Zhang says: ==================== hv_netvsc: Fix send indirection table offset Fix send indirection table offset issues related to guest and host bugs. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 35fc59c + 171c1fd commit d814b67

File tree

2 files changed

+32
-9
lines changed

2 files changed

+32
-9
lines changed

drivers/net/hyperv/hyperv_net.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,8 @@ struct nvsp_5_send_indirect_table {
609609
/* The number of entries in the send indirection table */
610610
u32 count;
611611

612-
/* The offset of the send indirection table from top of this struct.
612+
/* The offset of the send indirection table from the beginning of
613+
* struct nvsp_message.
613614
* The send indirection table tells which channel to put the send
614615
* traffic on. Each entry is a channel number.
615616
*/

drivers/net/hyperv/netvsc.c

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1178,20 +1178,39 @@ static int netvsc_receive(struct net_device *ndev,
11781178
}
11791179

11801180
static void netvsc_send_table(struct net_device *ndev,
1181-
const struct nvsp_message *nvmsg)
1181+
struct netvsc_device *nvscdev,
1182+
const struct nvsp_message *nvmsg,
1183+
u32 msglen)
11821184
{
11831185
struct net_device_context *net_device_ctx = netdev_priv(ndev);
1184-
u32 count, *tab;
1186+
u32 count, offset, *tab;
11851187
int i;
11861188

11871189
count = nvmsg->msg.v5_msg.send_table.count;
1190+
offset = nvmsg->msg.v5_msg.send_table.offset;
1191+
11881192
if (count != VRSS_SEND_TAB_SIZE) {
11891193
netdev_err(ndev, "Received wrong send-table size:%u\n", count);
11901194
return;
11911195
}
11921196

1193-
tab = (u32 *)((unsigned long)&nvmsg->msg.v5_msg.send_table +
1194-
nvmsg->msg.v5_msg.send_table.offset);
1197+
/* If negotiated version <= NVSP_PROTOCOL_VERSION_6, the offset may be
1198+
* wrong due to a host bug. So fix the offset here.
1199+
*/
1200+
if (nvscdev->nvsp_version <= NVSP_PROTOCOL_VERSION_6 &&
1201+
msglen >= sizeof(struct nvsp_message_header) +
1202+
sizeof(union nvsp_6_message_uber) + count * sizeof(u32))
1203+
offset = sizeof(struct nvsp_message_header) +
1204+
sizeof(union nvsp_6_message_uber);
1205+
1206+
/* Boundary check for all versions */
1207+
if (offset > msglen - count * sizeof(u32)) {
1208+
netdev_err(ndev, "Received send-table offset too big:%u\n",
1209+
offset);
1210+
return;
1211+
}
1212+
1213+
tab = (void *)nvmsg + offset;
11951214

11961215
for (i = 0; i < count; i++)
11971216
net_device_ctx->tx_table[i] = tab[i];
@@ -1209,12 +1228,14 @@ static void netvsc_send_vf(struct net_device *ndev,
12091228
net_device_ctx->vf_alloc ? "added" : "removed");
12101229
}
12111230

1212-
static void netvsc_receive_inband(struct net_device *ndev,
1213-
const struct nvsp_message *nvmsg)
1231+
static void netvsc_receive_inband(struct net_device *ndev,
1232+
struct netvsc_device *nvscdev,
1233+
const struct nvsp_message *nvmsg,
1234+
u32 msglen)
12141235
{
12151236
switch (nvmsg->hdr.msg_type) {
12161237
case NVSP_MSG5_TYPE_SEND_INDIRECTION_TABLE:
1217-
netvsc_send_table(ndev, nvmsg);
1238+
netvsc_send_table(ndev, nvscdev, nvmsg, msglen);
12181239
break;
12191240

12201241
case NVSP_MSG4_TYPE_SEND_VF_ASSOCIATION:
@@ -1232,6 +1253,7 @@ static int netvsc_process_raw_pkt(struct hv_device *device,
12321253
{
12331254
struct vmbus_channel *channel = nvchan->channel;
12341255
const struct nvsp_message *nvmsg = hv_pkt_data(desc);
1256+
u32 msglen = hv_pkt_datalen(desc);
12351257

12361258
trace_nvsp_recv(ndev, channel, nvmsg);
12371259

@@ -1247,7 +1269,7 @@ static int netvsc_process_raw_pkt(struct hv_device *device,
12471269
break;
12481270

12491271
case VM_PKT_DATA_INBAND:
1250-
netvsc_receive_inband(ndev, nvmsg);
1272+
netvsc_receive_inband(ndev, net_device, nvmsg, msglen);
12511273
break;
12521274

12531275
default:

0 commit comments

Comments
 (0)