From: Adrian Moreno Date: Mon, 26 Oct 2020 16:39:27 +0000 (+0100) Subject: net/virtio-user: ignore result if status is unsupported X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=5043a0608da1f4774465298a39ced350b151d80c;p=dpdk.git net/virtio-user: ignore result if status is unsupported GET/SET STATUS is an optional feature, so it may not be negotiated. In that case, the VIRTIO_GET_STATUS call will not update the status (given as a pointer argument). Failing to identify this case would lead to undefined behavior as the device status will be updated with the value of a stack-allocated variable. To fix this, return ENOTSUP if the feature is not supported and, in that case, don't update device status. Fixes: 44102e6298e7 ("net/virtio: check protocol feature in user backend") Cc stable@dpdk.org Signed-off-by: Adrian Moreno Reviewed-by: Maxime Coquelin --- diff --git a/drivers/net/virtio/virtio_user/vhost_user.c b/drivers/net/virtio/virtio_user/vhost_user.c index 450d77e921..b93e65c60b 100644 --- a/drivers/net/virtio/virtio_user/vhost_user.c +++ b/drivers/net/virtio/virtio_user/vhost_user.c @@ -281,7 +281,7 @@ vhost_user_sock(struct virtio_user_dev *dev, if (!(dev->status & VIRTIO_CONFIG_STATUS_FEATURES_OK) || (!(dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_STATUS)))) - return 0; + return -ENOTSUP; /* Fallthrough */ case VHOST_USER_GET_FEATURES: case VHOST_USER_GET_PROTOCOL_FEATURES: @@ -292,7 +292,7 @@ vhost_user_sock(struct virtio_user_dev *dev, if (!(dev->status & VIRTIO_CONFIG_STATUS_FEATURES_OK) || (!(dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_STATUS)))) - return 0; + return -ENOTSUP; if (has_reply_ack) msg.flags |= VHOST_USER_NEED_REPLY_MASK; diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c index 27814eadbb..5a1e76006f 100644 --- a/drivers/net/virtio/virtio_user/virtio_user_dev.c +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c @@ -818,15 +818,13 @@ virtio_user_send_status_update(struct virtio_user_dev *dev, uint8_t status) ret = dev->ops->send_request(dev, VHOST_USER_SET_STATUS, &status); else - return 0; + ret = -ENOTSUP; - if (ret) { + if (ret && ret != -ENOTSUP) { PMD_INIT_LOG(ERR, "VHOST_USER_SET_STATUS failed (%d): %s", ret, strerror(errno)); - return -1; } - - return 0; + return ret; } int @@ -849,17 +847,12 @@ virtio_user_update_status(struct virtio_user_dev *dev) err = dev->ops->send_request(dev, VHOST_USER_GET_STATUS, &status); } else { - return 0; - } - - if (err) { - PMD_INIT_LOG(ERR, "VHOST_USER_GET_STATUS failed (%d): %s", err, - strerror(errno)); - return -1; + err = -ENOTSUP; } - dev->status = status; - PMD_INIT_LOG(DEBUG, "Updated Device Status(0x%08x):\n" + if (!err) { + dev->status = status; + PMD_INIT_LOG(DEBUG, "Updated Device Status(0x%08x):\n" "\t-RESET: %u\n" "\t-ACKNOWLEDGE: %u\n" "\t-DRIVER: %u\n" @@ -875,5 +868,10 @@ virtio_user_update_status(struct virtio_user_dev *dev) !!(dev->status & VIRTIO_CONFIG_STATUS_FEATURES_OK), !!(dev->status & VIRTIO_CONFIG_STATUS_DEV_NEED_RESET), !!(dev->status & VIRTIO_CONFIG_STATUS_FAILED)); - return 0; + } else if (err != -ENOTSUP) { + PMD_INIT_LOG(ERR, "VHOST_USER_GET_STATUS failed (%d): %s", err, + strerror(errno)); + } + + return err; }