Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 34 additions & 5 deletions drivers/block/ublk_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -2885,6 +2885,15 @@ static struct ublk_device *ublk_get_device_from_id(int idx)
return ub;
}

static bool ublk_validate_user_pid(struct ublk_device *ub, pid_t ublksrv_pid)
{
rcu_read_lock();
ublksrv_pid = pid_nr(find_vpid(ublksrv_pid));
rcu_read_unlock();

return ub->ublksrv_tgid == ublksrv_pid;
}

static int ublk_ctrl_start_dev(struct ublk_device *ub,
const struct ublksrv_ctrl_cmd *header)
{
Expand Down Expand Up @@ -2953,7 +2962,7 @@ static int ublk_ctrl_start_dev(struct ublk_device *ub,
if (wait_for_completion_interruptible(&ub->completion) != 0)
return -EINTR;

if (ub->ublksrv_tgid != ublksrv_pid)
if (!ublk_validate_user_pid(ub, ublksrv_pid))
return -EINVAL;

mutex_lock(&ub->mutex);
Expand All @@ -2972,7 +2981,7 @@ static int ublk_ctrl_start_dev(struct ublk_device *ub,
disk->fops = &ub_fops;
disk->private_data = ub;

ub->dev_info.ublksrv_pid = ublksrv_pid;
ub->dev_info.ublksrv_pid = ub->ublksrv_tgid;
ub->ub_disk = disk;

ublk_apply_params(ub);
Expand Down Expand Up @@ -3320,12 +3329,32 @@ static int ublk_ctrl_stop_dev(struct ublk_device *ub)
static int ublk_ctrl_get_dev_info(struct ublk_device *ub,
const struct ublksrv_ctrl_cmd *header)
{
struct task_struct *p;
struct pid *pid;
struct ublksrv_ctrl_dev_info dev_info;
pid_t init_ublksrv_tgid = ub->dev_info.ublksrv_pid;
void __user *argp = (void __user *)(unsigned long)header->addr;

if (header->len < sizeof(struct ublksrv_ctrl_dev_info) || !header->addr)
return -EINVAL;

if (copy_to_user(argp, &ub->dev_info, sizeof(ub->dev_info)))
memcpy(&dev_info, &ub->dev_info, sizeof(dev_info));
dev_info.ublksrv_pid = -1;

if (init_ublksrv_tgid > 0) {
rcu_read_lock();
pid = find_pid_ns(init_ublksrv_tgid, &init_pid_ns);
p = pid_task(pid, PIDTYPE_TGID);
if (p) {
int vnr = task_tgid_vnr(p);

if (vnr)
dev_info.ublksrv_pid = vnr;
}
rcu_read_unlock();
}

if (copy_to_user(argp, &dev_info, sizeof(dev_info)))
return -EFAULT;

return 0;
Expand Down Expand Up @@ -3470,7 +3499,7 @@ static int ublk_ctrl_end_recovery(struct ublk_device *ub,
pr_devel("%s: All FETCH_REQs received, dev id %d\n", __func__,
header->dev_id);

if (ub->ublksrv_tgid != ublksrv_pid)
if (!ublk_validate_user_pid(ub, ublksrv_pid))
return -EINVAL;

mutex_lock(&ub->mutex);
Expand All @@ -3481,7 +3510,7 @@ static int ublk_ctrl_end_recovery(struct ublk_device *ub,
ret = -EBUSY;
goto out_unlock;
}
ub->dev_info.ublksrv_pid = ublksrv_pid;
ub->dev_info.ublksrv_pid = ub->ublksrv_tgid;
ub->dev_info.state = UBLK_S_DEV_LIVE;
pr_devel("%s: new ublksrv_pid %d, dev id %d\n",
__func__, ublksrv_pid, header->dev_id);
Expand Down