Commit graph

11824 commits

Author SHA1 Message Date
Radostin Stoyanov
bcda01319e
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-07-21 13:40:18 +02:00
Andrei Vagin
b36b380786
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-07-21 13:40:18 +02:00
Andrei Vagin
79f096653f
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-07-21 13:40:18 +02:00
Andrei Vagin
48ad6cbb4f
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-07-21 13:40:18 +02:00
Andrei Vagin
2e6967ac83
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-07-21 13:40:18 +02:00
Andrei Vagin
2b7f1eb53c
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-07-21 13:40:18 +02:00
Andrei Vagin
03d41eff5d
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-07-21 13:40:18 +02:00
Efim Verzakov
3d242917fa
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-07-21 13:40:18 +02:00
Ahmed Elaidy
b4dbd98e8b
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-07-21 13:40:18 +02:00
Andrei Vagin
79e7196350
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-07-21 13:40:18 +02:00
Ahmed Elaidy
59eec87d92
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-07-21 13:40:18 +02:00
David Francis
9b3a878745
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-07-21 13:40:18 +02:00
Ahmed Elaidy
358247a87b
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-07-21 13:40:18 +02:00
Ahmed Elaidy
83fc5aca02
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-07-21 13:40:18 +02:00
Pavel Tikhomirov
d72f1586bc
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-07-21 13:40:18 +02:00
Efim Verzakov
23e97002f8
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-07-21 13:40:18 +02:00
Ahmed Elaidy
d2816d4d23
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-07-21 13:40:18 +02:00
Andrei Vagin
b88d187022
sk-inet: remove trailing whitespace
Signed-off-by: Andrei Vagin <avagin@gmail.com>
2026-07-21 13:40:18 +02:00
Lorenzo Fontana
d990bd76e8
pagemap: detect EOF on truncated pages in process_async_reads()
Signed-off-by: Lorenzo Fontana <fontanalorenz@gmail.com>
2026-07-21 13:40:18 +02:00
Lorenzo Fontana
f21a484253
restorer: detect EOF on truncated pages file to prevent infinite loop
Signed-off-by: Lorenzo Fontana <fontanalorenz@gmail.com>
2026-07-21 13:40:18 +02:00
Andrei Vagin
27d7c84848
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-07-21 13:40:18 +02:00
Rowan-Ye
5b3a754098
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-07-21 13:40:18 +02:00
3idey
6e55b1d351
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-07-21 13:40:18 +02:00
3idey
12792bfca7
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-07-21 13:40:18 +02:00
Dmitry Sepp
8bfd6af996
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-07-21 13:40:18 +02:00
Pavel Tikhomirov
10f52d16b7
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-07-21 13:40:17 +02:00
Pavel Tikhomirov
20c724802d
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-07-21 13:40:17 +02:00
Pavel Tikhomirov
de732ded15
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-07-21 13:40:17 +02:00
Dmitry Sepp
51e1d41a0e
criu: Support binfmt_misc sandboxing
The Linux kernel already supports per user namespace sandboxed mounts:
21ca59b365c0 ("binfmt_misc: enable sandboxed mounts")

The overall dump/restore logic is based on the fact that a binfmt_misc
superblock is static and is allocated once per a binfmt_misc mount
within a given user namespace. So the code makes a temporary mount to
read/write the entries and then removes it. The binfmt_misc data is
stored to the USERNS image.

Signed-off-by: Dmitry Sepp <dmitry.sepp@virtuozzo.com>
2026-07-21 13:40:17 +02:00
Dmitry Sepp
d375c1904a
criu: kerndat: add kerndat_has_binfmt_misc_sandboxing()
Detect if the kernel supports binfmt_misc sandboxing and store the
result in kerndat.

The result will be used by the code that dumps and restores binfmt_misc
entries.

Signed-off-by: Dmitry Sepp <dmitry.sepp@virtuozzo.com>
2026-07-21 13:40:17 +02:00
Dmitry Sepp
5eae4ebd52
criu: Remove legacy binfmt_misc handling code
Remove the OpenVZ specific code that was not used outside of the OpenVZ
infrastructure in preparation for implementing support for upstream
Linux kernel binfmt_misc sandboxing.

Signed-off-by: Dmitry Sepp <dmitry.sepp@virtuozzo.com>
2026-07-21 13:40:17 +02:00
3idey
f6c885c31d
test: Add ZDTM test for SIGEV_THREAD_ID timer on thread leader
Add a test that creates a SIGEV_THREAD_ID posix timer targeting the
thread leader in a multithreaded process. This exercises the code path
where encode_notify_thread_id() must look up the thread leader's vtid
in threads[0].ns[0].virt.

Without the fix in the previous commit, this test fails during dump
with:
  Error (criu/timer.c:329): Unable to convert the notify thread id <pid>

The test creates a worker thread (so the process is multithreaded, which
triggers the collect_threads() path) and a SIGEV_THREAD_ID timer on the
main thread, then verifies the timer still fires after C/R.

Signed-off-by: 3idey <elaidya225@gmail.com>
2026-07-21 13:40:17 +02:00
3idey
fde7fb1b3b
dump: Initialize thread leader's vtid before dumping posix timers
In collect_threads(), threads[0] (the thread leader) gets its .real pid
set but .ns[0].virt is left uninitialized. Later in dump_one_task(),
item->pid->ns[0].virt is set from the parasite misc data, but
threads[0].ns[0].virt is not populated until dump_task_threads() runs.

The problem is that parasite_dump_posix_timers_seized() is called
*before* dump_task_threads(). When a posix timer has SIGEV_THREAD_ID
notification targeting the thread leader, encode_notify_thread_id()
looks up threads[i].ns[0].virt and finds an uninitialized (garbage)
value for threads[0]. This causes:
- On dump: the garbage vtid is written into the image as
  notify_thread_id.
- On restore: timer_create() fails with -EINVAL because the
  notify_thread_id is invalid.

Fix this by initializing threads[0].ns[0].virt right after
item->pid->ns[0].virt is set, before the posix timer dump.

Fixes: #2887
Signed-off-by: 3idey <elaidya225@gmail.com>
2026-07-21 13:40:17 +02:00
3idey
0836acfe4b
page-xfer: Fix page_read resource leak in page_pipe_from_pagemap()
page_pipe_from_pagemap() opens a page_read via open_page_read() but
never calls pr.close() on error or success paths. This leaks the
pagemap and pages image file descriptors, and any parent page_read
chain.

Add proper cleanup using goto err pattern to ensure pr.close() is
always called before returning. Also destroy the page_pipe on
fill_page_pipe() failure to avoid leaking its memory and pipe FDs.

Signed-off-by: 3idey <elaidya225@gmail.com>
2026-07-21 13:40:17 +02:00
WHOIM1205
5e48ebf4c7
sk-unix: fix mutex_ghost deadlock on connect failure in post_open_standalone
Signed-off-by: WHOIM1205 <rathourprateek8@gmail.com>
2026-07-21 13:40:17 +02:00
David Francis
642bdba874
plugin/amdgpu: Allow dump with victim unable to see all gpus
In container setups, particularly k8s, cgroup may be used to
restrict what GPUs a process has access to. CRIU may then be used
to checkpoint that process while CRIU itself has full access to
all GPUs.

In this case, the kfd CRIU ioctl will return only a subset of the
ioctls visible through sysfs.

Don't write these devices or any links connected to them to the
tology dump files.

Signed-off-by: David Francis <David.Francis@amd.com>
2026-07-21 13:40:17 +02:00
3idey
dd2fb045a9
fsnotify: Fix memory leak in pre_dump_one_fanotify error path
When irmap_queue_cache fails, the remaining fanotify mark entries
and the mark array are not freed, causing a memory leak.

Add cleanup label to ensure proper deallocation of remaining entries
and the mark array on error paths.

Signed-off-by: 3idey <elaidya225@gmail.com>
2026-07-21 13:40:17 +02:00
3idey
06348103d6
fsnotify: Fix memory leak in pre_dump_one_inotify error path
When irmap_queue_cache fails, the remaining inotify watch descriptors
and the wd array are not freed, causing a memory leak.

Add cleanup label to ensure proper deallocation of remaining entries
and the wd array on error paths.

Signed-off-by: 3idey <elaidya225@gmail.com>
2026-07-21 13:40:17 +02:00
3idey
14b325e36f
fsnotify: Improve error messages with more context
Error messages now include additional context to aid debugging:
- Device and inode numbers for file handles
- Watch descriptor (wd) for inotify operations
- Mask values for fanotify marks
- Mount ID for mount-related operations

This makes it much easier to diagnose checkpoint/restore failures
by providing complete information about which watch or mark failed
and why, without needing to add debug logging.

Signed-off-by: 3idey <elaidya225@gmail.com>
2026-07-21 13:40:17 +02:00
3idey
fb4c0aede6
fsnotify: Fix file descriptor leak in restore_one_inotify()
When restoring inotify watches, the restore_one_inotify() function opens
a file descriptor via get_mark_path() and stores it in the 'target'
variable. However, in two error paths, the function returns directly
without properly closing this file descriptor:

1. When INOTIFY_IOC_SETNEXTWD ioctl fails (line 556)
2. When has_inotify_setnextwd is true but watch descriptor mismatch
   occurs (line 577)

Both cases bypass the cleanup code at the 'err' label which calls
close_safe(&target), resulting in a file descriptor leak.

Fix this by using 'goto err' instead of 'return -1' in both error paths,
ensuring proper cleanup of the target file descriptor.

Signed-off-by: 3idey <elaidya225@gmail.com>
2026-07-21 13:40:17 +02:00
Andrei Vagin
859596d65b
github: add Copilot repository-specific instructions
Add repository-specific guidance for GitHub Copilot in
.github/copilot-instructions.md. This file includes information about:
- Coding style (Linux Kernel Coding Style)
- Architectural overview of the project
- PIE code requirements (must be self-contained and depend on compel)
- Descriptions of CRIU commands
- ZDTM test suite details
- Commit message formatting guidelines

This is just initial skeleton designed to optimize GitHub Copilot
reviews.

Signed-off-by: Andrei Vagin <avagin@gmail.com>
2026-07-21 13:40:17 +02:00
unichronic
ff2a955d94
pycriu: Fix self-dump failure with explicit PID
When `opts.pid` is explicitly set to `os.getpid()`, `pycriu` fails to
daemonize the `criu` process. This causes `criu` to run as a child of
the dumped process, leading to the error "The criu itself is within
dumped tree".

This can be fixed by modifying `_send_req_and_recv_resp` to check if the
target PID matches the current process PID. If so, it enables daemon
mode, ensuring `criu` is detached and the dump succeeds.

Signed-off-by: unichronic <ishuvam.pal@gmail.com>
2026-07-21 13:40:17 +02:00
Pavel Tikhomirov
195b14a7a6
cr-restore/shstk: Make arch_shstk_unlock use correct pid
In a simple case where the parent process and the child one are in one
pid namespace we can safely use vpid(item) to prace the child. But, for
the cases where the child is a pid namespace init, or the child is put
into external pid namespace, the parent and the child have different pid
namespaces and using pid vpid(item) (which e.g. for init will always be
1 here) to ptrace the child process is inorrect.

Let's use the pid reported to us from clone as it's always the right pid
of the child from the parent's point of view.

Fixes: 7dd583002 ("restore: add infrastructure to enable shadow stack")
Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
2026-07-21 13:40:17 +02:00
liqiang2020
2eb2dbd53c
restore/pie: check return value of sys_rseq on unregister
The return value of sys_rseq was previously ignored during
unregistration, under the assumption that it would not fail if the rseq
structure was properly registered.

However, if sys_rseq fails, the kernel retains the registration. If the
memory containing the rseq structure is subsequently unmapped or reused,
kernel updates to the rseq area can cause the process to crash (e.g.,
via SIGSEGV).

Check the return value of sys_rseq. If it fails, log the error code and
abort the restoration process. This makes rseq unregistration failures
fatal and explicit, aiding in debugging and preventing later obscure
crashes.

Signed-off-by: liqiang2020 <liqiang64@huawei.com>
2026-07-21 13:40:17 +02:00
Radostin Stoyanov
46390eefd0
crit: show dead task_state
In some cases, CRIU can observe tasks that exit during checkpointing,
and sets the state of these tasks to COMPEL_TASK_DEAD.
This patch adds a string representation of this value that can be used
by CRIT when decoding the images.

Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
2026-07-21 13:40:17 +02:00
Radostin Stoyanov
3e50d4ed39
crit: fix incorrect task state decoding
CRIU defines the following constants for task state in compel/include/uapi/task-state.h

COMPEL_TASK_ALIVE = 0x01
COMPEL_TASK_STOPPED = 0x03
COMPEL_TASK_ZOMBIE = 0x06

Thus, we need to swap the values for "zombie" and "stopped" used in CRIT.

Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
2026-07-21 13:40:17 +02:00
ImranullahKhann
193d946312
ci: add iproute2 to the list of packages in apt-packages.sh
When running the command 'make docker-test', almost all zdtm tests fail,
logging 'ip: not found'. 'ip' command of the iproute2 package was missing.
So added the package to the list of dependencies in 'apt-packages.sh'. Now
tests run

Signed-off-by: ImranullahKhann <imranullahkhann2004@gmail.com>
2026-07-21 13:40:17 +02:00
Radostin Stoyanov
c41d7547d1
amdgpu: use fseeko with large-file support instead of fseeko64
As of Alpine Linux 3.19, musl libc no longer contains separate
fopen64(), fseeko64(), or ftello64() functions. This causes building
CRIU with amdgpu plugin to fail with the following error:

amdgpu_plugin.c: In function 'parallel_restore_bo_contents':
amdgpu_plugin.c:2286:17: error: implicit declaration of function 'fseeko64'; did you mean 'fseeko'? [-Wimplicit-function-declaration]
 2286 |                 fseeko64(bo_contents_fp, entry->read_offset + offset, SEEK_SET);
      |                 ^~~~~~~~
      |                 fseeko
make[2]: *** [Makefile:31: amdgpu_plugin.so] Error 1
make[1]: *** [Makefile:363: amdgpu_plugin] Error 2

To fix this, add the missing $(DEFINES) to plugin builds, and since we
always compile with _FILE_OFFSET_BITS=64, we don't need the 64 suffix.

Fixes: #2826

Suggested-by: Andrei Vagin <avagin@google.com>
Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
2026-07-21 13:40:17 +02:00
Radostin Stoyanov
f43951964c
infect-types: fix user_gcs redefine error
In file included from compel/arch/aarch64/src/lib/infect.c:10:
compel/include/uapi/compel/asm/infect-types.h:24:8: error: redefinition of 'user_gcs'
   24 | struct user_gcs {
      |        ^
/usr/include/asm/ptrace.h:329:8: note: previous definition is here
  329 | struct user_gcs {
      |        ^
1 error generated.
make[1]: *** [/criu/scripts/nmk/scripts/build.mk:215: compel/arch/aarch64/src/lib/infect.o] Error 1

Suggested-by: Andrei Vagin <avagin@google.com>
Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
2026-07-21 13:40:17 +02:00
Pavel Tikhomirov
a14b5dcf79
util: Make close_safe() reset fd to -1 even on close() failure
The "man 2 close":"Dealing with error returns from close()" says:

  "Retrying the close() after a failure return is the wrong thing to do"

We should not leave the fd there, attempting to close it again on next
close()/close_safe() may lead to accidentally closing something else.

It confirms with the kernel code where sys_close() removes fd from
fdtable in this stack:

  +-> sys_close
    +-> file_close_fd
      +-> file_close_fd_locked
        +-> rcu_assign_pointer(fdt->fd[fd], NULL)

If there was an fd this stack is always reached and fd is always
removed.

Let's replace the fd with -1 after close no matter what.

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