@samitouri / QOSamiQemu / commits / e519832b25

linux-user: Implement finer grained madivse() syscall

Although most madvise() values are hints, some are important and are checked by userspace, especially by security-relevant applications like BoringSLL. So, return -EINVAL for those functions which we don't emulate. Signed-off-by: Helge Deller <deller@gmx.de> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3489

Helge Deller committed May 24, 2026 at 23:06 UTC e519832b2545362dbd40e8f5788f51ebf1519f91
1 file changed +33 -1
linux-user/mmap.c
+33 -1
@@ -1282,7 +1282,7 @@ abi_long target_madvise(abi_ulong start, abi_ulong len_in, int advice)
1282 case TARGET_MADV_KEEPONFORK: /* parisc */
1283 advice = MADV_KEEPONFORK;
1284 break;
1285 - /* we do not care about the other MADV_xxx values yet */
1285 + /* all other MADV_xxx values are the same across architectures */
1286 }
1287
1288 /*
@@ -1307,6 +1307,19 @@ abi_long target_madvise(abi_ulong start, abi_ulong len_in, int advice)
1307 */
1308 mmap_lock();
1309 switch (advice) {
1310 + case MADV_NORMAL:
1311 + case MADV_RANDOM:
1312 + case MADV_SEQUENTIAL:
1313 + case MADV_WILLNEED:
1314 + case MADV_DOFORK:
1315 + case MADV_FREE:
1316 + case MADV_COLD:
1317 + case MADV_PAGEOUT:
1318 + ret = 0; /* OK */
1319 + break;
1320 + case MADV_REMOVE:
1321 + ret = -EOPNOTSUPP;
1322 + break;
1323 case MADV_DONTDUMP:
1324 page_set_flags(start, start + len - 1, PAGE_DONTDUMP, 0);
1325 break;
@@ -1324,6 +1337,25 @@ abi_long target_madvise(abi_ulong start, abi_ulong len_in, int advice)
1337 page_reset_target_data(start, start + len - 1);
1338 }
1339 }
1340 + break;
1341 + case MADV_DONTFORK:
1342 + case MADV_HWPOISON:
1343 + case MADV_MERGEABLE:
1344 + case MADV_UNMERGEABLE:
1345 + case MADV_HUGEPAGE:
1346 + case MADV_NOHUGEPAGE:
1347 + case MADV_POPULATE_READ:
1348 + case MADV_POPULATE_WRITE:
1349 +#ifdef MADV_COLLAPSE
1350 + case MADV_COLLAPSE:
1351 +#endif
1352 + case -1: /* BoringSSL uses -1 to check if the environment is broken */
1353 + ret = -EINVAL;
1354 + break;
1355 + default:
1356 + qemu_log_mask(LOG_UNIMP, "Unhandled madvise(%d) call.\n", advice);
1357 + ret = -EINVAL; /* not yet known advise */
1358 + break;
1359 }
1360 mmap_unlock();
1361