From nobody Wed Feb 11 04:18:29 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 22ED03EBF25 for ; Tue, 10 Feb 2026 16:36:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770741417; cv=none; b=DfbsSYdJjdp9e15VZLSRA5dUo2gZ9HChjy2WPqGcUGBx+fg4638TZVzsifvh4A4wNl0E7zKKIV1xgZR12irrhJRl1rBtfjkyx1ndtfVwMmosvwFxu+W1RZESZprV2S4MBfccnteQoyTJwMLkG18rcNPft2/SDybWChX38aKPOlw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770741417; c=relaxed/simple; bh=naOq9zt4BYqb8oi/j4+zUOP4P/M+psDY05W0cStV6I4=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=laftQ0bLjTJmr4SHsBMTtQBom52anLb71mbn7CcF9czB4W3vmqzXHboKsC6GC4Vnk4KWcoEVQI6kW7CaGATk4/6NtwRP5xznu4KoGSrUwaHw47K3P3iSzwQIfnYZMYxS7Q248YFS0uDMjLVMLSVgNp6lMObuezdxdj+CIM8wcDg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=aYJpnCWU; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="aYJpnCWU" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1770741415; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=wQ4w7TUNhvmGRR094/wdhZnzztkYQptsZhG4t5guo2A=; b=aYJpnCWUBzSvG1vmkvz/EcD42Noh2KBUMnaie6sTCJVlX/7sZs2reWj0q1tCyG4/ypapFP PoxhX+phaSTancmXJEKhbDBYAtxqU8a5bTIdjC5pwdpJVkzfPpK3Mhclr5/XvcTFbVmF1b zIhHhc7TM2ZdBsprWMIht+tMFpVIhaY= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-488-j5dT-Pz0N660120MpT6Q1A-1; Tue, 10 Feb 2026 11:36:27 -0500 X-MC-Unique: j5dT-Pz0N660120MpT6Q1A-1 X-Mimecast-MFC-AGG-ID: j5dT-Pz0N660120MpT6Q1A_1770741386 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id F0B6E1944B0A; Tue, 10 Feb 2026 16:36:19 +0000 (UTC) Received: from localhost (unknown [10.2.16.202]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id D0E59300DDBE; Tue, 10 Feb 2026 16:36:18 +0000 (UTC) From: Stefan Hajnoczi To: Jens Axboe Cc: linux-kernel@vger.kernel.org, linux-block@vger.kernel.org, Stefan Hajnoczi , Christoph Hellwig , Martin Wilck , Benjamin Marzinski , Hannes Reinecke Subject: [PATCH] block: allow IOC_PR_READ_* ioctls with BLK_OPEN_READ Date: Tue, 10 Feb 2026 11:36:17 -0500 Message-ID: <20260210163617.144359-1-stefanha@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 Content-Type: text/plain; charset="utf-8" The recently added IOC_PR_READ_* ioctls require the same BLK_OPEN_WRITE permission as the older persistent reservation ioctls. This has the drawback that udev triggers when the file descriptor is closed, resulting in unnecessary activity like scanning partitions even though these read-only ioctls do not modify the device. Change IOC_PR_READ_KEYS and IOC_PR_READ_RESERVATION to require BLK_OPEN_READ. This prevents unnecessary activity every time `blkpr --read-keys` or `blkpr --read-reservation` is invoked by shell scripts, for example. It is safe to reduce the permission requirement from BLK_OPEN_WRITE to BLK_OPEN_READ since these two ioctls do not modify the persistent reservation state. Userspace cannot use the information fetched by these ioctls to make changes to the device unless it later opens the device with BLK_OPEN_WRITE. Fixes: 3e2cb9ee76c2 ("block: add IOC_PR_READ_RESERVATION ioctl") Fixes: 22a1ffea5f80 ("block: add IOC_PR_READ_KEYS ioctl") Cc: Christoph Hellwig Cc: Martin Wilck Cc: Benjamin Marzinski Suggested-by: Hannes Reinecke Signed-off-by: Stefan Hajnoczi --- block/ioctl.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/block/ioctl.c b/block/ioctl.c index 344478348a54e..337e4c3b65b2c 100644 --- a/block/ioctl.c +++ b/block/ioctl.c @@ -318,7 +318,13 @@ int blkdev_compat_ptr_ioctl(struct block_device *bdev,= blk_mode_t mode, EXPORT_SYMBOL(blkdev_compat_ptr_ioctl); #endif =20 -static bool blkdev_pr_allowed(struct block_device *bdev, blk_mode_t mode) +enum pr_direction { + PR_IN, /* read from device */ + PR_OUT, /* write to device */ +}; + +static bool blkdev_pr_allowed(struct block_device *bdev, blk_mode_t mode, + enum pr_direction dir) { /* no sense to make reservations for partitions */ if (bdev_is_partition(bdev)) @@ -326,11 +332,17 @@ static bool blkdev_pr_allowed(struct block_device *bd= ev, blk_mode_t mode) =20 if (capable(CAP_SYS_ADMIN)) return true; + /* - * Only allow unprivileged reservations if the file descriptor is open - * for writing. + * Only allow unprivileged reservation _out_ commands if the file + * descriptor is open for writing. Allow reservation _in_ commands if + * the file descriptor is open for reading since they do not modify the + * device. */ - return mode & BLK_OPEN_WRITE; + if (dir =3D=3D PR_IN) + return mode & BLK_OPEN_READ; + else + return mode & BLK_OPEN_WRITE; } =20 static int blkdev_pr_register(struct block_device *bdev, blk_mode_t mode, @@ -339,7 +351,7 @@ static int blkdev_pr_register(struct block_device *bdev= , blk_mode_t mode, const struct pr_ops *ops =3D bdev->bd_disk->fops->pr_ops; struct pr_registration reg; =20 - if (!blkdev_pr_allowed(bdev, mode)) + if (!blkdev_pr_allowed(bdev, mode, PR_OUT)) return -EPERM; if (!ops || !ops->pr_register) return -EOPNOTSUPP; @@ -357,7 +369,7 @@ static int blkdev_pr_reserve(struct block_device *bdev,= blk_mode_t mode, const struct pr_ops *ops =3D bdev->bd_disk->fops->pr_ops; struct pr_reservation rsv; =20 - if (!blkdev_pr_allowed(bdev, mode)) + if (!blkdev_pr_allowed(bdev, mode, PR_OUT)) return -EPERM; if (!ops || !ops->pr_reserve) return -EOPNOTSUPP; @@ -375,7 +387,7 @@ static int blkdev_pr_release(struct block_device *bdev,= blk_mode_t mode, const struct pr_ops *ops =3D bdev->bd_disk->fops->pr_ops; struct pr_reservation rsv; =20 - if (!blkdev_pr_allowed(bdev, mode)) + if (!blkdev_pr_allowed(bdev, mode, PR_OUT)) return -EPERM; if (!ops || !ops->pr_release) return -EOPNOTSUPP; @@ -393,7 +405,7 @@ static int blkdev_pr_preempt(struct block_device *bdev,= blk_mode_t mode, const struct pr_ops *ops =3D bdev->bd_disk->fops->pr_ops; struct pr_preempt p; =20 - if (!blkdev_pr_allowed(bdev, mode)) + if (!blkdev_pr_allowed(bdev, mode, PR_OUT)) return -EPERM; if (!ops || !ops->pr_preempt) return -EOPNOTSUPP; @@ -411,7 +423,7 @@ static int blkdev_pr_clear(struct block_device *bdev, b= lk_mode_t mode, const struct pr_ops *ops =3D bdev->bd_disk->fops->pr_ops; struct pr_clear c; =20 - if (!blkdev_pr_allowed(bdev, mode)) + if (!blkdev_pr_allowed(bdev, mode, PR_OUT)) return -EPERM; if (!ops || !ops->pr_clear) return -EOPNOTSUPP; @@ -434,7 +446,7 @@ static int blkdev_pr_read_keys(struct block_device *bde= v, blk_mode_t mode, size_t keys_copy_len; int ret; =20 - if (!blkdev_pr_allowed(bdev, mode)) + if (!blkdev_pr_allowed(bdev, mode, PR_IN)) return -EPERM; if (!ops || !ops->pr_read_keys) return -EOPNOTSUPP; @@ -486,7 +498,7 @@ static int blkdev_pr_read_reservation(struct block_devi= ce *bdev, struct pr_read_reservation out =3D {}; int ret; =20 - if (!blkdev_pr_allowed(bdev, mode)) + if (!blkdev_pr_allowed(bdev, mode, PR_IN)) return -EPERM; if (!ops || !ops->pr_read_reservation) return -EOPNOTSUPP; --=20 2.52.0