From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.openvz.org (unknown [69.168.225.77]) by lore.virtuozzo.com (Postfix) with ESMTPS id 26F2B802A5 for ; Wed, 14 Oct 2026 17:15:26 +0000 (UTC) Received: from mail.openvz.org (localhost [127.0.0.1]) by mail.openvz.org (8.14.4/8.14.4) with ESMTP id 69EHEDm6001440; Wed, 14 Oct 2026 20:14:14 +0300 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.openvz.org 69EHEDm6001440 Authentication-Results: mail.openvz.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=virtuozzo.com header.i=@virtuozzo.com header.b="G8WmfFkn" Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) by mail.openvz.org (8.14.4/8.14.4) with ESMTP id 69EHE5dO001416 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=FAIL) for ; Wed, 14 Oct 2026 20:14:06 +0300 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.openvz.org 69EHE5dO001416 Received: by mail-wr1-f70.google.com with SMTP id ffacd0b85a97d-48b0679906dso2725433f8f.3 for ; Wed, 14 Oct 2026 10:14:06 -0700 (PDT) X-Gm-Message-State: AFq9FYJ1cJpv1BPpu8O43pUX2PWUx8a0+0+BvjHursTCDt+o8O0QmE3Z 8XMBrqoN9QQ9Isa9wiQvVFg5GV3lmNrLtfwuibs5UW7Mqr4jlIJgBImlhRwD9GlL/cXWifY+SfM u7U5G5Wdr/YmuRvf6v3PNzraDDNTsE+hViNx7HOQwdqMkvMiG/9+WOg== X-Gm-Gg: AYBFou3QskYw5yDODbxggMkyFmEFF0WbI1aMjafGmiBb1/NWBA2DBZEY9E6LKJMmS5u VF4e253QwNLRdH8J2cfzHlUjptus0HntcXboP8BJd0rTTprvUxj2apY/Fh4bRSu3OJVI2Panhdx EA94bo2gJm/nYrLN+isc1Of6quM0sQypQe7jE8LqWn4p9LoInduEdhSyxjPl33Q7/mNeO9l4uFc 3iMcmcTKpDC5GSP9AadAKLvlfygh/WzHc1NXhNLrpj/MDQ/FJjBFCqt4K/TUn5G3E73wyp0ccpl OS6uoV0hsWqi0nLkGzmqLy5bQv8mtBzDTBWtkoalVl82W9+pkll9NMvyPtzArFCM9AZcVlogZhu MomMcnAjxmFH9GQfT X-Received: by 2002:a05:6000:288a:b0:488:89ad:56c0 with SMTP id ffacd0b85a97d-48dbaadbf6amr31275360f8f.11.1791998044488; Wed, 14 Oct 2026 10:14:04 -0700 (PDT) X-Received: by 2002:a05:6000:288a:b0:488:89ad:56c0 with SMTP id ffacd0b85a97d-48dbaadbf6amr31275273f8f.11.1791998043848; Wed, 14 Oct 2026 10:14:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1791998043; cv=none; d=google.com; s=arc-20260327; b=Qbk1Rscl4dos6bBxgVwlrwfDFGpAaCLjTrw/YW3+3Ku0fQF44WaiMBgmeWWlHhPjI/ bSypI+5RIfVDr5Fuqd8yEaskSuqpoVT3eXCYBfGhXZs+4pge6vCbDAW69092lEJ5tJRn /jb8Y7yQr+oCVvnSMk1JqsNauVZ28JnXrHjRPz4Q87zx6tRoKM79br9Nc7tqVd03IEpf sSIs+wdPbOy4OCfE4atriCJqHwtQIJ1xOSyfRFzKTjh/jfdP0PoB58RlQzkwIirGFJLd 5HIeTLyKjh9U39VOEJdH1HUDXcW6Y1gX+uflOWFJCbSvGTB0F6xJTs5fr//94jEvUv6s lZvA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:dkim-signature; bh=kUQecNXFCw8Mkm+mOJ7RIhclWpYDIVIPjA0/ODkta0w=; fh=M6ezeNk/y3cbOR/650/dsAq5I930+aQ0BOhwDOlCl24=; b=dlzGiFngiV9zWlPd2kf+s6qTkyFYnn+l2WHhIMNEBGrdx0f1kmL4Q/EkytNzh2yTm8 oi8wWRXkTMj2UAZjIH7YYmMh/09qTxxLx1CJ7dzns5L21aD8JR0O01jqvm7N7mcORwsY pQ3Gt+7gtsAaYAaYNisylUkg5Ch76PwJiift8rYgoD76v35GJbBUYPzFgA4Dp/UIrI6v 9kp0ysy4xtqVelXANxPe/6ltjUBlBbWFWEhd2EUSlcVpQxHp4rNJ7+/dK65+ipl4k+v9 5FIVSdRz24quLdwIk3hP4C65UCqluoiHQ38dPHz0gI7k8koan1P++HXy+f2Z4TWXjYZ9 VqLA==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@virtuozzo.com header.s=relay header.b=G8WmfFkn; spf=pass (google.com: domain of khorenko@virtuozzo.com designates 130.117.225.111 as permitted sender) smtp.mailfrom=khorenko@virtuozzo.com; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=virtuozzo.com Received: from relay.virtuozzo.com (relay.virtuozzo.com. [130.117.225.111]) by mx.google.com with ESMTPS id ffacd0b85a97d-48deec4e7d6si3162441f8f.30.2026.10.14.10.14.03 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Oct 2026 10:14:03 -0700 (PDT) Received-SPF: pass (google.com: domain of khorenko@virtuozzo.com designates 130.117.225.111 as permitted sender) client-ip=130.117.225.111; Authentication-Results: mx.google.com; dkim=pass header.i=@virtuozzo.com header.s=relay header.b=G8WmfFkn; spf=pass (google.com: domain of khorenko@virtuozzo.com designates 130.117.225.111 as permitted sender) smtp.mailfrom=khorenko@virtuozzo.com; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=virtuozzo.com DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=virtuozzo.com; s=relay; h=Message-Id:Content-Type:MIME-Version:Subject:Date :From; bh=kUQecNXFCw8Mkm+mOJ7RIhclWpYDIVIPjA0/ODkta0w=; b=G8WmfFknMnrTQBP11h7 JBLTDW9tpYfEBOw5AROo64x2LV8QoxgRgIAowX3adkrkI/4RHb2noQ8kamO3PsqurFffReRJ96S9I PXT16f1SE/qvT/EqhKvhT8xwbZMxgpTBDWSwes+fp5kOhzjhqWzxmVNB5WQwz4r7spyc57z27aL8G wufRcAxPYdhsvXQOUS2H9m0641HVJ7X7UgaVr+Hf7um3Epf0GbNgGscc2sMf5xlLF57cWkomPgUD/ Q0wMqIF+9S7XrpsqOB5W2W3TlWq4CqNgNRpOoX2106EUuuXtflq3nsgSVba0JoQe7H0Psy+Sn8LKo y6iV3kiiJz7m6hw==; Received: from ch-demo-asa.virtuozzo.com ([130.117.225.8] helo=f0.sw.ru) by relay.virtuozzo.com with esmtp (Exim 4.96) (envelope-from ) id 1xH2Uo-0084t6-1C; Wed, 14 Oct 2026 19:14:02 +0200 From: Konstantin Khorenko Date: Wed, 14 Oct 2026 19:14:01 +0200 MIME-Version: 1.0 Message-Id: <20261014-b4-prep-khorenko-vstor-103860-4-doexec-vfio-bars-v1-2-7be6c4d68114@virtuozzo.com> References: <20261014-b4-prep-khorenko-vstor-103860-4-doexec-vfio-bars-v1-0-7be6c4d68114@virtuozzo.com> In-Reply-To: <20261014-b4-prep-khorenko-vstor-103860-4-doexec-vfio-bars-v1-0-7be6c4d68114@virtuozzo.com> To: Andrey Drobyshev , Vasileios Almpanis , Pavel Tikhomirov X-Mailer: b4 0.16.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=7861; i=khorenko@virtuozzo.com; h=from:subject:message-id; bh=t4rr3kuVd0T2K0aqL9sWZecW0WC4e5pRCqlljgghYnU=; b=owEBbQKS/ZANAwAKAVGWCkf5YVwqAcsmYgBqz7hayeaLUeUydbqd/1rtdcHu17Vzg6Wg0HFd/ LvD640nTEGJAjMEAAEKAB0WIQRWD23IPcXT0GO9CCxRlgpH+WFcKgUCas+4WgAKCRBRlgpH+WFc KuNkD/9gmVEd0Xdi59dWZAMH60K6cggwScLBzt9pmk/+Q6w7rBr5qFg4t/0t6dMcaViUOmrdUkd IYBXJIUQhEtb83r8qQ9t89h+e/xR/D5oYU6LmE876qUaUP22+FMsSEqZX0OSs678V2bZThjObmA L4rIdv8Qq4YhEDgzbTs0gPNOQDKW5U7X4ukV3soI9CHsPOg4k7h84ao2S0prixlrcVsFaTDkCH2 z86BIA2GdLl+0V+2OtoQfYadghkVf7AchAlVbN59OeSZr2C7XhOhKtBn+9JLOXpDAiD3b/FuuR2 jEghLeH1j4t61cI3Js6YtOHB+q6/OzbHuuTzBIchL6J6lyME/7sshPv6BmdnEEXPF+sK9dlDIy2 5FXghSXVsWr7lhX2NGlXL0pP3CmH1Anvcy1yvMtuAFoWeKyraFm5xADXGn3XVH70Mdw/Y4eVBnO iEIDYeAv1JzubuoVGMPAQC5e4H1S/oSigdzab4JUQJmfZclVVo6xaC5dUsehR8xGx3TWR8ZvLH3 eOTLTezDviqaDm57HQY4d3mxf2OpH+ri7UiigHOcf1p5aVEwCAtGn3rwE0UZMrpeqiR1KmbYkBD qfmQsbh+e5gwQL2VJ7YxryuXq+Ixdo8cT9s6JCFYEw2p16IFevfTsXH+rMMzZCnAqcH32qkVJh3 k1f8p1jH1M1BD2Q== X-Developer-Key: i=khorenko@virtuozzo.com; a=openpgp; fpr=560F6DC83DC5D3D063BD082C51960A47F9615C2A X-OZ-Fwd: true Cc: devel@openvz.org Subject: [Devel] [PATCH hci-8.1 2/2] selftests/mm: check MADV_DOEXEC on VFIO BARs and other PFN mappings X-BeenThere: devel@openvz.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: OpenVZ development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: devel-bounces@openvz.org Errors-To: devel-bounces@openvz.org Add two cases to doexec: - A shared mapping of /dev/mem is a PFN mapping of a driver other than VFIO, and MADV_DOEXEC must refuse it. - BAR 0 of the PCI device named by DOEXEC_VFIO_DEVICE, which has to be bound to vfio-pci, is mapped through its VFIO device fd at an address aligned to the mapped size, so that huge PFN entries can be used. The test fills it with a pattern, marks it and execs. The new image must find the mapping at the same address with the pfn and shared flags in smaps and the pattern in place. A group that has only a noiommu node is set up with the no-IOMMU container. Without the variable the case is skipped. The test overwrites BAR 0, so the variable has to name a spare device whose BAR 0 is memory, such as an unused VGA frame buffer. https://virtuozzo.atlassian.net/browse/VSTOR-150233 Feature: oracle/mm: MADV_DOEXEC madvise() flag Assisted-by: LLM Signed-off-by: Konstantin Khorenko --- tools/testing/selftests/mm/doexec.c | 141 +++++++++++++++++++++++++++++++++++- 1 file changed, 139 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/mm/doexec.c b/tools/testing/selftests/mm/doexec.c index 97e045ba678e8..a89fe2f067df5 100644 --- a/tools/testing/selftests/mm/doexec.c +++ b/tools/testing/selftests/mm/doexec.c @@ -4,6 +4,8 @@ #include #include #include +#include +#include #include #include #include @@ -585,6 +587,132 @@ static int doexec_noexec(void) return ret; } +static bool smaps_has_flag(char *addr, const char *flag) +{ + FILE *file = fopen("/proc/self/smaps", "r"); + char line[256], want[32]; + bool in_vma = false, found = false; + + if (!file) + return false; + snprintf(want, sizeof(want), "%lx-", (unsigned long)addr); + while (fgets(line, sizeof(line), file)) { + char *space = strchr(line, ' '); + + if (!space) + continue; + if (memchr(line, '-', space - line) && !memchr(line, ':', space - line)) + in_vma = !strncmp(line, want, strlen(want)); + else if (in_vma && !strncmp(line, "VmFlags:", 8)) + found = strstr(line, flag) != NULL; + } + fclose(file); + return found; +} + +static int after_pfnmap_exec(char *bar, size_t size) +{ + size_t page = sysconf(_SC_PAGESIZE), i; + + if (!smaps_has_flag(bar, " pf ") || !smaps_has_flag(bar, " sh ")) + return KSFT_FAIL; + for (i = 0; i < size / page; i++) + if (__atomic_load_n((uint32_t *)(bar + i * page), __ATOMIC_RELAXED) != + (0xd0e00000 | i)) + return KSFT_FAIL; + return munmap(bar, size) ? KSFT_FAIL : KSFT_PASS; +} + +/* Only VFIO device mappings may be preserved; /dev/mem is a plain PFN map. */ +static int devmem_refused(void) +{ + size_t size = sysconf(_SC_PAGESIZE); + char *ram; + int fd; + + if (!preserved_ram(size)) + return errno == EINVAL ? KSFT_SKIP : KSFT_FAIL; + /* Without FMODE_WRITE, do_mmap() drops VM_SHARED from the mapping. */ + fd = open("/dev/mem", O_RDWR); + if (fd < 0) + return KSFT_SKIP; + ram = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); + close(fd); + if (ram == MAP_FAILED || !smaps_has_flag(ram, " pf ")) + return KSFT_SKIP; + return madvise(ram, size, MADV_DOEXEC) && errno == EINVAL ? KSFT_PASS : KSFT_FAIL; +} + +static int vfio_device_fd(const char *bdf) +{ + char path[PATH_MAX], link[PATH_MAX], *group_id; + int container, group, noiommu; + ssize_t len; + + snprintf(path, sizeof(path), "/sys/bus/pci/devices/%s/iommu_group", bdf); + len = readlink(path, link, sizeof(link) - 1); + if (len < 0) + return -1; + link[len] = 0; + group_id = strrchr(link, '/') + 1; + snprintf(path, sizeof(path), "/dev/vfio/%s", group_id); + noiommu = access(path, F_OK); + if (noiommu) + snprintf(path, sizeof(path), "/dev/vfio/noiommu-%s", group_id); + container = open("/dev/vfio/vfio", O_RDWR); + group = open(path, O_RDWR); + if (container < 0 || group < 0 || + ioctl(group, VFIO_GROUP_SET_CONTAINER, &container) || + ioctl(container, VFIO_SET_IOMMU, noiommu ? VFIO_NOIOMMU_IOMMU : VFIO_TYPE1v2_IOMMU)) + return -1; + return ioctl(group, VFIO_GROUP_GET_DEVICE_FD, bdf); +} + +/* Overwrites BAR 0 of DOEXEC_VFIO_DEVICE, so name a spare memory BAR. */ +static int vfio_bar_exec(void) +{ + struct vfio_region_info info = { + .argsz = sizeof(info), + .index = VFIO_PCI_BAR0_REGION_INDEX, + }; + size_t page = sysconf(_SC_PAGESIZE), size, i; + const char *bdf = getenv("DOEXEC_VFIO_DEVICE"); + char addr_arg[32], size_arg[32], *area, *bar; + uintptr_t aligned; + int dev; + + if (!bdf || !preserved_ram(page)) + return KSFT_SKIP; + dev = vfio_device_fd(bdf); + if (dev < 0 || ioctl(dev, VFIO_DEVICE_GET_REGION_INFO, &info) || + !(info.flags & VFIO_REGION_INFO_FLAG_MMAP) || info.size < page) { + ksft_print_msg("VFIO device %s: %s\n", bdf, strerror(errno)); + return KSFT_FAIL; + } + size = info.size < (4ul << 20) ? info.size : 4ul << 20; + /* Align to the size so that the BAR can be mapped with huge PFN entries. */ + area = mmap(NULL, 2 * size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (area == MAP_FAILED) + return KSFT_FAIL; + aligned = ((uintptr_t)area + size - 1) & ~(size - 1); + bar = mmap((void *)aligned, size, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_FIXED, dev, info.offset); + if (bar == MAP_FAILED) + return KSFT_FAIL; + for (i = 0; i < size / page; i++) + __atomic_store_n((uint32_t *)(bar + i * page), 0xd0e00000 | i, + __ATOMIC_RELAXED); + if (madvise(bar, size, MADV_DOEXEC)) { + ksft_print_msg("MADV_DOEXEC on a VFIO BAR: %s\n", strerror(errno)); + return KSFT_FAIL; + } + snprintf(addr_arg, sizeof(addr_arg), "%llu", + (unsigned long long)(uintptr_t)bar); + snprintf(size_arg, sizeof(size_arg), "%zu", size); + execl("/proc/self/exe", "doexec", "--pfnmap", addr_arg, size_arg, NULL); + return KSFT_FAIL; +} + static void *exec_thread(void *arg) { check_exec(arg, sysconf(_SC_PAGESIZE), 1, false); @@ -926,6 +1054,9 @@ int main(int argc, char **argv) return KSFT_FAIL; if (argc == 2 && !strcmp(argv[1], "--euid")) return geteuid() ? KSFT_SKIP : KSFT_PASS; + if (argc == 4 && !strcmp(argv[1], "--pfnmap")) + return after_pfnmap_exec((char *)(uintptr_t)strtoull(argv[2], NULL, 10), + strtoull(argv[3], NULL, 10)); if (argc == 5 && !strcmp(argv[1], "--proc")) return proc_exec((char *)(uintptr_t)strtoull(argv[2], NULL, 10), strtoull(argv[3], NULL, 10), atoi(argv[4])); @@ -945,7 +1076,7 @@ int main(int argc, char **argv) return KSFT_PASS; } ksft_print_header(); - ksft_set_plan(NR_TESTS + 11); + ksft_set_plan(NR_TESTS + 13); for (kind = 0; kind < NR_TESTS; kind++) { fflush(stdout); pid = fork(); @@ -968,7 +1099,7 @@ int main(int argc, char **argv) ksft_test_result_skip("pre-existing COW: DOEXEC unavailable\n"); else ksft_test_result(ret == KSFT_PASS, "pre-existing COW preserved\n"); - for (kind = 0; kind < 10; kind++) { + for (kind = 0; kind < 12; kind++) { static const char * const extra_names[] = { "CLONE_VM: recoverable EBUSY and retry", "own threads: preserving exec allowed", @@ -980,6 +1111,8 @@ int main(int argc, char **argv) "setuid exec: preserving exec refused", "private /dev/zero mapping: preserved across exec", "marked range: not executable until unmarked", + "shared /dev/mem mapping: MADV_DOEXEC refused", + "VFIO BAR: preserved across exec", }; fflush(stdout); @@ -1005,6 +1138,10 @@ int main(int argc, char **argv) _exit(devzero_exec()); case 9: _exit(doexec_noexec()); + case 10: + _exit(devmem_refused()); + case 11: + _exit(vfio_bar_exec()); } } ret = pid < 0 ? KSFT_FAIL : wait_child(pid); -- 2.43.0 _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel