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)
{
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);
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);
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;
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);
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);