Skip to content

Commit 47bdf1d

Browse files
Seamus Connoraxboe
authored andcommitted
ublk: fix ublksrv pid handling for pid namespaces
When ublksrv runs inside a pid namespace, START/END_RECOVERY compared the stored init-ns tgid against the userspace pid (getpid vnr), so the check failed and control ops could not proceed. Compare against the caller’s init-ns tgid and store that value, then translate it back to the caller’s pid namespace when reporting GET_DEV_INFO so ublk list shows a sensible pid. Testing: start/recover in a pid namespace; `ublk list` shows reasonable pid values in init, child, and sibling namespaces. Fixes: c2c8089 ("ublk: validate ublk server pid") Signed-off-by: Seamus Connor <sconnor@purestorage.com> Reviewed-by: Caleb Sander Mateos <csander@purestorage.com> Reviewed-by: Ming Lei <ming.lei@redhat.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent 07a1bc5 commit 47bdf1d

1 file changed

Lines changed: 34 additions & 5 deletions

File tree

drivers/block/ublk_drv.c

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2885,6 +2885,15 @@ static struct ublk_device *ublk_get_device_from_id(int idx)
28852885
return ub;
28862886
}
28872887

2888+
static bool ublk_validate_user_pid(struct ublk_device *ub, pid_t ublksrv_pid)
2889+
{
2890+
rcu_read_lock();
2891+
ublksrv_pid = pid_nr(find_vpid(ublksrv_pid));
2892+
rcu_read_unlock();
2893+
2894+
return ub->ublksrv_tgid == ublksrv_pid;
2895+
}
2896+
28882897
static int ublk_ctrl_start_dev(struct ublk_device *ub,
28892898
const struct ublksrv_ctrl_cmd *header)
28902899
{
@@ -2953,7 +2962,7 @@ static int ublk_ctrl_start_dev(struct ublk_device *ub,
29532962
if (wait_for_completion_interruptible(&ub->completion) != 0)
29542963
return -EINTR;
29552964

2956-
if (ub->ublksrv_tgid != ublksrv_pid)
2965+
if (!ublk_validate_user_pid(ub, ublksrv_pid))
29572966
return -EINVAL;
29582967

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

2975-
ub->dev_info.ublksrv_pid = ublksrv_pid;
2984+
ub->dev_info.ublksrv_pid = ub->ublksrv_tgid;
29762985
ub->ub_disk = disk;
29772986

29782987
ublk_apply_params(ub);
@@ -3320,12 +3329,32 @@ static int ublk_ctrl_stop_dev(struct ublk_device *ub)
33203329
static int ublk_ctrl_get_dev_info(struct ublk_device *ub,
33213330
const struct ublksrv_ctrl_cmd *header)
33223331
{
3332+
struct task_struct *p;
3333+
struct pid *pid;
3334+
struct ublksrv_ctrl_dev_info dev_info;
3335+
pid_t init_ublksrv_tgid = ub->dev_info.ublksrv_pid;
33233336
void __user *argp = (void __user *)(unsigned long)header->addr;
33243337

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

3328-
if (copy_to_user(argp, &ub->dev_info, sizeof(ub->dev_info)))
3341+
memcpy(&dev_info, &ub->dev_info, sizeof(dev_info));
3342+
dev_info.ublksrv_pid = -1;
3343+
3344+
if (init_ublksrv_tgid > 0) {
3345+
rcu_read_lock();
3346+
pid = find_pid_ns(init_ublksrv_tgid, &init_pid_ns);
3347+
p = pid_task(pid, PIDTYPE_TGID);
3348+
if (p) {
3349+
int vnr = task_tgid_vnr(p);
3350+
3351+
if (vnr)
3352+
dev_info.ublksrv_pid = vnr;
3353+
}
3354+
rcu_read_unlock();
3355+
}
3356+
3357+
if (copy_to_user(argp, &dev_info, sizeof(dev_info)))
33293358
return -EFAULT;
33303359

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

3473-
if (ub->ublksrv_tgid != ublksrv_pid)
3502+
if (!ublk_validate_user_pid(ub, ublksrv_pid))
34743503
return -EINVAL;
34753504

34763505
mutex_lock(&ub->mutex);
@@ -3481,7 +3510,7 @@ static int ublk_ctrl_end_recovery(struct ublk_device *ub,
34813510
ret = -EBUSY;
34823511
goto out_unlock;
34833512
}
3484-
ub->dev_info.ublksrv_pid = ublksrv_pid;
3513+
ub->dev_info.ublksrv_pid = ub->ublksrv_tgid;
34853514
ub->dev_info.state = UBLK_S_DEV_LIVE;
34863515
pr_devel("%s: new ublksrv_pid %d, dev id %d\n",
34873516
__func__, ublksrv_pid, header->dev_id);

0 commit comments

Comments
 (0)