Skip to content

Commit bb77e83

Browse files
Seamus Connorkawasaki
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: d37a224fc119 ("ublk: validate ublk server pid") Signed-off-by: Seamus Connor <sconnor@purestorage.com> Reviewed-by: Caleb Sander Mateos <csander@purestorage.com>
1 parent f962a4d commit bb77e83

File tree

1 file changed

+29
-1
lines changed

1 file changed

+29
-1
lines changed

drivers/block/ublk_drv.c

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2946,6 +2946,10 @@ static int ublk_ctrl_start_dev(struct ublk_device *ub,
29462946
if (wait_for_completion_interruptible(&ub->completion) != 0)
29472947
return -EINTR;
29482948

2949+
rcu_read_lock();
2950+
ublksrv_pid = pid_nr(find_vpid(ublksrv_pid));
2951+
rcu_read_unlock();
2952+
29492953
if (ub->ublksrv_tgid != ublksrv_pid)
29502954
return -EINVAL;
29512955

@@ -3313,12 +3317,32 @@ static int ublk_ctrl_stop_dev(struct ublk_device *ub)
33133317
static int ublk_ctrl_get_dev_info(struct ublk_device *ub,
33143318
const struct ublksrv_ctrl_cmd *header)
33153319
{
3320+
struct task_struct *p;
3321+
struct pid *pid;
3322+
struct ublksrv_ctrl_dev_info dev_info;
3323+
pid_t init_ublksrv_tgid = ub->dev_info.ublksrv_pid;
33163324
void __user *argp = (void __user *)(unsigned long)header->addr;
33173325

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

3321-
if (copy_to_user(argp, &ub->dev_info, sizeof(ub->dev_info)))
3329+
memcpy(&dev_info, &ub->dev_info, sizeof(dev_info));
3330+
dev_info.ublksrv_pid = -1;
3331+
3332+
if (init_ublksrv_tgid > 0) {
3333+
rcu_read_lock();
3334+
pid = find_pid_ns(init_ublksrv_tgid, &init_pid_ns);
3335+
p = pid_task(pid, PIDTYPE_TGID);
3336+
if (p) {
3337+
int vnr = task_tgid_vnr(p);
3338+
3339+
if (vnr)
3340+
dev_info.ublksrv_pid = vnr;
3341+
}
3342+
rcu_read_unlock();
3343+
}
3344+
3345+
if (copy_to_user(argp, &dev_info, sizeof(dev_info)))
33223346
return -EFAULT;
33233347

33243348
return 0;
@@ -3463,6 +3487,10 @@ static int ublk_ctrl_end_recovery(struct ublk_device *ub,
34633487
pr_devel("%s: All FETCH_REQs received, dev id %d\n", __func__,
34643488
header->dev_id);
34653489

3490+
rcu_read_lock();
3491+
ublksrv_pid = pid_nr(find_vpid(ublksrv_pid));
3492+
rcu_read_unlock();
3493+
34663494
if (ub->ublksrv_tgid != ublksrv_pid)
34673495
return -EINVAL;
34683496

0 commit comments

Comments
 (0)