Skip to content

Commit

Permalink
vhost: vduse toctou
Browse files Browse the repository at this point in the history
Signed-off-by: David Marchand <[email protected]>
  • Loading branch information
david-marchand committed Oct 22, 2024
1 parent cff6dba commit 7f90c66
Showing 1 changed file with 13 additions and 21 deletions.
34 changes: 13 additions & 21 deletions lib/vhost/vduse.c
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,6 @@ vduse_device_create(const char *path, bool compliant_ol_flags)
struct virtio_net_config vnet_config = {{ 0 }};
uint64_t ver = VHOST_VDUSE_API_VERSION;
uint64_t features;
struct vduse_dev_config *dev_config = NULL;
const char *name = path + strlen("/dev/vduse/");
char reconnect_file[PATH_MAX];
struct vhost_reconnect_data *reconnect_log = NULL;
Expand Down Expand Up @@ -530,13 +529,13 @@ vduse_device_create(const char *path, bool compliant_ol_flags)
ret = rte_vhost_driver_get_features(path, &features);
if (ret < 0) {
VHOST_CONFIG_LOG(name, ERR, "Failed to get backend features");
goto out_free;
goto out_dev_close;
}

ret = rte_vhost_driver_get_queue_num(path, &max_queue_pairs);
if (ret < 0) {
VHOST_CONFIG_LOG(name, ERR, "Failed to get max queue pairs");
goto out_free;
goto out_dev_close;
}

VHOST_CONFIG_LOG(path, INFO, "VDUSE max queue pairs: %u", max_queue_pairs);
Expand All @@ -547,7 +546,8 @@ vduse_device_create(const char *path, bool compliant_ol_flags)
else
total_queues += 1; /* Includes ctrl queue */

if (access(path, F_OK) == 0) {
dev_fd = open(path, O_RDWR);
if (dev_fd >= 0) {
VHOST_CONFIG_LOG(name, INFO, "Device already exists, reconnecting...");
reconnect = true;

Expand Down Expand Up @@ -594,7 +594,10 @@ vduse_device_create(const char *path, bool compliant_ol_flags)
ret = -1;
goto out_ctrl_close;
}
} else {
} else if (errno == ENOENT) {
char buf[offsetof(struct vduse_dev_config, config) + sizeof(vnet_config)];
struct vduse_dev_config *dev_config = (struct vduse_dev_config *)buf;

reco_fd = open(reconnect_file, O_CREAT | O_EXCL | O_RDWR, 0600);
if (reco_fd < 0) {
if (errno == EEXIST) {
Expand Down Expand Up @@ -628,14 +631,6 @@ vduse_device_create(const char *path, bool compliant_ol_flags)

reconnect_log->version = VHOST_RECONNECT_VERSION;

dev_config = malloc(offsetof(struct vduse_dev_config, config) +
sizeof(vnet_config));
if (!dev_config) {
VHOST_CONFIG_LOG(name, ERR, "Failed to allocate VDUSE config");
ret = -1;
goto out_ctrl_close;
}

vnet_config.max_virtqueue_pairs = max_queue_pairs;
memset(dev_config, 0, sizeof(struct vduse_dev_config));

Expand All @@ -652,16 +647,15 @@ vduse_device_create(const char *path, bool compliant_ol_flags)
if (ret < 0) {
VHOST_CONFIG_LOG(name, ERR, "Failed to create VDUSE device: %s",
strerror(errno));
goto out_free;
goto out_dev_close;
}

memcpy(&reconnect_log->config, &vnet_config, sizeof(vnet_config));
reconnect_log->nr_vrings = total_queues;
free(dev_config);
dev_config = NULL;

dev_fd = open(path, O_RDWR);
}

dev_fd = open(path, O_RDWR);
if (dev_fd < 0) {
VHOST_CONFIG_LOG(name, ERR, "Failed to open device %s: %s",
path, strerror(errno));
Expand Down Expand Up @@ -765,12 +759,10 @@ vduse_device_create(const char *path, bool compliant_ol_flags)
out_dev_destroy:
vhost_destroy_device(vid);
out_dev_close:
if (dev_fd >= 0)
close(dev_fd);
ioctl(control_fd, VDUSE_DESTROY_DEV, name);
out_free:
free(dev_config);
out_ctrl_close:
if (dev_fd >= 0)
close(dev_fd);
close(control_fd);

return ret;
Expand Down

0 comments on commit 7f90c66

Please sign in to comment.