From nobody Sun May 24 21:39:31 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 592AF36683B for ; Thu, 21 May 2026 09:11:02 +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=1779354664; cv=none; b=TrdafVPpLcpuEJMMX8tEOfnOYklnINOzZYSM/X9LCMKoE4Akud7AThRaWS4NeWtWmTSnZaVUD2V5EGfF+ZonAl/E9olzvh3DSiITV82kGPLxC/5YuQd0aSq9ihofhAzhPdmEyKo+r+xPRElvwqaXTWXuF4PGc2Sw/Fn6o+L9t5g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779354664; c=relaxed/simple; bh=5Tv/PuOUE3lMfNJIxFBx6QKMiev0LMyHcGnY1FLbFjI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=UycMNDkrGJtFDp19Pu3u9COd9PzhhApxHXLTGJcYrkj4B4VSrubE9ECKhFV/3I2aqpVwAnoqjMPwFbBFxAJBr9Ege7gZKBeJJpJHkOXKXzjSr0BF5OlOJ+zKGPK//n/FMenL38lRwgN6EyRNSQt0gdUHK3dgLbtkyUCVUz4yrY8= 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=DCegUFZU; 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="DCegUFZU" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1779354661; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/PCaVPAbPc0wJCZVNgUDA/e9ykpfDoQlMxFOJwanDFI=; b=DCegUFZUsz7mG+iXBPSE8m2nBGBlQGLUdKMZcwy2HVgCNEchSpRZ+0mKg2X385qf3nVOZA 3e+8EzHVNVXWyC1FKoeO9VgnbL3xsAun+nme0End7+aWaXbdWgGidSDFCSUTSVCpb1dPpC o8vMFCseTI1P4GcKdATR2NPHYtRS2Ik= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-336-5AfHoqXmMYqWQbFsJppvBA-1; Thu, 21 May 2026 05:10:57 -0400 X-MC-Unique: 5AfHoqXmMYqWQbFsJppvBA-1 X-Mimecast-MFC-AGG-ID: 5AfHoqXmMYqWQbFsJppvBA_1779354656 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id D0774180035D; Thu, 21 May 2026 09:10:55 +0000 (UTC) Received: from [192.168.1.153] (headnet01.pony-001.prod.iad2.dc.redhat.com [10.2.32.101]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id D16AC19560A6; Thu, 21 May 2026 09:10:52 +0000 (UTC) From: Albert Esteve Date: Thu, 21 May 2026 11:10:14 +0200 Subject: [PATCH 1/2] dma-buf: add DMA_BUF_IOCTL_DERIVE for reduced-permission aliases Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260521-dmabuf-limit-access-v1-1-26c01e27365a@redhat.com> References: <20260521-dmabuf-limit-access-v1-0-26c01e27365a@redhat.com> In-Reply-To: <20260521-dmabuf-limit-access-v1-0-26c01e27365a@redhat.com> To: Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= , Benjamin Gaignard , Brian Starkey , John Stultz , "T.J. Mercier" , Shuah Khan Cc: linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Albert Esteve , mripard@kernel.org X-Developer-Signature: v=1; a=ed25519-sha256; t=1779354648; l=6318; i=aesteve@redhat.com; s=20260303; h=from:subject:message-id; bh=5Tv/PuOUE3lMfNJIxFBx6QKMiev0LMyHcGnY1FLbFjI=; b=+HlK3v2Xzm8Vf64ep+Nz1sznpvOeM1j58Tv1jogL0OTcxB9lXU3UhW8W5us50KJpKHWWv4Txy v3oGcjCaj+vAhNnTiz1EEsvzhBfy0/oKY/TzaUxusdwJ6eugzuQVYQB X-Developer-Key: i=aesteve@redhat.com; a=ed25519; pk=YSFz6sOHd2L45+Fr8DIvHTi6lSIjhLZ5T+rkxspJt1s= X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 When sharing a dma-buf between components of different trust levels, the allocator may need to hand out a read-only view of a buffer it holds with read-write access. Currently there is no mechanism to do this: the file flags set at allocation time are fixed for the lifetime of the dma-buf, and dup(2) and dup3(2) cannot change the access mode of the new fd. Add DMA_BUF_IOCTL_DERIVE, which takes a struct dma_buf_derive carrying the desired access flags and returns a new file descriptor for the same buffer with those flags applied. Permission escalation is rejected with EACCES. The new fd aliases the same struct dma_buf, same dma_resv, same exporter ops, same underlying memory. Importers that attach to either fd operate on the same object and observe the same fence timeline. To support multiple struct file instances sharing one struct dma_buf, two small internal adjustments are required. First, move __dma_buf_list_del() to dma_buf_release() so that list removal fires exactly once when the dentry is destroyed. Second, update dma_buf_file_release() to call dma_buf_put() only for the files that are not primary dmabuf files, leaving the primary fd's refcount managed by the normal dentry lifecycle. Finally, enforce the access restriction in dma_buf_mmap_internal(): a shared writable mapping (MAP_SHARED + PROT_WRITE) on a read-only fd is rejected with -EACCES. Without this check, O_RDONLY on a dma-buf fd would be cosmetic, as the VFS does not enforce f_mode for writable mmap on anonymous inodes. Signed-off-by: Albert Esteve --- drivers/dma-buf/dma-buf.c | 58 ++++++++++++++++++++++++++++++++++++++++= +++- include/uapi/linux/dma-buf.h | 28 +++++++++++++++++++++ 2 files changed, 85 insertions(+), 1 deletion(-) diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 71f37544a5c61..34a3872365730 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -180,6 +180,7 @@ static void dma_buf_release(struct dentry *dentry) */ BUG_ON(dmabuf->cb_in.active || dmabuf->cb_out.active); =20 + __dma_buf_list_del(dmabuf); dmabuf->ops->release(dmabuf); =20 if (dmabuf->resv =3D=3D (struct dma_resv *)&dmabuf[1]) @@ -193,10 +194,13 @@ static void dma_buf_release(struct dentry *dentry) =20 static int dma_buf_file_release(struct inode *inode, struct file *file) { + struct dma_buf *dmabuf =3D file->private_data; + if (!is_dma_buf_file(file)) return -EINVAL; =20 - __dma_buf_list_del(file->private_data); + if (file !=3D dmabuf->file) + dma_buf_put(dmabuf); =20 return 0; } @@ -232,6 +236,11 @@ static int dma_buf_mmap_internal(struct file *file, st= ruct vm_area_struct *vma) if (!is_dma_buf_file(file)) return -EINVAL; =20 + if ((vma->vm_flags & VM_WRITE) && + (vma->vm_flags & VM_SHARED) && + !(file->f_mode & FMODE_WRITE)) + return -EACCES; + dmabuf =3D file->private_data; =20 /* check if buffer supports mmap */ @@ -537,6 +546,50 @@ static long dma_buf_import_sync_file(struct dma_buf *d= mabuf, } #endif =20 +static const struct file_operations dma_buf_fops; + +static int dma_buf_ioctl_derive(struct dma_buf *dmabuf, struct file *file, + void __user *udata) +{ + struct dma_buf_derive params; + struct file *new_file; + int new_fd; + + if (copy_from_user(¶ms, udata, sizeof(params))) + return -EFAULT; + + if (params.flags & ~(O_ACCMODE | O_CLOEXEC)) + return -EINVAL; + + /* Escalating permissions is not allowed. */ + if ((params.flags & O_ACCMODE) =3D=3D O_RDWR && + !(file->f_mode & FMODE_WRITE)) + return -EACCES; + + new_file =3D alloc_file_clone(dmabuf->file, params.flags, &dma_buf_fops); + if (IS_ERR(new_file)) + return PTR_ERR(new_file); + + get_dma_buf(dmabuf); + new_file->private_data =3D dmabuf; + + new_fd =3D get_unused_fd_flags(params.flags & O_CLOEXEC ? O_CLOEXEC : 0); + if (new_fd < 0) { + fput(new_file); + return new_fd; + } + + params.fd =3D new_fd; + if (copy_to_user(udata, ¶ms, sizeof(params))) { + put_unused_fd(new_fd); + fput(new_file); + return -EFAULT; + } + + fd_install(new_fd, new_file); + return 0; +} + static long dma_buf_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -587,6 +640,9 @@ static long dma_buf_ioctl(struct file *file, return dma_buf_import_sync_file(dmabuf, (const void __user *)arg); #endif =20 + case DMA_BUF_IOCTL_DERIVE: + return dma_buf_ioctl_derive(dmabuf, file, (void __user *)arg); + default: return -ENOTTY; } diff --git a/include/uapi/linux/dma-buf.h b/include/uapi/linux/dma-buf.h index e827c9d20c5d3..d0cf616228e55 100644 --- a/include/uapi/linux/dma-buf.h +++ b/include/uapi/linux/dma-buf.h @@ -168,6 +168,33 @@ struct dma_buf_import_sync_file { __s32 fd; }; =20 +/** + * struct dma_buf_derive - Obtain a dma-buf fd with reduced access permiss= ions + * + * Userspace can perform a DMA_BUF_IOCTL_DERIVE to obtain a second file + * descriptor for the same dma-buf with a subset of the calling fd's + * permissions. This allows a producer holding read-write access to hand a + * read-only view to a less-privileged consumer without giving up its own + * write access or allocating a separate buffer. + * + * Unlike first-export ioctls, the new fd is not a re-export. It shares the + * same reservation object, exporter ops, and underlying memory as the + * original. + * + * The requested permissions must not exceed those of the calling fd. + */ +struct dma_buf_derive { + /** + * @flags: Requested access flags. + * + * Accepts O_RDONLY or O_RDWR, optionally combined with O_CLOEXEC. + * All other bits must be zero. + */ + __u32 flags; + /** @fd: Returned file descriptor with the requested permissions */ + __s32 fd; +}; + #define DMA_BUF_BASE 'b' #define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync) =20 @@ -179,5 +206,6 @@ struct dma_buf_import_sync_file { #define DMA_BUF_SET_NAME_B _IOW(DMA_BUF_BASE, 1, __u64) #define DMA_BUF_IOCTL_EXPORT_SYNC_FILE _IOWR(DMA_BUF_BASE, 2, struct dma_b= uf_export_sync_file) #define DMA_BUF_IOCTL_IMPORT_SYNC_FILE _IOW(DMA_BUF_BASE, 3, struct dma_bu= f_import_sync_file) +#define DMA_BUF_IOCTL_DERIVE _IOWR(DMA_BUF_BASE, 4, struct dma_buf_derive) =20 #endif --=20 2.53.0 From nobody Sun May 24 21:39:31 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 6A48736827E for ; Thu, 21 May 2026 09:11:03 +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=1779354665; cv=none; b=GYHw7TQh1IfZ8EmYzhmThcPbWHYg/52xoXIvEgU3L4DG6hLMJoLbYnxbcDDb1R5Wq8nMD6PTA+3D8VJP/fVPdokHSdQL5HzuMbDnZdnDS8cwbOq+uxHjShQEd3c+0fmJH0QPrhE7hbyrn36KZxQkFPIxUZc03tRcJZWmH/5wGjc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779354665; c=relaxed/simple; bh=/ApxYmdq3kHu3thKFegK+YtWMiL83D621EF8tkmYSG4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=bIYKorA1VsCGCpoHC/B/hA1rr8z0fgt8IYq0bmiEPlICRU+4xJV1sVS+lTDPNZKMwqp9DHYvkt3IfX+jWWw6RosjkcmrCcLRdg61kQBqwqb1wsgcU9j962I8wd1OtQdkRHolot+spkPSsiYmHh3TvfuogZO4/d3BF6irw7ZxvLk= 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=KWMJ3eRg; 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="KWMJ3eRg" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1779354662; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=vjxV//gOyz/n+AtRONHMGYrZm4NAi0bq2+NJ8phfFu8=; b=KWMJ3eRgBFxjZDGaRvoW+xY6wp/YCvoK5Xp7gRHmxrMK2658EQqvcySRF8gGER8YBnitF5 S2fJky5zagAFGOs2HquxD6N1Q5MNNEsAuSDwVaQtrnZJlChhPu/NmrZmTvoYSrxRGaANPY eB4S3yDk3vI/8kccdLPE2+rEHb7ydvU= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-160-qNw0hdrzO3mUsAwMX-eh-w-1; Thu, 21 May 2026 05:11:01 -0400 X-MC-Unique: qNw0hdrzO3mUsAwMX-eh-w-1 X-Mimecast-MFC-AGG-ID: qNw0hdrzO3mUsAwMX-eh-w_1779354659 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 4CD221800343; Thu, 21 May 2026 09:10:59 +0000 (UTC) Received: from [192.168.1.153] (headnet01.pony-001.prod.iad2.dc.redhat.com [10.2.32.101]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 33E7C19560A3; Thu, 21 May 2026 09:10:56 +0000 (UTC) From: Albert Esteve Date: Thu, 21 May 2026 11:10:15 +0200 Subject: [PATCH 2/2] selftests: dma-buf: add DERIVE ioctl tests Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260521-dmabuf-limit-access-v1-2-26c01e27365a@redhat.com> References: <20260521-dmabuf-limit-access-v1-0-26c01e27365a@redhat.com> In-Reply-To: <20260521-dmabuf-limit-access-v1-0-26c01e27365a@redhat.com> To: Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= , Benjamin Gaignard , Brian Starkey , John Stultz , "T.J. Mercier" , Shuah Khan Cc: linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Albert Esteve , mripard@kernel.org X-Developer-Signature: v=1; a=ed25519-sha256; t=1779354648; l=4904; i=aesteve@redhat.com; s=20260303; h=from:subject:message-id; bh=/ApxYmdq3kHu3thKFegK+YtWMiL83D621EF8tkmYSG4=; b=Xw1Be6/9oJc7tUp8Mo1663PiOX1fvKwqDaWX3WJ3OMPYs/gXgAh7yML6JMuLdi5QSXy/RKbdE 8UmbeD0gzGDCHTDVwDgZf86kMG0+6oi6wy+eK+Yz6BDr1US2pGcJXSz X-Developer-Key: i=aesteve@redhat.com; a=ed25519; pk=YSFz6sOHd2L45+Fr8DIvHTi6lSIjhLZ5T+rkxspJt1s= X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 dma-buf now supports aliasing an existing file descriptor with reduced access permissions via DMA_BUF_IOCTL_DERIVE ioctl, and enforces that a shared writable mapping cannot be created through a read-only file descriptor. Add two tests to the dmabuf-heaps selftest to exercise this behaviour. The positive test allocates a buffer, derives its file descriptor as O_RDONLY through the ioctl, confirms that a read-only shared mapping succeeds, and verifies that data written through the original read-write file descriptor is visible through the derived one. The negative test confirms that attempting a DMA_BUF_IOCTL_DERIVE ioctl call with RW flags on a read-only file descriptor is rejected with EACCES. Same for mmap() escalation attempt. Signed-off-by: Albert Esteve --- tools/testing/selftests/dmabuf-heaps/dmabuf-heap.c | 114 +++++++++++++++++= +++- 1 file changed, 113 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/dmabuf-heaps/dmabuf-heap.c b/tools/tes= ting/selftests/dmabuf-heaps/dmabuf-heap.c index fc9694fc4e89e..c3856189200be 100644 --- a/tools/testing/selftests/dmabuf-heaps/dmabuf-heap.c +++ b/tools/testing/selftests/dmabuf-heaps/dmabuf-heap.c @@ -390,6 +390,116 @@ static void test_alloc_errors(char *heap_name) close(heap_fd); } =20 +static int setup_ro_derive(int heap_fd, int *dmabuf_fd, int *ro_fd) +{ + struct dma_buf_derive params =3D { + .flags =3D O_RDONLY | O_CLOEXEC, + }; + int ret; + + ret =3D dmabuf_heap_alloc(heap_fd, ONE_MEG, 0, dmabuf_fd); + ksft_test_result(!ret, "Allocate RW buffer\n"); + if (ret) + return -1; + + ret =3D ioctl(*dmabuf_fd, DMA_BUF_IOCTL_DERIVE, ¶ms); + ksft_test_result(!ret, "Derive as O_RDONLY %s\n", + ret < 0 ? strerror(errno) : "OK"); + if (ret < 0) { + close(*dmabuf_fd); + *dmabuf_fd =3D -1; + return -1; + } + + *ro_fd =3D params.fd; + return 0; +} + +static void test_ro_derive(char *heap_name) +{ + int heap_fd =3D -1, dmabuf_fd =3D -1, ro_fd =3D -1; + void *rw_map =3D MAP_FAILED, *ro_map =3D MAP_FAILED; + int ret; + + heap_fd =3D dmabuf_heap_open(heap_name); + + ksft_print_msg("Testing read-only derive with mmap:\n"); + + if (setup_ro_derive(heap_fd, &dmabuf_fd, &ro_fd)) + goto out; + + rw_map =3D mmap(NULL, ONE_MEG, PROT_READ | PROT_WRITE, MAP_SHARED, + dmabuf_fd, 0); + ksft_test_result(rw_map !=3D MAP_FAILED, "RW mmap on RW fd %s\n", + rw_map =3D=3D MAP_FAILED ? strerror(errno) : "OK"); + if (rw_map =3D=3D MAP_FAILED) + goto out; + + dmabuf_sync(dmabuf_fd, DMA_BUF_SYNC_START); + memset(rw_map, 0xab, ONE_MEG); + dmabuf_sync(dmabuf_fd, DMA_BUF_SYNC_END); + + ro_map =3D mmap(NULL, ONE_MEG, PROT_READ, MAP_SHARED, ro_fd, 0); + ksft_test_result(ro_map !=3D MAP_FAILED, "RO mmap on RO fd %s\n", + ro_map =3D=3D MAP_FAILED ? strerror(errno) : "OK"); + if (ro_map =3D=3D MAP_FAILED) + goto out; + + dmabuf_sync(ro_fd, DMA_BUF_SYNC_START); + ret =3D memcmp(rw_map, ro_map, ONE_MEG); + dmabuf_sync(ro_fd, DMA_BUF_SYNC_END); + ksft_test_result(!ret, "Data written via RW fd visible through RO fd\n"); + +out: + if (ro_map !=3D MAP_FAILED) + munmap(ro_map, ONE_MEG); + if (rw_map !=3D MAP_FAILED) + munmap(rw_map, ONE_MEG); + if (ro_fd >=3D 0) + close(ro_fd); + if (dmabuf_fd >=3D 0) + close(dmabuf_fd); + close(heap_fd); +} + +static void test_ro_derive_escalation(char *heap_name) +{ + struct dma_buf_derive params =3D { + .flags =3D O_RDWR | O_CLOEXEC, + }; + int heap_fd =3D -1, dmabuf_fd =3D -1, ro_fd =3D -1, ret =3D 0; + void *bad_map; + + heap_fd =3D dmabuf_heap_open(heap_name); + + ksft_print_msg("Testing read-only derive with escalation attempt:\n"); + + if (setup_ro_derive(heap_fd, &dmabuf_fd, &ro_fd)) + goto out; + + ret =3D ioctl(ro_fd, DMA_BUF_IOCTL_DERIVE, ¶ms); + ksft_test_result(ret < 0 && errno =3D=3D EACCES, + "O_RDWR derive on RO fd correctly rejected (errno=3D%d)\n", + errno); + if (!ret) + close(params.fd); + + bad_map =3D mmap(NULL, ONE_MEG, PROT_READ | PROT_WRITE, MAP_SHARED, + ro_fd, 0); + ksft_test_result(bad_map =3D=3D MAP_FAILED && errno =3D=3D EACCES, + "RW shared mmap on RO fd correctly rejected (errno=3D%d)\n", + errno); + if (bad_map !=3D MAP_FAILED) + munmap(bad_map, ONE_MEG); + +out: + if (ro_fd >=3D 0) + close(ro_fd); + if (dmabuf_fd >=3D 0) + close(dmabuf_fd); + close(heap_fd); +} + static int numer_of_heaps(void) { DIR *d =3D opendir(DEVPATH); @@ -420,7 +530,7 @@ int main(void) return KSFT_SKIP; } =20 - ksft_set_plan(11 * numer_of_heaps()); + ksft_set_plan(20 * numer_of_heaps()); =20 while ((dir =3D readdir(d))) { if (!strncmp(dir->d_name, ".", 2)) @@ -435,6 +545,8 @@ int main(void) test_alloc_zeroed(dir->d_name, ONE_MEG); test_alloc_compat(dir->d_name); test_alloc_errors(dir->d_name); + test_ro_derive(dir->d_name); + test_ro_derive_escalation(dir->d_name); } closedir(d); =20 --=20 2.53.0