Commit graph

11823 commits

Author SHA1 Message Date
Ahmed Elaidy
985e6c6ddf images: add timerslack_ns field to thread_core_entry
Add optional uint64 timerslack_ns field (= 17) to thread_core_entry.
This allows CRIU to save and restore the per-thread timer slack value
(controlled via PR_SET_TIMERSLACK / PR_GET_TIMERSLACK) across
checkpoint/restore cycles.

Signed-off-by: Ahmed Elaidy <elaidya225@gmail.com>
2026-03-19 21:35:31 -07:00
Adrian Reber
21c14313d6 contributing: document AI-assisted contribution guidelines
Add an "AI-assisted contributions" section to CONTRIBUTING.md
describing the Assisted-by tag format for commits that involve
AI coding assistants, following the Linux kernel guidance at
docs.kernel.org/process/coding-assistants.html.

Also add concise instructions to GEMINI.md (symlinked to
CLAUDE.md) so that AI agents use the Assisted-by tag instead
of free-form attribution lines.

Assisted-by: Claude:claude-opus-4-6
Signed-off-by: Adrian Reber <areber@redhat.com>
2026-03-19 16:44:10 +00:00
Andrei Vagin
33dca7905b zdtm: add file_lease05 test for broken read lease restore
Add a test that exercises the broken read lease restore path. The test:

 1. Opens a file O_RDONLY and takes a read lease (F_RDLCK).
 2. Triggers the breaking sequence by attempting a conflicting
    O_WRONLY | O_NONBLOCK open (which returns EWOULDBLOCK).
 3. Forks a child to verify post-restore lease state.
 4. Calls test_daemon() / test_waitsig() to go through C/R.
 5. After restore, the child verifies that the lease type is F_UNLCK
    (the expected target type for a broken read lease), confirming
    that the breaking sequence was correctly re-established.

Without the preceding fix, restore_lease_prebreaking_state() would set a
write lease (F_WRLCK) instead of a read lease on the read-only fd,
causing either a restore failure (EACCES) or a wrong lease type
post-restore. This test fails without the fix and passes with it.

Signed-off-by: Andrei Vagin <avagin@google.com>
2026-03-18 08:08:59 -07:00
Andrei Vagin
64c8d4a112 file-lock: fix type confusion in broken lease restore
When restoring a breaking lease, CRIU needs to first restore the
pre-breaking state of the lease and then trigger the break again.

Previously, restore_lease_prebreaking_state() was incorrectly using the
file descriptor type (e.g., FD_TYPES__REG) instead of the lease type to
determine which lease to set. This caused it to use O_RDONLY/O_WRONLY
logic on a value that wasn't an open flag.

Fix this by:
1. Passing the target lease type (with the LEASE_BREAKING bit cleared)
   to restore_lease_prebreaking_state().
2. Updating set_file_lease() to optionally suppress error messages when
   a lease cannot be set (EWOULDBLOCK), which happens when we try to
   guess the original lease type.
3. In restore_lease_prebreaking_state(), try to set a read lease first
   if the target type is F_UNLCK. If it fails, or if the target type is
   F_RDLCK, try a write lease.

This ensures that we correctly attempt to restore the original lease
type even though it's not explicitly stored in the image when it's
in the process of being broken.

Reported-by: Prateek Singh Rathour <rathourprateek8@gmail.com>
Signed-off-by: Andrei Vagin <avagin@google.com>
2026-03-18 08:08:59 -07:00
Adrian Reber
33e340bed4 zdtm: fix TOCTOU race creating criu.tree directory
When running tests in parallel (-p 2) with GCOV=1, multiple
forked processes race to create ../criu.tree. The check-then-
create pattern (os.access + os.mkdir) allows two processes to
both see the directory as missing and then both attempt mkdir,
causing FileExistsError in the second process.

Replace with os.makedirs(exist_ok=True) which handles the race
atomically.

Assisted-by: Claude:claude-opus-4-6
Signed-off-by: Adrian Reber <areber@redhat.com>
2026-03-17 22:53:45 -07:00
Karim Vergnes
010a346c67 feat: remove build-time patches from Nixpkgs
Upstream Nixpkgs shadows Google's version of the default protobufs,
which is no longer applicable given that they are copied into the
repository, and causes builds to fail.

Signed-off-by: Karim Vergnes <me@thesola.io>
2026-03-15 21:04:43 +00:00
Karim Vergnes
bbcadd85fd feat: specify ourselves as Nix flake source
This allows users to directly use the criu package declared in the flake
as a bleeding-edge substitute to the one found in Nixpkgs, and leverage
the existing NixOS testing infrastructure with their development version.

Signed-off-by: Karim Vergnes <me@thesola.io>
2026-03-15 21:04:43 +00:00
fiyinfoluwa001
f81e46b731 ci: upgrade CodeQL actions from v3 to v4
Signed-off-by: fiyinfoluwa001 <boluwatifehonour@gmail.com>
2026-03-15 00:14:17 +00:00
David Francis
bce0a3c756 plugin/amdgpu: Don't print error when restoring drm file
When the amdgpu plugin is called for restore of a file img,
we don't initially know if it's a kfd or drm file. So we first
try to open a kfd file, and if that fails, we assume it's
a drm file. That failure leads to a lot of error messages like

Error amdgpu_plugin: amdgpu-kfd-141.img: Failed to open for read

For this normal behaviour.

Add an option on open_img_file to suppress this error when
we aren't sure if the file we're trying to open exists.

Signed-off-by: David Francis <David.Francis@amd.com>
2026-03-13 10:00:38 -07:00
David Francis
bd4cd4e9ee plugin/amdgpu: Check output of open_img_file
open_img_file can return null if, for example, the dump file
isn't present. Tehre were three places where this wasn't checked.

Check it.

Signed-off-by: David Francis <David.Francis@amd.com>
2026-03-13 10:00:38 -07:00
Andrei Vagin
af3f4be066 ci: remove mips64el-stable-cross and mips64el-unstable-cross
These jobs are failing for a long time. Debian is in the process of
removing mips64el:
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1105972.

Signed-off-by: Andrei Vagin <avagin@google.com>
2026-03-13 07:51:33 +00:00
Andrei Vagin
7582216e17 loongarch64: implement atomic_dec_and_test
It is used in criu/pie/restorer.c.

Signed-off-by: Andrei Vagin <avagin@google.com>
2026-03-12 18:03:08 +00:00
Farzan Aman Khan
65cb18af2c pycriu: Force python protobuf backend in 3.14+
Default to the pure-python protobuf implementation
on Python 3.14+ when the user has not explicitly
selected a backend. This avoids known protobuf
C-extension import failures seen in some distro
packaging setups.

Fixes #2848
Signed-off-by: Farzan Aman Khan <farzanaman99@gmail.com>
2026-03-12 09:12:45 +00:00
Ahmed Elaidy
c9a0190f07 ci: mark archlinux-test as continue-on-error
archlinux:latest is a rolling-release image and pacman -Syu pulls
the latest packages on every build. Failures caused by upstream
package churn or mirror outages are beyond CRIU's control and
should not block merges.

The cross-compile job already uses continue-on-error: true for
its experimental targets; apply the same treatment to
archlinux-test.

Fixes: #2911
Signed-off-by: Ahmed Elaidy <elaidya225@gmail.com>
2026-03-11 15:42:34 -07:00
Ahmed Elaidy
a13ce915c2 zdtm: use private bind-mount as GCOV external mount target
With GCOV=1, zdtm.py passes the CRIU workspace parent as an
external bind-mount into the test namespace (ZDTM_CRIU).  On
restore in the uns flavor CRIU calls open_tree(OPEN_TREE_CLONE)
on that path.  Because the workspace is a parent of the user
namespace mount tree, its mounts are MNT_LOCKED, and open_tree
returns EINVAL.

Fix by creating a private bind-mount of the workspace parent at
'../criu.tree' before each test run, then using that path as the
source of the bind-mount inside the ZDTM namespace (ns.c).  On
restore, point the external mapping at 'criu.tree' instead of
the raw workspace path.

Because criu.tree is MS_PRIVATE and is created before any CRIU
run, cgroupfs submounts that CRIU later creates inside the
workspace (cg_yard via mkdtemp) do not propagate into it.
open_tree(OPEN_TREE_CLONE, criu.tree) therefore sees no locked
submounts and succeeds.

This replaces the earlier --work-dir workaround, which was
correct in principle but broke the RPC test path where
criu_rpc.__set_opts has no handler for --work-dir.

Fixes: #2911
Signed-off-by: Ahmed Elaidy <elaidya225@gmail.com>
2026-03-11 15:10:23 -07:00
Ahmed Elaidy
e6bea0372b ci: stabilize gcov-test coverage upload
Two problems made gcov-test unreliable:

1. The gcov step ran with --max-procs 4, causing multiple gcov
   processes to concurrently read and update the same .gcda files.
   GCC does not protect these files against concurrent access, so
   this can silently corrupt coverage data or produce
   non-deterministic failures. Drop --max-procs to serialize gcov.

2. 'make codecov' curls the uploader binary from
   https://uploader.codecov.io/latest/linux/codecov at job
   runtime. This fails on Codecov CDN outages and on pull requests
   from forks where CODECOV_TOKEN is not forwarded. Replace this
   step with the pinned codecov/codecov-action@v5, which avoids
   the runtime curl and handles both authenticated and
   unauthenticated cases gracefully.

Fixes: #2911
Signed-off-by: Ahmed Elaidy <elaidya225@gmail.com>
2026-03-11 15:10:23 -07:00
Radostin Stoyanov
bcd66dc302 scripts: fully qualify base image references
Use fully qualified image names (e.g. "docker.io/...") in Dockerfiles
instead of relying on implicit registry resolution. This makes the
registry explicit and avoids ambiguity in environments where Docker
and Podman may use different default registries.

Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
2026-03-09 08:33:03 -07:00
Radostin Stoyanov
a72bf212ec scripts: improve layer caching of container builds
The scripts installing dependencies are now copied and executed before
copying the full source tree. This allows to cache the dependency
installation layers as long as these scripts remain unchanged.
Previously, copying the entire repository invalidated the cache on every
source change. While our CI intentionally doesn't preserve cached layers
across independent runs, the changes in this patch help with local testing
when investigating issues.

Examples:
 - sudo -E make -C scripts/ci alpine GCC=1
 - sudo -E make -C scripts/ci alpine CLANG=1

Suggested-by: Andrei Vagin <avagin@google.com>
Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
2026-03-09 08:33:03 -07:00
Radostin Stoyanov
941f9b108b readme: update reference to consolidated workflows
Use the new consolidated GitHub Actions workflow (ci.yml)
instead of individual workflow badges.

Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
2026-03-09 10:29:57 +00:00
Radostin Stoyanov
5e1531888d ci: use clean state before self-contained check
The check-commit target verifies that each commit builds successfully
on its own. However, without cleaning previously generated build artifacts
(e.g. auto-generated `*.o` files) this can cause the check to fail:

make[2]: *** No rule to make target 'compel/include/uapi/compel/asm/breakpoints.h', needed by 'compel/arch/x86/src/lib/infect.o'.  Stop.
make[1]: *** [Makefile.compel:35: compel/libcompel.a] Error 2

To fix this, we add 'git clean -dfx' to remove all untracked and ignored
files before attempting the build.

Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
2026-03-09 10:29:42 +00:00
Andrei Vagin
5add27e6c9 compel/infect: optimize compel_stop_tasks_on_syscall
Update the state machine to track entry and exit stages for all
syscalls, not just the target one. This allows skipping
ptrace_get_regs() calls on the exit stage of syscalls.

Signed-off-by: Andrei Vagin <avagin@google.com>
2026-03-08 23:01:54 -07:00
Andrei Vagin
4a67a9a46e restorer: use atomic to synchronize threads
The restorer used a futex to synchronize threads right before sigreturn.
This could lead to a deadlock when compel_stop_tasks_on_syscall executes
all restored tasks/threads sequentially, allowing each to execute one
syscall per iteration. One task might wait for another one that hasn't
had a chance to run yet.

To avoid this, this patch replaces the futex with an atomic variable.
The last thread to finish the restoration process handles the final
cleanup tasks, such as closing the log and unmapping restorer memory.

Signed-off-by: Andrei Vagin <avagin@google.com>
2026-03-08 23:01:54 -07:00
Andrei Vagin
e718fac152 compel: simplify compel_stop_on_syscall
compel_stop_on_syscall is only ever called for a single task. Simplify
its implementation by removing the 'tasks' parameter and the associated
logic for handling multiple tasks. It now takes a 'pid' directly and
waits for that specific task to exit the required syscall.

Signed-off-by: Andrei Vagin <avagin@google.com>
2026-03-08 23:01:54 -07:00
Andrei Vagin
7daebbe469 compel: remove hardware breakpoint usage
Hardware breakpoints were originally intended to speed up the resume process
by stopping the process at a specific point in the pie code. However, it
turned out that they don't provide a significant speedup and, in some cases,
can even slow it down. This is especially critical for hosts with a large
number of CPUs.

Hardware Breakpoint Restore Performance Benchmark
==================================================

System: Linux 6.17.0-1007-gcp x86_64
CPU:    INTEL(R) XEON(R) PLATINUM 8581C CPU @ 2.10GHz
Virt:   google
CRIU:   Version: 4.2
Iterations per data point: 5

Threads         With BP (us) Without BP (us)     Diff (%)
--------        ------------ ---------------     --------
>>> Benchmarking with 1 thread(s)...
1                        391             326        19.9%
>>> Benchmarking with 10 thread(s)...
10                      1098             695        58.0%
>>> Benchmarking with 50 thread(s)...
50                      3772            2344        60.9%
>>> Benchmarking with 100 thread(s)...
100                     6740            4504        49.6%
>>> Benchmarking with 500 thread(s)...
500                    31382           19982        57.1%
>>> Benchmarking with 1000 thread(s)...
1000                   58617           40568        44.5%

Notes:
  'With BP'    = hardware breakpoints enabled (current default)
  'Without BP' = CRIU_FAULT=130 (FI_NO_BREAKPOINTS, uses PTRACE_SYSCALL)
  Positive diff% means breakpoints are slower

Signed-off-by: Andrei Vagin <avagin@google.com>
2026-03-08 23:01:54 -07:00
Andrei Vagin
869d481cf2 restore: parallelize task stopping in attach_to_tasks and catch_tasks
Splitting the ptrace interrupt and wait loops allows us to send the
interrupt to all tasks and threads first, so they can start stopping in
parallel while we're still sending interrupts to the remaining ones.
This should improve restore performance for large process trees.

The redundant parse_threads calls in catch_tasks are removed as threads
are already parsed in attach_to_tasks which is called earlier.

Signed-off-by: Andrei Vagin <avagin@google.com>
2026-03-08 23:01:54 -07:00
Andrei Vagin
15f11e404b compel/infect: Use waitpid with specific PIDs in compel_stop_tasks_on_syscall
When CRIU traces a large number of tasks, calling wait4(-1, ...) can
be slow because the kernel has to iterate over many tasks to find one
that has changed state. This overhead becomes significant when
thousands of tasks are involved. The time complexity of the old approach
was O(n^2) because we called wait4(-1, ...) N times, and each call
took O(N) time in the kernel.

This patch introduces compel_stop_tasks_on_syscall which takes an
array of PIDs and waits for each one specifically. This avoids the
O(N) search in the kernel's do_wait implementation and significantly
improves performance during the restore phase when many tasks are
being resumed and stopped at the rt_sigreturn syscall.

Some parallelism still exists in this approach. The loop waits for each
process to stop on a syscall, verifies it, and then lets it continue
running. While we move to wait for the next process in the array, the
previously processed ones continue their execution in parallel.

The performance profile of the bottleneck showed:
   - 70.45% entry_SYSCALL_64
      - do_syscall_64
         - 68.29% __do_sys_wait4
            - kernel_wait4
               - 68.28% do_wait
                  - 68.26% __do_wait
                     - 65.69% wait_consider_task
                          8.71% _raw_spin_lock_irq
                          2.39% _raw_spin_unlock_irq

Signed-off-by: Andrei Vagin <avagin@google.com>
2026-03-08 23:01:54 -07:00
Efim Verzakov
09134c8ca8 restore: read user ns from pstree ids image
Commit 6b29103 adds the function read_user_ns_img to read user namespace
image.  It looks up the user namespace by id.  However, user namespace
can not be found because only mnt, net and pid namespaces are added to
the nsid list.  The user namespace is not read from pstree ids.

This commit adds user namespace to the nsid list from the pstree ids
image.

Fixes: 6b29103 ("criu: fix double-open of userns image in --stream mode")
Fixes: #2938

Signed-off-by: Efim Verzakov <efimverzakov@gmail.com>
2026-03-05 11:21:44 -08:00
Andrei Vagin
f5974cc326 pagemap-cache: stop filling cache on VMA_AREA_GUARD
VMA_AREA_GUARD areas are added to the end of the vma_area_list and
are not necessarily sorted by address. pmc_fill_cache() expects
VMAs to be sorted and triggers BUG_ON() if it meets a VMA with
a lower address than the current cache window.

Since guard VMAs don't have pagemap entries and are skipped during
dump, just stop the lookahead loop when we encounter one.

Signed-off-by: Andrei Vagin <avagin@gmail.com>
2026-03-05 10:33:37 +01:00
Ahmed Elaidy
1bcbc55eb5 criu: fix double-open of userns image in --stream mode
restore_userns_binfmt_misc() was opening the userns image a second
time, but criu-image-streamer rejects duplicate file requests:

  criu-image-streamer Error: CRIU is requesting the image file
  userns-15.img multiple times. This is not allowed to keep the
  memory usage low

Fix by pre-reading the image once in a new read_user_ns_img()
helper, called from prepare_namespace_before_tasks() which runs
before the first clone().  Following the same pattern as NetnsEntry
on net namespace ids, the UsernsEntry is stored in a new 'user.e'
field on the ns_id structure for the user namespace.  Both the CRIU
coordinator (prepare_userns) and the forked root task
(restore_userns_binfmt_misc) look up the ns_id and access the
entry from there -- no second open_image() call is needed.

Tested with:
  sudo ./test/zdtm.py run --stream -t zdtm/static/env00 --ignore-taint
  sudo ./test/zdtm.py run --stream -t zdtm/static/env00 --ignore-taint -f uns

Both pass with the fix applied.

Fixes: e6510a338a ("criu: Support binfmt_misc sandboxing")
Fixes: #2924

Signed-off-by: Ahmed Elaidy <elaidya225@gmail.com>
2026-03-04 23:41:08 -08:00
Ahmed Elaidy
04f1b9fb62 test: libcriu: use installed headers and library
Install libcriu into a local staging directory (.install/) using
'make install-lib' and reference only that directory during build
and test:

  CFLAGS  := -I$(INSTALL_DIR)/include/criu
  LDFLAGS := -L$(INSTALL_DIR)/lib -lcriu
  LD_LIBRARY_PATH=${MAIN_DIR}/.install/lib

Nothing from the non-test part of the repo is used at compile,
link, or run time.

The compile rule is also corrected to use $< instead of $^
for gcc -c.

Fixes: #2927

Signed-off-by: Ahmed Elaidy <elaidya225@gmail.com>
2026-03-04 11:06:12 +00:00
Andrei Vagin
3f3acc3200 scripts: rseq: fix detection of rseq_cpu_id_state
gcc doesn't report any warnings if there are two identical enums with the
same name. Actually, we wanted to detect if a specific enum is already
exists. By using a different member name in the test, we ensure that a
conflict occurs if the enum is already defined in the system headers.

Signed-off-by: Andrei Vagin <avagin@gmail.com>
2026-03-03 11:49:59 -08:00
Andrei Vagin
8c29a7ccd5 ci: Consolidate test workflows and gate them by Alpine Test
Rework GitHub workflows to consolidate all test-related jobs into a
single ci.yml file. This ensures that the alpine-test job runs first,
and all other tests are executed only if it passes.

This reduces redundant triggers and provides a clear dependency path
for CI runs.

Signed-off-by: Andrei Vagin <avagin@gmail.com>
2026-03-03 14:08:03 +00:00
Ahmed Elaidy
5468d4a539 plugin/amdgpu: fix pr_perror trailing newline
pr_perror already appends a newline; the explicit \n in the
format string violates the lint rule and breaks CI.

Fixes: 555b257c5e77 ("plugin/amdgpu: Catch error for failure to open drm device")
Signed-off-by: Ahmed Elaidy <elaidya225@gmail.com>
2026-03-02 17:15:54 -08:00
David Francis
555b257c58 plugin/amdgpu: Catch error for failure to open drm device
kfd_criu_device_bucket.drm_fd is an unsigned int, so the comparison
device_bucket->drm_fd < 0
was always false.

Fix that, and also make the error message a bit more descriptive.

Signed-off-by: David Francis <David.Francis@amd.com>
2026-03-02 10:33:18 -08:00
Ahmed Elaidy
50e22d80a5 sk-queue: Fix memory leaks in error paths
Fix several memory leaks in sk-queue error handling:

- collect_one_packet(): Free pkt->data when n_scm > 1 check fails.

- collect_one_packet(): Move list_add_tail() after read_img_buf() so
  that a packet with freed data is never left on the list.

- dump_scm_rights(): Free scme when dump_my_file() fails. The
  allocation from xmalloc() was leaked on this error path.

- send_one_pkt(): Free pkt->scm (allocated in prepare_scms()) after
  sendmsg(), alongside the existing xfree(pkt->data).

Signed-off-by: Ahmed Elaidy <elaidya225@gmail.com>
2026-03-02 10:30:43 -08:00
Ahmed Elaidy
1524ffc996 sk-queue: Add missing MSG_CTRUNC check in dump_sk_queue
After recvmsg() with MSG_PEEK, dump_sk_queue() checks for MSG_TRUNC
(data truncation) but not MSG_CTRUNC (control data truncation). When
the control message buffer is too small, the kernel sets MSG_CTRUNC
and silently discards the overflowing ancillary data. For SCM_RIGHTS,
this means passed file descriptors are lost without any error.

Add a MSG_CTRUNC check right after the existing MSG_TRUNC check so
that dump fails explicitly instead of silently producing an incomplete
image.

Signed-off-by: Ahmed Elaidy <elaidya225@gmail.com>
2026-03-02 10:30:43 -08:00
Pavel Tikhomirov
c180188db0 zdtm: fix incorrect open() syscall use for file creation without mode
We saw compilation errors like:

  error: call to ‘__open_missing_mode’ declared with attribute error:
  open with O_CREAT or O_TMPFILE in second argument needs 3 arguments

Let's fix them by adding mode 0777 everywhere.

Before this change the mode was taken randomly from stack (according to
man 2 open) and that is likely not what we want.

Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
2026-02-26 10:51:09 -08:00
Efim Verzakov
f22c95d2d9 restore: move cgroup restore after creds are prepared
prepare_cgroup_namespace() can call userns_call() to move
the task into a cgroup. userns_call() uses
sendmsg() with SCM_CREDENTIALS to communicate with usernsd.

If the user namespace maps are configured such that the parent's UID
(typically 0) is not mapped to the same UID in the child namespace
(i.e., lower_first != 0), the getuid() syscall in the child will return
the overflow UID (65534) until the child's credentials are explicitly
set within the namespace.

When sendmsg() is called with SCM_CREDENTIALS containing the overflow UID,
the kernel's __scm_send function returns -EINVAL, causing the restore
to fail.

[avagin: tweaked the commit message]
Signed-off-by: Efim Verzakov <efimverzakov@gmail.com>
Signed-off-by: Andrei Vagin <avagin@gmail.com>
2026-02-26 09:42:09 -08:00
Ahmed Elaidy
1a4b338eda unix: fix dangling pointers in icon hash on error path
In unix_collect_one(), icons (in-flight connections) are added to the
global unix_listen_icons hash table. Previously, if xzalloc() failed
mid-loop while allocating an icon, the code could leave partially
inserted icons in the global hash, resulting in dangling pointers and
potential use-after-free crashes.

This patch changes the logic to pre-allocate all unix_sk_listen_icon
nodes before inserting any of them into unix_listen_icons. If allocation
fails, the temporary list is freed and the function aborts before
mutating the global hash. This ensures that the hash is only updated
when all allocations succeed, and avoids the need to traverse and remove
icons from the hash on error.

Signed-off-by: Ahmed Elaidy <elaidya225@gmail.com>
2026-02-23 23:05:33 -08:00
Andrei Vagin
813e1a525d sk-inet: remove trailing whitespace
Signed-off-by: Andrei Vagin <avagin@gmail.com>
2026-02-23 18:13:37 +00:00
Lorenzo Fontana
39c66a7047 pagemap: detect EOF on truncated pages in process_async_reads()
Signed-off-by: Lorenzo Fontana <fontanalorenz@gmail.com>
2026-02-23 06:56:03 +00:00
Lorenzo Fontana
cf2b8c4bcc restorer: detect EOF on truncated pages file to prevent infinite loop
Signed-off-by: Lorenzo Fontana <fontanalorenz@gmail.com>
2026-02-23 06:56:03 +00:00
Andrei Vagin
7c5b745c61 MAINTAINERS: Update maintainer roles
Pavel Emelyanov, the founder and long-time leader of the CRIU project,
is moving to a retired role. As the project's inventor, Pavel's vision
and leadership over many years were fundamental in bringing CRIU to its
current status as a production-ready solution.

Andrey Vagin is appointed as the chief maintainer.

Signed-off-by: Andrei Vagin <avagin@gmail.com>
2026-02-22 15:23:04 -08:00
Rowan-Ye
c5b81c0d7c Add UPDATE_INETSK hook for inet address rewrite
We need to support restoring processes on different nodes or subnets
where the original socket IPs may no longer be valid. This change
introduces a new plugin hook, CR_PLUGIN_HOOK__UPDATE_INETSK, and wires
it into both the plugin API and the legacy descriptor autogen so that
existing plugins remain compatible.

The hook is invoked from collect_one_inetsk() before address validation,
port reservation, or bind()/connect(). A plugin may rewrite the IPv4 or
IPv6 src/dst address fields in InetSkEntry in‑place and return 0.
Returning -ENOTSUP skips to the next plugin; any other negative value
aborts the restore for that socket. Only the IP addresses may change —
family, ports, ifname and length constraints remain enforced.

This mechanism is mainly intended for cross‑node or Kubernetes‑style
scenarios where the final IP is only known after the target network
namespace is created and configured. Pre‑editing image files would be
awkward or infeasible otherwise.

Note: for established TCP connections, external coordination or preserving
the original 4‑tuple is still required. This hook only adjusts addresses
and does not modify TCP state.

Signed-off-by: Rowan-Ye <rowenye1@gmail.com>
2026-02-22 15:15:38 -08:00
3idey
cff99dbcc2 fsnotify: Fix mnt_id type to avoid undefined behavior with -1 sentinel
mnt_id was declared as uint32_t but assigned -1 when absent, which yields
UINT32_MAX. When passed to mntns_get_root_by_mnt_id(int), the conversion
from UINT32_MAX to int is implementation-defined and can become a large
positive value, potentially causing lookup_nsid_by_mnt_id() to return NULL
and trigger BUG_ON().

Change mnt_id to int with an explicit cast from f_handle->mnt_id when
present, so the sentinel -1 is preserved reliably across platforms.

Signed-off-by: 3idey <elaidya225@gmail.com>
2026-02-18 10:02:18 -08:00
3idey
859924c2f6 fsnotify: Check mntns_get_root_by_mnt_id() return value in get_mark_path()
Add checks for mntns_get_root_by_mnt_id() return value before using it
in openat() calls. This prevents using an invalid file descriptor if
the mount namespace root lookup fails.

Add error logging when mntns_get_root_by_mnt_id() fails to provide
diagnostic context about which mount namespace and path were being
accessed.

Also rename local variable 'path' to 'fpath' to avoid shadowing the
outer scope variable of the same name.

Signed-off-by: 3idey <elaidya225@gmail.com>
2026-02-18 10:02:18 -08:00
Dmitry Sepp
82c09bb921 ci: Re-enable zdtm/static/binfmt_misc
The binfmt_misc functionality is not OpenVZ specific anymore. Do not
exclude it.

Signed-off-by: Dmitry Sepp <dmitry.sepp@virtuozzo.com>
2026-02-17 17:07:29 +00:00
Pavel Tikhomirov
5c994447a0 zdtm/static/binfmt_misc: make the random generation actually random
Before that patch we always had exactly the same magic and extentsion
patterns generated.

While on it let's fix the data restrictions:

- The length of extension and magic should be non-zero.
- Let's explicitly wrap extension characters with 256.

Fixes: #2886
Co-developed-by: Andrei Vagin <avagin@google.com>
Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
2026-02-17 17:07:29 +00:00
Pavel Tikhomirov
838a59087d zdtm/static/binfmt_misc: run cleanup hook before restore
In ns flavor for instance the binfmt_misc is not c/r-ed, but without
this cleanup the test will not detect that as it would inherit correct
unchanged binfmt_misc step which was there on dump.

Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
2026-02-17 17:07:29 +00:00
Pavel Tikhomirov
577c9a0f2f zdtm.py: ignore utf-8 conversion errors in test logs
In zdtm/static/binfmt_misc we print the string which contains random
bytes, some of which may not map to utf-8. So let's ignore those bytes
we can't show in utf-8.

Else we can get:

  File ".../criu/test/zdtm.py", line 660, in print_output
    print(output.read())
          ~~~~~~~~~~~^^
  File "<frozen codecs>", line 325, in decode
  UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe3 in position 180: invalid continuation byte

Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
2026-02-17 17:07:29 +00:00