Commit graph

11814 commits

Author SHA1 Message Date
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
Dmitry Sepp
e6510a338a 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-02-17 17:07:29 +00:00
Dmitry Sepp
ecab9e3570 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-02-17 17:07:29 +00:00
Dmitry Sepp
0ae3a9498c 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-02-17 17:07:29 +00:00
Tushar Mohapatra
100b3087fc compel/x86: probe kernel task_size at runtime
Change compel_task_size() to probe the actual kernel address space
limit at runtime via mmap() with MAP_FIXED_NOREPLACE flag.

On systems where the CPU supports 5-level paging but the kernel
doesn't have it enabled, we need to detect the actual task size the
kernel is using.

On x86-64, task_size is either (1UL << 47) for 4-level paging or
(1UL << 56) for 5-level paging. The function probes by attempting
to mmap at the 4-level boundary and if it succeeds or the address
is already occupied, the kernel supports 5-level paging.

Fixes: #2877

Signed-off-by: Tushar Mohapatra <tusharmohapatra.gig@gmail.com>
2026-02-16 22:35:00 -08:00
3idey
c676864d41 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-02-14 18:51:45 -08:00
3idey
aef72658cb 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-02-14 18:51:45 -08:00
3idey
4d293afbe2 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-02-14 12:52:26 -08:00
WHOIM1205
b5d531eb4f sk-unix: fix mutex_ghost deadlock on connect failure in post_open_standalone
Signed-off-by: WHOIM1205 <rathourprateek8@gmail.com>
2026-02-10 23:22:36 -08:00
David Francis
fc2cddbdb9 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-02-09 23:00:50 -08:00