Devicetree
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "João Peixoto" <jpeixoto@osyx.tech>
Cc: robh@kernel.org, conor+dt@kernel.org, devicetree@vger.kernel.org
Subject: Re: [RFC PATCH v3 2/6] virt: bao: add IPC shared-memory driver
Date: Fri, 07 Aug 2026 07:56:43 +0000	[thread overview]
Message-ID: <20260807075644.91E091F000E9@smtp.kernel.org> (raw)
In-Reply-To: <33a72238392b1feb519d5721b5aacf693929e15c.1786010512.git.jpeixoto@osyx.tech>

Thank you for your contribution! Sashiko AI review found 8 potential issue(s) to consider:
- [High] Unbinding the device while the misc character device is open causes a Use-After-Free of the driver context and unmapped memory access.
- [High] Missing memory barrier before notifying the peer guest via hypercall, causing potential data corruption due to stale memory observation.
- [High] Missing write-protection enforcement allows userspace to mmap the read region with write permissions, triggering a hypervisor stage-2 fault.
- [Medium] The mmap offset calculation uses `unsigned long`, which overflows on 32-bit architectures, contradicting the author's intent to fix u32 overflows.
- [Medium] The mmap logic fails entirely for the write region if the read region's size is not page-aligned.
- [Medium] Missing `.llseek` operation prevents userspace from resetting the file position, allowing the device to be read or written only once per open.
- [Low] The device label string buffer is too small to hold the maximum device ID, leading to truncation and potential naming collisions.
- [Low] Missing architecture dependencies in Kconfig will cause build failures on unsupported architectures.
--

--- Patch [2]: [RFC PATCH v3 2/6] virt: bao: add IPC shared-memory driver ---
commit 79e4d2a70a45b49aa525420ee0e59987417ec11f
Author: João Peixoto <jpeixoto@osyx.tech>
Subject: virt: bao: add IPC shared-memory driver

Adds a driver for guests running on the Bao static-partitioning hypervisor
to communicate through shared memory. Userspace accesses the regions through
a misc character device using read(), write(), and mmap(), where a write()
notifies the peer guest through an architecture-specific hypercall.

> diff --git a/drivers/virt/bao/ipcshmem/Kconfig b/drivers/virt/bao/ipcshmem/Kconfig
> --- /dev/null
> +++ b/drivers/virt/bao/ipcshmem/Kconfig
> @@ -0,0 +1,10 @@
> +# SPDX-License-Identifier: GPL-2.0
> +config BAO_SHMEM
> +	tristate "Bao hypervisor shared memory support"

[Severity: Low]
Does this config need an architecture dependency?

Building this on an unsupported architecture like x86 (e.g., via
allmodconfig) might fail because it unconditionally includes <asm/bao.h>
which only exists for ARM, ARM64, and RISC-V.

[ ... ]
> diff --git a/drivers/virt/bao/ipcshmem/ipcshmem.c b/drivers/virt/bao/ipcshmem/ipcshmem.c
> --- /dev/null
> +++ b/drivers/virt/bao/ipcshmem/ipcshmem.c
[ ... ]
> +static int bao_ipcshmem_mmap(struct file *filp, struct vm_area_struct *vma)
> +{
> +	struct bao_ipcshmem *bao = filp->private_data;
> +	unsigned long vsize = vma->vm_end - vma->vm_start;
> +	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;

[Severity: Medium]
Will this offset calculation overflow on 32-bit architectures?

Since unsigned long is 32 bits there, an offset larger than 4GB might cause
an overflow. This seems to contradict the commit message's goal to avoid u32
overflows.

> +	phys_addr_t region_phys;
> +	size_t region_size;
> +
> +	if (!vsize)
> +		return -EINVAL;
> +
> +	/*
> +	 * The read region is exposed at offset 0 and the write region right
> +	 * after it. A single mapping cannot span both regions, since they are
> +	 * not guaranteed to be physically contiguous.
> +	 */
> +	if (offset < bao->read_size) {
> +		region_phys = bao->read_phys;
> +		region_size = bao->read_size;

[Severity: High]
Can a user map the read region with write permissions here?

If userspace opens the device O_RDWR and maps this region with PROT_WRITE,
the kernel will create writable PTEs because vma->vm_page_prot is used
directly during remap_pfn_range().

If the hypervisor maps the read region as read-only at Stage-2, a subsequent
write from userspace could trigger a Stage-2 permission fault and crash the
guest VM. Does this need a check to enforce !(vma->vm_flags & VM_WRITE)?

> +	} else if (offset < bao->read_size + bao->write_size) {
> +		offset -= bao->read_size;

[Severity: Medium]
What happens if the device tree specifies a read_size that is not
page-aligned?

Subtracting an unaligned read_size from a page-aligned offset would result
in an unaligned offset. This would then cause the PAGE_ALIGNED(region_phys)
check below to fail unconditionally, preventing userspace from mapping the
write region.

> +		region_phys = bao->write_phys;
> +		region_size = bao->write_size;
> +	} else {
> +		return -EINVAL;
> +	}
[ ... ]
> +static ssize_t bao_ipcshmem_write(struct file *filp, const char __user *buf,
> +				  size_t count, loff_t *ppos)
> +{
[ ... ]
> +	if (copy_from_user(bao->write_base + *ppos, buf, count))
> +		return -EFAULT;
> +
> +	*ppos += count;
> +
> +	/* Notify Bao hypervisor */
> +	bao_ipcshmem_hypercall(BAO_IPCSHMEM_HYPERCALL_ID, bao->id);

[Severity: High]
Is a memory barrier needed here before notifying the peer guest?

The hypercall provides a Context Synchronization Event, but it does not
guarantee that prior memory stores to the MEMREMAP_WB (cacheable) memory are
globally visible.

Could the peer guest observe stale data if the local CPU's store buffer
hasn't drained before the hypervisor wakes it up?

> +	return count;
> +}
[ ... ]
> +static const struct file_operations bao_ipcshmem_fops = {
> +	.owner = THIS_MODULE,
> +	.read = bao_ipcshmem_read,
> +	.write = bao_ipcshmem_write,
> +	.mmap = bao_ipcshmem_mmap,
> +	.open = bao_ipcshmem_open,
> +	.release = bao_ipcshmem_release,
> +};

[Severity: Medium]
Does this file operations structure need an .llseek callback (such as
default_llseek)?

Without it, the VFS will clear the FMODE_LSEEK flag during open(). Any
subsequent lseek() calls will return -ESPIPE. Once a read() or write() hits
the end of the shared memory region, userspace might be completely unable to
rewind the offset without closing and reopening the character device.

> +static int bao_ipcshmem_probe(struct platform_device *pdev)
> +{
[ ... ]
> +	bao = devm_kzalloc(dev, sizeof(*bao), GFP_KERNEL);
> +	if (!bao)
> +		return -ENOMEM;
> +
> +	bao->read_base = devm_memremap(dev, read_res->start,
> +				       resource_size(read_res), MEMREMAP_WB);
> +	if (IS_ERR(bao->read_base))
> +		return PTR_ERR(bao->read_base);
[ ... ]
> +	bao->id = id;
> +	bao->read_phys = read_res->start;
> +	bao->read_size = resource_size(read_res);

[Severity: Medium]
Will resource_size() be truncated here on 32-bit systems with LPAE?

The resource_size() helper returns a 64-bit resource_size_t, but read_size
(and write_size) are defined as size_t in the bao_ipcshmem struct, which
will be 32 bits on those platforms.

> +	bao->write_phys = write_res->start;
> +	bao->write_size = resource_size(write_res);
> +
> +	scnprintf(bao->label, BAO_IPCSHMEM_NAME_LEN, "baoipc%u", id);

[Severity: Low]
Can this label string be truncated?

If the bao,id from the device tree is a 10-digit number (e.g., 4294967295),
the formatted string requires 17 bytes including the null terminator. Since
BAO_IPCSHMEM_NAME_LEN is 16, the last digit could be truncated, potentially
leading to naming collisions.

[ ... ]
> +static void bao_ipcshmem_remove(struct platform_device *pdev)
> +{
> +	struct bao_ipcshmem *bao = platform_get_drvdata(pdev);
> +
> +	misc_deregister(&bao->miscdev);
> +}

[Severity: High]
Can this result in a use-after-free if the driver is unbound while the
character device is still open?

While misc_deregister() removes the device, it does not revoke existing open
file descriptors. When bao_ipcshmem_remove() returns, devres will
automatically free the bao structure and unmap the MEMREMAP_WB regions.

If a user process subsequently calls read, write, or mmap on the open file
descriptor, could it dereference the freed bao structure and access unmapped
memory?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1786010512.git.jpeixoto@osyx.tech?part=2

  reply	other threads:[~2026-08-07  7:56 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-07  7:39 [RFC PATCH v3 0/6] virt: bao: Add Bao hypervisor IPC and I/O dispatcher drivers João Peixoto
2026-08-07  7:39 ` [RFC PATCH v3 1/6] dt-bindings: bao: add IPC shared-memory device João Peixoto
2026-08-07  7:45   ` sashiko-bot
2026-08-07  7:39 ` [RFC PATCH v3 2/6] virt: bao: add IPC shared-memory driver João Peixoto
2026-08-07  7:56   ` sashiko-bot [this message]
2026-08-07  7:39 ` [RFC PATCH v3 3/6] dt-bindings: bao: add I/O dispatcher device João Peixoto
2026-08-07  7:39 ` [RFC PATCH v3 4/6] virt: bao: add I/O dispatcher driver João Peixoto
2026-08-07  7:54   ` sashiko-bot
2026-08-07  7:39 ` [RFC PATCH v3 5/6] virt: bao: consolidate the IPC hypercall ID in include/linux/bao.h João Peixoto
2026-08-07  7:50   ` sashiko-bot
2026-08-07  7:39 ` [RFC PATCH v3 6/6] MAINTAINERS: add Bao hypervisor entry João Peixoto

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260807075644.91E091F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=jpeixoto@osyx.tech \
    --cc=robh@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox