Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions Documentation/criu.txt
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,30 @@ The 'mode' may be one of the following:
*skip*::: Don't lock the network. If *--tcp-close* is not used, the network
must be locked externally to allow CRIU to dump TCP connections.

*--allow-uprobes*::
Allow dumping when uprobes vma is present. When used on dump, this option is
required on restore as well.

A uprobes vma is automatically created by the kernel once a uprobe is
triggered. This mapping is not removed even once the uprobe is deleted. So,
even if a process once had uprobes attached to it, and they're removed by
the time the process is dumped, this option is still required because criu
has no way of knowing whether there are active uprobes or not.

When using this option on restore, make sure the uprobes (if any) active on
the dumped processes are still active. Otherwise, when execution reaches
a uprobe'd location in any of the restored processes, that process will be
sent a SIGTRAP.

As an example, say a uprobe is set at function foo in the executable of the
process p_bar. Whenever execution in p_bar reaches function foo, the uprobe
is triggered. If the uprobe has been triggered at least once, then the kernel
will have created the uprobes vma. To dump p_bar, this option is
necessary. After dumping, say the uprobe is deleted. Now, on restoring with
this option, once execution reaches function foo, SIGTRAP will be sent to
the restored p_bar. Unless it has a signal handler installed for SIGTRAP,
it will be terminated and core dumped.

*restore*
~~~~~~~~~
Restores previously checkpointed processes.
Expand Down Expand Up @@ -692,6 +716,10 @@ The 'mode' may be one of the following:
*--skip-file-rwx-check*::
Skip checking file permissions (r/w/x for u/g/o) on restore.

*--allow-uprobes*::
Required when dumped with this option. Refer to this option in the section
on dumping for more details.

*check*
~~~~~~~
Checks whether the kernel supports the features needed by *criu* to
Expand Down
3 changes: 3 additions & 0 deletions contrib/dependencies/apk-packages.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ apk add --no-cache \
build-base \
coreutils \
e2fsprogs \
elfutils-dev \
git \
gnutls-dev \
go \
Expand All @@ -20,6 +21,8 @@ apk add --no-cache \
libdrm-dev \
libnet-dev \
libnl3-dev \
libtraceevent-dev \
libtracefs-dev \
nftables \
nftables-dev \
perl \
Expand Down
5 changes: 4 additions & 1 deletion contrib/dependencies/apt-cross-packages.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ fi
libc6-"${DEBIAN_ARCH}"-cross \
libc6-dev-"${DEBIAN_ARCH}"-cross \
libcap-dev:"${DEBIAN_ARCH}" \
libdrm-dev:"${DEBIAN_ARCH}" \
libelf-dev:"${DEBIAN_ARCH}" \
libexpat1-dev:"${DEBIAN_ARCH}" \
libgnutls28-dev:"${DEBIAN_ARCH}" \
libnet-dev:"${DEBIAN_ARCH}" \
Expand All @@ -23,9 +25,10 @@ fi
libprotobuf-c-dev:"${DEBIAN_ARCH}" \
libprotobuf-dev:"${DEBIAN_ARCH}" \
libssl-dev:"${DEBIAN_ARCH}" \
libtraceevent-dev:"${DEBIAN_ARCH}" \
libtracefs-dev:"${DEBIAN_ARCH}" \
ncurses-dev:"${DEBIAN_ARCH}" \
uuid-dev:"${DEBIAN_ARCH}" \
libdrm-dev:"${DEBIAN_ARCH}" \
build-essential \
pkg-config \
git \
Expand Down
3 changes: 3 additions & 0 deletions contrib/dependencies/apt-packages.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ fi
libbsd-dev \
libcap-dev \
libdrm-dev \
libelf-dev \
libgnutls28-dev \
libgnutls30 \
libnet-dev \
Expand All @@ -28,6 +29,8 @@ fi
libprotobuf-c-dev \
libprotobuf-dev \
libselinux-dev \
libtraceevent-dev \
libtracefs-dev \
pkg-config \
protobuf-c-compiler \
protobuf-compiler \
Expand Down
5 changes: 4 additions & 1 deletion contrib/dependencies/dnf-packages.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
dnf install -y \
asciidoc \
binutils \
elfutils-libelf-devel \
gcc \
git \
glibc-devel \
Expand All @@ -18,6 +19,8 @@ dnf install -y \
libnet-devel \
libnl3-devel \
libselinux-devel \
libtraceevent-devel \
libtracefs-devel \
libuuid-devel \
make \
nftables \
Expand All @@ -27,9 +30,9 @@ dnf install -y \
protobuf-c-devel \
protobuf-compiler \
protobuf-devel \
python-devel \
python3-importlib-metadata \
python3-protobuf \
python3-pyyaml \
python-devel \
rubygem-asciidoctor \
xmlto
3 changes: 3 additions & 0 deletions contrib/dependencies/pacman-packages.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@ pacman -Syu --noconfirm \
libbsd \
libcap \
libdrm \
libelf \
libnet \
libnl \
libtraceevent \
libtracefs \
nftables \
pkg-config \
protobuf \
Expand Down
1 change: 1 addition & 0 deletions coredump/criu_coredump/coredump.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"VMA_AREA_VVAR": 1 << 12,
"VMA_AREA_AIORING": 1 << 13,
"VMA_AREA_MEMFD": 1 << 14,
"VMA_AREA_UPROBES": 1 << 17,
"VMA_AREA_UNSUPP": 1 << 31
}

Expand Down
2 changes: 2 additions & 0 deletions criu/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "cr_options.h"
#include "filesystems.h"
#include "file-lock.h"
#include "image.h"
#include "irmap.h"
#include "mount.h"
#include "mount-v2.h"
Expand Down Expand Up @@ -703,6 +704,7 @@ int parse_options(int argc, char **argv, bool *usage_error, bool *has_exec_cmd,
BOOL_OPT("mntns-compat-mode", &opts.mntns_compat_mode),
BOOL_OPT("unprivileged", &opts.unprivileged),
BOOL_OPT("ghost-fiemap", &opts.ghost_fiemap),
BOOL_OPT(OPT_ALLOW_UPROBES, &opts.allow_uprobes),
{},
};

Expand Down
4 changes: 4 additions & 0 deletions criu/cr-dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -2319,6 +2319,10 @@ int cr_dump_tasks(pid_t pid)
goto err;

he.has_pre_dump_mode = false;
if (found_uprobes_vma()) {
he.has_allow_uprobes = true;
he.allow_uprobes = true;
}

ret = write_img_inventory(&he);
if (ret)
Expand Down
2 changes: 1 addition & 1 deletion criu/crtools.c
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ int main(int argc, char *argv[], char *envp[])
" --network-lock METHOD network locking/unlocking method; argument\n"
" can be 'nftables' or 'iptables' (default).\n"
" --unprivileged accept limitations when running as non-root\n"
" consult documentation for further details\n"
" --allow-uprobes allow dump/restore with uprobes vma\n"
"\n"
"* External resources support:\n"
" --external RES dump objects from this list as external resources:\n"
Expand Down
5 changes: 5 additions & 0 deletions criu/image.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ int check_img_inventory(bool restore)
goto out_err;
}

if (restore && he->allow_uprobes && !opts.allow_uprobes) {
pr_err("Dumped with --" OPT_ALLOW_UPROBES ". Need to set it on restore as well.\n");
goto out_err;
}

if (restore) {
if (!he->has_network_lock_method) {
/*
Expand Down
1 change: 1 addition & 0 deletions criu/include/cr_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ struct cr_options {
char *work_dir;
int network_lock_method;
int skip_file_rwx_check;
int allow_uprobes;

/*
* When we scheduler for removal some functionality we first
Expand Down
9 changes: 9 additions & 0 deletions criu/include/image.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@
* about virtual address space ranges covered by
* MADV_GUARD_INSTALL guards. These ones must be always at
* the end of the vma_area_list and properly skipped a.e.
* - uprobes
* stands for a "[uprobes]" vma that's automatically mapped by
* the kernel when an active uprobe is hit. Contents of this vma
* are not dumped and neither are its madvise bits restored,
* because the kernel is in complete control of this vma. This is
* just used to track the existence of the uprobes vma.
*/
#define VMA_AREA_NONE (0 << 0)
#define VMA_AREA_REGULAR (1 << 0)
Expand All @@ -94,6 +100,7 @@
#define VMA_AREA_MEMFD (1 << 14)
#define VMA_AREA_SHSTK (1 << 15)
#define VMA_AREA_GUARD (1 << 16)
#define VMA_AREA_UPROBES (1 << 17)

Check warning on line 103 in criu/include/image.h

View workflow job for this annotation

GitHub Actions / build


#define VMA_EXT_PLUGIN (1 << 27)
#define VMA_CLOSE (1 << 28)
Expand All @@ -107,6 +114,8 @@

#define CR_PARENT_LINK "parent"

#define OPT_ALLOW_UPROBES "allow-uprobes"

extern bool ns_per_id;
extern bool img_common_magic;

Expand Down
2 changes: 2 additions & 0 deletions criu/include/proc_parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,6 @@ extern int parse_uptime(uint64_t *upt);

extern int parse_timens_offsets(struct timespec *boff, struct timespec *moff);

extern bool found_uprobes_vma(void);

#endif /* __CR_PROC_PARSE_H__ */
24 changes: 23 additions & 1 deletion criu/proc_parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@

static struct buffer __buf;
static char *buf = __buf.buf;
/* only ever goes from false to true, if at all */
static bool uprobes_vma_exists = false;

/*
* This is how AIO ring buffers look like in proc
Expand Down Expand Up @@ -202,8 +204,11 @@
* vmsplice doesn't work for VM_IO and VM_PFNMAP mappings, the
* only exception is VVAR area that mapped by the kernel as
* VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP
*
* The uprobes vma is also mapped by the kernel with VM_IO, among other flags
*/
if (io_pf && !vma_area_is(vma_area, VMA_AREA_VVAR) && !vma_entry_is(vma_area->e, VMA_FILE_SHARED))
if (io_pf && !vma_area_is(vma_area, VMA_AREA_VVAR) && !vma_entry_is(vma_area->e, VMA_FILE_SHARED)

Check warning on line 210 in criu/proc_parse.c

View workflow job for this annotation

GitHub Actions / build

&& !vma_area_is(vma_area, VMA_AREA_UPROBES))
vma_area->e->status |= VMA_UNSUPP;

if (vma_area->e->madv)
Expand Down Expand Up @@ -603,6 +608,14 @@
goto err;
} else if (!strcmp(file_path, "[heap]")) {
vma_area->e->status |= VMA_AREA_REGULAR | VMA_AREA_HEAP;
} else if (!strcmp(file_path, "[uprobes]")) {
uprobes_vma_exists = true;
if (!opts.allow_uprobes) {
pr_err("PID %d has uprobes vma. Consider using --" OPT_ALLOW_UPROBES ".\n",
pid);

Check warning on line 615 in criu/proc_parse.c

View workflow job for this annotation

GitHub Actions / build

goto err;
}
vma_area->e->status |= VMA_AREA_UPROBES;
} else {
vma_area->e->status = VMA_AREA_REGULAR;
}
Expand Down Expand Up @@ -739,6 +752,10 @@
*/
pr_debug("Device file mapping %016" PRIx64 "-%016" PRIx64 " supported via device plugins\n",
vma_area->e->start, vma_area->e->end);
} else if (vma_area->e->status & VMA_AREA_UPROBES) {
pr_debug("Skipping uprobes vma %016" PRIx64 "-%016" PRIx64 "\n", vma_area->e->start,
vma_area->e->end);

Check warning on line 757 in criu/proc_parse.c

View workflow job for this annotation

GitHub Actions / build

return 0;
} else if (vma_area->e->status & VMA_UNSUPP) {
pr_err("Unsupported mapping found %016" PRIx64 "-%016" PRIx64 "\n", vma_area->e->start,
vma_area->e->end);
Expand Down Expand Up @@ -2929,3 +2946,8 @@
fclose(f);
return 0;
}

bool found_uprobes_vma(void)
{
return uprobes_vma_exists;
}
1 change: 1 addition & 0 deletions criu/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ static void vma_opt_str(const struct vma_area *v, char *opt)
opt2s(VMA_ANON_PRIVATE, "ap");
opt2s(VMA_AREA_SYSVIPC, "sysv");
opt2s(VMA_AREA_SOCKET, "sk");
opt2s(VMA_AREA_UPROBES, "uprobes");

#undef opt2s
}
Expand Down
1 change: 1 addition & 0 deletions images/inventory.proto
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,5 @@ message inventory_entry {
// This is currently used to delete the correct nftables
// network locking rule.
optional string dump_criu_run_id = 13;
optional bool allow_uprobes = 14;
}
1 change: 1 addition & 0 deletions lib/pycriu/images/pb2dict.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ def _custom_conv(field):
('VMA_AREA_AIORING', 1 << 13),
('VMA_AREA_MEMFD', 1 << 14),
('VMA_AREA_SHSTK', 1 << 15),
('VMA_AREA_UPROBES', 1 << 17),
('VMA_UNSUPP', 1 << 31),
]

Expand Down
9 changes: 8 additions & 1 deletion test/zdtm/static/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ TST_NOFILE := \

PKG_CONFIG ?= pkg-config
pkg-config-check = $(shell sh -c '$(PKG_CONFIG) $(1) && echo y')
pkg-config-atleast-version = $(shell sh -c '$(PKG_CONFIG) --atleast-version=$(2) $(1) && echo y')
ifeq ($(call pkg-config-check,libbpf),y)
TST_NOFILE += \
bpf_hash \
Expand All @@ -298,7 +299,10 @@ endif

ifneq ($(ARCH),arm)
ifneq ($(COMPAT_TEST),y)
TST_NOFILE += maps03
TST_NOFILE += maps03
ifeq ($(call pkg-config-atleast-version,libtracefs,1.7),y)
TST_NOFILE += uprobes
endif
endif
endif

Expand Down Expand Up @@ -727,6 +731,9 @@ sk-unix-listen04: CFLAGS += -DSK_UNIX_LISTEN02 -DSK_UNIX_LISTEN03

cgroupv2_01: LDLIBS += -pthread

uprobes: CFLAGS += $(call pkg-cflags, libtracefs libtraceevent)
uprobes: LDLIBS += $(call pkg-libs, libtracefs libelf)

$(LIB): force
$(Q) $(MAKE) -C $(LIBDIR)

Expand Down
Loading
Loading