Skip to content

Commit 80bdfbb

Browse files
ps-ushankaraxboe
authored andcommitted
ublk: enforce ublks_max only for unprivileged devices
Commit 403ebc8 ("ublk_drv: add module parameter of ublks_max for limiting max allowed ublk dev"), claimed ublks_max was added to prevent a DoS situation with an untrusted user creating too many ublk devices. If that's the case, ublks_max should only restrict the number of unprivileged ublk devices in the system. Enforce the limit only for unprivileged ublk devices, and rename variables accordingly. Leave the external-facing parameter name unchanged, since changing it may break systems which use it (but still update its documentation to reflect its new meaning). As a result of this change, in a system where there are only normal (non-unprivileged) devices, the maximum number of such devices is increased to 1 << MINORBITS, or 1048576. That ought to be enough for anyone, right? Signed-off-by: Uday Shankar <[email protected]> Reviewed-by: Ming Lei <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent 3aab938 commit 80bdfbb

File tree

1 file changed

+27
-15
lines changed

1 file changed

+27
-15
lines changed

drivers/block/ublk_drv.c

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -490,15 +490,17 @@ static wait_queue_head_t ublk_idr_wq; /* wait until one idr is freed */
490490

491491
static DEFINE_MUTEX(ublk_ctl_mutex);
492492

493+
494+
#define UBLK_MAX_UBLKS UBLK_MINORS
495+
493496
/*
494-
* Max ublk devices allowed to add
497+
* Max unprivileged ublk devices allowed to add
495498
*
496499
* It can be extended to one per-user limit in future or even controlled
497500
* by cgroup.
498501
*/
499-
#define UBLK_MAX_UBLKS UBLK_MINORS
500-
static unsigned int ublks_max = 64;
501-
static unsigned int ublks_added; /* protected by ublk_ctl_mutex */
502+
static unsigned int unprivileged_ublks_max = 64;
503+
static unsigned int unprivileged_ublks_added; /* protected by ublk_ctl_mutex */
502504

503505
static struct miscdevice ublk_misc;
504506

@@ -2203,7 +2205,8 @@ static int ublk_add_chdev(struct ublk_device *ub)
22032205
if (ret)
22042206
goto fail;
22052207

2206-
ublks_added++;
2208+
if (ub->dev_info.flags & UBLK_F_UNPRIVILEGED_DEV)
2209+
unprivileged_ublks_added++;
22072210
return 0;
22082211
fail:
22092212
put_device(dev);
@@ -2232,11 +2235,16 @@ static int ublk_add_tag_set(struct ublk_device *ub)
22322235

22332236
static void ublk_remove(struct ublk_device *ub)
22342237
{
2238+
bool unprivileged;
2239+
22352240
ublk_stop_dev(ub);
22362241
cancel_work_sync(&ub->nosrv_work);
22372242
cdev_device_del(&ub->cdev, &ub->cdev_dev);
2243+
unprivileged = ub->dev_info.flags & UBLK_F_UNPRIVILEGED_DEV;
22382244
ublk_put_device(ub);
2239-
ublks_added--;
2245+
2246+
if (unprivileged)
2247+
unprivileged_ublks_added--;
22402248
}
22412249

22422250
static struct ublk_device *ublk_get_device_from_id(int idx)
@@ -2501,7 +2509,8 @@ static int ublk_ctrl_add_dev(struct io_uring_cmd *cmd)
25012509
return ret;
25022510

25032511
ret = -EACCES;
2504-
if (ublks_added >= ublks_max)
2512+
if ((info.flags & UBLK_F_UNPRIVILEGED_DEV) &&
2513+
unprivileged_ublks_added >= unprivileged_ublks_max)
25052514
goto out_unlock;
25062515

25072516
ret = -ENOMEM;
@@ -3138,23 +3147,26 @@ static void __exit ublk_exit(void)
31383147
module_init(ublk_init);
31393148
module_exit(ublk_exit);
31403149

3141-
static int ublk_set_max_ublks(const char *buf, const struct kernel_param *kp)
3150+
static int ublk_set_max_unprivileged_ublks(const char *buf,
3151+
const struct kernel_param *kp)
31423152
{
31433153
return param_set_uint_minmax(buf, kp, 0, UBLK_MAX_UBLKS);
31443154
}
31453155

3146-
static int ublk_get_max_ublks(char *buf, const struct kernel_param *kp)
3156+
static int ublk_get_max_unprivileged_ublks(char *buf,
3157+
const struct kernel_param *kp)
31473158
{
3148-
return sysfs_emit(buf, "%u\n", ublks_max);
3159+
return sysfs_emit(buf, "%u\n", unprivileged_ublks_max);
31493160
}
31503161

3151-
static const struct kernel_param_ops ublk_max_ublks_ops = {
3152-
.set = ublk_set_max_ublks,
3153-
.get = ublk_get_max_ublks,
3162+
static const struct kernel_param_ops ublk_max_unprivileged_ublks_ops = {
3163+
.set = ublk_set_max_unprivileged_ublks,
3164+
.get = ublk_get_max_unprivileged_ublks,
31543165
};
31553166

3156-
module_param_cb(ublks_max, &ublk_max_ublks_ops, &ublks_max, 0644);
3157-
MODULE_PARM_DESC(ublks_max, "max number of ublk devices allowed to add(default: 64)");
3167+
module_param_cb(ublks_max, &ublk_max_unprivileged_ublks_ops,
3168+
&unprivileged_ublks_max, 0644);
3169+
MODULE_PARM_DESC(ublks_max, "max number of unprivileged ublk devices allowed to add(default: 64)");
31583170

31593171
MODULE_AUTHOR("Ming Lei <[email protected]>");
31603172
MODULE_DESCRIPTION("Userspace block device");

0 commit comments

Comments
 (0)