2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-09-01 06:45:35 +00:00

Run 'make indent' on all C files

Acked-by: Mike Rapoport <rppt@linux.ibm.com>
Signed-off-by: Adrian Reber <areber@redhat.com>
This commit is contained in:
Adrian Reber
2021-07-19 07:28:38 +00:00
committed by Andrei Vagin
parent 1e26f170ca
commit 93dd984ca0
542 changed files with 9346 additions and 11605 deletions

View File

@@ -7,7 +7,7 @@
#include "log.h"
#undef LOG_PREFIX
#undef LOG_PREFIX
#define LOG_PREFIX "cpu: "
static compel_cpuinfo_t rt_info;
@@ -22,11 +22,24 @@ static void fetch_rt_cpuinfo(void)
}
}
void compel_set_cpu_cap(compel_cpuinfo_t *info, unsigned int feature) { }
void compel_clear_cpu_cap(compel_cpuinfo_t *info, unsigned int feature) { }
int compel_test_cpu_cap(compel_cpuinfo_t *info, unsigned int feature) { return 0; }
int compel_test_fpu_cap(compel_cpuinfo_t *info, unsigned int feature) { return 0; }
int compel_cpuid(compel_cpuinfo_t *info) { return 0; }
void compel_set_cpu_cap(compel_cpuinfo_t *info, unsigned int feature)
{
}
void compel_clear_cpu_cap(compel_cpuinfo_t *info, unsigned int feature)
{
}
int compel_test_cpu_cap(compel_cpuinfo_t *info, unsigned int feature)
{
return 0;
}
int compel_test_fpu_cap(compel_cpuinfo_t *info, unsigned int feature)
{
return 0;
}
int compel_cpuid(compel_cpuinfo_t *info)
{
return 0;
}
bool compel_cpu_has_feature(unsigned int feature)
{

View File

@@ -5,15 +5,13 @@
#include "piegen.h"
#include "log.h"
static const unsigned char __maybe_unused
elf_ident_64_le[EI_NIDENT] = {
0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00,
static const unsigned char __maybe_unused elf_ident_64_le[EI_NIDENT] = {
0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00, /* clang-format */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
static const unsigned char __maybe_unused
elf_ident_64_be[EI_NIDENT] = {
0x7f, 0x45, 0x4c, 0x46, 0x02, 0x02, 0x01, 0x00,
static const unsigned char __maybe_unused elf_ident_64_be[EI_NIDENT] = {
0x7f, 0x45, 0x4c, 0x46, 0x02, 0x02, 0x01, 0x00, /* clang-format */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

View File

@@ -18,12 +18,11 @@ unsigned __page_shift = 0;
* Injected syscall instruction
*/
const char code_syscall[] = {
0x01, 0x00, 0x00, 0xd4, /* SVC #0 */
0x00, 0x00, 0x20, 0xd4 /* BRK #0 */
0x01, 0x00, 0x00, 0xd4, /* SVC #0 */
0x00, 0x00, 0x20, 0xd4 /* BRK #0 */
};
static const int
code_syscall_aligned = round_up(sizeof(code_syscall), sizeof(long));
static const int code_syscall_aligned = round_up(sizeof(code_syscall), sizeof(long));
static inline void __always_unused __check_code_syscall(void)
{
@@ -31,17 +30,15 @@ static inline void __always_unused __check_code_syscall(void)
BUILD_BUG_ON(!is_log2(sizeof(code_syscall)));
}
int sigreturn_prep_regs_plain(struct rt_sigframe *sigframe,
user_regs_struct_t *regs,
user_fpregs_struct_t *fpregs)
int sigreturn_prep_regs_plain(struct rt_sigframe *sigframe, user_regs_struct_t *regs, user_fpregs_struct_t *fpregs)
{
struct fpsimd_context *fpsimd = RT_SIGFRAME_FPU(sigframe);
memcpy(sigframe->uc.uc_mcontext.regs, regs->regs, sizeof(regs->regs));
sigframe->uc.uc_mcontext.sp = regs->sp;
sigframe->uc.uc_mcontext.pc = regs->pc;
sigframe->uc.uc_mcontext.pstate = regs->pstate;
sigframe->uc.uc_mcontext.sp = regs->sp;
sigframe->uc.uc_mcontext.pc = regs->pc;
sigframe->uc.uc_mcontext.pstate = regs->pstate;
memcpy(fpsimd->vregs, fpregs->vregs, 32 * sizeof(__uint128_t));
@@ -54,15 +51,13 @@ int sigreturn_prep_regs_plain(struct rt_sigframe *sigframe,
return 0;
}
int sigreturn_prep_fpu_frame_plain(struct rt_sigframe *sigframe,
struct rt_sigframe *rsigframe)
int sigreturn_prep_fpu_frame_plain(struct rt_sigframe *sigframe, struct rt_sigframe *rsigframe)
{
return 0;
}
int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs,
user_fpregs_struct_t *ext_regs, save_regs_t save,
void *arg, __maybe_unused unsigned long flags)
int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs, user_fpregs_struct_t *ext_regs, save_regs_t save,
void *arg, __maybe_unused unsigned long flags)
{
user_fpregs_struct_t tmp, *fpsimd = ext_regs ? ext_regs : &tmp;
struct iovec iov;
@@ -104,13 +99,8 @@ int compel_set_task_ext_regs(pid_t pid, user_fpregs_struct_t *ext_regs)
return 0;
}
int compel_syscall(struct parasite_ctl *ctl, int nr, long *ret,
unsigned long arg1,
unsigned long arg2,
unsigned long arg3,
unsigned long arg4,
unsigned long arg5,
unsigned long arg6)
int compel_syscall(struct parasite_ctl *ctl, int nr, long *ret, unsigned long arg1, unsigned long arg2,
unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6)
{
user_regs_struct_t regs = ctl->orig.regs;
int err;
@@ -131,15 +121,12 @@ int compel_syscall(struct parasite_ctl *ctl, int nr, long *ret,
return err;
}
void *remote_mmap(struct parasite_ctl *ctl,
void *addr, size_t length, int prot,
int flags, int fd, off_t offset)
void *remote_mmap(struct parasite_ctl *ctl, void *addr, size_t length, int prot, int flags, int fd, off_t offset)
{
long map;
int err;
err = compel_syscall(ctl, __NR_mmap, &map,
(unsigned long)addr, length, prot, flags, fd, offset);
err = compel_syscall(ctl, __NR_mmap, &map, (unsigned long)addr, length, prot, flags, fd, offset);
if (err < 0 || (long)map < 0)
map = 0;
@@ -166,9 +153,7 @@ int arch_fetch_sas(struct parasite_ctl *ctl, struct rt_sigframe *s)
long ret;
int err;
err = compel_syscall(ctl, __NR_sigaltstack,
&ret, 0, (unsigned long)&s->uc.uc_stack,
0, 0, 0, 0);
err = compel_syscall(ctl, __NR_sigaltstack, &ret, 0, (unsigned long)&s->uc.uc_stack, 0, 0, 0, 0);
return err ? err : ret;
}
@@ -191,4 +176,3 @@ unsigned long compel_task_size(void)
break;
return task_size;
}

View File

@@ -5,9 +5,8 @@
#include "piegen.h"
#include "log.h"
static const unsigned char __maybe_unused
elf_ident_32[EI_NIDENT] = {
0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00,
static const unsigned char __maybe_unused elf_ident_32[EI_NIDENT] = {
0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, /* clang-format */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

View File

@@ -17,12 +17,11 @@
* Injected syscall instruction
*/
const char code_syscall[] = {
0x00, 0x00, 0x00, 0xef, /* SVC #0 */
0xf0, 0x01, 0xf0, 0xe7 /* UDF #32 */
0x00, 0x00, 0x00, 0xef, /* SVC #0 */
0xf0, 0x01, 0xf0, 0xe7 /* UDF #32 */
};
static const int
code_syscall_aligned = round_up(sizeof(code_syscall), sizeof(long));
static const int code_syscall_aligned = round_up(sizeof(code_syscall), sizeof(long));
static inline __always_unused void __check_code_syscall(void)
{
@@ -30,9 +29,7 @@ static inline __always_unused void __check_code_syscall(void)
BUILD_BUG_ON(!is_log2(sizeof(code_syscall)));
}
int sigreturn_prep_regs_plain(struct rt_sigframe *sigframe,
user_regs_struct_t *regs,
user_fpregs_struct_t *fpregs)
int sigreturn_prep_regs_plain(struct rt_sigframe *sigframe, user_regs_struct_t *regs, user_fpregs_struct_t *fpregs)
{
struct aux_sigframe *aux = (struct aux_sigframe *)(void *)&sigframe->sig.uc.uc_regspace;
@@ -62,16 +59,14 @@ int sigreturn_prep_regs_plain(struct rt_sigframe *sigframe,
return 0;
}
int sigreturn_prep_fpu_frame_plain(struct rt_sigframe *sigframe,
struct rt_sigframe *rsigframe)
int sigreturn_prep_fpu_frame_plain(struct rt_sigframe *sigframe, struct rt_sigframe *rsigframe)
{
return 0;
}
#define PTRACE_GETVFPREGS 27
int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs,
user_fpregs_struct_t *ext_regs, save_regs_t save,
void *arg, __maybe_unused unsigned long flags)
int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs, user_fpregs_struct_t *ext_regs, save_regs_t save,
void *arg, __maybe_unused unsigned long flags)
{
user_fpregs_struct_t tmp, *vfp = ext_regs ? ext_regs : &tmp;
int ret = -1;
@@ -116,13 +111,8 @@ int compel_set_task_ext_regs(pid_t pid, user_fpregs_struct_t *ext_regs)
return 0;
}
int compel_syscall(struct parasite_ctl *ctl, int nr, long *ret,
unsigned long arg1,
unsigned long arg2,
unsigned long arg3,
unsigned long arg4,
unsigned long arg5,
unsigned long arg6)
int compel_syscall(struct parasite_ctl *ctl, int nr, long *ret, unsigned long arg1, unsigned long arg2,
unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6)
{
user_regs_struct_t regs = ctl->orig.regs;
int err;
@@ -141,9 +131,7 @@ int compel_syscall(struct parasite_ctl *ctl, int nr, long *ret,
return err;
}
void *remote_mmap(struct parasite_ctl *ctl,
void *addr, size_t length, int prot,
int flags, int fd, off_t offset)
void *remote_mmap(struct parasite_ctl *ctl, void *addr, size_t length, int prot, int flags, int fd, off_t offset)
{
long map;
int err;
@@ -151,8 +139,7 @@ void *remote_mmap(struct parasite_ctl *ctl,
if (offset & ~PAGE_MASK)
return 0;
err = compel_syscall(ctl, __NR_mmap2, &map,
(unsigned long)addr, length, prot, flags, fd, offset >> 12);
err = compel_syscall(ctl, __NR_mmap2, &map, (unsigned long)addr, length, prot, flags, fd, offset >> 12);
if (err < 0 || map > ctl->ictx.task_size)
map = 0;
@@ -182,9 +169,7 @@ int arch_fetch_sas(struct parasite_ctl *ctl, struct rt_sigframe *s)
long ret;
int err;
err = compel_syscall(ctl, __NR_sigaltstack,
&ret, 0, (unsigned long)&s->sig.uc.uc_stack,
0, 0, 0, 0);
err = compel_syscall(ctl, __NR_sigaltstack, &ret, 0, (unsigned long)&s->sig.uc.uc_stack, 0, 0, 0, 0);
return err ? err : ret;
}
@@ -193,9 +178,9 @@ int arch_fetch_sas(struct parasite_ctl *ctl, struct rt_sigframe *s)
* arch/arm/include/asm/memory.h
* arch/arm/Kconfig (PAGE_OFFSET values in Memory split section)
*/
#define TASK_SIZE_MIN 0x3f000000
#define TASK_SIZE_MAX 0xbf000000
#define SZ_1G 0x40000000
#define TASK_SIZE_MIN 0x3f000000
#define TASK_SIZE_MAX 0xbf000000
#define SZ_1G 0x40000000
unsigned long compel_task_size(void)
{
@@ -207,4 +192,3 @@ unsigned long compel_task_size(void)
return task_size;
}

View File

@@ -6,22 +6,27 @@
#include "common/compiler.h"
#include "log.h"
#undef LOG_PREFIX
#undef LOG_PREFIX
#define LOG_PREFIX "cpu: "
static compel_cpuinfo_t rt_info;
static bool rt_info_done = false;
void compel_set_cpu_cap(compel_cpuinfo_t *c, unsigned int feature){ }
void compel_set_cpu_cap(compel_cpuinfo_t *c, unsigned int feature)
{
}
void compel_clear_cpu_cap(compel_cpuinfo_t *c, unsigned int feature){ }
void compel_clear_cpu_cap(compel_cpuinfo_t *c, unsigned int feature)
{
}
int compel_test_cpu_cap(compel_cpuinfo_t *c, unsigned int feature)
{
return 0;
}
int compel_cpuid(compel_cpuinfo_t *c){
int compel_cpuid(compel_cpuinfo_t *c)
{
return 0;
}

View File

@@ -5,9 +5,8 @@
#include "piegen.h"
#include "log.h"
static const unsigned char __maybe_unused
elf_ident_64_le[EI_NIDENT] = {
0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00,
static const unsigned char __maybe_unused elf_ident_64_le[EI_NIDENT] = {
0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00, /* clang-format */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

View File

@@ -23,8 +23,8 @@
* mips64el is Little Endian
*/
const char code_syscall[] = {
0x0c, 0x00, 0x00, 0x00, /* syscall */
0x0d, 0x00, 0x00, 0x00 /* break */
0x0c, 0x00, 0x00, 0x00, /* syscall */
0x0d, 0x00, 0x00, 0x00 /* break */
};
/* 10-byte legacy floating point register */
@@ -40,10 +40,7 @@ struct fpxreg {
uint16_t padding[3];
};
int sigreturn_prep_regs_plain(struct rt_sigframe *sigframe,
user_regs_struct_t *regs,
user_fpregs_struct_t *fpregs)
int sigreturn_prep_regs_plain(struct rt_sigframe *sigframe, user_regs_struct_t *regs, user_fpregs_struct_t *fpregs)
{
sigframe->rs_uc.uc_mcontext.sc_regs[0] = regs->regs[0];
sigframe->rs_uc.uc_mcontext.sc_regs[1] = regs->regs[1];
@@ -117,17 +114,15 @@ int sigreturn_prep_regs_plain(struct rt_sigframe *sigframe,
return 0;
}
int sigreturn_prep_fpu_frame_plain(struct rt_sigframe *sigframe,
struct rt_sigframe *rsigframe)
int sigreturn_prep_fpu_frame_plain(struct rt_sigframe *sigframe, struct rt_sigframe *rsigframe)
{
return 0;
}
int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs,
user_fpregs_struct_t *ext_regs, save_regs_t save,
void *arg, __maybe_unused unsigned long flags)
int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs, user_fpregs_struct_t *ext_regs, save_regs_t save,
void *arg, __maybe_unused unsigned long flags)
{
user_fpregs_struct_t xsave = { }, *xs = ext_regs ? ext_regs : &xsave;
user_fpregs_struct_t xsave = {}, *xs = ext_regs ? ext_regs : &xsave;
int ret = -1;
pr_info("Dumping GP/FPU registers for %d\n", pid);
@@ -143,7 +138,7 @@ int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs,
case ERESTARTNOHAND:
case ERESTARTSYS:
case ERESTARTNOINTR:
regs->regs[2] = regs->regs[0];
regs->regs[2] = regs->regs[0];
regs->regs[7] = regs->regs[26];
regs->cp0_epc -= 4;
break;
@@ -170,13 +165,8 @@ int compel_set_task_ext_regs(pid_t pid, user_fpregs_struct_t *ext_regs)
return 0;
}
int compel_syscall(struct parasite_ctl *ctl, int nr, long *ret,
unsigned long arg1,
unsigned long arg2,
unsigned long arg3,
unsigned long arg4,
unsigned long arg5,
unsigned long arg6)
int compel_syscall(struct parasite_ctl *ctl, int nr, long *ret, unsigned long arg1, unsigned long arg2,
unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6)
{
/*refer to glibc-2.20/sysdeps/unix/sysv/linux/mips/mips64/syscall.S*/
user_regs_struct_t regs = ctl->orig.regs;
@@ -193,18 +183,15 @@ int compel_syscall(struct parasite_ctl *ctl, int nr, long *ret,
err = compel_execute_syscall(ctl, &regs, code_syscall);
*ret = regs.regs[2];
return err;
return err;
}
void *remote_mmap(struct parasite_ctl *ctl,
void *addr, size_t length, int prot,
int flags, int fd, off_t offset)
void *remote_mmap(struct parasite_ctl *ctl, void *addr, size_t length, int prot, int flags, int fd, off_t offset)
{
long map;
int err;
err = compel_syscall(ctl, __NR_mmap, &map,
(unsigned long)addr, length, prot, flags, fd, offset >> PAGE_SHIFT);
err = compel_syscall(ctl, __NR_mmap, &map, (unsigned long)addr, length, prot, flags, fd, offset >> PAGE_SHIFT);
if (err < 0 || IS_ERR_VALUE(map)) {
pr_err("remote mmap() failed: %s\n", strerror(-map));
@@ -236,13 +223,10 @@ int arch_fetch_sas(struct parasite_ctl *ctl, struct rt_sigframe *s)
long ret;
int err;
err = compel_syscall(ctl, __NR_sigaltstack,
&ret, 0, (unsigned long)&s->rs_uc.uc_stack,
0, 0, 0, 0);
err = compel_syscall(ctl, __NR_sigaltstack, &ret, 0, (unsigned long)&s->rs_uc.uc_stack, 0, 0, 0, 0);
return err ? err : ret;
}
int ptrace_set_breakpoint(pid_t pid, void *addr)
{
return 0;
@@ -256,9 +240,12 @@ int ptrace_flush_breakpoints(pid_t pid)
/*refer to kernel linux-3.10/arch/mips/include/asm/processor.h*/
#define TASK_SIZE32 0x7fff8000UL
#define TASK_SIZE64 0x10000000000UL
#define TASK_SIZE TASK_SIZE64
#define TASK_SIZE TASK_SIZE64
unsigned long compel_task_size(void) { return TASK_SIZE; }
unsigned long compel_task_size(void)
{
return TASK_SIZE;
}
/*
* Get task registers (overwrites weak function)
@@ -292,30 +279,31 @@ void compel_relocs_apply_mips(void *mem, void *vbase, struct parasite_blob_desc
for (i = 0, j = 0; i < nr_relocs; i++) {
if (elf_relocs[i].type & COMPEL_TYPE_MIPS_26) {
int *where = (mem + elf_relocs[i].offset);
*where = *where | ((elf_relocs[i].addend + ((unsigned long)vbase & 0x00fffffff) /*low 28 bit*/)>>2);
*where = *where |
((elf_relocs[i].addend + ((unsigned long)vbase & 0x00fffffff) /*low 28 bit*/) >> 2);
} else if (elf_relocs[i].type & COMPEL_TYPE_MIPS_64) {
unsigned long *where = (mem + elf_relocs[i].offset);
*where = elf_relocs[i].addend + (unsigned long)vbase;
} else if (elf_relocs[i].type & COMPEL_TYPE_MIPS_HI16) {
/* refer to binutils mips.cc */
int *where = (mem + elf_relocs[i].offset);
int v_lo16 = (unsigned long)vbase &0x00ffff;
int v_lo16 = (unsigned long)vbase & 0x00ffff;
if ((v_lo16+elf_relocs[i].value+elf_relocs[i].addend) >= 0x8000) {
*where = *where | ((((unsigned long)vbase>>16) &0xffff)+0x1);
if ((v_lo16 + elf_relocs[i].value + elf_relocs[i].addend) >= 0x8000) {
*where = *where | ((((unsigned long)vbase >> 16) & 0xffff) + 0x1);
} else {
*where = *where | ((((unsigned long)vbase>>16) &0xffff));
*where = *where | ((((unsigned long)vbase >> 16) & 0xffff));
}
} else if (elf_relocs[i].type & COMPEL_TYPE_MIPS_LO16) {
int *where = (mem + elf_relocs[i].offset);
int v_lo16 = (unsigned long)vbase &0x00ffff;
int v_lo16 = (unsigned long)vbase & 0x00ffff;
*where = *where | ((v_lo16 + elf_relocs[i].addend) & 0xffff);
} else if (elf_relocs[i].type & COMPEL_TYPE_MIPS_HIGHER) {
int *where = (mem + elf_relocs[i].offset);
*where = *where | ((( (unsigned long)vbase + (uint64_t) 0x80008000) >> 32) & 0xffff);
*where = *where | ((((unsigned long)vbase + (uint64_t)0x80008000) >> 32) & 0xffff);
} else if (elf_relocs[i].type & COMPEL_TYPE_MIPS_HIGHEST) {
int *where = (mem + elf_relocs[i].offset);
*where = *where | ((( (unsigned long)vbase + (uint64_t) 0x800080008000llu) >> 48) & 0xffff);
*where = *where | ((((unsigned long)vbase + (uint64_t)0x800080008000llu) >> 48) & 0xffff);
} else {
BUG();
}

View File

@@ -10,7 +10,7 @@
#include "log.h"
#undef LOG_PREFIX
#undef LOG_PREFIX
#define LOG_PREFIX "cpu: "
static compel_cpuinfo_t rt_info;
@@ -25,10 +25,20 @@ static void fetch_rt_cpuinfo(void)
}
}
void compel_set_cpu_cap(compel_cpuinfo_t *info, unsigned int feature) { }
void compel_clear_cpu_cap(compel_cpuinfo_t *info, unsigned int feature) { }
int compel_test_fpu_cap(compel_cpuinfo_t *info, unsigned int feature) { return 0; }
int compel_test_cpu_cap(compel_cpuinfo_t *info, unsigned int feature) { return 0; }
void compel_set_cpu_cap(compel_cpuinfo_t *info, unsigned int feature)
{
}
void compel_clear_cpu_cap(compel_cpuinfo_t *info, unsigned int feature)
{
}
int compel_test_fpu_cap(compel_cpuinfo_t *info, unsigned int feature)
{
return 0;
}
int compel_test_cpu_cap(compel_cpuinfo_t *info, unsigned int feature)
{
return 0;
}
int compel_cpuid(compel_cpuinfo_t *info)
{

View File

@@ -5,15 +5,13 @@
#include "piegen.h"
#include "log.h"
static const unsigned char __maybe_unused
elf_ident_64_le[EI_NIDENT] = {
0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00,
static const unsigned char __maybe_unused elf_ident_64_le[EI_NIDENT] = {
0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00, /* clang-format */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
static const unsigned char __maybe_unused
elf_ident_64_be[EI_NIDENT] = {
0x7f, 0x45, 0x4c, 0x46, 0x02, 0x02, 0x01, 0x00,
static const unsigned char __maybe_unused elf_ident_64_be[EI_NIDENT] = {
0x7f, 0x45, 0x4c, 0x46, 0x02, 0x02, 0x01, 0x00, /* clang-format */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

View File

@@ -15,11 +15,11 @@
#include "infect-priv.h"
#ifndef NT_PPC_TM_SPR
#define NT_PPC_TM_CGPR 0x108 /* TM checkpointed GPR Registers */
#define NT_PPC_TM_CFPR 0x109 /* TM checkpointed FPR Registers */
#define NT_PPC_TM_CVMX 0x10a /* TM checkpointed VMX Registers */
#define NT_PPC_TM_CVSX 0x10b /* TM checkpointed VSX Registers */
#define NT_PPC_TM_SPR 0x10c /* TM Special Purpose Registers */
#define NT_PPC_TM_CGPR 0x108 /* TM checkpointed GPR Registers */
#define NT_PPC_TM_CFPR 0x109 /* TM checkpointed FPR Registers */
#define NT_PPC_TM_CVMX 0x10a /* TM checkpointed VMX Registers */
#define NT_PPC_TM_CVSX 0x10b /* TM checkpointed VSX Registers */
#define NT_PPC_TM_SPR 0x10c /* TM Special Purpose Registers */
#endif
unsigned __page_size = 0;
@@ -29,8 +29,8 @@ unsigned __page_shift = 0;
* Injected syscall instruction
*/
const uint32_t code_syscall[] = {
0x44000002, /* sc */
0x0fe00000 /* twi 31,0,0 */
0x44000002, /* sc */
0x0fe00000 /* twi 31,0,0 */
};
static inline __always_unused void __check_code_syscall(void)
@@ -43,14 +43,14 @@ static void prep_gp_regs(mcontext_t *dst, user_regs_struct_t *regs)
{
memcpy(dst->gp_regs, regs->gpr, sizeof(regs->gpr));
dst->gp_regs[PT_NIP] = regs->nip;
dst->gp_regs[PT_MSR] = regs->msr;
dst->gp_regs[PT_ORIG_R3] = regs->orig_gpr3;
dst->gp_regs[PT_CTR] = regs->ctr;
dst->gp_regs[PT_LNK] = regs->link;
dst->gp_regs[PT_XER] = regs->xer;
dst->gp_regs[PT_CCR] = regs->ccr;
dst->gp_regs[PT_TRAP] = regs->trap;
dst->gp_regs[PT_NIP] = regs->nip;
dst->gp_regs[PT_MSR] = regs->msr;
dst->gp_regs[PT_ORIG_R3] = regs->orig_gpr3;
dst->gp_regs[PT_CTR] = regs->ctr;
dst->gp_regs[PT_LNK] = regs->link;
dst->gp_regs[PT_XER] = regs->xer;
dst->gp_regs[PT_CCR] = regs->ccr;
dst->gp_regs[PT_TRAP] = regs->trap;
}
static void put_fpu_regs(mcontext_t *mc, uint64_t *fpregs)
@@ -74,9 +74,7 @@ static void put_vsx_regs(mcontext_t *mc, uint64_t *vsxregs)
memcpy((uint64_t *)(mc->v_regs + 1), vsxregs, sizeof(*vsxregs) * NVSXREG);
}
int sigreturn_prep_regs_plain(struct rt_sigframe *sigframe,
user_regs_struct_t *regs,
user_fpregs_struct_t *fpregs)
int sigreturn_prep_regs_plain(struct rt_sigframe *sigframe, user_regs_struct_t *regs, user_fpregs_struct_t *fpregs)
{
mcontext_t *dst_tc = &sigframe->uc_transact.uc_mcontext;
mcontext_t *dst = &sigframe->uc.uc_mcontext;
@@ -134,14 +132,12 @@ static void update_vregs(mcontext_t *lcontext, mcontext_t *rcontext)
uint64_t offset = (uint64_t)(lcontext->v_regs) - (uint64_t)lcontext;
lcontext->v_regs = (vrregset_t *)((uint64_t)rcontext + offset);
pr_debug("Updated v_regs:%llx (rcontext:%llx)\n",
(unsigned long long)lcontext->v_regs,
pr_debug("Updated v_regs:%llx (rcontext:%llx)\n", (unsigned long long)lcontext->v_regs,
(unsigned long long)rcontext);
}
}
int sigreturn_prep_fpu_frame_plain(struct rt_sigframe *frame,
struct rt_sigframe *rframe)
int sigreturn_prep_fpu_frame_plain(struct rt_sigframe *frame, struct rt_sigframe *rframe)
{
uint64_t msr = frame->uc.uc_mcontext.gp_regs[PT_MSR];
@@ -155,9 +151,8 @@ int sigreturn_prep_fpu_frame_plain(struct rt_sigframe *frame,
/* Updating the transactional state address if any */
if (frame->uc.uc_link) {
update_vregs(&frame->uc_transact.uc_mcontext,
&rframe->uc_transact.uc_mcontext);
frame->uc.uc_link = &rframe->uc_transact;
update_vregs(&frame->uc_transact.uc_mcontext, &rframe->uc_transact.uc_mcontext);
frame->uc.uc_link = &rframe->uc_transact;
}
return 0;
@@ -214,7 +209,7 @@ static int get_fpu_regs(pid_t pid, user_fpregs_struct_t *fp)
static int get_altivec_regs(pid_t pid, user_fpregs_struct_t *fp)
{
if (ptrace(PTRACE_GETVRREGS, pid, 0, (void*)&fp->vrregs) < 0) {
if (ptrace(PTRACE_GETVRREGS, pid, 0, (void *)&fp->vrregs) < 0) {
/* PTRACE_GETVRREGS returns EIO if Altivec is not supported.
* This should not happen if msr_vec is set. */
if (errno != EIO) {
@@ -240,7 +235,7 @@ static int get_altivec_regs(pid_t pid, user_fpregs_struct_t *fp)
*/
static int get_vsx_regs(pid_t pid, user_fpregs_struct_t *fp)
{
if (ptrace(PTRACE_GETVSRREGS, pid, 0, (void*)fp->vsxregs) < 0) {
if (ptrace(PTRACE_GETVSRREGS, pid, 0, (void *)fp->vsxregs) < 0) {
/*
* EIO is returned in the case PTRACE_GETVRREGS is not
* supported.
@@ -263,22 +258,23 @@ static int get_tm_regs(pid_t pid, user_fpregs_struct_t *fpregs)
pr_debug("Dumping TM registers\n");
#define TM_REQUIRED 0
#define TM_OPTIONAL 1
#define PTRACE_GET_TM(s,n,c,u) do { \
iov.iov_base = &s; \
iov.iov_len = sizeof(s); \
if (ptrace(PTRACE_GETREGSET, pid, c, &iov)) { \
if (!u || errno != EIO) { \
pr_perror("Couldn't get TM "n); \
pr_err("Your kernel seems to not support the " \
"new TM ptrace API (>= 4.8)\n"); \
goto out_free; \
} \
pr_debug("TM "n" not supported.\n"); \
iov.iov_base = NULL; \
} \
} while(0)
#define TM_REQUIRED 0
#define TM_OPTIONAL 1
#define PTRACE_GET_TM(s, n, c, u) \
do { \
iov.iov_base = &s; \
iov.iov_len = sizeof(s); \
if (ptrace(PTRACE_GETREGSET, pid, c, &iov)) { \
if (!u || errno != EIO) { \
pr_perror("Couldn't get TM " n); \
pr_err("Your kernel seems to not support the " \
"new TM ptrace API (>= 4.8)\n"); \
goto out_free; \
} \
pr_debug("TM " n " not supported.\n"); \
iov.iov_base = NULL; \
} \
} while (0)
/* Get special registers */
PTRACE_GET_TM(fpregs->tm.tm_spr_regs, "SPR", NT_PPC_TM_SPR, TM_REQUIRED);
@@ -304,11 +300,10 @@ static int get_tm_regs(pid_t pid, user_fpregs_struct_t *fpregs)
return 0;
out_free:
return -1; /* still failing the checkpoint */
return -1; /* still failing the checkpoint */
}
static int __get_task_regs(pid_t pid, user_regs_struct_t *regs,
user_fpregs_struct_t *fpregs)
static int __get_task_regs(pid_t pid, user_regs_struct_t *regs, user_fpregs_struct_t *fpregs)
{
pr_info("Dumping GP/FPU registers for %d\n", pid);
@@ -317,7 +312,7 @@ static int __get_task_regs(pid_t pid, user_regs_struct_t *regs,
* arch/powerpc/kernel/signal.c
*/
#ifndef TRAP
#define TRAP(r) ((r).trap & ~0xF)
#define TRAP(r) ((r).trap & ~0xF)
#endif
if (TRAP(*regs) == 0x0C00 && regs->ccr & 0x10000000) {
@@ -347,10 +342,8 @@ static int __get_task_regs(pid_t pid, user_regs_struct_t *regs,
* impossible) or suspended (easy to get).
*/
if (MSR_TM_ACTIVE(regs->msr)) {
pr_debug("Task %d has %s TM operation at 0x%lx\n",
pid,
(regs->msr & MSR_TMS) ? "a suspended" : "an active",
regs->nip);
pr_debug("Task %d has %s TM operation at 0x%lx\n", pid,
(regs->msr & MSR_TMS) ? "a suspended" : "an active", regs->nip);
if (get_tm_regs(pid, fpregs))
return -1;
fpregs->flags = USER_FPREGS_FL_TM;
@@ -372,9 +365,8 @@ static int __get_task_regs(pid_t pid, user_regs_struct_t *regs,
return 0;
}
int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs,
user_fpregs_struct_t *ext_regs, save_regs_t save,
void *arg, __maybe_unused unsigned long flags)
int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs, user_fpregs_struct_t *ext_regs, save_regs_t save,
void *arg, __maybe_unused unsigned long flags)
{
user_fpregs_struct_t tmp, *fpregs = ext_regs ? ext_regs : &tmp;
int ret;
@@ -401,11 +393,11 @@ int compel_set_task_ext_regs(pid_t pid, user_fpregs_struct_t *ext_regs)
}
if (ext_regs->flags & USER_FPREGS_FL_ALTIVEC) {
if (ptrace(PTRACE_SETVRREGS, pid, 0, (void*)&ext_regs->vrregs) < 0) {
if (ptrace(PTRACE_SETVRREGS, pid, 0, (void *)&ext_regs->vrregs) < 0) {
pr_perror("Couldn't set Altivec registers");
ret = -1;
}
if (ptrace(PTRACE_SETVSRREGS, pid, 0, (void*)ext_regs->vsxregs) < 0) {
if (ptrace(PTRACE_SETVSRREGS, pid, 0, (void *)ext_regs->vsxregs) < 0) {
pr_perror("Couldn't set VSX registers");
ret = -1;
}
@@ -414,13 +406,8 @@ int compel_set_task_ext_regs(pid_t pid, user_fpregs_struct_t *ext_regs)
return ret;
}
int compel_syscall(struct parasite_ctl *ctl, int nr, long *ret,
unsigned long arg1,
unsigned long arg2,
unsigned long arg3,
unsigned long arg4,
unsigned long arg5,
unsigned long arg6)
int compel_syscall(struct parasite_ctl *ctl, int nr, long *ret, unsigned long arg1, unsigned long arg2,
unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6)
{
user_regs_struct_t regs = ctl->orig.regs;
int err;
@@ -433,21 +420,18 @@ int compel_syscall(struct parasite_ctl *ctl, int nr, long *ret,
regs.gpr[7] = arg5;
regs.gpr[8] = arg6;
err = compel_execute_syscall(ctl, &regs, (char*)code_syscall);
err = compel_execute_syscall(ctl, &regs, (char *)code_syscall);
*ret = regs.gpr[3];
return err;
}
void *remote_mmap(struct parasite_ctl *ctl,
void *addr, size_t length, int prot,
int flags, int fd, off_t offset)
void *remote_mmap(struct parasite_ctl *ctl, void *addr, size_t length, int prot, int flags, int fd, off_t offset)
{
long map = 0;
int err;
err = compel_syscall(ctl, __NR_mmap, &map,
(unsigned long)addr, length, prot, flags, fd, offset);
err = compel_syscall(ctl, __NR_mmap, &map, (unsigned long)addr, length, prot, flags, fd, offset);
if (err < 0 || (long)map < 0)
map = 0;
@@ -463,7 +447,7 @@ void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *
regs->gpr[12] = new_ip;
regs->nip = new_ip;
if (stack)
regs->gpr[1] = (unsigned long) stack;
regs->gpr[1] = (unsigned long)stack;
regs->trap = 0;
}
@@ -480,9 +464,7 @@ int arch_fetch_sas(struct parasite_ctl *ctl, struct rt_sigframe *s)
long ret;
int err;
err = compel_syscall(ctl, __NR_sigaltstack,
&ret, 0, (unsigned long)&s->uc.uc_stack,
0, 0, 0, 0);
err = compel_syscall(ctl, __NR_sigaltstack, &ret, 0, (unsigned long)&s->uc.uc_stack, 0, 0, 0, 0);
return err ? err : ret;
}
@@ -491,7 +473,7 @@ int arch_fetch_sas(struct parasite_ctl *ctl, struct rt_sigframe *s)
*
* NOTE: 32bit tasks are not supported.
*/
#define TASK_SIZE_64TB (0x0000400000000000UL)
#define TASK_SIZE_64TB (0x0000400000000000UL)
#define TASK_SIZE_512TB (0x0002000000000000UL)
#define TASK_SIZE_MIN TASK_SIZE_64TB

View File

@@ -3,14 +3,13 @@
/*
* Define prototype because of compile error if we include uapi/std/syscall.h
*/
long sys_old_mmap (struct mmap_arg_struct *);
long sys_old_mmap(struct mmap_arg_struct *);
/*
* On s390 we have defined __ARCH_WANT_SYS_OLD_MMAP - Therefore implement
* system call with one parameter "mmap_arg_struct".
*/
unsigned long sys_mmap(void *addr, unsigned long len, unsigned long prot,
unsigned long flags, unsigned long fd,
unsigned long sys_mmap(void *addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd,
unsigned long offset)
{
struct mmap_arg_struct arg_struct;

View File

@@ -9,7 +9,7 @@
#include "log.h"
#undef LOG_PREFIX
#undef LOG_PREFIX
#define LOG_PREFIX "cpu: "
static compel_cpuinfo_t rt_info;
@@ -23,10 +23,20 @@ static void fetch_rt_cpuinfo(void)
}
}
void compel_set_cpu_cap(compel_cpuinfo_t *c, unsigned int feature) { }
void compel_clear_cpu_cap(compel_cpuinfo_t *c, unsigned int feature) { }
int compel_test_fpu_cap(compel_cpuinfo_t *info, unsigned int feature) { return 0; }
int compel_test_cpu_cap(compel_cpuinfo_t *c, unsigned int feature) { return 0; }
void compel_set_cpu_cap(compel_cpuinfo_t *c, unsigned int feature)
{
}
void compel_clear_cpu_cap(compel_cpuinfo_t *c, unsigned int feature)
{
}
int compel_test_fpu_cap(compel_cpuinfo_t *info, unsigned int feature)
{
return 0;
}
int compel_test_cpu_cap(compel_cpuinfo_t *c, unsigned int feature)
{
return 0;
}
int compel_cpuid(compel_cpuinfo_t *info)
{

View File

@@ -5,9 +5,8 @@
#include "piegen.h"
#include "log.h"
static const unsigned char __maybe_unused
elf_ident_64[EI_NIDENT] = {
0x7f, 0x45, 0x4c, 0x46, 0x02, 0x02, 0x01, 0x00,
static const unsigned char __maybe_unused elf_ident_64[EI_NIDENT] = {
0x7f, 0x45, 0x4c, 0x46, 0x02, 0x02, 0x01, 0x00, /* clang-format */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

View File

@@ -17,25 +17,23 @@
#include "ptrace.h"
#include "infect-priv.h"
#define NT_PRFPREG 2
#define NT_S390_VXRS_LOW 0x309
#define NT_S390_VXRS_HIGH 0x30a
#define NT_S390_GS_CB 0x30b
#define NT_S390_GS_BC 0x30c
#define NT_S390_RI_CB 0x30d
#define NT_PRFPREG 2
#define NT_S390_VXRS_LOW 0x309
#define NT_S390_VXRS_HIGH 0x30a
#define NT_S390_GS_CB 0x30b
#define NT_S390_GS_BC 0x30c
#define NT_S390_RI_CB 0x30d
/*
* Print general purpose and access registers
*/
static void print_user_regs_struct(const char *msg, int pid,
user_regs_struct_t *regs)
static void print_user_regs_struct(const char *msg, int pid, user_regs_struct_t *regs)
{
int i;
pr_debug("%s: Registers for pid=%d\n", msg, pid);
pr_debug("system_call %08lx\n", (unsigned long) regs->system_call);
pr_debug(" psw %016lx %016lx\n", regs->prstatus.psw.mask,
regs->prstatus.psw.addr);
pr_debug("system_call %08lx\n", (unsigned long)regs->system_call);
pr_debug(" psw %016lx %016lx\n", regs->prstatus.psw.mask, regs->prstatus.psw.addr);
pr_debug(" orig_gpr2 %016lx\n", regs->prstatus.orig_gpr2);
for (i = 0; i < 16; i++)
pr_debug(" g%02d %016lx\n", i, regs->prstatus.gprs[i]);
@@ -57,9 +55,7 @@ static void print_vxrs(user_fpregs_struct_t *fpregs)
for (i = 0; i < 16; i++)
pr_debug(" vx_low%02d %016lx\n", i, fpregs->vxrs_low[i]);
for (i = 0; i < 16; i++)
pr_debug(" vx_high%02d %016lx %016lx\n", i,
fpregs->vxrs_high[i].part1,
fpregs->vxrs_high[i].part2);
pr_debug(" vx_high%02d %016lx %016lx\n", i, fpregs->vxrs_high[i].part1, fpregs->vxrs_high[i].part2);
}
/*
@@ -111,8 +107,7 @@ static void print_ri_cb(user_fpregs_struct_t *fpregs)
* Print FP registers, VX registers, guarded-storage, and
* runtime-instrumentation
*/
static void print_user_fpregs_struct(const char *msg, int pid,
user_fpregs_struct_t *fpregs)
static void print_user_fpregs_struct(const char *msg, int pid, user_fpregs_struct_t *fpregs)
{
int i;
@@ -126,28 +121,19 @@ static void print_user_fpregs_struct(const char *msg, int pid,
print_ri_cb(fpregs);
}
int sigreturn_prep_regs_plain(struct rt_sigframe *sigframe,
user_regs_struct_t *regs,
user_fpregs_struct_t *fpregs)
int sigreturn_prep_regs_plain(struct rt_sigframe *sigframe, user_regs_struct_t *regs, user_fpregs_struct_t *fpregs)
{
_sigregs_ext *dst_ext = &sigframe->uc.uc_mcontext_ext;
_sigregs *dst = &sigframe->uc.uc_mcontext;
memcpy(dst->regs.gprs, regs->prstatus.gprs,
sizeof(regs->prstatus.gprs));
memcpy(dst->regs.acrs, regs->prstatus.acrs,
sizeof(regs->prstatus.acrs));
memcpy(&dst->regs.psw, &regs->prstatus.psw,
sizeof(regs->prstatus.psw));
memcpy(&dst->fpregs.fpc, &fpregs->prfpreg.fpc,
sizeof(fpregs->prfpreg.fpc));
memcpy(&dst->fpregs.fprs, &fpregs->prfpreg.fprs,
sizeof(fpregs->prfpreg.fprs));
memcpy(dst->regs.gprs, regs->prstatus.gprs, sizeof(regs->prstatus.gprs));
memcpy(dst->regs.acrs, regs->prstatus.acrs, sizeof(regs->prstatus.acrs));
memcpy(&dst->regs.psw, &regs->prstatus.psw, sizeof(regs->prstatus.psw));
memcpy(&dst->fpregs.fpc, &fpregs->prfpreg.fpc, sizeof(fpregs->prfpreg.fpc));
memcpy(&dst->fpregs.fprs, &fpregs->prfpreg.fprs, sizeof(fpregs->prfpreg.fprs));
if (fpregs->flags & USER_FPREGS_VXRS) {
memcpy(&dst_ext->vxrs_low, &fpregs->vxrs_low,
sizeof(fpregs->vxrs_low));
memcpy(&dst_ext->vxrs_high, &fpregs->vxrs_high,
sizeof(fpregs->vxrs_high));
memcpy(&dst_ext->vxrs_low, &fpregs->vxrs_low, sizeof(fpregs->vxrs_low));
memcpy(&dst_ext->vxrs_high, &fpregs->vxrs_high, sizeof(fpregs->vxrs_high));
} else {
memset(&dst_ext->vxrs_low, 0, sizeof(dst_ext->vxrs_low));
memset(&dst_ext->vxrs_high, 0, sizeof(dst_ext->vxrs_high));
@@ -155,8 +141,7 @@ int sigreturn_prep_regs_plain(struct rt_sigframe *sigframe,
return 0;
}
int sigreturn_prep_fpu_frame_plain(struct rt_sigframe *sigframe,
struct rt_sigframe *rsigframe)
int sigreturn_prep_fpu_frame_plain(struct rt_sigframe *sigframe, struct rt_sigframe *rsigframe)
{
return 0;
}
@@ -169,9 +154,7 @@ static inline void rewind_psw(psw_t *psw, unsigned long bytes)
unsigned long mask;
pr_debug("Rewind psw: %016lx bytes=%lu\n", psw->addr, bytes);
mask = (psw->mask & PSW_MASK_EA) ? -1UL :
(psw->mask & PSW_MASK_BA) ? (1UL << 31) - 1 :
(1UL << 24) - 1;
mask = (psw->mask & PSW_MASK_EA) ? -1UL : (psw->mask & PSW_MASK_BA) ? (1UL << 31) - 1 : (1UL << 24) - 1;
psw->addr = (psw->addr - bytes) & mask;
}
@@ -310,9 +293,8 @@ static int s390_disable_ri_bit(pid_t pid, user_regs_struct_t *regs)
/*
* Prepare task registers for restart
*/
int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs,
user_fpregs_struct_t *ext_regs, save_regs_t save,
void *arg, __maybe_unused unsigned long flags)
int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs, user_fpregs_struct_t *ext_regs, save_regs_t save,
void *arg, __maybe_unused unsigned long flags)
{
user_fpregs_struct_t tmp, *fpregs = ext_regs ? ext_regs : &tmp;
struct iovec iov;
@@ -429,10 +411,10 @@ int compel_set_task_ext_regs(pid_t pid, user_fpregs_struct_t *ext_regs)
* Injected syscall instruction
*/
const char code_syscall[] = {
0x0a, 0x00, /* sc 0 */
0x00, 0x01, /* S390_BREAKPOINT_U16 */
0x00, 0x01, /* S390_BREAKPOINT_U16 */
0x00, 0x01, /* S390_BREAKPOINT_U16 */
0x0a, 0x00, /* sc 0 */
0x00, 0x01, /* S390_BREAKPOINT_U16 */
0x00, 0x01, /* S390_BREAKPOINT_U16 */
0x00, 0x01, /* S390_BREAKPOINT_U16 */
};
static inline void __check_code_syscall(void)
@@ -444,19 +426,14 @@ static inline void __check_code_syscall(void)
/*
* Issue s390 system call
*/
int compel_syscall(struct parasite_ctl *ctl, int nr, long *ret,
unsigned long arg1,
unsigned long arg2,
unsigned long arg3,
unsigned long arg4,
unsigned long arg5,
unsigned long arg6)
int compel_syscall(struct parasite_ctl *ctl, int nr, long *ret, unsigned long arg1, unsigned long arg2,
unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6)
{
user_regs_struct_t regs = ctl->orig.regs;
int err;
/* Load syscall number into %r1 */
regs.prstatus.gprs[1] = (unsigned long) nr;
regs.prstatus.gprs[1] = (unsigned long)nr;
/* Load parameter registers %r2-%r7 */
regs.prstatus.gprs[2] = arg1;
regs.prstatus.gprs[3] = arg2;
@@ -465,7 +442,7 @@ int compel_syscall(struct parasite_ctl *ctl, int nr, long *ret,
regs.prstatus.gprs[6] = arg5;
regs.prstatus.gprs[7] = arg6;
err = compel_execute_syscall(ctl, &regs, (char *) code_syscall);
err = compel_execute_syscall(ctl, &regs, (char *)code_syscall);
/* Return code from system is in %r2 */
if (ret)
@@ -476,9 +453,7 @@ int compel_syscall(struct parasite_ctl *ctl, int nr, long *ret,
/*
* Issue s390 mmap call
*/
void *remote_mmap(struct parasite_ctl *ctl,
void *addr, size_t length, int prot,
int flags, int fd, off_t offset)
void *remote_mmap(struct parasite_ctl *ctl, void *addr, size_t length, int prot, int flags, int fd, off_t offset)
{
void *where = (void *)ctl->ictx.syscall_ip + BUILTIN_SYSCALL_SIZE;
struct mmap_arg_struct arg_struct;
@@ -501,8 +476,7 @@ void *remote_mmap(struct parasite_ctl *ctl,
}
/* Do syscall */
err = compel_syscall(ctl, __NR_mmap, &map, (unsigned long) where,
0, 0, 0, 0, 0);
err = compel_syscall(ctl, __NR_mmap, &map, (unsigned long)where, 0, 0, 0, 0, 0);
if (err < 0 || (long)map < 0)
map = 0;
@@ -510,8 +484,7 @@ void *remote_mmap(struct parasite_ctl *ctl,
if (ptrace_poke_area(pid, &arg_struct, where, sizeof(arg_struct))) {
pr_err("Can't restore mmap args (pid: %d)\n", pid);
if (map != 0) {
err = compel_syscall(ctl, __NR_munmap, NULL, map,
length, 0, 0, 0, 0);
err = compel_syscall(ctl, __NR_munmap, NULL, map, length, 0, 0, 0, 0);
if (err)
pr_err("Can't munmap %d\n", err);
map = 0;
@@ -524,14 +497,12 @@ void *remote_mmap(struct parasite_ctl *ctl,
/*
* Setup registers for parasite call
*/
void parasite_setup_regs(unsigned long new_ip, void *stack,
user_regs_struct_t *regs)
void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *regs)
{
regs->prstatus.psw.addr = new_ip;
if (!stack)
return;
regs->prstatus.gprs[15] = ((unsigned long) stack) -
STACK_FRAME_OVERHEAD;
regs->prstatus.gprs[15] = ((unsigned long)stack) - STACK_FRAME_OVERHEAD;
}
/*
@@ -579,9 +550,7 @@ int arch_fetch_sas(struct parasite_ctl *ctl, struct rt_sigframe *s)
long ret;
int err;
err = compel_syscall(ctl, __NR_sigaltstack,
&ret, 0, (unsigned long)&s->uc.uc_stack,
0, 0, 0, 0);
err = compel_syscall(ctl, __NR_sigaltstack, &ret, 0, (unsigned long)&s->uc.uc_stack, 0, 0, 0, 0);
return err ? err : ret;
}
@@ -655,9 +624,9 @@ enum kernel_ts_level {
};
/* See arch/s390/include/asm/processor.h */
#define TASK_SIZE_LEVEL_3 0x40000000000UL /* 4 TB */
#define TASK_SIZE_LEVEL_4 0x20000000000000UL /* 8 PB */
#define TASK_SIZE_LEVEL_5 0xffffffffffffefffUL /* 16 EB - 0x1000 */
#define TASK_SIZE_LEVEL_3 0x40000000000UL /* 4 TB */
#define TASK_SIZE_LEVEL_4 0x20000000000000UL /* 8 PB */
#define TASK_SIZE_LEVEL_5 0xffffffffffffefffUL /* 16 EB - 0x1000 */
/*
* Return detected kernel version regarding task size level
@@ -671,12 +640,12 @@ static enum kernel_ts_level get_kernel_ts_level(void)
/* Check for 5 levels */
if (criu_end_addr >= TASK_SIZE_LEVEL_4)
return KERNEL_TS_LEVEL_5;
else if (munmap((void *) TASK_SIZE_LEVEL_4, 0x1000) == 0)
else if (munmap((void *)TASK_SIZE_LEVEL_4, 0x1000) == 0)
return KERNEL_TS_LEVEL_5;
if (criu_end_addr < TASK_SIZE_LEVEL_3) {
/* Check for 4 level kernel with fix */
if (munmap((void *) TASK_SIZE_LEVEL_3, 0x1000) == 0)
if (munmap((void *)TASK_SIZE_LEVEL_3, 0x1000) == 0)
return KERNEL_TS_LEVEL_4_FIX_YES;
else
return KERNEL_TS_LEVEL_4_FIX_NO;

View File

@@ -1,16 +1,16 @@
#include "asm/types.h"
#include "syscall-32.h"
#define SYS_SOCKET 1 /* sys_socket(2) */
#define SYS_BIND 2 /* sys_bind(2) */
#define SYS_CONNECT 3 /* sys_connect(2) */
#define SYS_SENDTO 11 /* sys_sendto(2) */
#define SYS_RECVFROM 12 /* sys_recvfrom(2) */
#define SYS_SHUTDOWN 13 /* sys_shutdown(2) */
#define SYS_SETSOCKOPT 14 /* sys_setsockopt(2) */
#define SYS_GETSOCKOPT 15 /* sys_getsockopt(2) */
#define SYS_SENDMSG 16 /* sys_sendmsg(2) */
#define SYS_RECVMSG 17 /* sys_recvmsg(2) */
#define SYS_SOCKET 1 /* sys_socket(2) */
#define SYS_BIND 2 /* sys_bind(2) */
#define SYS_CONNECT 3 /* sys_connect(2) */
#define SYS_SENDTO 11 /* sys_sendto(2) */
#define SYS_RECVFROM 12 /* sys_recvfrom(2) */
#define SYS_SHUTDOWN 13 /* sys_shutdown(2) */
#define SYS_SETSOCKOPT 14 /* sys_setsockopt(2) */
#define SYS_GETSOCKOPT 15 /* sys_getsockopt(2) */
#define SYS_SENDMSG 16 /* sys_sendmsg(2) */
#define SYS_RECVMSG 17 /* sys_recvmsg(2) */
long sys_socket(int domain, int type, int protocol)
{
@@ -20,59 +20,61 @@ long sys_socket(int domain, int type, int protocol)
long sys_connect(int sockfd, struct sockaddr *addr, int addrlen)
{
uint32_t a[] = {(uint32_t)sockfd, (uint32_t)addr, (uint32_t)addrlen};
uint32_t a[] = { (uint32_t)sockfd, (uint32_t)addr, (uint32_t)addrlen };
return sys_socketcall(SYS_CONNECT, (unsigned long *)a);
}
long sys_sendto(int sockfd, void *buff, size_t len, unsigned int flags, struct sockaddr *addr, int addr_len)
{
uint32_t a[] = {(uint32_t)sockfd, (uint32_t)buff, (uint32_t)len, (uint32_t)flags, (uint32_t)addr, (uint32_t)addr_len};
uint32_t a[] = { (uint32_t)sockfd, (uint32_t)buff, (uint32_t)len,
(uint32_t)flags, (uint32_t)addr, (uint32_t)addr_len };
return sys_socketcall(SYS_SENDTO, (unsigned long *)a);
}
long sys_recvfrom(int sockfd, void *ubuf, size_t size, unsigned int flags, struct sockaddr *addr, int *addr_len)
{
uint32_t a[] = {(uint32_t)sockfd, (uint32_t)ubuf, (uint32_t)size, (uint32_t)flags, (uint32_t)addr, (uint32_t)addr_len};
uint32_t a[] = { (uint32_t)sockfd, (uint32_t)ubuf, (uint32_t)size,
(uint32_t)flags, (uint32_t)addr, (uint32_t)addr_len };
return sys_socketcall(SYS_RECVFROM, (unsigned long *)a);
}
long sys_sendmsg(int sockfd, const struct msghdr *msg, int flags)
{
uint32_t a[] = {(uint32_t)sockfd, (uint32_t)msg, (uint32_t)flags};
uint32_t a[] = { (uint32_t)sockfd, (uint32_t)msg, (uint32_t)flags };
return sys_socketcall(SYS_SENDMSG, (unsigned long *)a);
}
long sys_recvmsg(int sockfd, struct msghdr *msg, int flags)
{
uint32_t a[] = {(uint32_t)sockfd, (uint32_t)msg, (uint32_t)flags};
uint32_t a[] = { (uint32_t)sockfd, (uint32_t)msg, (uint32_t)flags };
return sys_socketcall(SYS_RECVMSG, (unsigned long *)a);
}
long sys_shutdown(int sockfd, int how)
{
uint32_t a[] = {(uint32_t)sockfd, (uint32_t)how};
uint32_t a[] = { (uint32_t)sockfd, (uint32_t)how };
return sys_socketcall(SYS_SHUTDOWN, (unsigned long *)a);
}
long sys_bind(int sockfd, const struct sockaddr *addr, int addrlen)
{
uint32_t a[] = {(uint32_t)sockfd, (uint32_t)addr, (uint32_t)addrlen};
uint32_t a[] = { (uint32_t)sockfd, (uint32_t)addr, (uint32_t)addrlen };
return sys_socketcall(SYS_BIND, (unsigned long *)a);
}
long sys_setsockopt(int sockfd, int level, int optname, const void *optval, unsigned int optlen)
{
uint32_t a[] = {(uint32_t)sockfd, (uint32_t)level, (uint32_t)optname, (uint32_t)optval, (uint32_t)optlen};
uint32_t a[] = { (uint32_t)sockfd, (uint32_t)level, (uint32_t)optname, (uint32_t)optval, (uint32_t)optlen };
return sys_socketcall(SYS_SETSOCKOPT, (unsigned long *)a);
}
long sys_getsockopt(int sockfd, int level, int optname, const void *optval, unsigned int *optlen)
{
uint32_t a[] = {(uint32_t)sockfd, (uint32_t)level, (uint32_t)optname, (uint32_t)optval, (uint32_t)optlen};
uint32_t a[] = { (uint32_t)sockfd, (uint32_t)level, (uint32_t)optname, (uint32_t)optval, (uint32_t)optlen };
return sys_socketcall(SYS_GETSOCKOPT, (unsigned long *)a);
}
#define SHMAT 21
#define SHMAT 21
long sys_shmat(int shmid, void *shmaddr, int shmflag)
{

View File

@@ -8,7 +8,7 @@
#include "log.h"
#include "common/bug.h"
#undef LOG_PREFIX
#undef LOG_PREFIX
#define LOG_PREFIX "cpu: "
static compel_cpuinfo_t rt_info;
@@ -29,32 +29,24 @@ static void fetch_rt_cpuinfo(void)
* to save/restore PT state in Linux.
*/
static const char * const xfeature_names[] = {
"x87 floating point registers" ,
"SSE registers" ,
"AVX registers" ,
"MPX bounds registers" ,
"MPX CSR" ,
"AVX-512 opmask" ,
"AVX-512 Hi256" ,
"AVX-512 ZMM_Hi256" ,
"Processor Trace" ,
static const char *const xfeature_names[] = {
"x87 floating point registers",
"SSE registers",
"AVX registers",
"MPX bounds registers",
"MPX CSR",
"AVX-512 opmask",
"AVX-512 Hi256",
"AVX-512 ZMM_Hi256",
"Processor Trace",
"Protection Keys User registers",
"Hardware Duty Cycling" ,
"Hardware Duty Cycling",
};
static short xsave_cpuid_features[] = {
X86_FEATURE_FPU,
X86_FEATURE_XMM,
X86_FEATURE_AVX,
X86_FEATURE_MPX,
X86_FEATURE_MPX,
X86_FEATURE_AVX512F,
X86_FEATURE_AVX512F,
X86_FEATURE_AVX512F,
X86_FEATURE_INTEL_PT,
X86_FEATURE_PKU,
X86_FEATURE_HDC,
X86_FEATURE_FPU, X86_FEATURE_XMM, X86_FEATURE_AVX, X86_FEATURE_MPX,
X86_FEATURE_MPX, X86_FEATURE_AVX512F, X86_FEATURE_AVX512F, X86_FEATURE_AVX512F,
X86_FEATURE_INTEL_PT, X86_FEATURE_PKU, X86_FEATURE_HDC,
};
void compel_set_cpu_cap(compel_cpuinfo_t *c, unsigned int feature)
@@ -89,8 +81,7 @@ static int compel_fpuid(compel_cpuinfo_t *c)
uint32_t eax, ebx, ecx, edx;
size_t i;
BUILD_BUG_ON(ARRAY_SIZE(xsave_cpuid_features) !=
ARRAY_SIZE(xfeature_names));
BUILD_BUG_ON(ARRAY_SIZE(xsave_cpuid_features) != ARRAY_SIZE(xfeature_names));
if (!compel_test_cpu_cap(c, X86_FEATURE_FPU)) {
pr_err("fpu: No FPU detected\n");
@@ -98,9 +89,7 @@ static int compel_fpuid(compel_cpuinfo_t *c)
}
if (!compel_test_cpu_cap(c, X86_FEATURE_XSAVE)) {
pr_info("fpu: x87 FPU will use %s\n",
compel_test_cpu_cap(c, X86_FEATURE_FXSR) ?
"FXSAVE" : "FSAVE");
pr_info("fpu: x87 FPU will use %s\n", compel_test_cpu_cap(c, X86_FEATURE_FXSR) ? "FXSAVE" : "FSAVE");
return 0;
}
@@ -140,12 +129,11 @@ static int compel_fpuid(compel_cpuinfo_t *c)
c->xsaves_size = ebx;
pr_debug("fpu: xfeatures_mask 0x%llx xsave_size %u xsave_size_max %u xsaves_size %u\n",
(unsigned long long)c->xfeatures_mask,
c->xsave_size, c->xsave_size_max, c->xsaves_size);
(unsigned long long)c->xfeatures_mask, c->xsave_size, c->xsave_size_max, c->xsaves_size);
if (c->xsave_size_max > sizeof(struct xsave_struct))
pr_warn_once("fpu: max xsave frame exceed xsave_struct (%u %u)\n",
c->xsave_size_max, (unsigned)sizeof(struct xsave_struct));
pr_warn_once("fpu: max xsave frame exceed xsave_struct (%u %u)\n", c->xsave_size_max,
(unsigned)sizeof(struct xsave_struct));
memset(c->xstate_offsets, 0xff, sizeof(c->xstate_offsets));
memset(c->xstate_sizes, 0xff, sizeof(c->xstate_sizes));
@@ -160,10 +148,10 @@ static int compel_fpuid(compel_cpuinfo_t *c)
* in the fixed offsets in the xsave area in either compacted form
* or standard form.
*/
c->xstate_offsets[0] = 0;
c->xstate_sizes[0] = offsetof(struct i387_fxsave_struct, xmm_space);
c->xstate_offsets[1] = c->xstate_sizes[0];
c->xstate_sizes[1] = FIELD_SIZEOF(struct i387_fxsave_struct, xmm_space);
c->xstate_offsets[0] = 0;
c->xstate_sizes[0] = offsetof(struct i387_fxsave_struct, xmm_space);
c->xstate_offsets[1] = c->xstate_sizes[0];
c->xstate_sizes[1] = FIELD_SIZEOF(struct i387_fxsave_struct, xmm_space);
for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
if (!(c->xfeatures_mask & (1UL << i)))
@@ -189,8 +177,7 @@ static int compel_fpuid(compel_cpuinfo_t *c)
* highest offset in the buffer. Ensure it does.
*/
if (last_good_offset > c->xstate_offsets[i])
pr_warn_once("fpu: misordered xstate %d %d\n",
last_good_offset, c->xstate_offsets[i]);
pr_warn_once("fpu: misordered xstate %d %d\n", last_good_offset, c->xstate_offsets[i]);
last_good_offset = c->xstate_offsets[i];
}
@@ -198,10 +185,10 @@ static int compel_fpuid(compel_cpuinfo_t *c)
BUILD_BUG_ON(sizeof(c->xstate_offsets) != sizeof(c->xstate_sizes));
BUILD_BUG_ON(sizeof(c->xstate_comp_offsets) != sizeof(c->xstate_comp_sizes));
c->xstate_comp_offsets[0] = 0;
c->xstate_comp_sizes[0] = offsetof(struct i387_fxsave_struct, xmm_space);
c->xstate_comp_offsets[1] = c->xstate_comp_sizes[0];
c->xstate_comp_sizes[1] = FIELD_SIZEOF(struct i387_fxsave_struct, xmm_space);
c->xstate_comp_offsets[0] = 0;
c->xstate_comp_sizes[0] = offsetof(struct i387_fxsave_struct, xmm_space);
c->xstate_comp_offsets[1] = c->xstate_comp_sizes[0];
c->xstate_comp_sizes[1] = FIELD_SIZEOF(struct i387_fxsave_struct, xmm_space);
if (!compel_test_cpu_cap(c, X86_FEATURE_XSAVES)) {
for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
@@ -211,8 +198,7 @@ static int compel_fpuid(compel_cpuinfo_t *c)
}
}
} else {
c->xstate_comp_offsets[FIRST_EXTENDED_XFEATURE] =
FXSAVE_SIZE + XSAVE_HDR_SIZE;
c->xstate_comp_offsets[FIRST_EXTENDED_XFEATURE] = FXSAVE_SIZE + XSAVE_HDR_SIZE;
for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
if ((c->xfeatures_mask & (1UL << i)))
@@ -221,8 +207,7 @@ static int compel_fpuid(compel_cpuinfo_t *c)
c->xstate_comp_sizes[i] = 0;
if (i > FIRST_EXTENDED_XFEATURE) {
c->xstate_comp_offsets[i] = c->xstate_comp_offsets[i-1]
+ c->xstate_comp_sizes[i-1];
c->xstate_comp_offsets[i] = c->xstate_comp_offsets[i - 1] + c->xstate_comp_sizes[i - 1];
/*
* The value returned by ECX[1] indicates the alignment
@@ -240,9 +225,9 @@ static int compel_fpuid(compel_cpuinfo_t *c)
for (i = 0; i < ARRAY_SIZE(c->xstate_offsets); i++) {
if (!(c->xfeatures_mask & (1UL << i)))
continue;
pr_debug("fpu: %-32s xstate_offsets %6d / %-6d xstate_sizes %6d / %-6d\n",
xfeature_names[i], c->xstate_offsets[i], c->xstate_comp_offsets[i],
c->xstate_sizes[i], c->xstate_comp_sizes[i]);
pr_debug("fpu: %-32s xstate_offsets %6d / %-6d xstate_sizes %6d / %-6d\n", xfeature_names[i],
c->xstate_offsets[i], c->xstate_comp_offsets[i], c->xstate_sizes[i],
c->xstate_comp_sizes[i]);
}
}
@@ -261,20 +246,15 @@ int compel_cpuid(compel_cpuinfo_t *c)
*/
/* Get vendor name */
cpuid(0x00000000,
(unsigned int *)&c->cpuid_level,
(unsigned int *)&c->x86_vendor_id[0],
(unsigned int *)&c->x86_vendor_id[8],
(unsigned int *)&c->x86_vendor_id[4]);
cpuid(0x00000000, (unsigned int *)&c->cpuid_level, (unsigned int *)&c->x86_vendor_id[0],
(unsigned int *)&c->x86_vendor_id[8], (unsigned int *)&c->x86_vendor_id[4]);
if (!strcmp(c->x86_vendor_id, "GenuineIntel")) {
c->x86_vendor = X86_VENDOR_INTEL;
} else if (!strcmp(c->x86_vendor_id, "AuthenticAMD") ||
!strcmp(c->x86_vendor_id, "HygonGenuine")) {
} else if (!strcmp(c->x86_vendor_id, "AuthenticAMD") || !strcmp(c->x86_vendor_id, "HygonGenuine")) {
c->x86_vendor = X86_VENDOR_AMD;
} else {
pr_err("Unsupported CPU vendor %s\n",
c->x86_vendor_id);
pr_err("Unsupported CPU vendor %s\n", c->x86_vendor_id);
return -1;
}
@@ -369,7 +349,7 @@ int compel_cpuid(compel_cpuinfo_t *c)
while (*p)
*q++ = *p++;
while (q <= &c->x86_model_id[48])
*q++ = '\0'; /* Zero-pad the rest */
*q++ = '\0'; /* Zero-pad the rest */
}
}
@@ -440,8 +420,7 @@ int compel_cpuid(compel_cpuinfo_t *c)
break;
}
pr_debug("x86_family %u x86_vendor_id %s x86_model_id %s\n",
c->x86_family, c->x86_vendor_id, c->x86_model_id);
pr_debug("x86_family %u x86_vendor_id %s x86_model_id %s\n", c->x86_family, c->x86_vendor_id, c->x86_model_id);
return compel_fpuid(c);
}
@@ -461,8 +440,7 @@ bool compel_fpu_has_feature(unsigned int feature)
uint32_t compel_fpu_feature_size(unsigned int feature)
{
fetch_rt_cpuinfo();
if (feature >= FIRST_EXTENDED_XFEATURE &&
feature < XFEATURE_MAX)
if (feature >= FIRST_EXTENDED_XFEATURE && feature < XFEATURE_MAX)
return rt_info.xstate_sizes[feature];
return 0;
}
@@ -470,8 +448,7 @@ uint32_t compel_fpu_feature_size(unsigned int feature)
uint32_t compel_fpu_feature_offset(unsigned int feature)
{
fetch_rt_cpuinfo();
if (feature >= FIRST_EXTENDED_XFEATURE &&
feature < XFEATURE_MAX)
if (feature >= FIRST_EXTENDED_XFEATURE && feature < XFEATURE_MAX)
return rt_info.xstate_offsets[feature];
return 0;
}

View File

@@ -5,9 +5,8 @@
#include "piegen.h"
#include "log.h"
static const unsigned char __maybe_unused
elf_ident_64_le[EI_NIDENT] = {
0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00,
static const unsigned char __maybe_unused elf_ident_64_le[EI_NIDENT] = {
0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00, /* clang-format */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

View File

@@ -24,29 +24,27 @@
#include "log.h"
#ifndef NT_X86_XSTATE
#define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */
#define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */
#endif
#ifndef NT_PRSTATUS
#define NT_PRSTATUS 1 /* Contains copy of prstatus struct */
#define NT_PRSTATUS 1 /* Contains copy of prstatus struct */
#endif
/*
* Injected syscall instruction
*/
const char code_syscall[] = {
0x0f, 0x05, /* syscall */
0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc /* int 3, ... */
0x0f, 0x05, /* syscall */
0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc /* int 3, ... */
};
const char code_int_80[] = {
0xcd, 0x80, /* int $0x80 */
0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc /* int 3, ... */
0xcd, 0x80, /* int $0x80 */
0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc /* int 3, ... */
};
static const int
code_syscall_aligned = round_up(sizeof(code_syscall), sizeof(long));
static const int
code_int_80_aligned = round_up(sizeof(code_syscall), sizeof(long));
static const int code_syscall_aligned = round_up(sizeof(code_syscall), sizeof(long));
static const int code_int_80_aligned = round_up(sizeof(code_syscall), sizeof(long));
static inline __always_unused void __check_code_syscall(void)
{
@@ -57,22 +55,22 @@ static inline __always_unused void __check_code_syscall(void)
/* 10-byte legacy floating point register */
struct fpreg {
uint16_t significand[4];
uint16_t exponent;
uint16_t significand[4];
uint16_t exponent;
};
/* 16-byte floating point register */
struct fpxreg {
uint16_t significand[4];
uint16_t exponent;
uint16_t padding[3];
uint16_t significand[4];
uint16_t exponent;
uint16_t padding[3];
};
#define FPREG_ADDR(f, n) ((void *)&(f)->st_space + (n) * 16)
#define FP_EXP_TAG_VALID 0
#define FP_EXP_TAG_ZERO 1
#define FP_EXP_TAG_SPECIAL 2
#define FP_EXP_TAG_EMPTY 3
#define FPREG_ADDR(f, n) ((void *)&(f)->st_space + (n)*16)
#define FP_EXP_TAG_VALID 0
#define FP_EXP_TAG_ZERO 1
#define FP_EXP_TAG_SPECIAL 2
#define FP_EXP_TAG_EMPTY 3
static inline uint32_t twd_fxsr_to_i387(struct i387_fxsave_struct *fxsave)
{
@@ -92,9 +90,7 @@ static inline uint32_t twd_fxsr_to_i387(struct i387_fxsave_struct *fxsave)
tag = FP_EXP_TAG_SPECIAL;
break;
case 0x0000:
if (!st->significand[0] &&
!st->significand[1] &&
!st->significand[2] &&
if (!st->significand[0] && !st->significand[1] && !st->significand[2] &&
!st->significand[3])
tag = FP_EXP_TAG_ZERO;
else
@@ -115,8 +111,7 @@ static inline uint32_t twd_fxsr_to_i387(struct i387_fxsave_struct *fxsave)
return ret;
}
void compel_convert_from_fxsr(struct user_i387_ia32_struct *env,
struct i387_fxsave_struct *fxsave)
void compel_convert_from_fxsr(struct user_i387_ia32_struct *env, struct i387_fxsave_struct *fxsave)
{
struct fpxreg *from = (struct fpxreg *)&fxsave->st_space[0];
struct fpreg *to = (struct fpreg *)env->st_space;
@@ -140,16 +135,12 @@ void compel_convert_from_fxsr(struct user_i387_ia32_struct *env,
memcpy(&to[i], &from[i], sizeof(to[0]));
}
int sigreturn_prep_regs_plain(struct rt_sigframe *sigframe,
user_regs_struct_t *regs,
user_fpregs_struct_t *fpregs)
int sigreturn_prep_regs_plain(struct rt_sigframe *sigframe, user_regs_struct_t *regs, user_fpregs_struct_t *fpregs)
{
bool is_native = user_regs_native(regs);
fpu_state_t *fpu_state = is_native ?
&sigframe->native.fpu_state :
&sigframe->compat.fpu_state;
fpu_state_t *fpu_state = is_native ? &sigframe->native.fpu_state : &sigframe->compat.fpu_state;
if (is_native) {
#define cpreg64_native(d, s) sigframe->native.uc.uc_mcontext.d = regs->native.s
#define cpreg64_native(d, s) sigframe->native.uc.uc_mcontext.d = regs->native.s
cpreg64_native(rdi, di);
cpreg64_native(rsi, si);
cpreg64_native(rbp, bp);
@@ -173,7 +164,7 @@ int sigreturn_prep_regs_plain(struct rt_sigframe *sigframe,
sigframe->is_native = true;
#undef cpreg64_native
} else {
#define cpreg32_compat(d) sigframe->compat.uc.uc_mcontext.d = regs->compat.d
#define cpreg32_compat(d) sigframe->compat.uc.uc_mcontext.d = regs->compat.d
cpreg32_compat(gs);
cpreg32_compat(fs);
cpreg32_compat(es);
@@ -206,34 +197,28 @@ int sigreturn_prep_regs_plain(struct rt_sigframe *sigframe,
return 0;
}
int sigreturn_prep_fpu_frame_plain(struct rt_sigframe *sigframe,
struct rt_sigframe *rsigframe)
int sigreturn_prep_fpu_frame_plain(struct rt_sigframe *sigframe, struct rt_sigframe *rsigframe)
{
fpu_state_t *fpu_state = (sigframe->is_native) ?
&rsigframe->native.fpu_state :
&rsigframe->compat.fpu_state;
fpu_state_t *fpu_state = (sigframe->is_native) ? &rsigframe->native.fpu_state : &rsigframe->compat.fpu_state;
if (sigframe->is_native) {
unsigned long addr = (unsigned long)(void *)&fpu_state->fpu_state_64.xsave;
if ((addr % 64ul)) {
pr_err("Unaligned address passed: %lx (native %d)\n",
addr, sigframe->is_native);
pr_err("Unaligned address passed: %lx (native %d)\n", addr, sigframe->is_native);
return -1;
}
sigframe->native.uc.uc_mcontext.fpstate = (uint64_t)addr;
} else if (!sigframe->is_native) {
sigframe->compat.uc.uc_mcontext.fpstate =
(uint32_t)(unsigned long)(void *)&fpu_state->fpu_state_ia32;
sigframe->compat.uc.uc_mcontext.fpstate = (uint32_t)(unsigned long)(void *)&fpu_state->fpu_state_ia32;
}
return 0;
}
#define get_signed_user_reg(pregs, name) \
((user_regs_native(pregs)) ? (int64_t)((pregs)->native.name) : \
(int32_t)((pregs)->compat.name))
#define get_signed_user_reg(pregs, name) \
((user_regs_native(pregs)) ? (int64_t)((pregs)->native.name) : (int32_t)((pregs)->compat.name))
static int get_task_xsave(pid_t pid, user_fpregs_struct_t *xsave)
{
@@ -310,8 +295,7 @@ static int corrupt_extregs(pid_t pid)
* - zdtm.py will grep it auto-magically from logs
* (and the seed will be known from an automatical testing)
*/
pr_err("Corrupting %s for %d, seed %u\n",
use_xsave ? "xsave" : "fpuregs", pid, seed);
pr_err("Corrupting %s for %d, seed %u\n", use_xsave ? "xsave" : "fpuregs", pid, seed);
if (!use_xsave) {
if (ptrace(PTRACE_SETFPREGS, pid, NULL, &ext_regs)) {
@@ -334,15 +318,13 @@ static int corrupt_extregs(pid_t pid)
return 0;
}
int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs,
user_fpregs_struct_t *ext_regs, save_regs_t save,
void *arg, unsigned long flags)
int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs, user_fpregs_struct_t *ext_regs, save_regs_t save,
void *arg, unsigned long flags)
{
user_fpregs_struct_t xsave = { }, *xs = ext_regs ? ext_regs : &xsave;
user_fpregs_struct_t xsave = {}, *xs = ext_regs ? ext_regs : &xsave;
int ret = -1;
pr_info("Dumping general registers for %d in %s mode\n", pid,
user_regs_native(regs) ? "native" : "compat");
pr_info("Dumping general registers for %d in %s mode\n", pid, user_regs_native(regs) ? "native" : "compat");
/* Did we come from a system call? */
if (get_signed_user_reg(regs, orig_ax) >= 0) {
@@ -423,13 +405,8 @@ int compel_set_task_ext_regs(pid_t pid, user_fpregs_struct_t *ext_regs)
return 0;
}
int compel_syscall(struct parasite_ctl *ctl, int nr, long *ret,
unsigned long arg1,
unsigned long arg2,
unsigned long arg3,
unsigned long arg4,
unsigned long arg5,
unsigned long arg6)
int compel_syscall(struct parasite_ctl *ctl, int nr, long *ret, unsigned long arg1, unsigned long arg2,
unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6)
{
user_regs_struct_t regs = ctl->orig.regs;
bool native = user_regs_native(&regs);
@@ -438,51 +415,47 @@ int compel_syscall(struct parasite_ctl *ctl, int nr, long *ret,
if (native) {
user_regs_struct64 *r = &regs.native;
r->ax = (uint64_t)nr;
r->di = arg1;
r->si = arg2;
r->dx = arg3;
r->ax = (uint64_t)nr;
r->di = arg1;
r->si = arg2;
r->dx = arg3;
r->r10 = arg4;
r->r8 = arg5;
r->r9 = arg6;
r->r8 = arg5;
r->r9 = arg6;
err = compel_execute_syscall(ctl, &regs, code_syscall);
} else {
user_regs_struct32 *r = &regs.compat;
r->ax = (uint32_t)nr;
r->bx = arg1;
r->cx = arg2;
r->dx = arg3;
r->si = arg4;
r->di = arg5;
r->bp = arg6;
r->ax = (uint32_t)nr;
r->bx = arg1;
r->cx = arg2;
r->dx = arg3;
r->si = arg4;
r->di = arg5;
r->bp = arg6;
err = compel_execute_syscall(ctl, &regs, code_int_80);
}
*ret = native ?
(long)get_user_reg(&regs, ax) :
(int)get_user_reg(&regs, ax);
*ret = native ? (long)get_user_reg(&regs, ax) : (int)get_user_reg(&regs, ax);
return err;
}
void *remote_mmap(struct parasite_ctl *ctl,
void *addr, size_t length, int prot,
int flags, int fd, off_t offset)
void *remote_mmap(struct parasite_ctl *ctl, void *addr, size_t length, int prot, int flags, int fd, off_t offset)
{
long map;
int err;
bool compat_task = !user_regs_native(&ctl->orig.regs);
err = compel_syscall(ctl, __NR(mmap, compat_task), &map,
(unsigned long)addr, length, prot, flags, fd, offset);
err = compel_syscall(ctl, __NR(mmap, compat_task), &map, (unsigned long)addr, length, prot, flags, fd, offset);
if (err < 0)
return NULL;
if (map == -EACCES && (prot & PROT_WRITE) && (prot & PROT_EXEC)) {
pr_warn("mmap(PROT_WRITE | PROT_EXEC) failed for %d, "
"check selinux execmem policy\n", ctl->rpid);
"check selinux execmem policy\n",
ctl->rpid);
return NULL;
}
if (IS_ERR_VALUE(map)) {
@@ -507,18 +480,17 @@ void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *
{
set_user_reg(regs, ip, new_ip);
if (stack)
set_user_reg(regs, sp, (unsigned long) stack);
set_user_reg(regs, sp, (unsigned long)stack);
/* Avoid end of syscall processing */
set_user_reg(regs, orig_ax, -1);
/* Make sure flags are in known state */
set_user_reg(regs, flags, get_user_reg(regs, flags) &
~(X86_EFLAGS_TF | X86_EFLAGS_DF | X86_EFLAGS_IF));
set_user_reg(regs, flags, get_user_reg(regs, flags) & ~(X86_EFLAGS_TF | X86_EFLAGS_DF | X86_EFLAGS_IF));
}
#define USER32_CS 0x23
#define USER_CS 0x33
#define USER32_CS 0x23
#define USER_CS 0x33
static bool ldt_task_selectors(pid_t pid)
{
@@ -574,30 +546,26 @@ bool arch_can_dump_task(struct parasite_ctl *ctl)
int arch_fetch_sas(struct parasite_ctl *ctl, struct rt_sigframe *s)
{
int native = compel_mode_native(ctl);
void *where = native ?
(void *)&s->native.uc.uc_stack :
(void *)&s->compat.uc.uc_stack;
void *where = native ? (void *)&s->native.uc.uc_stack : (void *)&s->compat.uc.uc_stack;
long ret;
int err;
err = compel_syscall(ctl, __NR(sigaltstack, !native),
&ret, 0, (unsigned long)where,
0, 0, 0, 0);
err = compel_syscall(ctl, __NR(sigaltstack, !native), &ret, 0, (unsigned long)where, 0, 0, 0, 0);
return err ? err : ret;
}
/* Copied from the gdb header gdb/nat/x86-dregs.h */
/* Debug registers' indices. */
#define DR_FIRSTADDR 0
#define DR_LASTADDR 3
#define DR_NADDR 4 /* The number of debug address registers. */
#define DR_STATUS 6 /* Index of debug status register (DR6). */
#define DR_CONTROL 7 /* Index of debug control register (DR7). */
#define DR_FIRSTADDR 0
#define DR_LASTADDR 3
#define DR_NADDR 4 /* The number of debug address registers. */
#define DR_STATUS 6 /* Index of debug status register (DR6). */
#define DR_CONTROL 7 /* Index of debug control register (DR7). */
#define DR_LOCAL_ENABLE_SHIFT 0 /* Extra shift to the local enable bit. */
#define DR_GLOBAL_ENABLE_SHIFT 1 /* Extra shift to the global enable bit. */
#define DR_ENABLE_SIZE 2 /* Two enable bits per debug register. */
#define DR_LOCAL_ENABLE_SHIFT 0 /* Extra shift to the local enable bit. */
#define DR_GLOBAL_ENABLE_SHIFT 1 /* Extra shift to the global enable bit. */
#define DR_ENABLE_SIZE 2 /* Two enable bits per debug register. */
/* Locally enable the break/watchpoint in the I'th debug register. */
#define X86_DR_LOCAL_ENABLE(i) (1 << (DR_LOCAL_ENABLE_SHIFT + DR_ENABLE_SIZE * (i)))
@@ -607,17 +575,14 @@ int ptrace_set_breakpoint(pid_t pid, void *addr)
int ret;
/* Set a breakpoint */
if (ptrace(PTRACE_POKEUSER, pid,
offsetof(struct user, u_debugreg[DR_FIRSTADDR]),
addr)) {
if (ptrace(PTRACE_POKEUSER, pid, offsetof(struct user, u_debugreg[DR_FIRSTADDR]), addr)) {
pr_perror("Unable to setup a breakpoint into %d", pid);
return -1;
}
/* Enable the breakpoint */
if (ptrace(PTRACE_POKEUSER, pid,
offsetof(struct user, u_debugreg[DR_CONTROL]),
X86_DR_LOCAL_ENABLE(DR_FIRSTADDR))) {
if (ptrace(PTRACE_POKEUSER, pid, offsetof(struct user, u_debugreg[DR_CONTROL]),
X86_DR_LOCAL_ENABLE(DR_FIRSTADDR))) {
pr_perror("Unable to enable the breakpoint for %d", pid);
return -1;
}
@@ -634,9 +599,7 @@ int ptrace_set_breakpoint(pid_t pid, void *addr)
int ptrace_flush_breakpoints(pid_t pid)
{
/* Disable the breakpoint */
if (ptrace(PTRACE_POKEUSER, pid,
offsetof(struct user, u_debugreg[DR_CONTROL]),
0)) {
if (ptrace(PTRACE_POKEUSER, pid, offsetof(struct user, u_debugreg[DR_CONTROL]), 0)) {
pr_perror("Unable to disable the breakpoint for %d", pid);
return -1;
}
@@ -668,8 +631,7 @@ int ptrace_get_regs(pid_t pid, user_regs_struct_t *regs)
}
pr_err("PTRACE_GETREGSET read %zu bytes for pid %d, but native/compat regs sizes are %zu/%zu bytes\n",
iov.iov_len, pid,
sizeof(regs->native), sizeof(regs->compat));
iov.iov_len, pid, sizeof(regs->native), sizeof(regs->compat));
return -1;
}
@@ -687,11 +649,14 @@ int ptrace_set_regs(pid_t pid, user_regs_struct_t *regs)
return ptrace(PTRACE_SETREGSET, pid, NT_PRSTATUS, &iov);
}
#define TASK_SIZE ((1UL << 47) - PAGE_SIZE)
#define TASK_SIZE ((1UL << 47) - PAGE_SIZE)
/*
* Task size may be limited to 3G but we need a
* higher limit, because it's backward compatible.
*/
#define TASK_SIZE_IA32 (0xffffe000)
#define TASK_SIZE_IA32 (0xffffe000)
unsigned long compel_task_size(void) { return TASK_SIZE; }
unsigned long compel_task_size(void)
{
return TASK_SIZE;
}

View File

@@ -8,7 +8,7 @@
#include "infect-priv.h"
#ifndef PTRACE_GET_THREAD_AREA
# define PTRACE_GET_THREAD_AREA 25
#define PTRACE_GET_THREAD_AREA 25
#endif
/*
@@ -49,12 +49,10 @@ int __compel_arch_fetch_thread_area(int tid, struct thread_ctx *th)
d->entry_number = GDT_ENTRY_TLS_MIN + i;
}
for (i = 0; i < GDT_ENTRY_TLS_NUM; i++)
{
for (i = 0; i < GDT_ENTRY_TLS_NUM; i++) {
user_desc_t *d = &ptls->desc[i];
err = ptrace(PTRACE_GET_THREAD_AREA, tid,
GDT_ENTRY_TLS_MIN + i, d);
err = ptrace(PTRACE_GET_THREAD_AREA, tid, GDT_ENTRY_TLS_MIN + i, d);
/*
* Ignoring absent syscall on !CONFIG_IA32_EMULATION
* where such mixed code can't run.

View File

@@ -9,8 +9,8 @@
#include "common/compiler.h"
#include "common/bug.h"
#define __sys(foo) sys_##foo
#define __sys_err(ret) ret
#define __sys(foo) sys_##foo
#define __sys_err(ret) ret
#include "common/scm.h"

View File

@@ -12,8 +12,7 @@ void *shmem_create(unsigned long size)
void *mem;
struct shmem_plugin_msg spi;
mem = (void *)sys_mmap(NULL, size, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, 0, 0);
mem = (void *)sys_mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
if (mem == MAP_FAILED)
return NULL;

View File

@@ -10,7 +10,7 @@
#include "common/compiler.h"
#include "common/bug.h"
#define __sys(foo) sys_##foo
#define __sys_err(ret) ret
#define __sys(foo) sys_##foo
#define __sys_err(ret) ret
#include "common/scm-code.c"

View File

@@ -5,9 +5,9 @@
#include "common/lock.h"
#include "common/page.h"
#define pr_err(fmt, ...) print_on_level(1, fmt, ##__VA_ARGS__)
#define pr_info(fmt, ...) print_on_level(3, fmt, ##__VA_ARGS__)
#define pr_debug(fmt, ...) print_on_level(4, fmt, ##__VA_ARGS__)
#define pr_err(fmt, ...) print_on_level(1, fmt, ##__VA_ARGS__)
#define pr_info(fmt, ...) print_on_level(3, fmt, ##__VA_ARGS__)
#define pr_debug(fmt, ...) print_on_level(4, fmt, ##__VA_ARGS__)
#include "common/bug.h"
@@ -51,8 +51,7 @@ static int __parasite_daemon_reply_ack(unsigned int cmd, int err)
return -1;
}
pr_debug("__sent ack msg: %d %d %d\n",
m.cmd, m.ack, m.err);
pr_debug("__sent ack msg: %d %d %d\n", m.cmd, m.ack, m.err);
return 0;
}
@@ -64,16 +63,14 @@ static int __parasite_daemon_wait_msg(struct ctl_msg *m)
pr_debug("Daemon waits for command\n");
while (1) {
*m = (struct ctl_msg){ };
*m = (struct ctl_msg){};
ret = sys_recvfrom(tsock, m, sizeof(*m), MSG_WAITALL, NULL, 0);
if (ret != sizeof(*m)) {
pr_err("Trimmed message received (%d/%d)\n",
(int)sizeof(*m), ret);
pr_err("Trimmed message received (%d/%d)\n", (int)sizeof(*m), ret);
return -1;
}
pr_debug("__fetched msg: %d %d %d\n",
m->cmd, m->ack, m->err);
pr_debug("__fetched msg: %d %d %d\n", m->cmd, m->ack, m->err);
return 0;
}
@@ -94,8 +91,7 @@ static int fini(void)
parasite_cleanup();
new_sp = (long)sigframe + RT_SIGFRAME_OFFSET(sigframe);
pr_debug("%ld: new_sp=%lx ip %lx\n", sys_gettid(),
new_sp, RT_SIGFRAME_REGIP(sigframe));
pr_debug("%ld: new_sp=%lx ip %lx\n", sys_gettid(), new_sp, RT_SIGFRAME_REGIP(sigframe));
sys_close(tsock);
std_log_set_fd(-1);
@@ -155,7 +151,7 @@ static noinline __used int parasite_init_daemon(void *data)
int ret;
args->sigreturn_addr = (uint64_t)(uintptr_t)fini_sigreturn;
sigframe = (void*)(uintptr_t)args->sigframe;
sigframe = (void *)(uintptr_t)args->sigframe;
#ifdef ARCH_HAS_LONG_PAGES
__page_size = args->page_size;
#endif
@@ -193,7 +189,7 @@ err:
}
#ifndef __parasite_entry
# define __parasite_entry
#define __parasite_entry
#endif
/*
@@ -205,7 +201,7 @@ err:
* initialization. Otherwise, we end up with COMMON symbols.
*/
unsigned int __export_parasite_service_cmd = 0;
void * __export_parasite_service_args_ptr = NULL;
void *__export_parasite_service_args_ptr = NULL;
int __used __parasite_entry parasite_service(void)
{

View File

@@ -46,11 +46,9 @@ err:
return ret;
}
#define plugin_init_count(size) ((size) / (sizeof(plugin_init_t *)))
#define plugin_init_count(size) ((size) / (sizeof(plugin_init_t *)))
int __export_std_compel_start(struct prologue_init_args *args,
const plugin_init_t * const *init_array,
size_t init_size)
int __export_std_compel_start(struct prologue_init_args *args, const plugin_init_t *const *init_array, size_t init_size)
{
unsigned int i;
int ret = 0;

View File

@@ -100,18 +100,11 @@ void std_vdprintf(int fd, const char *format, va_list args)
std_dputs(fd, va_arg(args, char *));
break;
case 'd':
__std_vprint_long(buf, sizeof(buf),
along ?
va_arg(args, long) :
(long)va_arg(args, int),
&t);
__std_vprint_long(buf, sizeof(buf), along ? va_arg(args, long) : (long)va_arg(args, int), &t);
std_dputs(fd, t);
break;
case 'x':
__std_vprint_long_hex(buf, sizeof(buf),
along ?
va_arg(args, long) :
(long)va_arg(args, int),
__std_vprint_long_hex(buf, sizeof(buf), along ? va_arg(args, long) : (long)va_arg(args, int),
&t);
std_dputs(fd, t);
break;
@@ -130,9 +123,7 @@ void std_dprintf(int fd, const char *format, ...)
static inline bool __isspace(unsigned char c)
{
return c == ' ' || c == '\f' ||
c == '\n' || c == '\r' ||
c == '\t' || c == '\v';
return c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v';
}
static unsigned char __tolower(unsigned char c)
@@ -142,8 +133,7 @@ static unsigned char __tolower(unsigned char c)
static inline bool __isalpha(unsigned char c)
{
return ((c <= 'Z' && c >= 'A') ||
(c <= 'z' && c >= 'a'));
return ((c <= 'Z' && c >= 'A') || (c <= 'z' && c >= 'a'));
}
static inline bool __isdigit(unsigned char c)
@@ -208,7 +198,7 @@ unsigned long std_strtoul(const char *nptr, char **endptr, int base)
if (__isspace(*s))
continue;
if (!__isalnum(*s))
goto fin;
goto fin;
v = __conv_val(*s);
if (v == -1u || v > base)
goto fin;
@@ -222,7 +212,6 @@ fin:
return neg ? (unsigned long)-num : (unsigned long)num;
}
/*
* C compiler is free to insert implicit calls to memcmp, memset,
* memcpy and memmove, assuming they are available during linking.
@@ -267,7 +256,7 @@ void *memset(void *s, const int c, size_t count)
size_t i = 0;
while (i < count)
dest[i++] = (char) c;
dest[i++] = (char)c;
return s;
}

View File

@@ -28,44 +28,39 @@ static bool __ptr_oob(const uintptr_t ptr, const uintptr_t start, const size_t s
}
/* Check if pointed structure's end is out-of-bound */
static bool __ptr_struct_end_oob(const uintptr_t ptr, const size_t struct_size,
const uintptr_t start, const size_t size)
static bool __ptr_struct_end_oob(const uintptr_t ptr, const size_t struct_size, const uintptr_t start,
const size_t size)
{
/* the last byte of the structure should be inside [begin, end) */
return __ptr_oob(ptr + struct_size - 1, start, size);
}
/* Check if pointed structure is out-of-bound */
static bool __ptr_struct_oob(const uintptr_t ptr, const size_t struct_size,
const uintptr_t start, const size_t size)
static bool __ptr_struct_oob(const uintptr_t ptr, const size_t struct_size, const uintptr_t start, const size_t size)
{
return __ptr_oob(ptr, start, size) ||
__ptr_struct_end_oob(ptr, struct_size, start, size);
return __ptr_oob(ptr, start, size) || __ptr_struct_end_oob(ptr, struct_size, start, size);
}
static bool test_pointer(const void *ptr, const void *start, const size_t size,
const char *name, const char *file, const int line)
static bool test_pointer(const void *ptr, const void *start, const size_t size, const char *name, const char *file,
const int line)
{
if (__ptr_oob((const uintptr_t)ptr, (const uintptr_t)start, size)) {
pr_err("Corrupted pointer %p (%s) at %s:%d\n",
ptr, name, file, line);
pr_err("Corrupted pointer %p (%s) at %s:%d\n", ptr, name, file, line);
return true;
}
return false;
}
#define ptr_func_exit(__ptr) \
do { \
if (test_pointer((__ptr), mem, size, #__ptr, \
__FILE__, __LINE__)) { \
free(sec_hdrs); \
return -1; \
} \
#define ptr_func_exit(__ptr) \
do { \
if (test_pointer((__ptr), mem, size, #__ptr, __FILE__, __LINE__)) { \
free(sec_hdrs); \
return -1; \
} \
} while (0)
#ifdef ELF_PPC64
static int do_relative_toc(long value, uint16_t *location,
unsigned long mask, int complain_signed)
static int do_relative_toc(long value, uint16_t *location, unsigned long mask, int complain_signed)
{
if (complain_signed && (value + 0x8000 > 0xffff)) {
pr_err("TOC16 relocation overflows (%ld)\n", value);
@@ -73,8 +68,7 @@ static int do_relative_toc(long value, uint16_t *location,
}
if ((~mask & 0xffff) & value) {
pr_err("bad TOC16 relocation (%ld) (0x%lx)\n",
value, (~mask & 0xffff) & value);
pr_err("bad TOC16 relocation (%ld) (0x%lx)\n", value, (~mask & 0xffff) & value);
return -1;
}
@@ -89,23 +83,24 @@ static bool is_header_supported(Elf_Ehdr *hdr)
return false;
if ((hdr->e_type != ET_REL
#ifdef NO_RELOCS
&& hdr->e_type != ET_EXEC
&& hdr->e_type != ET_EXEC
#endif
) || hdr->e_version != EV_CURRENT)
) ||
hdr->e_version != EV_CURRENT)
return false;
return true;
}
static const char *get_strings_section(Elf_Ehdr *hdr, uintptr_t mem, size_t size)
{
size_t sec_table_size = ((size_t) hdr->e_shentsize) * hdr->e_shnum;
size_t sec_table_size = ((size_t)hdr->e_shentsize) * hdr->e_shnum;
uintptr_t sec_table = mem + hdr->e_shoff;
Elf_Shdr *secstrings_hdr;
uintptr_t addr;
if (__ptr_struct_oob(sec_table, sec_table_size, mem, size)) {
pr_err("Section table [%#zx, %#zx) is out of [%#zx, %#zx)\n",
sec_table, sec_table + sec_table_size, mem, mem + size);
pr_err("Section table [%#zx, %#zx) is out of [%#zx, %#zx)\n", sec_table, sec_table + sec_table_size,
mem, mem + size);
return NULL;
}
@@ -113,24 +108,22 @@ static const char *get_strings_section(Elf_Ehdr *hdr, uintptr_t mem, size_t size
* strings section header's offset in section headers table is
* (size of section header * index of string section header)
*/
addr = sec_table + ((size_t) hdr->e_shentsize) * hdr->e_shstrndx;
if (__ptr_struct_oob(addr, sizeof(Elf_Shdr),
sec_table, sec_table_size)) {
pr_err("String section header @%#zx is out of [%#zx, %#zx)\n",
addr, sec_table, sec_table + sec_table_size);
addr = sec_table + ((size_t)hdr->e_shentsize) * hdr->e_shstrndx;
if (__ptr_struct_oob(addr, sizeof(Elf_Shdr), sec_table, sec_table_size)) {
pr_err("String section header @%#zx is out of [%#zx, %#zx)\n", addr, sec_table,
sec_table + sec_table_size);
return NULL;
}
secstrings_hdr = (void*)addr;
secstrings_hdr = (void *)addr;
addr = mem + secstrings_hdr->sh_offset;
if (__ptr_struct_oob(addr, secstrings_hdr->sh_size, mem, size)) {
pr_err("String section @%#zx size %#lx is out of [%#zx, %#zx)\n",
addr, (unsigned long)secstrings_hdr->sh_size,
mem, mem + size);
pr_err("String section @%#zx size %#lx is out of [%#zx, %#zx)\n", addr,
(unsigned long)secstrings_hdr->sh_size, mem, mem + size);
return NULL;
}
return (void*)addr;
return (void *)addr;
}
/*
@@ -159,8 +152,7 @@ int __handle_elf(void *mem, size_t size)
pr_debug("Header\n");
pr_debug("------------\n");
pr_debug("\ttype 0x%x machine 0x%x version 0x%x\n",
(unsigned)hdr->e_type, (unsigned)hdr->e_machine,
pr_debug("\ttype 0x%x machine 0x%x version 0x%x\n", (unsigned)hdr->e_type, (unsigned)hdr->e_machine,
(unsigned)hdr->e_version);
if (!is_header_supported(hdr)) {
@@ -189,8 +181,7 @@ int __handle_elf(void *mem, size_t size)
symtab_hdr = sh;
ptr_func_exit(&secstrings[sh->sh_name]);
pr_debug("\t index %-2zd type 0x%-2x name %s\n", i,
(unsigned)sh->sh_type, &secstrings[sh->sh_name]);
pr_debug("\t index %-2zd type 0x%-2x name %s\n", i, (unsigned)sh->sh_type, &secstrings[sh->sh_name]);
sec_hdrs[i] = sh;
@@ -214,9 +205,7 @@ int __handle_elf(void *mem, size_t size)
}
if (sh->sh_addr && sh->sh_addr != k)
pr_info("Overriding unexpected precalculated address of section (section %s addr 0x%lx expected 0x%lx)\n",
&secstrings[sh->sh_name],
(unsigned long) sh->sh_addr,
(unsigned long) k);
&secstrings[sh->sh_name], (unsigned long)sh->sh_addr, (unsigned long)k);
sh->sh_addr = k;
k += sh->sh_size;
}
@@ -262,8 +251,8 @@ int __handle_elf(void *mem, size_t size)
continue;
pr_debug("\ttype 0x%-2x bind 0x%-2x shndx 0x%-4x value 0x%-2lx name %s\n",
(unsigned)ELF_ST_TYPE(sym->st_info), (unsigned)ELF_ST_BIND(sym->st_info),
(unsigned)sym->st_shndx, (unsigned long)sym->st_value, name);
(unsigned)ELF_ST_TYPE(sym->st_info), (unsigned)ELF_ST_BIND(sym->st_info),
(unsigned)sym->st_shndx, (unsigned long)sym->st_value, name);
#ifdef ELF_PPC64
if (!sym->st_value && !strncmp(name, ".TOC.", 6)) {
if (!toc_offset) {
@@ -276,18 +265,15 @@ int __handle_elf(void *mem, size_t size)
#endif
if (strncmp(name, "__export", 8))
continue;
if ((sym->st_shndx && sym->st_shndx < hdr->e_shnum) ||
sym->st_shndx == SHN_ABS) {
if ((sym->st_shndx && sym->st_shndx < hdr->e_shnum) || sym->st_shndx == SHN_ABS) {
if (sym->st_shndx == SHN_ABS) {
sh_src = NULL;
} else {
sh_src = sec_hdrs[sym->st_shndx];
ptr_func_exit(sh_src);
}
pr_out("#define %s_sym%s 0x%lx\n",
opts.prefix, name,
(unsigned long)(sym->st_value +
(sh_src ? sh_src->sh_addr : 0)));
pr_out("#define %s_sym%s 0x%lx\n", opts.prefix, name,
(unsigned long)(sym->st_value + (sh_src ? sh_src->sh_addr : 0)));
}
}
@@ -305,9 +291,8 @@ int __handle_elf(void *mem, size_t size)
sh_rel = sec_hdrs[sh->sh_info];
ptr_func_exit(sh_rel);
pr_debug("\tsection %2zd type 0x%-2x link 0x%-2x info 0x%-2x name %s\n", i,
(unsigned)sh->sh_type, (unsigned)sh->sh_link,
(unsigned)sh->sh_info, &secstrings[sh->sh_name]);
pr_debug("\tsection %2zd type 0x%-2x link 0x%-2x info 0x%-2x name %s\n", i, (unsigned)sh->sh_type,
(unsigned)sh->sh_link, (unsigned)sh->sh_info, &secstrings[sh->sh_name]);
for (k = 0; k < sh->sh_size / sh->sh_entsize; k++) {
int64_t __maybe_unused addend64, __maybe_unused value64;
@@ -334,8 +319,7 @@ int __handle_elf(void *mem, size_t size)
pr_debug("\t\tr_offset 0x%-4lx r_info 0x%-4lx / sym 0x%-2lx type 0x%-2lx symsecoff 0x%-4lx\n",
(unsigned long)r->rel.r_offset, (unsigned long)r->rel.r_info,
(unsigned long)ELF_R_SYM(r->rel.r_info),
(unsigned long)ELF_R_TYPE(r->rel.r_info),
(unsigned long)ELF_R_SYM(r->rel.r_info), (unsigned long)ELF_R_TYPE(r->rel.r_info),
(unsigned long)sh_rel->sh_addr);
if (sym->st_shndx == SHN_UNDEF) {
@@ -345,8 +329,7 @@ int __handle_elf(void *mem, size_t size)
* Their type is STT_NOTYPE, so report any
* other one.
*/
if (ELF32_ST_TYPE(sym->st_info) != STT_NOTYPE
|| strncmp(name, ".TOC.", 6)) {
if (ELF32_ST_TYPE(sym->st_info) != STT_NOTYPE || strncmp(name, ".TOC.", 6)) {
pr_err("Unexpected undefined symbol:%s\n", name);
goto err;
}
@@ -385,8 +368,8 @@ int __handle_elf(void *mem, size_t size)
Elf_Shdr *sh_src;
if ((unsigned)sym->st_shndx > (unsigned)hdr->e_shnum) {
pr_err("Unexpected symbol section index %u/%u\n",
(unsigned)sym->st_shndx, hdr->e_shnum);
pr_err("Unexpected symbol section index %u/%u\n", (unsigned)sym->st_shndx,
hdr->e_shnum);
goto err;
}
sh_src = sec_hdrs[sym->st_shndx];
@@ -419,11 +402,10 @@ int __handle_elf(void *mem, size_t size)
*
* Here we are only handle the case '3' which is the most commonly seen.
*/
#define LOCAL_OFFSET(s) ((s->st_other >> 5) & 0x7)
#define LOCAL_OFFSET(s) ((s->st_other >> 5) & 0x7)
if (LOCAL_OFFSET(sym)) {
if (LOCAL_OFFSET(sym) != 3) {
pr_err("Unexpected local offset value %d\n",
LOCAL_OFFSET(sym));
pr_err("Unexpected local offset value %d\n", LOCAL_OFFSET(sym));
goto err;
}
pr_debug("\t\t\tUsing local offset\n");
@@ -435,28 +417,28 @@ int __handle_elf(void *mem, size_t size)
switch (ELF_R_TYPE(r->rel.r_info)) {
#ifdef CONFIG_MIPS
case R_MIPS_PC16:
/* s+a-p relative */
*((int32_t *)where) = *((int32_t *)where) | ((value32 + addend32 - place)>>2);
break;
/* s+a-p relative */
*((int32_t *)where) = *((int32_t *)where) | ((value32 + addend32 - place) >> 2);
break;
case R_MIPS_26:
/* local : (((A << 2) | (P & 0xf0000000) + S) >> 2
/* local : (((A << 2) | (P & 0xf0000000) + S) >> 2
* external : (signextend(A < 2) + S) >> 2
*/
if (((unsigned)ELF_ST_BIND(sym->st_info) == 0x1)
|| ((unsigned)ELF_ST_BIND(sym->st_info) == 0x2)){
/* bind type local is 0x0 ,global is 0x1,WEAK is 0x2 */
addend32 = value32;
}
pr_out(" { .offset = 0x%-8x, .type = COMPEL_TYPE_MIPS_26, "
".addend = %-8d, .value = 0x%-16x, }, /* R_MIPS_26 */\n",
(unsigned int)place, addend32, value32);
break;
if (((unsigned)ELF_ST_BIND(sym->st_info) == 0x1) ||
((unsigned)ELF_ST_BIND(sym->st_info) == 0x2)) {
/* bind type local is 0x0 ,global is 0x1,WEAK is 0x2 */
addend32 = value32;
}
pr_out(" { .offset = 0x%-8x, .type = COMPEL_TYPE_MIPS_26, "
".addend = %-8d, .value = 0x%-16x, }, /* R_MIPS_26 */\n",
(unsigned int)place, addend32, value32);
break;
case R_MIPS_32:
/* S+A */
break;
/* S+A */
break;
case R_MIPS_64:
pr_out(" { .offset = 0x%-8x, .type = COMPEL_TYPE_MIPS_64, "
@@ -465,39 +447,38 @@ int __handle_elf(void *mem, size_t size)
break;
case R_MIPS_HIGHEST:
pr_out(" { .offset = 0x%-8x, .type = COMPEL_TYPE_MIPS_HIGHEST, "
".addend = %-8d, .value = 0x%-16x, }, /* R_MIPS_HIGHEST */\n",
(unsigned int)place, addend32, value32);
break;
pr_out(" { .offset = 0x%-8x, .type = COMPEL_TYPE_MIPS_HIGHEST, "
".addend = %-8d, .value = 0x%-16x, }, /* R_MIPS_HIGHEST */\n",
(unsigned int)place, addend32, value32);
break;
case R_MIPS_HIGHER:
pr_out(" { .offset = 0x%-8x, .type = COMPEL_TYPE_MIPS_HIGHER, "
".addend = %-8d, .value = 0x%-16x, }, /* R_MIPS_HIGHER */\n",
(unsigned int)place, addend32, value32);
break;
pr_out(" { .offset = 0x%-8x, .type = COMPEL_TYPE_MIPS_HIGHER, "
".addend = %-8d, .value = 0x%-16x, }, /* R_MIPS_HIGHER */\n",
(unsigned int)place, addend32, value32);
break;
case R_MIPS_HI16:
pr_out(" { .offset = 0x%-8x, .type = COMPEL_TYPE_MIPS_HI16, "
".addend = %-8d, .value = 0x%-16x, }, /* R_MIPS_HI16 */\n",
(unsigned int)place, addend32, value32);
break;
pr_out(" { .offset = 0x%-8x, .type = COMPEL_TYPE_MIPS_HI16, "
".addend = %-8d, .value = 0x%-16x, }, /* R_MIPS_HI16 */\n",
(unsigned int)place, addend32, value32);
break;
case R_MIPS_LO16:
if((unsigned)ELF_ST_BIND(sym->st_info) == 0x1){
/* bind type local is 0x0 ,global is 0x1 */
addend32 = value32;
}
pr_out(" { .offset = 0x%-8x, .type = COMPEL_TYPE_MIPS_LO16, "
".addend = %-8d, .value = 0x%-16x, }, /* R_MIPS_LO16 */\n",
(unsigned int)place, addend32, value32);
break;
if ((unsigned)ELF_ST_BIND(sym->st_info) == 0x1) {
/* bind type local is 0x0 ,global is 0x1 */
addend32 = value32;
}
pr_out(" { .offset = 0x%-8x, .type = COMPEL_TYPE_MIPS_LO16, "
".addend = %-8d, .value = 0x%-16x, }, /* R_MIPS_LO16 */\n",
(unsigned int)place, addend32, value32);
break;
#endif
#ifdef ELF_PPC64
case R_PPC64_REL24:
/* Update PC relative offset, linker has not done this yet */
pr_debug("\t\t\tR_PPC64_REL24 at 0x%-4lx val 0x%lx\n",
place, value64);
pr_debug("\t\t\tR_PPC64_REL24 at 0x%-4lx val 0x%lx\n", place, value64);
/* Convert value to relative */
value64 -= place;
if (value64 + 0x2000000 > 0x3ffffff || (value64 & 3) != 0) {
@@ -505,60 +486,54 @@ int __handle_elf(void *mem, size_t size)
goto err;
}
/* Only replace bits 2 through 26 */
*(uint32_t *)where = (*(uint32_t *)where & ~0x03fffffc) |
(value64 & 0x03fffffc);
*(uint32_t *)where = (*(uint32_t *)where & ~0x03fffffc) | (value64 & 0x03fffffc);
break;
case R_PPC64_ADDR32:
case R_PPC64_REL32:
pr_debug("\t\t\tR_PPC64_ADDR32 at 0x%-4lx val 0x%x\n",
place, (unsigned int)(value32 + addend32));
pr_debug("\t\t\tR_PPC64_ADDR32 at 0x%-4lx val 0x%x\n", place,
(unsigned int)(value32 + addend32));
pr_out(" { .offset = 0x%-8x, .type = COMPEL_TYPE_INT, "
" .addend = %-8d, .value = 0x%-16x, "
"}, /* R_PPC64_ADDR32 */\n",
(unsigned int) place, addend32, value32);
(unsigned int)place, addend32, value32);
break;
case R_PPC64_ADDR64:
case R_PPC64_REL64:
pr_debug("\t\t\tR_PPC64_ADDR64 at 0x%-4lx val 0x%lx\n",
place, value64 + addend64);
pr_debug("\t\t\tR_PPC64_ADDR64 at 0x%-4lx val 0x%lx\n", place, value64 + addend64);
pr_out("\t{ .offset = 0x%-8x, .type = COMPEL_TYPE_LONG,"
" .addend = %-8ld, .value = 0x%-16lx, "
"}, /* R_PPC64_ADDR64 */\n",
(unsigned int) place, (long)addend64, (long)value64);
(unsigned int)place, (long)addend64, (long)value64);
break;
case R_PPC64_TOC16_HA:
pr_debug("\t\t\tR_PPC64_TOC16_HA at 0x%-4lx val 0x%lx\n",
place, value64 + addend64 - toc_offset + 0x8000);
if (do_relative_toc((value64 + addend64 - toc_offset + 0x8000) >> 16,
where, 0xffff, 1))
pr_debug("\t\t\tR_PPC64_TOC16_HA at 0x%-4lx val 0x%lx\n", place,
value64 + addend64 - toc_offset + 0x8000);
if (do_relative_toc((value64 + addend64 - toc_offset + 0x8000) >> 16, where, 0xffff, 1))
goto err;
break;
case R_PPC64_TOC16_LO:
pr_debug("\t\t\tR_PPC64_TOC16_LO at 0x%-4lx val 0x%lx\n",
place, value64 + addend64 - toc_offset);
if (do_relative_toc(value64 + addend64 - toc_offset,
where, 0xffff, 1))
pr_debug("\t\t\tR_PPC64_TOC16_LO at 0x%-4lx val 0x%lx\n", place,
value64 + addend64 - toc_offset);
if (do_relative_toc(value64 + addend64 - toc_offset, where, 0xffff, 1))
goto err;
break;
case R_PPC64_TOC16_LO_DS:
pr_debug("\t\t\tR_PPC64_TOC16_LO_DS at 0x%-4lx val 0x%lx\n",
place, value64 + addend64 - toc_offset);
if (do_relative_toc(value64 + addend64 - toc_offset,
where, 0xfffc, 0))
pr_debug("\t\t\tR_PPC64_TOC16_LO_DS at 0x%-4lx val 0x%lx\n", place,
value64 + addend64 - toc_offset);
if (do_relative_toc(value64 + addend64 - toc_offset, where, 0xfffc, 0))
goto err;
break;
case R_PPC64_REL16_HA:
value64 += addend64 - place;
pr_debug("\t\t\tR_PPC64_REL16_HA at 0x%-4lx val 0x%lx\n",
place, value64);
pr_debug("\t\t\tR_PPC64_REL16_HA at 0x%-4lx val 0x%lx\n", place, value64);
/* check that we are dealing with the addis 2,12 instruction */
if (((*(uint32_t*)where) & 0xffff0000) != 0x3c4c0000) {
if (((*(uint32_t *)where) & 0xffff0000) != 0x3c4c0000) {
pr_err("Unexpected instruction for R_PPC64_REL16_HA\n");
goto err;
}
@@ -567,10 +542,9 @@ int __handle_elf(void *mem, size_t size)
case R_PPC64_REL16_LO:
value64 += addend64 - place;
pr_debug("\t\t\tR_PPC64_REL16_LO at 0x%-4lx val 0x%lx\n",
place, value64);
pr_debug("\t\t\tR_PPC64_REL16_LO at 0x%-4lx val 0x%lx\n", place, value64);
/* check that we are dealing with the addi 2,2 instruction */
if (((*(uint32_t*)where) & 0xffff0000) != 0x38420000) {
if (((*(uint32_t *)where) & 0xffff0000) != 0x38420000) {
pr_err("Unexpected instruction for R_PPC64_REL16_LO\n");
goto err;
}
@@ -594,14 +568,16 @@ int __handle_elf(void *mem, size_t size)
(unsigned int)place, (long)addend64, (long)value64);
break;
case R_X86_64_PC32: /* Symbol + Addend - Place (4 bytes) */
pr_debug("\t\t\t\tR_X86_64_PC32 at 0x%-4lx val 0x%x\n", place, value32 + addend32 - (int32_t)place);
pr_debug("\t\t\t\tR_X86_64_PC32 at 0x%-4lx val 0x%x\n", place,
value32 + addend32 - (int32_t)place);
/*
* R_X86_64_PC32 are relative, patch them inplace.
*/
*((int32_t *)where) = value32 + addend32 - place;
break;
case R_X86_64_PLT32: /* ProcLinkage + Addend - Place (4 bytes) */
pr_debug("\t\t\t\tR_X86_64_PLT32 at 0x%-4lx val 0x%x\n", place, value32 + addend32 - (int32_t)place);
pr_debug("\t\t\t\tR_X86_64_PLT32 at 0x%-4lx val 0x%x\n", place,
value32 + addend32 - (int32_t)place);
/*
* R_X86_64_PLT32 are relative, patch them inplace.
*/
@@ -626,7 +602,8 @@ int __handle_elf(void *mem, size_t size)
(unsigned int)place, addend32, value32);
break;
case R_386_PC32: /* Symbol + Addend - Place */
pr_debug("\t\t\t\tR_386_PC32 at 0x%-4lx val 0x%x\n", place, value32 + addend32 - (int32_t)place);
pr_debug("\t\t\t\tR_386_PC32 at 0x%-4lx val 0x%x\n", place,
value32 + addend32 - (int32_t)place);
/*
* R_386_PC32 are relative, patch them inplace.
*/
@@ -661,7 +638,7 @@ int __handle_elf(void *mem, size_t size)
#endif
default:
pr_err("Unsupported relocation of type %lu\n",
(unsigned long)ELF_R_TYPE(r->rel.r_info));
(unsigned long)ELF_R_TYPE(r->rel.r_info));
goto err;
}
}
@@ -679,11 +656,11 @@ int __handle_elf(void *mem, size_t size)
if (!(sh->sh_flags & SHF_ALLOC) || !sh->sh_size)
continue;
shdata = mem + sh->sh_offset;
shdata = mem + sh->sh_offset;
pr_debug("Copying section '%s'\n"
"\tstart:0x%lx (gap:0x%lx) size:0x%lx\n",
&secstrings[sh->sh_name], (unsigned long) sh->sh_addr,
(unsigned long)(sh->sh_addr - k), (unsigned long) sh->sh_size);
&secstrings[sh->sh_name], (unsigned long)sh->sh_addr, (unsigned long)(sh->sh_addr - k),
(unsigned long)sh->sh_size);
/* write 0 in the gap between the 2 sections */
for (; k < sh->sh_addr; k++) {
@@ -704,21 +681,20 @@ int __handle_elf(void *mem, size_t size)
pr_out("};\n");
pr_out("\n");
pr_out("static void __maybe_unused %s_setup_c_header_desc(struct parasite_blob_desc *pbd, bool native)\n",
opts.prefix);
pr_out(
"{\n"
" pbd->parasite_type = COMPEL_BLOB_CHEADER;\n"
);
opts.prefix);
pr_out("{\n"
" pbd->parasite_type = COMPEL_BLOB_CHEADER;\n");
pr_out("\tpbd->hdr.mem = %s_blob;\n", opts.prefix);
pr_out("\tpbd->hdr.bsize = sizeof(%s_blob);\n",
opts.prefix);
pr_out("\tpbd->hdr.bsize = sizeof(%s_blob);\n", opts.prefix);
pr_out("\tif (native)\n");
pr_out("\t\tpbd->hdr.parasite_ip_off = "
"%s_sym__export_parasite_head_start;\n", opts.prefix);
"%s_sym__export_parasite_head_start;\n",
opts.prefix);
pr_out("#ifdef CONFIG_COMPAT\n");
pr_out("\telse\n");
pr_out("\t\tpbd->hdr.parasite_ip_off = "
"%s_sym__export_parasite_head_start_compat;\n", opts.prefix);
"%s_sym__export_parasite_head_start_compat;\n",
opts.prefix);
pr_out("#endif /* CONFIG_COMPAT */\n");
pr_out("\tpbd->hdr.cmd_off = %s_sym__export_parasite_service_cmd;\n", opts.prefix);
pr_out("\tpbd->hdr.args_ptr_off = %s_sym__export_parasite_service_args_ptr;\n", opts.prefix);
@@ -727,12 +703,11 @@ int __handle_elf(void *mem, size_t size)
pr_out("\tpbd->hdr.data_off = %#lx;\n", data_off);
pr_out("\tpbd->hdr.relocs = %s_relocs;\n", opts.prefix);
pr_out("\tpbd->hdr.nr_relocs = "
"sizeof(%s_relocs) / sizeof(%s_relocs[0]);\n",
opts.prefix, opts.prefix);
"sizeof(%s_relocs) / sizeof(%s_relocs[0]);\n",
opts.prefix, opts.prefix);
pr_out("}\n");
pr_out("\n");
pr_out("static void __maybe_unused %s_setup_c_header(struct parasite_ctl *ctl)\n",
opts.prefix);
pr_out("static void __maybe_unused %s_setup_c_header(struct parasite_ctl *ctl)\n", opts.prefix);
pr_out("{\n");
pr_out("\t%s_setup_c_header_desc(compel_parasite_blob_desc(ctl), compel_mode_native(ctl));\n", opts.prefix);
pr_out("}\n");

View File

@@ -19,8 +19,7 @@ static int __parasite_send_cmd(int sockfd, struct ctl_msg *m)
pr_perror("Failed to send command %d to daemon", m->cmd);
return -1;
} else if (ret != sizeof(*m)) {
pr_err("Message to daemon is trimmed (%d/%d)\n",
(int)sizeof(*m), ret);
pr_err("Message to daemon is trimmed (%d/%d)\n", (int)sizeof(*m), ret);
return -1;
}
@@ -42,12 +41,10 @@ int parasite_wait_ack(int sockfd, unsigned int cmd, struct ctl_msg *m)
pr_perror("Failed to read ack");
return -1;
} else if (ret != sizeof(*m)) {
pr_err("Message reply from daemon is trimmed (%d/%d)\n",
(int)sizeof(*m), ret);
pr_err("Message reply from daemon is trimmed (%d/%d)\n", (int)sizeof(*m), ret);
return -1;
}
pr_debug("Fetched ack: %d %d %d\n",
m->cmd, m->ack, m->err);
pr_debug("Fetched ack: %d %d %d\n", m->cmd, m->ack, m->err);
if (m->cmd != cmd || m->ack != cmd) {
pr_err("Communication error, this is not "
@@ -68,8 +65,7 @@ int compel_rpc_sync(unsigned int cmd, struct parasite_ctl *ctl)
return -1;
if (m.err != 0) {
pr_err("Command %d for daemon failed with %d\n",
cmd, m.err);
pr_err("Command %d for daemon failed with %d\n", cmd, m.err);
return -1;
}

View File

@@ -27,18 +27,17 @@
#include "rpc-pie-priv.h"
#include "infect-util.h"
#define __sys(foo) foo
#define __sys_err(ret) (-errno)
#define __sys(foo) foo
#define __sys_err(ret) (-errno)
#include "common/scm.h"
#include "common/scm-code.c"
#ifndef UNIX_PATH_MAX
#define UNIX_PATH_MAX (sizeof(struct sockaddr_un) - \
(size_t)((struct sockaddr_un *) 0)->sun_path)
#define UNIX_PATH_MAX (sizeof(struct sockaddr_un) - (size_t)((struct sockaddr_un *)0)->sun_path)
#endif
#define PARASITE_STACK_SIZE (16 << 10)
#define PARASITE_STACK_SIZE (16 << 10)
#ifndef SECCOMP_MODE_DISABLED
#define SECCOMP_MODE_DISABLED 0
@@ -193,10 +192,9 @@ static int skip_sigstop(int pid, int nr_signals)
* of it so the task would not know if it was saddled
* up with someone else.
*/
int compel_wait_task(int pid, int ppid,
int (*get_status)(int pid, struct seize_task_status *, void *),
void (*free_status)(int pid, struct seize_task_status *, void *),
struct seize_task_status *ss, void *data)
int compel_wait_task(int pid, int ppid, int (*get_status)(int pid, struct seize_task_status *, void *),
void (*free_status)(int pid, struct seize_task_status *, void *), struct seize_task_status *ss,
void *data)
{
siginfo_t si;
int status, nr_sigstop;
@@ -232,8 +230,8 @@ try_again:
if (pid == getpid())
pr_err("The criu itself is within dumped tree.\n");
else
pr_err("Unseizable non-zombie %d found, state %c, err %d/%d\n",
pid, ss->state, ret, wait_errno);
pr_err("Unseizable non-zombie %d found, state %c, err %d/%d\n", pid, ss->state, ret,
wait_errno);
return -1;
}
@@ -244,8 +242,7 @@ try_again:
}
if ((ppid != -1) && (ss->ppid != ppid)) {
pr_err("Task pid reused while suspending (%d: %d -> %d)\n",
pid, ppid, ss->ppid);
pr_err("Task pid reused while suspending (%d: %d -> %d)\n", pid, ppid, ss->ppid);
goto err;
}
@@ -267,8 +264,7 @@ try_again:
* handle one and repeat.
*/
if (ptrace(PTRACE_CONT, pid, NULL,
(void *)(unsigned long)si.si_signo)) {
if (ptrace(PTRACE_CONT, pid, NULL, (void *)(unsigned long)si.si_signo)) {
pr_perror("Can't continue signal handling, aborting");
goto err;
}
@@ -368,8 +364,7 @@ static int gen_parasite_saddr(struct sockaddr_un *saddr, int key)
int sun_len;
saddr->sun_family = AF_UNIX;
snprintf(saddr->sun_path, UNIX_PATH_MAX,
"X/crtools-pr-%d", key);
snprintf(saddr->sun_path, UNIX_PATH_MAX, "X/crtools-pr-%d", key);
sun_len = SUN_LEN(saddr);
*saddr->sun_path = '\0';
@@ -377,8 +372,7 @@ static int gen_parasite_saddr(struct sockaddr_un *saddr, int key)
return sun_len;
}
static int prepare_tsock(struct parasite_ctl *ctl, pid_t pid,
struct parasite_init_args *args)
static int prepare_tsock(struct parasite_ctl *ctl, pid_t pid, struct parasite_init_args *args)
{
int ssock = -1;
socklen_t sk_len;
@@ -395,7 +389,7 @@ static int prepare_tsock(struct parasite_ctl *ctl, pid_t pid,
goto err;
}
if (getsockname(ssock, (struct sockaddr *) &addr, &sk_len) < 0) {
if (getsockname(ssock, (struct sockaddr *)&addr, &sk_len) < 0) {
pr_perror("Unable to get name for a socket");
return -1;
}
@@ -430,8 +424,8 @@ err:
static int setup_child_handler(struct parasite_ctl *ctl)
{
struct sigaction sa = {
.sa_sigaction = ctl->ictx.child_handler,
.sa_flags = SA_SIGINFO | SA_RESTART,
.sa_sigaction = ctl->ictx.child_handler,
.sa_flags = SA_SIGINFO | SA_RESTART,
};
sigemptyset(&sa.sa_mask);
@@ -454,8 +448,8 @@ static int restore_child_handler(struct parasite_ctl *ctl)
return 0;
}
static int parasite_run(pid_t pid, int cmd, unsigned long ip, void *stack,
user_regs_struct_t *regs, struct thread_ctx *octx)
static int parasite_run(pid_t pid, int cmd, unsigned long ip, void *stack, user_regs_struct_t *regs,
struct thread_ctx *octx)
{
k_rtsigset_t block;
@@ -493,8 +487,7 @@ err_sig:
return -1;
}
static int restore_thread_ctx(int pid, struct thread_ctx *ctx,
bool restore_ext_regs)
static int restore_thread_ctx(int pid, struct thread_ctx *ctx, bool restore_ext_regs)
{
int ret = 0;
@@ -515,10 +508,8 @@ static int restore_thread_ctx(int pid, struct thread_ctx *ctx,
}
/* we run at @regs->ip */
static int parasite_trap(struct parasite_ctl *ctl, pid_t pid,
user_regs_struct_t *regs,
struct thread_ctx *octx,
bool may_use_extended_regs)
static int parasite_trap(struct parasite_ctl *ctl, pid_t pid, user_regs_struct_t *regs, struct thread_ctx *octx,
bool may_use_extended_regs)
{
siginfo_t siginfo;
int status;
@@ -546,12 +537,11 @@ static int parasite_trap(struct parasite_ctl *ctl, pid_t pid,
if (ptrace_get_regs(pid, regs)) {
pr_perror("Can't obtain registers (pid: %d)", pid);
goto err;
goto err;
}
if (WSTOPSIG(status) != SIGTRAP || siginfo.si_code != ARCH_SI_TRAP) {
pr_debug("** delivering signal %d si_code=%d\n",
siginfo.si_signo, siginfo.si_code);
pr_debug("** delivering signal %d si_code=%d\n", siginfo.si_signo, siginfo.si_code);
pr_err("Unexpected %d task interruption, aborting\n", pid);
goto err;
@@ -569,9 +559,7 @@ err:
return ret;
}
int compel_execute_syscall(struct parasite_ctl *ctl,
user_regs_struct_t *regs, const char *code_syscall)
int compel_execute_syscall(struct parasite_ctl *ctl, user_regs_struct_t *regs, const char *code_syscall)
{
pid_t pid = ctl->rpid;
int err;
@@ -582,8 +570,7 @@ int compel_execute_syscall(struct parasite_ctl *ctl,
* we will need it to restore original program content.
*/
memcpy(code_orig, code_syscall, sizeof(code_orig));
if (ptrace_swap_area(pid, (void *)ctl->ictx.syscall_ip,
(void *)code_orig, sizeof(code_orig))) {
if (ptrace_swap_area(pid, (void *)ctl->ictx.syscall_ip, (void *)code_orig, sizeof(code_orig))) {
pr_err("Can't inject syscall blob (pid: %d)\n", pid);
return -1;
}
@@ -592,8 +579,7 @@ int compel_execute_syscall(struct parasite_ctl *ctl,
if (!err)
err = parasite_trap(ctl, pid, regs, &ctl->orig, false);
if (ptrace_poke_area(pid, (void *)code_orig,
(void *)ctl->ictx.syscall_ip, sizeof(code_orig))) {
if (ptrace_poke_area(pid, (void *)code_orig, (void *)ctl->ictx.syscall_ip, sizeof(code_orig))) {
pr_err("Can't restore syscall blob (pid: %d)\n", ctl->rpid);
err = -1;
}
@@ -633,7 +619,7 @@ static int parasite_init_daemon(struct parasite_ctl *ctl)
struct parasite_init_args *args;
pid_t pid = ctl->rpid;
user_regs_struct_t regs;
struct ctl_msg m = { };
struct ctl_msg m = {};
*ctl->cmd = PARASITE_CMD_INIT_DAEMON;
@@ -674,12 +660,11 @@ static int parasite_init_daemon(struct parasite_ctl *ctl)
pr_info("Wait for parasite being daemonized...\n");
if (parasite_wait_ack(ctl->tsock, PARASITE_CMD_INIT_DAEMON, &m)) {
pr_err("Can't switch parasite %d to daemon mode %d\n",
pid, m.err);
pr_err("Can't switch parasite %d to daemon mode %d\n", pid, m.err);
goto err;
}
ctl->sigreturn_addr = (void*)(uintptr_t)args->sigreturn_addr;
ctl->sigreturn_addr = (void *)(uintptr_t)args->sigreturn_addr;
ctl->daemonized = true;
pr_info("Parasite %d has been switched to daemon mode\n", pid);
return 0;
@@ -698,8 +683,7 @@ static int parasite_start_daemon(struct parasite_ctl *ctl)
* while in daemon it is not such.
*/
if (compel_get_task_regs(pid, &ctl->orig.regs, NULL, ictx->save_regs,
ictx->regs_arg, ictx->flags)) {
if (compel_get_task_regs(pid, &ctl->orig.regs, NULL, ictx->save_regs, ictx->regs_arg, ictx->flags)) {
pr_err("Can't obtain regs for thread %d\n", pid);
return -1;
}
@@ -722,8 +706,7 @@ static int parasite_mmap_exchange(struct parasite_ctl *ctl, unsigned long size,
{
int fd;
ctl->remote_map = remote_mmap(ctl, NULL, size, remote_prot,
MAP_ANONYMOUS | MAP_SHARED, -1, 0);
ctl->remote_map = remote_mmap(ctl, NULL, size, remote_prot, MAP_ANONYMOUS | MAP_SHARED, -1, 0);
if (!ctl->remote_map) {
pr_err("Can't allocate memory for parasite blob (pid: %d)\n", ctl->rpid);
return -1;
@@ -731,13 +714,12 @@ static int parasite_mmap_exchange(struct parasite_ctl *ctl, unsigned long size,
ctl->map_length = round_up(size, page_size());
fd = ctl->ictx.open_proc(ctl->rpid, O_RDWR, "map_files/%lx-%lx",
(long)ctl->remote_map, (long)ctl->remote_map + ctl->map_length);
fd = ctl->ictx.open_proc(ctl->rpid, O_RDWR, "map_files/%lx-%lx", (long)ctl->remote_map,
(long)ctl->remote_map + ctl->map_length);
if (fd < 0)
return -1;
ctl->local_map = mmap(NULL, size, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_FILE, fd, 0);
ctl->local_map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FILE, fd, 0);
close(fd);
if (ctl->local_map == MAP_FAILED) {
@@ -779,8 +761,7 @@ static int parasite_memfd_exchange(struct parasite_ctl *ctl, unsigned long size,
return -1;
}
ret = compel_syscall(ctl, __NR(memfd_create, compat_task), &sret,
(unsigned long)where, 0, 0, 0, 0, 0);
ret = compel_syscall(ctl, __NR(memfd_create, compat_task), &sret, (unsigned long)where, 0, 0, 0, 0, 0);
if (ptrace_poke_area(pid, orig_code, where, sizeof(orig_code))) {
fd = (int)sret;
@@ -812,15 +793,13 @@ static int parasite_memfd_exchange(struct parasite_ctl *ctl, unsigned long size,
goto err_cure;
}
ctl->remote_map = remote_mmap(ctl, NULL, size, remote_prot,
MAP_FILE | MAP_SHARED, fd, 0);
ctl->remote_map = remote_mmap(ctl, NULL, size, remote_prot, MAP_FILE | MAP_SHARED, fd, 0);
if (!ctl->remote_map) {
pr_err("Can't rmap memfd for parasite blob\n");
goto err_curef;
}
ctl->local_map = mmap(NULL, size, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_FILE, lfd, 0);
ctl->local_map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FILE, lfd, 0);
if (ctl->local_map == MAP_FAILED) {
ctl->local_map = NULL;
pr_perror("Can't lmap memfd for parasite blob");
@@ -867,7 +846,8 @@ void compel_relocs_apply(void *mem, void *vbase, struct parasite_blob_desc *pbd)
int rel;
got[j] = vbase + elf_relocs[i].value;
rel = (unsigned)((void *)&got[j] - (void *)mem) - elf_relocs[i].offset + elf_relocs[i].addend;
rel = (unsigned)((void *)&got[j] - (void *)mem) - elf_relocs[i].offset +
elf_relocs[i].addend;
*value = rel;
j++;
@@ -888,8 +868,7 @@ long remote_mprotect(struct parasite_ctl *ctl, void *addr, size_t len, int prot)
int err;
bool compat_task = !user_regs_native(&ctl->orig.regs);
err = compel_syscall(ctl, __NR(mprotect, compat_task), &ret,
(unsigned long)addr, len, prot, 0, 0, 0);
err = compel_syscall(ctl, __NR(mprotect, compat_task), &ret, (unsigned long)addr, len, prot, 0, 0, 0);
if (err < 0) {
pr_err("compel_syscall for mprotect failed\n");
return -1;
@@ -917,8 +896,7 @@ static int compel_map_exchange(struct parasite_ctl *ctl, unsigned long size)
if (!ctl->pblob.hdr.data_off)
return 0;
ret = remote_mprotect(ctl, ctl->remote_map + ctl->pblob.hdr.data_off,
size - ctl->pblob.hdr.data_off,
ret = remote_mprotect(ctl, ctl->remote_map + ctl->pblob.hdr.data_off, size - ctl->pblob.hdr.data_off,
PROT_READ | PROT_WRITE);
if (ret)
pr_err("remote_mprotect failed\n");
@@ -1000,7 +978,7 @@ int compel_infect(struct parasite_ctl *ctl, unsigned long nr_threads, unsigned l
* already the case, as args follows the GOT table, which is 8 bytes
* aligned.
*/
if ((unsigned long)ctl->args & (4-1)) {
if ((unsigned long)ctl->args & (4 - 1)) {
pr_err("BUG: args are not 4 bytes aligned: %p\n", ctl->args);
goto err;
}
@@ -1010,8 +988,8 @@ int compel_infect(struct parasite_ctl *ctl, unsigned long nr_threads, unsigned l
p = parasite_size;
ctl->rsigframe = ctl->remote_map + p;
ctl->sigframe = ctl->local_map + p;
ctl->rsigframe = ctl->remote_map + p;
ctl->sigframe = ctl->local_map + p;
p += RESTORE_STACK_SIGFRAME;
p += PARASITE_STACK_SIZE;
@@ -1022,12 +1000,11 @@ int compel_infect(struct parasite_ctl *ctl, unsigned long nr_threads, unsigned l
* It is already the case as RESTORE_STACK_SIGFRAME is a multiple of
* 64, and PARASITE_STACK_SIZE is 0x4000.
*/
if ((unsigned long)ctl->rstack & (16-1)) {
if ((unsigned long)ctl->rstack & (16 - 1)) {
pr_err("BUG: stack is not 16 bytes aligned: %p\n", ctl->rstack);
goto err;
}
if (nr_threads > 1) {
p += PARASITE_STACK_SIZE;
ctl->r_thread_stack = ctl->remote_map + p;
@@ -1035,8 +1012,7 @@ int compel_infect(struct parasite_ctl *ctl, unsigned long nr_threads, unsigned l
ret = arch_fetch_sas(ctl, ctl->rsigframe);
if (ret) {
pr_err("Can't fetch sigaltstack for task %d (ret %d)\n",
ctl->rpid, ret);
pr_err("Can't fetch sigaltstack for task %d (ret %d)\n", ctl->rpid, ret);
goto err;
}
@@ -1227,14 +1203,12 @@ static void handle_sigchld(int signal, siginfo_t *siginfo, void *data)
if (pid <= 0)
return;
pr_err("si_code=%d si_pid=%d si_status=%d\n",
siginfo->si_code, siginfo->si_pid, siginfo->si_status);
pr_err("si_code=%d si_pid=%d si_status=%d\n", siginfo->si_code, siginfo->si_pid, siginfo->si_status);
if (WIFEXITED(status))
pr_err("%d exited with %d unexpectedly\n", pid, WEXITSTATUS(status));
else if (WIFSIGNALED(status))
pr_err("%d was killed by %d unexpectedly: %s\n",
pid, WTERMSIG(status), strsignal(WTERMSIG(status)));
pr_err("%d was killed by %d unexpectedly: %s\n", pid, WTERMSIG(status), strsignal(WTERMSIG(status)));
else if (WIFSTOPPED(status))
pr_err("%d was stopped by %d unexpectedly\n", pid, WSTOPSIG(status));
@@ -1325,9 +1299,8 @@ err:
static bool task_in_parasite(struct parasite_ctl *ctl, user_regs_struct_t *regs)
{
void *addr = (void *) REG_IP(*regs);
return addr >= ctl->remote_map &&
addr < ctl->remote_map + ctl->map_length;
void *addr = (void *)REG_IP(*regs);
return addr >= ctl->remote_map && addr < ctl->remote_map + ctl->map_length;
}
static int parasite_fini_seized(struct parasite_ctl *ctl)
@@ -1376,13 +1349,11 @@ static int parasite_fini_seized(struct parasite_ctl *ctl)
return -1;
/* Go to sigreturn as closer as we can */
ret = compel_stop_pie(pid, ctl->sigreturn_addr, &flag,
ctl->ictx.flags & INFECT_NO_BREAKPOINTS);
ret = compel_stop_pie(pid, ctl->sigreturn_addr, &flag, ctl->ictx.flags & INFECT_NO_BREAKPOINTS);
if (ret < 0)
return ret;
if (compel_stop_on_syscall(1, __NR(rt_sigreturn, 0),
__NR(rt_sigreturn, 1), flag))
if (compel_stop_on_syscall(1, __NR(rt_sigreturn, 0), __NR(rt_sigreturn, 1), flag))
return -1;
if (ptrace_flush_breakpoints(pid))
@@ -1429,15 +1400,13 @@ int compel_cure_remote(struct parasite_ctl *ctl)
if (!ctl->remote_map)
return 0;
err = compel_syscall(ctl, __NR(munmap, !compel_mode_native(ctl)), &ret,
(unsigned long)ctl->remote_map, ctl->map_length,
0, 0, 0, 0);
err = compel_syscall(ctl, __NR(munmap, !compel_mode_native(ctl)), &ret, (unsigned long)ctl->remote_map,
ctl->map_length, 0, 0, 0, 0);
if (err)
return err;
if (ret) {
pr_err("munmap for remote map %p, %lu returned %lu\n",
ctl->remote_map, ctl->map_length, ret);
pr_err("munmap for remote map %p, %lu returned %lu\n", ctl->remote_map, ctl->map_length, ret);
return -1;
}
@@ -1519,8 +1488,7 @@ int compel_unmap(struct parasite_ctl *ctl, unsigned long addr)
if (ret)
goto err;
ret = compel_stop_on_syscall(1, __NR(munmap, 0),
__NR(munmap, 1), TRACE_ENTER);
ret = compel_stop_on_syscall(1, __NR(munmap, 0), __NR(munmap, 1), TRACE_ENTER);
/*
* Don't touch extended registers here: they were restored
@@ -1576,25 +1544,22 @@ static bool task_is_trapped(int status, pid_t pid)
if (WIFEXITED(status))
pr_err("Task exited with %d\n", WEXITSTATUS(status));
if (WIFSIGNALED(status))
pr_err("Task signaled with %d: %s\n",
WTERMSIG(status), strsignal(WTERMSIG(status)));
pr_err("Task signaled with %d: %s\n", WTERMSIG(status), strsignal(WTERMSIG(status)));
if (WIFSTOPPED(status))
pr_err("Task stopped with %d: %s\n",
WSTOPSIG(status), strsignal(WSTOPSIG(status)));
pr_err("Task stopped with %d: %s\n", WSTOPSIG(status), strsignal(WSTOPSIG(status)));
if (WIFCONTINUED(status))
pr_err("Task continued\n");
return false;
}
static inline int is_required_syscall(user_regs_struct_t *regs, pid_t pid,
const int sys_nr, const int sys_nr_compat)
static inline int is_required_syscall(user_regs_struct_t *regs, pid_t pid, const int sys_nr, const int sys_nr_compat)
{
const char *mode = user_regs_native(regs) ? "native" : "compat";
int req_sysnr = user_regs_native(regs) ? sys_nr : sys_nr_compat;
pr_debug("%d (%s) is going to execute the syscall %lu, required is %d\n",
pid, mode, REG_SYSCALL_NR(*regs), req_sysnr);
pr_debug("%d (%s) is going to execute the syscall %lu, required is %d\n", pid, mode, REG_SYSCALL_NR(*regs),
req_sysnr);
return (REG_SYSCALL_NR(*regs) == req_sysnr);
}
@@ -1606,9 +1571,7 @@ static inline int is_required_syscall(user_regs_struct_t *regs, pid_t pid,
* sys_nr - the required syscall number
* sys_nr_compat - the required compatible syscall number
*/
int compel_stop_on_syscall(int tasks,
const int sys_nr, const int sys_nr_compat,
enum trace_flags trace)
int compel_stop_on_syscall(int tasks, const int sys_nr, const int sys_nr_compat, enum trace_flags trace)
{
user_regs_struct_t regs;
int status, ret;
@@ -1668,7 +1631,7 @@ int compel_stop_on_syscall(int tasks,
tasks--;
continue;
}
goon:
goon:
ret = ptrace(PTRACE_SYSCALL, pid, NULL, NULL);
if (ret) {
pr_perror("ptrace");
@@ -1699,10 +1662,9 @@ k_rtsigset_t *compel_task_sigmask(struct parasite_ctl *ctl)
return thread_ctx_sigmask(&ctl->orig);
}
int compel_get_thread_regs(struct parasite_thread_ctl *tctl, save_regs_t save, void * arg)
int compel_get_thread_regs(struct parasite_thread_ctl *tctl, save_regs_t save, void *arg)
{
return compel_get_task_regs(tctl->tid, &tctl->th.regs, &tctl->th.ext_regs,
save, arg, tctl->ctl->ictx.flags);
return compel_get_task_regs(tctl->tid, &tctl->th.regs, &tctl->th.ext_regs, save, arg, tctl->ctl->ictx.flags);
}
struct infect_ctx *compel_infect_ctx(struct parasite_ctl *ctl)

View File

@@ -93,8 +93,7 @@ int ptrace_swap_area(pid_t pid, void *dst, void *src, long bytes)
if (err) {
int err2;
pr_err("Can't poke %d @ %p from %p sized %ld\n",
pid, dst, src, bytes);
pr_err("Can't poke %d @ %p from %p sized %ld\n", pid, dst, src, bytes);
err2 = ptrace_poke_area(pid, t, dst, bytes);
if (err2) {
@@ -109,7 +108,8 @@ int ptrace_swap_area(pid_t pid, void *dst, void *src, long bytes)
return 0;
}
int __attribute__((weak)) ptrace_get_regs(int pid, user_regs_struct_t *regs) {
int __attribute__((weak)) ptrace_get_regs(int pid, user_regs_struct_t *regs)
{
struct iovec iov;
iov.iov_base = regs;

View File

@@ -17,44 +17,44 @@
#include "piegen.h"
#include "log.h"
#define CFLAGS_DEFAULT_SET \
"-Wstrict-prototypes " \
#define CFLAGS_DEFAULT_SET \
"-Wstrict-prototypes " \
"-fno-stack-protector -nostdlib -fomit-frame-pointer "
#define COMPEL_CFLAGS_PIE CFLAGS_DEFAULT_SET "-fpie"
#define COMPEL_CFLAGS_NOPIC CFLAGS_DEFAULT_SET "-fno-pic"
#define COMPEL_CFLAGS_PIE CFLAGS_DEFAULT_SET "-fpie"
#define COMPEL_CFLAGS_NOPIC CFLAGS_DEFAULT_SET "-fno-pic"
#ifdef NO_RELOCS
#define COMPEL_LDFLAGS_COMMON "-z noexecstack -T "
#define COMPEL_LDFLAGS_COMMON "-z noexecstack -T "
#else
#define COMPEL_LDFLAGS_COMMON "-r -z noexecstack -T "
#define COMPEL_LDFLAGS_COMMON "-r -z noexecstack -T "
#endif
typedef struct {
const char *arch; // dir name under arch/
const char *cflags;
const char *cflags_compat;
const char *arch; // dir name under arch/
const char *cflags;
const char *cflags_compat;
} flags_t;
static const flags_t flags = {
#if defined CONFIG_X86_64
.arch = "x86",
.cflags = COMPEL_CFLAGS_PIE,
.cflags_compat = COMPEL_CFLAGS_NOPIC,
.arch = "x86",
.cflags = COMPEL_CFLAGS_PIE,
.cflags_compat = COMPEL_CFLAGS_NOPIC,
#elif defined CONFIG_AARCH64
.arch = "aarch64",
.cflags = COMPEL_CFLAGS_PIE,
.arch = "aarch64",
.cflags = COMPEL_CFLAGS_PIE,
#elif defined(CONFIG_ARMV6) || defined(CONFIG_ARMV7)
.arch = "arm",
.cflags = COMPEL_CFLAGS_PIE,
.arch = "arm",
.cflags = COMPEL_CFLAGS_PIE,
#elif defined CONFIG_PPC64
.arch = "ppc64",
.cflags = COMPEL_CFLAGS_PIE,
.arch = "ppc64",
.cflags = COMPEL_CFLAGS_PIE,
#elif defined CONFIG_S390
.arch = "s390",
.cflags = COMPEL_CFLAGS_PIE,
.arch = "s390",
.cflags = COMPEL_CFLAGS_PIE,
#elif defined CONFIG_MIPS
.arch = "mips",
.arch = "mips",
#else
#error "CONFIG_<ARCH> not defined, or unsupported ARCH"
#endif
@@ -123,23 +123,23 @@ static void cli_log(unsigned int lvl, const char *fmt, va_list parms)
vfprintf(f, fmt, parms);
}
static int usage(int rc) {
static int usage(int rc)
{
FILE *out = (rc == 0) ? stdout : stderr;
fprintf(out,
"Usage:\n"
" compel [--compat] includes | cflags | ldflags\n"
" compel plugins [PLUGIN_NAME ...]\n"
" compel [--compat] [--static] libs\n"
" compel -f FILE -o FILE [-p NAME] [-l N] hgen\n"
" -f, --file FILE input (parasite object) file name\n"
" -o, --output FILE output (header) file name\n"
" -p, --prefix NAME prefix for var names\n"
" -l, --log-level NUM log level (default: %d)\n"
" compel -h|--help\n"
" compel -V|--version\n"
, COMPEL_DEFAULT_LOGLEVEL
);
"Usage:\n"
" compel [--compat] includes | cflags | ldflags\n"
" compel plugins [PLUGIN_NAME ...]\n"
" compel [--compat] [--static] libs\n"
" compel -f FILE -o FILE [-p NAME] [-l N] hgen\n"
" -f, --file FILE input (parasite object) file name\n"
" -o, --output FILE output (header) file name\n"
" -p, --prefix NAME prefix for var names\n"
" -l, --log-level NUM log level (default: %d)\n"
" compel -h|--help\n"
" compel -V|--version\n",
COMPEL_DEFAULT_LOGLEVEL);
return rc;
}
@@ -182,12 +182,9 @@ static void print_ldflags(bool compat)
printf("%s", COMPEL_LDFLAGS_COMMON);
if (uninst_root) {
printf("%s/arch/%s/scripts/compel-pack%s.lds.S\n",
uninst_root, flags.arch, compat_str);
printf("%s/arch/%s/scripts/compel-pack%s.lds.S\n", uninst_root, flags.arch, compat_str);
} else {
printf("%s/compel/scripts/compel-pack%s.lds.S\n",
LIBEXECDIR, compat_str);
printf("%s/compel/scripts/compel-pack%s.lds.S\n", LIBEXECDIR, compat_str);
}
}
@@ -196,8 +193,7 @@ static void print_plugin(const char *name)
const char suffix[] = ".lib.a";
if (uninst_root)
printf("%s/plugins/%s%s\n",
uninst_root, name, suffix);
printf("%s/plugins/%s%s\n", uninst_root, name, suffix);
else
printf("%s/compel/%s%s\n", LIBEXECDIR, name, suffix);
}
@@ -307,15 +303,15 @@ int main(int argc, char *argv[])
static const char short_opts[] = "csf:o:p:hVl:";
static struct option long_opts[] = {
{ "compat", no_argument, 0, 'c' },
{ "static", no_argument, 0, 's' },
{ "file", required_argument, 0, 'f' },
{ "output", required_argument, 0, 'o' },
{ "prefix", required_argument, 0, 'p' },
{ "help", no_argument, 0, 'h' },
{ "version", no_argument, 0, 'V' },
{ "log-level", required_argument, 0, 'l' },
{ },
{ "compat", no_argument, 0, 'c' },
{ "static", no_argument, 0, 's' },
{ "file", required_argument, 0, 'f' },
{ "output", required_argument, 0, 'o' },
{ "prefix", required_argument, 0, 'p' },
{ "help", no_argument, 0, 'h' },
{ "version", no_argument, 0, 'V' },
{ "log-level", required_argument, 0, 'l' },
{},
};
uninst_root = getenv("COMPEL_UNINSTALLED_ROOTDIR");
@@ -347,9 +343,7 @@ int main(int argc, char *argv[])
case 'h':
return usage(0);
case 'V':
printf("Version: %d.%d.%d\n",
COMPEL_SO_VERSION_MAJOR,
COMPEL_SO_VERSION_MINOR,
printf("Version: %d.%d.%d\n", COMPEL_SO_VERSION_MAJOR, COMPEL_SO_VERSION_MINOR,
COMPEL_SO_VERSION_SUBLEVEL);
exit(0);
break;

View File

@@ -6,11 +6,19 @@
/*
* Stubs for std compel plugin.
*/
int compel_main(void *arg_p, unsigned int arg_s) { return 0; }
int parasite_trap_cmd(int cmd, void *args) { return 0; }
void parasite_cleanup(void) { }
int compel_main(void *arg_p, unsigned int arg_s)
{
return 0;
}
int parasite_trap_cmd(int cmd, void *args)
{
return 0;
}
void parasite_cleanup(void)
{
}
#define PARASITE_CMD_GETFD PARASITE_USER_CMDS
#define PARASITE_CMD_GETFD PARASITE_USER_CMDS
int parasite_daemon_cmd(int cmd, void *args)
{

View File

@@ -11,7 +11,7 @@
#include "parasite.h"
#define PARASITE_CMD_GETFD PARASITE_USER_CMDS
#define PARASITE_CMD_GETFD PARASITE_USER_CMDS
static void print_vmsg(unsigned int lvl, const char *fmt, va_list parms)
{
@@ -21,7 +21,11 @@ static void print_vmsg(unsigned int lvl, const char *fmt, va_list parms)
static int do_infection(int pid, int *stolen_fd)
{
#define err_and_ret(msg) do { fprintf(stderr, msg); return -1; } while (0)
#define err_and_ret(msg) \
do { \
fprintf(stderr, msg); \
return -1; \
} while (0)
int state;
struct parasite_ctl *ctl;
@@ -135,14 +139,22 @@ int main(int argc, char **argv)
printf("Run the victim\n");
pid = vfork();
if (pid == 0) {
close(p_in[1]); dup2(p_in[0], 0); close(p_in[0]);
close(p_out[0]); dup2(p_out[1], 1); close(p_out[1]);
close(p_err[0]); dup2(p_err[1], 2); close(p_err[1]);
close(p_in[1]);
dup2(p_in[0], 0);
close(p_in[0]);
close(p_out[0]);
dup2(p_out[1], 1);
close(p_out[1]);
close(p_err[0]);
dup2(p_err[1], 2);
close(p_err[1]);
execl("./victim", "victim", NULL);
exit(1);
}
close(p_in[0]); close(p_out[1]); close(p_err[1]);
close(p_in[0]);
close(p_out[1]);
close(p_err[1]);
/*
* Now do the infection with parasite.c

View File

@@ -6,11 +6,16 @@
/*
* Stubs for std compel plugin.
*/
int parasite_trap_cmd(int cmd, void *args) { return 0; }
void parasite_cleanup(void) { }
int parasite_trap_cmd(int cmd, void *args)
{
return 0;
}
void parasite_cleanup(void)
{
}
#define PARASITE_CMD_INC PARASITE_USER_CMDS
#define PARASITE_CMD_DEC PARASITE_USER_CMDS + 1
#define PARASITE_CMD_INC PARASITE_USER_CMDS
#define PARASITE_CMD_DEC PARASITE_USER_CMDS + 1
int parasite_daemon_cmd(int cmd, void *args)
{

View File

@@ -8,8 +8,8 @@
#include "parasite.h"
#define PARASITE_CMD_INC PARASITE_USER_CMDS
#define PARASITE_CMD_DEC PARASITE_USER_CMDS + 1
#define PARASITE_CMD_INC PARASITE_USER_CMDS
#define PARASITE_CMD_DEC PARASITE_USER_CMDS + 1
static void print_vmsg(unsigned int lvl, const char *fmt, va_list parms)
{
@@ -19,7 +19,11 @@ static void print_vmsg(unsigned int lvl, const char *fmt, va_list parms)
static int do_infection(int pid)
{
#define err_and_ret(msg) do { fprintf(stderr, msg); return -1; } while (0)
#define err_and_ret(msg) \
do { \
fprintf(stderr, msg); \
return -1; \
} while (0)
int state;
struct parasite_ctl *ctl;
@@ -110,14 +114,22 @@ int main(int argc, char **argv)
pid = vfork();
if (pid == 0) {
close(p_in[1]); dup2(p_in[0], 0); close(p_in[0]);
close(p_out[0]); dup2(p_out[1], 1); close(p_out[1]);
close(p_err[0]); dup2(p_err[1], 2); close(p_err[1]);
close(p_in[1]);
dup2(p_in[0], 0);
close(p_in[0]);
close(p_out[0]);
dup2(p_out[1], 1);
close(p_out[1]);
close(p_err[0]);
dup2(p_err[1], 2);
close(p_err[1]);
execl("./victim", "victim", NULL);
exit(1);
}
close(p_in[0]); close(p_out[1]); close(p_err[1]);
close(p_in[0]);
close(p_out[1]);
close(p_err[1]);
/*
* Tell the little guy some numbers

View File

@@ -15,7 +15,11 @@ static void print_vmsg(unsigned int lvl, const char *fmt, va_list parms)
static int do_rsetsid(int pid)
{
#define err_and_ret(msg) do { fprintf(stderr, msg); return -1; } while (0)
#define err_and_ret(msg) \
do { \
fprintf(stderr, msg); \
return -1; \
} while (0)
int state;
long ret;
@@ -85,14 +89,22 @@ int main(int argc, char **argv)
pid = vfork();
if (pid == 0) {
close(p_in[1]); dup2(p_in[0], 0); close(p_in[0]);
close(p_out[0]); dup2(p_out[1], 1); close(p_out[1]);
close(p_err[0]); dup2(p_err[1], 2); close(p_err[1]);
close(p_in[1]);
dup2(p_in[0], 0);
close(p_in[0]);
close(p_out[0]);
dup2(p_out[1], 1);
close(p_out[1]);
close(p_err[0]);
dup2(p_err[1], 2);
close(p_err[1]);
execl("./victim", "victim", NULL);
exit(1);
}
close(p_in[0]); close(p_out[1]); close(p_err[1]);
close(p_in[0]);
close(p_out[1]);
close(p_err[1]);
sid = getsid(0);
/*

View File

@@ -18,18 +18,18 @@
#include "common/scm.h"
static const char *action_names[ACT_MAX] = {
[ ACT_PRE_DUMP ] = "pre-dump",
[ ACT_POST_DUMP ] = "post-dump",
[ ACT_PRE_RESTORE ] = "pre-restore",
[ ACT_POST_RESTORE ] = "post-restore",
[ ACT_NET_LOCK ] = "network-lock",
[ ACT_NET_UNLOCK ] = "network-unlock",
[ ACT_SETUP_NS ] = "setup-namespaces",
[ ACT_POST_SETUP_NS ] = "post-setup-namespaces",
[ ACT_PRE_RESUME ] = "pre-resume",
[ ACT_POST_RESUME ] = "post-resume",
[ ACT_ORPHAN_PTS_MASTER ] = "orphan-pts-master",
[ ACT_STATUS_READY ] = "status-ready",
[ACT_PRE_DUMP] = "pre-dump",
[ACT_POST_DUMP] = "post-dump",
[ACT_PRE_RESTORE] = "pre-restore",
[ACT_POST_RESTORE] = "post-restore",
[ACT_NET_LOCK] = "network-lock",
[ACT_NET_UNLOCK] = "network-unlock",
[ACT_SETUP_NS] = "setup-namespaces",
[ACT_POST_SETUP_NS] = "post-setup-namespaces",
[ACT_PRE_RESUME] = "pre-resume",
[ACT_POST_RESUME] = "post-resume",
[ACT_ORPHAN_PTS_MASTER] = "orphan-pts-master",
[ACT_STATUS_READY] = "status-ready",
};
struct script {
@@ -37,11 +37,7 @@ struct script {
char *path;
};
enum {
SCRIPTS_NONE,
SCRIPTS_SHELL,
SCRIPTS_RPC
};
enum { SCRIPTS_NONE, SCRIPTS_SHELL, SCRIPTS_RPC };
static int scripts_mode = SCRIPTS_NONE;
static LIST_HEAD(scripts);
@@ -52,8 +48,8 @@ static int run_shell_scripts(const char *action)
struct script *script;
static unsigned env_set = 0;
#define ENV_IMGDIR 0x1
#define ENV_ROOTPID 0x2
#define ENV_IMGDIR 0x1
#define ENV_ROOTPID 0x2
if (setenv("CRTOOLS_SCRIPT_ACTION", action, 1)) {
pr_perror("Can't set CRTOOLS_SCRIPT_ACTION=%s", action);
@@ -62,7 +58,7 @@ static int run_shell_scripts(const char *action)
if (!(env_set & ENV_IMGDIR)) {
char image_dir[PATH_MAX];
sprintf(image_dir, "/proc/%ld/fd/%d", (long) getpid(), get_service_fd(IMG_FD_OFF));
sprintf(image_dir, "/proc/%ld/fd/%d", (long)getpid(), get_service_fd(IMG_FD_OFF));
if (setenv("CRTOOLS_IMAGE_DIR", image_dir, 1)) {
pr_perror("Can't set CRTOOLS_IMAGE_DIR=%s", image_dir);
return -1;
@@ -88,8 +84,7 @@ static int run_shell_scripts(const char *action)
list_for_each_entry(script, &scripts, node) {
int err;
pr_debug("\t[%s]\n", script->path);
err = cr_system(-1, -1, -1, script->path,
(char *[]) { script->path, NULL }, 0);
err = cr_system(-1, -1, -1, script->path, (char *[]){ script->path, NULL }, 0);
if (err)
pr_err("Script %s exited with %d\n", script->path, err);
retval |= err;

View File

@@ -38,8 +38,7 @@ int dump_aio_ring(MmEntry *mme, struct vma_area *vma)
}
mme->aios[nr] = re;
mme->n_aios = nr + 1;
pr_info("Dumping AIO ring @%"PRIx64"-%"PRIx64"\n",
vma->e->start, vma->e->end);
pr_info("Dumping AIO ring @%" PRIx64 "-%" PRIx64 "\n", vma->e->start, vma->e->end);
return 0;
}
@@ -56,7 +55,7 @@ void free_aios(MmEntry *mme)
unsigned int aio_estimate_nr_reqs(unsigned int size)
{
unsigned int k_max_reqs = NR_IOEVENTS_IN_NPAGES(size/PAGE_SIZE);
unsigned int k_max_reqs = NR_IOEVENTS_IN_NPAGES(size / PAGE_SIZE);
if (size & ~PAGE_MASK) {
pr_err("Ring size is not aligned\n");
@@ -82,8 +81,7 @@ unsigned int aio_estimate_nr_reqs(unsigned int size)
unsigned long aio_rings_args_size(struct vm_area_list *vmas)
{
return sizeof(struct parasite_check_aios_args) +
vmas->nr_aios * sizeof(struct parasite_aio);
return sizeof(struct parasite_check_aios_args) + vmas->nr_aios * sizeof(struct parasite_aio);
}
int parasite_collect_aios(struct parasite_ctl *ctl, struct vm_area_list *vmas)
@@ -111,8 +109,7 @@ int parasite_collect_aios(struct parasite_ctl *ctl, struct vm_area_list *vmas)
if (!vma_area_is(vma, VMA_AREA_AIORING))
continue;
pr_debug(" `- Ring #%ld @%"PRIx64"\n",
(long)(pa - &aa->ring[0]), vma->e->start);
pr_debug(" `- Ring #%ld @%" PRIx64 "\n", (long)(pa - &aa->ring[0]), vma->e->start);
pa->ctx = vma->e->start;
pa->size = vma->e->end - vma->e->start;
pa++;

View File

@@ -1,4 +1,4 @@
#undef LOG_PREFIX
#undef LOG_PREFIX
#define LOG_PREFIX "cpu: "
#include <errno.h>

View File

@@ -21,7 +21,7 @@
#include "restorer.h"
#include "compel/infect.h"
#define assign_reg(dst, src, e) dst->e = (__typeof__(dst->e))(src)->e
#define assign_reg(dst, src, e) dst->e = (__typeof__(dst->e))(src)->e
int save_task_regs(void *x, user_regs_struct_t *regs, user_fpregs_struct_t *fpsimd)
{
@@ -35,12 +35,10 @@ int save_task_regs(void *x, user_regs_struct_t *regs, user_fpregs_struct_t *fpsi
assign_reg(core->ti_aarch64->gpregs, regs, pc);
assign_reg(core->ti_aarch64->gpregs, regs, pstate);
// Save the FP/SIMD state
for (i = 0; i < 32; ++i)
{
core->ti_aarch64->fpsimd->vregs[2*i] = fpsimd->vregs[i];
core->ti_aarch64->fpsimd->vregs[2*i + 1] = fpsimd->vregs[i] >> 64;
for (i = 0; i < 32; ++i) {
core->ti_aarch64->fpsimd->vregs[2 * i] = fpsimd->vregs[i];
core->ti_aarch64->fpsimd->vregs[2 * i + 1] = fpsimd->vregs[i] >> 64;
}
assign_reg(core->ti_aarch64->fpsimd, fpsimd, fpsr);
assign_reg(core->ti_aarch64->fpsimd, fpsimd, fpcr);
@@ -65,7 +63,7 @@ int arch_alloc_thread_info(CoreEntry *core)
goto err;
user_aarch64_regs_entry__init(gpregs);
gpregs->regs = xmalloc(31*sizeof(uint64_t));
gpregs->regs = xmalloc(31 * sizeof(uint64_t));
if (!gpregs->regs)
goto err;
gpregs->n_regs = 31;
@@ -77,7 +75,7 @@ int arch_alloc_thread_info(CoreEntry *core)
goto err;
user_aarch64_fpsimd_context_entry__init(fpsimd);
ti_aarch64->fpsimd = fpsimd;
fpsimd->vregs = xmalloc(64*sizeof(fpsimd->vregs[0]));
fpsimd->vregs = xmalloc(64 * sizeof(fpsimd->vregs[0]));
fpsimd->n_vregs = 64;
if (!fpsimd->vregs)
goto err;
@@ -110,8 +108,8 @@ int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core)
return 1;
for (i = 0; i < 32; ++i)
fpsimd->vregs[i] = (__uint128_t)core->ti_aarch64->fpsimd->vregs[2*i] |
((__uint128_t)core->ti_aarch64->fpsimd->vregs[2*i + 1] << 64);
fpsimd->vregs[i] = (__uint128_t)core->ti_aarch64->fpsimd->vregs[2 * i] |
((__uint128_t)core->ti_aarch64->fpsimd->vregs[2 * i + 1] << 64);
assign_reg(fpsimd, core->ti_aarch64->fpsimd, fpsr);
assign_reg(fpsimd, core->ti_aarch64->fpsimd, fpcr);
@@ -123,7 +121,7 @@ int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core)
int restore_gpregs(struct rt_sigframe *f, UserRegsEntry *r)
{
#define CPREG1(d) f->uc.uc_mcontext.d = r->d
#define CPREG1(d) f->uc.uc_mcontext.d = r->d
int i;

View File

@@ -2,8 +2,7 @@
#include <compel/asm/infect-types.h>
#include "asm/sigframe.h"
int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe,
struct rt_sigframe *rsigframe)
int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe, struct rt_sigframe *rsigframe)
{
return 0;
}

View File

@@ -8,13 +8,12 @@
#include "common/bug.h"
#ifdef LOG_PREFIX
# undef LOG_PREFIX
#undef LOG_PREFIX
#endif
#define LOG_PREFIX "vdso: "
int vdso_redirect_calls(unsigned long base_to, unsigned long base_from,
struct vdso_symtable *to, struct vdso_symtable *from,
bool __always_unused compat_vdso)
int vdso_redirect_calls(unsigned long base_to, unsigned long base_from, struct vdso_symtable *to,
struct vdso_symtable *from, bool __always_unused compat_vdso)
{
unsigned int i;
@@ -22,12 +21,10 @@ int vdso_redirect_calls(unsigned long base_to, unsigned long base_from,
if (vdso_symbol_empty(&from->symbols[i]))
continue;
pr_debug("br: %lx/%lx -> %lx/%lx (index %d)\n",
base_from, from->symbols[i].offset,
base_to, to->symbols[i].offset, i);
pr_debug("br: %lx/%lx -> %lx/%lx (index %d)\n", base_from, from->symbols[i].offset, base_to,
to->symbols[i].offset, i);
write_intraprocedure_branch(base_to + to->symbols[i].offset,
base_from + from->symbols[i].offset);
write_intraprocedure_branch(base_to + to->symbols[i].offset, base_from + from->symbols[i].offset);
}
return 0;

View File

@@ -1,4 +1,4 @@
#undef LOG_PREFIX
#undef LOG_PREFIX
#define LOG_PREFIX "cpu: "
#include <errno.h>

View File

@@ -20,7 +20,7 @@
#include "restorer.h"
#include "compel/infect.h"
#define assign_reg(dst, src, e) dst->e = (__typeof__(dst->e))((src)->ARM_##e)
#define assign_reg(dst, src, e) dst->e = (__typeof__(dst->e))((src)->ARM_##e)
int save_task_regs(void *x, user_regs_struct_t *regs, user_fpregs_struct_t *fpregs)
{
@@ -47,7 +47,6 @@ int save_task_regs(void *x, user_regs_struct_t *regs, user_fpregs_struct_t *fpre
assign_reg(core->ti_arm->gpregs, regs, cpsr);
core->ti_arm->gpregs->orig_r0 = regs->ARM_ORIG_r0;
// Save the VFP state
memcpy(CORE_THREAD_ARCH_INFO(core)->fpstate->vfp_regs, &fpregs->fpregs, sizeof(fpregs->fpregs));
@@ -77,7 +76,7 @@ int arch_alloc_thread_info(CoreEntry *core)
goto err;
user_arm_vfpstate_entry__init(fpstate);
ti_arm->fpstate = fpstate;
fpstate->vfp_regs = xmalloc(32*sizeof(unsigned long long));
fpstate->vfp_regs = xmalloc(32 * sizeof(unsigned long long));
fpstate->n_vfp_regs = 32;
if (!fpstate->vfp_regs)
goto err;
@@ -113,8 +112,8 @@ int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core)
int restore_gpregs(struct rt_sigframe *f, UserArmRegsEntry *r)
{
#define CPREG1(d) f->sig.uc.uc_mcontext.arm_##d = r->d
#define CPREG2(d, s) f->sig.uc.uc_mcontext.arm_##d = r->s
#define CPREG1(d) f->sig.uc.uc_mcontext.arm_##d = r->d
#define CPREG2(d, s) f->sig.uc.uc_mcontext.arm_##d = r->s
CPREG1(r0);
CPREG1(r1);

View File

@@ -41,8 +41,7 @@ int restore_nonsigframe_gpregs(UserArmRegsEntry *r)
* allocated with shmat(shmid, NULL, shmflg).
*/
#define SHMLBA (4UL * PAGE_SIZE)
unsigned long arch_shmat(int shmid, void *shmaddr,
int shmflg, unsigned long size)
unsigned long arch_shmat(int shmid, void *shmaddr, int shmflg, unsigned long size)
{
unsigned long smap;
@@ -65,8 +64,7 @@ unsigned long arch_shmat(int shmid, void *shmaddr,
pr_warn("Make sure that you don't migrate shmem from non-VIPT cached CPU to VIPT cached (e.g., ARMv7 -> ARMv6)\n");
pr_warn("Otherwise YOU HAVE A CHANCE OF DATA CORRUPTIONS in writeable shmem\n");
smap = sys_mremap(smap, size, size,
MREMAP_FIXED | MREMAP_MAYMOVE, (unsigned long)shmaddr);
smap = sys_mremap(smap, size, size, MREMAP_FIXED | MREMAP_MAYMOVE, (unsigned long)shmaddr);
if (IS_ERR_VALUE(smap))
pr_err("mremap() for shmem failed: %d\n", (int)smap);
return smap;

View File

@@ -2,8 +2,7 @@
#include <compel/asm/infect-types.h>
#include "asm/sigframe.h"
int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe,
struct rt_sigframe *rsigframe)
int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe, struct rt_sigframe *rsigframe)
{
return 0;
}

View File

@@ -9,32 +9,31 @@
#include "common/bug.h"
#ifdef LOG_PREFIX
# undef LOG_PREFIX
#undef LOG_PREFIX
#endif
#define LOG_PREFIX "vdso: "
static void insert_trampoline(uintptr_t from, uintptr_t to)
{
struct {
uint32_t ldr_pc;
uint32_t imm32;
uint32_t guards;
uint32_t ldr_pc;
uint32_t imm32;
uint32_t guards;
} __packed jmp = {
.ldr_pc = 0xe51ff004, /* ldr pc, [pc, #-4] */
.imm32 = to,
.guards = 0xe1200070, /* bkpt 0x0000 */
.ldr_pc = 0xe51ff004, /* ldr pc, [pc, #-4] */
.imm32 = to,
.guards = 0xe1200070, /* bkpt 0x0000 */
};
void *iflush_start = (void *)from;
void *iflush_end = iflush_start + sizeof(jmp);
void *iflush_start = (void *)from;
void *iflush_end = iflush_start + sizeof(jmp);
memcpy((void *)from, &jmp, sizeof(jmp));
__builtin___clear_cache(iflush_start, iflush_end);
}
int vdso_redirect_calls(unsigned long base_to, unsigned long base_from,
struct vdso_symtable *sto, struct vdso_symtable *sfrom,
bool compat_vdso)
int vdso_redirect_calls(unsigned long base_to, unsigned long base_from, struct vdso_symtable *sto,
struct vdso_symtable *sfrom, bool compat_vdso)
{
unsigned int i;
@@ -44,9 +43,8 @@ int vdso_redirect_calls(unsigned long base_to, unsigned long base_from,
if (vdso_symbol_empty(&sfrom->symbols[i]))
continue;
pr_debug("jmp: %lx/%lx -> %lx/%lx (index %d)\n",
base_from, sfrom->symbols[i].offset,
base_to, sto->symbols[i].offset, i);
pr_debug("jmp: %lx/%lx -> %lx/%lx (index %d)\n", base_from, sfrom->symbols[i].offset, base_to,
sto->symbols[i].offset, i);
from = base_from + sfrom->symbols[i].offset;
to = base_to + sto->symbols[i].offset;

View File

@@ -20,7 +20,7 @@
#include "protobuf.h"
#include "images/cpuinfo.pb-c.h"
#undef LOG_PREFIX
#undef LOG_PREFIX
#define LOG_PREFIX "cpu: "
int cpu_init(void)

View File

@@ -27,7 +27,6 @@
#include "images/core.pb-c.h"
#include "images/creds.pb-c.h"
int save_task_regs(void *x, user_regs_struct_t *regs, user_fpregs_struct_t *fpregs)
{
CoreEntry *core = x;
@@ -203,7 +202,6 @@ int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core)
return 0;
}
int restore_gpregs(struct rt_sigframe *f, UserMipsRegsEntry *r)
{
f->rs_uc.uc_mcontext.sc_regs[0] = r->r0;

View File

@@ -17,8 +17,7 @@ int restore_nonsigframe_gpregs(UserMipsRegsEntry *r)
}
#define SHMLBA 0x40000
unsigned long arch_shmat(int shmid, void *shmaddr,
int shmflg, unsigned long size)
unsigned long arch_shmat(int shmid, void *shmaddr, int shmflg, unsigned long size)
{
unsigned long smap;
@@ -36,13 +35,12 @@ unsigned long arch_shmat(int shmid, void *shmaddr,
if (smap == (unsigned long)shmaddr)
return smap;
/* Warn ALOUD */
/* Warn ALOUD */
pr_warn("Restoring shmem %p unaligned to SHMLBA.\n", shmaddr);
pr_warn("Make sure that you don't migrate shmem from non-VIPT cached CPU to VIPT cached \n");
pr_warn("Otherwise YOU HAVE A CHANCE OF DATA CORRUPTIONS in writeable shmem\n");
smap = sys_mremap(smap, size, size,
MREMAP_FIXED | MREMAP_MAYMOVE, (unsigned long)shmaddr);
smap = sys_mremap(smap, size, size, MREMAP_FIXED | MREMAP_MAYMOVE, (unsigned long)shmaddr);
if (IS_ERR_VALUE(smap))
pr_err("mremap() for shmem failed: %d\n", (int)smap);
return smap;

View File

@@ -5,7 +5,7 @@
#include <compel/plugins/std/syscall-codes.h>
#ifdef CR_NOGLIBC
# include <compel/plugins/std/string.h>
#include <compel/plugins/std/string.h>
#endif
#include "cpu.h"
@@ -16,4 +16,3 @@ int arch_compat_rt_sigaction(void *stack32, int sig, rt_sigaction_t_compat *act)
{
return 0;
}

View File

@@ -6,8 +6,7 @@
#include "log.h"
#include <stdio.h>
int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe,
struct rt_sigframe *rsigframe)
int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe, struct rt_sigframe *rsigframe)
{
return 0;
}

View File

@@ -8,31 +8,30 @@
#include "common/bug.h"
#ifdef LOG_PREFIX
# undef LOG_PREFIX
#undef LOG_PREFIX
#endif
#define LOG_PREFIX "vdso: "
static void insert_trampoline(uintptr_t from, uintptr_t to)
{
struct {
uint32_t ldr_pc;
uint32_t imm32;
uint32_t guards;
uint32_t ldr_pc;
uint32_t imm32;
uint32_t guards;
} __packed jmp = {
.ldr_pc = 0x1000fffe, /* b -4 */
.imm32 = to,
.guards = 0x0000000d, /* break */
.ldr_pc = 0x1000fffe, /* b -4 */
.imm32 = to,
.guards = 0x0000000d, /* break */
};
void *iflush_start = (void *)from;
void *iflush_end = iflush_start + sizeof(jmp);
void *iflush_start = (void *)from;
void *iflush_end = iflush_start + sizeof(jmp);
memcpy((void *)from, &jmp, sizeof(jmp));
sys_cacheflush(iflush_start, sizeof(jmp), 0);
}
int vdso_redirect_calls(unsigned long base_to, unsigned long base_from,
struct vdso_symtable *sto, struct vdso_symtable *sfrom,
bool compat_vdso)
int vdso_redirect_calls(unsigned long base_to, unsigned long base_from, struct vdso_symtable *sto,
struct vdso_symtable *sfrom, bool compat_vdso)
{
unsigned int i;
@@ -42,9 +41,8 @@ int vdso_redirect_calls(unsigned long base_to, unsigned long base_from,
if (vdso_symbol_empty(&sfrom->symbols[i]))
continue;
pr_debug("jmp: %lx/%lx -> %lx/%lx (index %d)\n",
base_from, sfrom->symbols[i].offset,
base_to, sto->symbols[i].offset, i);
pr_debug("jmp: %lx/%lx -> %lx/%lx (index %d)\n", base_from, sfrom->symbols[i].offset, base_to,
sto->symbols[i].offset, i);
from = base_from + sfrom->symbols[i].offset;
to = base_to + sto->symbols[i].offset;

View File

@@ -1,4 +1,4 @@
#undef LOG_PREFIX
#undef LOG_PREFIX
#define LOG_PREFIX "cpu: "
#include <sys/auxv.h>
@@ -19,9 +19,9 @@
static compel_cpuinfo_t rt_cpuinfo;
#ifdef __LITTLE_ENDIAN__
#define CURRENT_ENDIANNESS CPUINFO_PPC64_ENTRY__ENDIANNESS__LITTLEENDIAN
#define CURRENT_ENDIANNESS CPUINFO_PPC64_ENTRY__ENDIANNESS__LITTLEENDIAN
#else
#define CURRENT_ENDIANNESS CPUINFO_PPC64_ENTRY__ENDIANESS__BIGENDIAN
#define CURRENT_ENDIANNESS CPUINFO_PPC64_ENTRY__ENDIANESS__BIGENDIAN
#endif
int cpu_init(void)
@@ -83,21 +83,23 @@ int cpu_validate_cpuinfo(void)
goto error;
}
#define CHECK_FEATURE(s,f) do { \
if ((cpu_ppc64_entry->hwcap[s] & f) && \
!(rt_cpuinfo.hwcap[s] & f)) { \
pr_err("CPU Feature %s required by image " \
"is not supported on host.\n", #f); \
goto error; \
} \
} while(0)
#define CHECK_FEATURE(s, f) \
do { \
if ((cpu_ppc64_entry->hwcap[s] & f) && !(rt_cpuinfo.hwcap[s] & f)) { \
pr_err("CPU Feature %s required by image " \
"is not supported on host.\n", \
#f); \
goto error; \
} \
} while (0)
#define REQUIRE_FEATURE(s,f) do { \
if (!(cpu_ppc64_entry->hwcap[s] & f)) { \
#define REQUIRE_FEATURE(s, f) \
do { \
if (!(cpu_ppc64_entry->hwcap[s] & f)) { \
pr_err("CPU Feature %s missing in image.\n", #f); \
goto error; \
} \
} while(0)
goto error; \
} \
} while (0)
REQUIRE_FEATURE(0, PPC_FEATURE_64);
REQUIRE_FEATURE(0, PPC_FEATURE_HAS_FPU);

View File

@@ -53,7 +53,7 @@ static void put_fpu_regs(mcontext_t *mc, UserPpc64FpstateEntry *fpe)
size_t i;
for (i = 0; i < fpe->n_fpregs; i++)
mcfp[i] = fpe->fpregs[i];
mcfp[i] = fpe->fpregs[i];
}
static UserPpc64VrstateEntry *copy_altivec_regs(__vector128 *vrregs)
@@ -69,7 +69,7 @@ static UserPpc64VrstateEntry *copy_altivec_regs(__vector128 *vrregs)
user_ppc64_vrstate_entry__init(vse);
/* protocol buffer store only 64bit entries and we need 128bit */
vse->n_vrregs = (NVRREG-1) * 2;
vse->n_vrregs = (NVRREG - 1) * 2;
vse->vrregs = xmalloc(vse->n_vrregs * sizeof(vse->vrregs[0]));
if (!vse->vrregs) {
xfree(vse);
@@ -77,13 +77,13 @@ static UserPpc64VrstateEntry *copy_altivec_regs(__vector128 *vrregs)
}
/* Vectors are 2*64bits entries */
for (i = 0; i < (NVRREG-1); i++) {
p64 = (uint64_t*) &vrregs[i];
vse->vrregs[i*2] = p64[0];
vse->vrregs[i*2 + 1] = p64[1];
for (i = 0; i < (NVRREG - 1); i++) {
p64 = (uint64_t *)&vrregs[i];
vse->vrregs[i * 2] = p64[0];
vse->vrregs[i * 2 + 1] = p64[1];
}
p32 = (uint32_t*) &vrregs[NVRREG-1];
p32 = (uint32_t *)&vrregs[NVRREG - 1];
vse->vrsave = *p32;
return vse;
@@ -95,7 +95,7 @@ static int put_altivec_regs(mcontext_t *mc, UserPpc64VrstateEntry *vse)
pr_debug("Restoring Altivec registers\n");
if (vse->n_vrregs != (NVRREG-1)*2) {
if (vse->n_vrregs != (NVRREG - 1) * 2) {
pr_err("Corrupted Altivec dump data\n");
return -1;
}
@@ -103,8 +103,7 @@ static int put_altivec_regs(mcontext_t *mc, UserPpc64VrstateEntry *vse)
/* Note that this should only be done in the case MSR_VEC is set but
* this is not a big deal to do that in all cases.
*/
memcpy(&v_regs->vrregs[0][0], vse->vrregs,
sizeof(uint64_t) * 2 * (NVRREG-1));
memcpy(&v_regs->vrregs[0][0], vse->vrregs, sizeof(uint64_t) * 2 * (NVRREG - 1));
/* vscr has been restored with the previous memcpy which copied 32
* 128bits registers + a 128bits field containing the vscr value in
* the low part.
@@ -116,7 +115,7 @@ static int put_altivec_regs(mcontext_t *mc, UserPpc64VrstateEntry *vse)
return 0;
}
static UserPpc64VsxstateEntry* copy_vsx_regs(uint64_t *vsregs)
static UserPpc64VsxstateEntry *copy_vsx_regs(uint64_t *vsregs)
{
UserPpc64VsxstateEntry *vse;
int i;
@@ -128,7 +127,7 @@ static UserPpc64VsxstateEntry* copy_vsx_regs(uint64_t *vsregs)
user_ppc64_vsxstate_entry__init(vse);
vse->n_vsxregs = NVSXREG;
vse->vsxregs = xmalloc(vse->n_vsxregs*sizeof(vse->vsxregs[0]));
vse->vsxregs = xmalloc(vse->n_vsxregs * sizeof(vse->vsxregs[0]));
if (!vse->vsxregs) {
xfree(vse);
return NULL;
@@ -153,25 +152,25 @@ static int put_vsx_regs(mcontext_t *mc, UserPpc64VsxstateEntry *vse)
}
/* point after the Altivec registers */
buf = (uint64_t*) (mc->v_regs + 1);
buf = (uint64_t *)(mc->v_regs + 1);
/* Copy the value saved by get_vsx_regs in the sigframe */
for (i=0; i < vse->n_vsxregs; i++)
for (i = 0; i < vse->n_vsxregs; i++)
buf[i] = vse->vsxregs[i];
return 0;
}
static void copy_gp_regs(UserPpc64RegsEntry *dst, user_regs_struct_t *src)
{
int i;
#define assign_reg(e) do { \
dst->e = (__typeof__(dst->e))src->e; \
} while (0)
#define assign_reg(e) \
do { \
dst->e = (__typeof__(dst->e))src->e; \
} while (0)
for (i=0; i<32; i++)
for (i = 0; i < 32; i++)
assign_reg(gpr[i]);
assign_reg(nip);
assign_reg(msr);
@@ -189,17 +188,17 @@ static void restore_gp_regs(mcontext_t *dst, UserPpc64RegsEntry *src)
int i;
/* r0 to r31 */
for (i=0; i<32; i++)
dst->gp_regs[i] = src->gpr[i];
for (i = 0; i < 32; i++)
dst->gp_regs[i] = src->gpr[i];
dst->gp_regs[PT_NIP] = src->nip;
dst->gp_regs[PT_MSR] = src->msr;
dst->gp_regs[PT_ORIG_R3] = src->orig_gpr3;
dst->gp_regs[PT_CTR] = src->ctr;
dst->gp_regs[PT_LNK] = src->link;
dst->gp_regs[PT_XER] = src->xer;
dst->gp_regs[PT_CCR] = src->ccr;
dst->gp_regs[PT_TRAP] = src->trap;
dst->gp_regs[PT_NIP] = src->nip;
dst->gp_regs[PT_MSR] = src->msr;
dst->gp_regs[PT_ORIG_R3] = src->orig_gpr3;
dst->gp_regs[PT_CTR] = src->ctr;
dst->gp_regs[PT_LNK] = src->link;
dst->gp_regs[PT_XER] = src->xer;
dst->gp_regs[PT_CCR] = src->ccr;
dst->gp_regs[PT_TRAP] = src->trap;
}
static UserPpc64RegsEntry *allocate_gp_regs(void)
@@ -250,7 +249,7 @@ static void xfree_tm_state(UserPpc64TmRegsEntry *tme)
static int put_tm_regs(struct rt_sigframe *f, UserPpc64TmRegsEntry *tme)
{
/*
/*
* WARNING: As stated in kernel's restore_tm_sigcontexts, TEXASR has to be
* restored by the process itself :
* TEXASR was set by the signal delivery reclaim, as was TFIAR.
@@ -261,20 +260,17 @@ static int put_tm_regs(struct rt_sigframe *f, UserPpc64TmRegsEntry *tme)
*/
ucontext_t *tm_uc = &f->uc_transact;
pr_debug("Restoring TM registers FP:%d VR:%d VSX:%d\n",
!!(tme->fpstate), !!(tme->vrstate), !!(tme->vsxstate));
pr_debug("Restoring TM registers FP:%d VR:%d VSX:%d\n", !!(tme->fpstate), !!(tme->vrstate), !!(tme->vsxstate));
restore_gp_regs(&tm_uc->uc_mcontext, tme->gpregs);
if (tme->fpstate)
put_fpu_regs(&tm_uc->uc_mcontext, tme->fpstate);
if (tme->vrstate && put_altivec_regs(&tm_uc->uc_mcontext,
tme->vrstate))
if (tme->vrstate && put_altivec_regs(&tm_uc->uc_mcontext, tme->vrstate))
return -1;
if (tme->vsxstate && put_vsx_regs(&tm_uc->uc_mcontext,
tme->vsxstate))
if (tme->vsxstate && put_vsx_regs(&tm_uc->uc_mcontext, tme->vsxstate))
return -1;
f->uc.uc_link = tm_uc;
@@ -282,8 +278,7 @@ static int put_tm_regs(struct rt_sigframe *f, UserPpc64TmRegsEntry *tme)
}
/****************************************************************************/
static int copy_tm_regs(user_regs_struct_t *regs, user_fpregs_struct_t *fpregs,
CoreEntry *core)
static int copy_tm_regs(user_regs_struct_t *regs, user_fpregs_struct_t *fpregs, CoreEntry *core)
{
UserPpc64TmRegsEntry *tme;
UserPpc64RegsEntry *gpregs = core->ti_ppc64->gpregs;
@@ -299,13 +294,12 @@ static int copy_tm_regs(user_regs_struct_t *regs, user_fpregs_struct_t *fpregs,
if (!tme->gpregs)
goto out_free;
gpregs->has_tfhar = true;
gpregs->tfhar = fpregs->tm.tm_spr_regs.tfhar;
gpregs->has_texasr = true;
gpregs->texasr = fpregs->tm.tm_spr_regs.texasr;
gpregs->has_tfiar = true;
gpregs->tfiar = fpregs->tm.tm_spr_regs.tfiar;
gpregs->has_tfhar = true;
gpregs->tfhar = fpregs->tm.tm_spr_regs.tfhar;
gpregs->has_texasr = true;
gpregs->texasr = fpregs->tm.tm_spr_regs.texasr;
gpregs->has_tfiar = true;
gpregs->tfiar = fpregs->tm.tm_spr_regs.tfiar;
/* This is the checkpointed state, we must save it in place of the
* current state because the signal handler is made in this way.
@@ -352,9 +346,7 @@ out_free:
return -1;
}
static int __copy_task_regs(user_regs_struct_t *regs,
user_fpregs_struct_t *fpregs,
CoreEntry *core)
static int __copy_task_regs(user_regs_struct_t *regs, user_fpregs_struct_t *fpregs, CoreEntry *core)
{
UserPpc64RegsEntry *gpregs;
UserPpc64FpstateEntry **fpstate;
@@ -423,7 +415,7 @@ int arch_alloc_thread_info(CoreEntry *core)
ThreadInfoPpc64 *ti_ppc64;
ti_ppc64 = xmalloc(sizeof(*ti_ppc64));
if(!ti_ppc64)
if (!ti_ppc64)
return -1;
thread_info_ppc64__init(ti_ppc64);
@@ -466,28 +458,24 @@ int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core)
int ret = 0;
if (CORE_THREAD_ARCH_INFO(core)->fpstate)
put_fpu_regs(&sigframe->uc.uc_mcontext,
CORE_THREAD_ARCH_INFO(core)->fpstate);
put_fpu_regs(&sigframe->uc.uc_mcontext, CORE_THREAD_ARCH_INFO(core)->fpstate);
if (CORE_THREAD_ARCH_INFO(core)->vrstate)
ret = put_altivec_regs(&sigframe->uc.uc_mcontext,
CORE_THREAD_ARCH_INFO(core)->vrstate);
ret = put_altivec_regs(&sigframe->uc.uc_mcontext, CORE_THREAD_ARCH_INFO(core)->vrstate);
else if (core->ti_ppc64->gpregs->msr & MSR_VEC) {
pr_err("Register's data mismatch, corrupted image ?\n");
ret = -1;
}
if (!ret && CORE_THREAD_ARCH_INFO(core)->vsxstate)
ret = put_vsx_regs(&sigframe->uc.uc_mcontext,
CORE_THREAD_ARCH_INFO(core)->vsxstate);
ret = put_vsx_regs(&sigframe->uc.uc_mcontext, CORE_THREAD_ARCH_INFO(core)->vsxstate);
else if (core->ti_ppc64->gpregs->msr & MSR_VSX) {
pr_err("VSX register's data mismatch, corrupted image ?\n");
ret = -1;
}
if (!ret && CORE_THREAD_ARCH_INFO(core)->tmstate)
ret = put_tm_regs(sigframe,
CORE_THREAD_ARCH_INFO(core)->tmstate);
ret = put_tm_regs(sigframe, CORE_THREAD_ARCH_INFO(core)->tmstate);
else if (MSR_TM_ACTIVE(core->ti_ppc64->gpregs->msr)) {
pr_err("TM register's data mismatch, corrupted image ?\n");
ret = -1;

View File

@@ -9,35 +9,32 @@
int restore_nonsigframe_gpregs(UserPpc64RegsEntry *r)
{
#define SPRN_TFHAR 128
#define SPRN_TFIAR 129
#define SPRN_TEXASR 130
#define SPRN_TFHAR 128
#define SPRN_TFIAR 129
#define SPRN_TEXASR 130
if (r->has_tfhar) {
asm __volatile__ (
"ld 3, %[value] ;"
"mtspr %[sprn],3 ;"
: [value]"=m"(r->tfhar)
: [sprn]"i"(SPRN_TFHAR)
: "r3");
asm __volatile__("ld 3, %[value] ;"
"mtspr %[sprn],3 ;"
: [value] "=m"(r->tfhar)
: [sprn] "i"(SPRN_TFHAR)
: "r3");
}
if (r->has_tfiar) {
asm __volatile__ (
"ld 3, %[value] ;"
"mtspr %[sprn],3 ;"
: [value]"=m"(r->tfiar)
: [sprn]"i"(SPRN_TFIAR)
: "r3");
asm __volatile__("ld 3, %[value] ;"
"mtspr %[sprn],3 ;"
: [value] "=m"(r->tfiar)
: [sprn] "i"(SPRN_TFIAR)
: "r3");
}
if (r->has_texasr) {
asm __volatile__ (
"ld 3, %[value] ;"
"mtspr %[sprn],3 ;"
: [value]"=m"(r->texasr)
: [sprn]"i"(SPRN_TEXASR)
: "r3");
asm __volatile__("ld 3, %[value] ;"
"mtspr %[sprn],3 ;"
: [value] "=m"(r->texasr)
: [sprn] "i"(SPRN_TEXASR)
: "r3");
}
return 0;
@@ -48,15 +45,14 @@ unsigned long sys_shmat(int shmid, const void *shmaddr, int shmflg)
unsigned long raddr;
int ret;
ret = sys_ipc(21 /*SHMAT */,
shmid, /* first */
shmflg, /* second */
(unsigned long)&raddr, /* third */
shmaddr, /* ptr */
0 /* fifth not used */);
ret = sys_ipc(21 /*SHMAT */, shmid, /* first */
shmflg, /* second */
(unsigned long)&raddr, /* third */
shmaddr, /* ptr */
0 /* fifth not used */);
if (ret)
raddr = (unsigned long) ret;
raddr = (unsigned long)ret;
return raddr;
}

View File

@@ -18,14 +18,12 @@ static inline void update_vregs(mcontext_t *lcontext, mcontext_t *rcontext)
uint64_t offset = (uint64_t)(lcontext->v_regs) - (uint64_t)lcontext;
lcontext->v_regs = (vrregset_t *)((uint64_t)rcontext + offset);
pr_debug("Updated v_regs:%llx (rcontext:%llx)\n",
(unsigned long long) lcontext->v_regs,
(unsigned long long) rcontext);
pr_debug("Updated v_regs:%llx (rcontext:%llx)\n", (unsigned long long)lcontext->v_regs,
(unsigned long long)rcontext);
}
}
int sigreturn_prep_fpu_frame(struct rt_sigframe *frame,
struct rt_sigframe *rframe)
int sigreturn_prep_fpu_frame(struct rt_sigframe *frame, struct rt_sigframe *rframe)
{
uint64_t msr = frame->uc.uc_mcontext.gp_regs[PT_MSR];
@@ -39,9 +37,8 @@ int sigreturn_prep_fpu_frame(struct rt_sigframe *frame,
/* Updating the transactional state address if any */
if (frame->uc.uc_link) {
update_vregs(&frame->uc_transact.uc_mcontext,
&rframe->uc_transact.uc_mcontext);
frame->uc.uc_link = &rframe->uc_transact;
update_vregs(&frame->uc_transact.uc_mcontext, &rframe->uc_transact.uc_mcontext);
frame->uc.uc_link = &rframe->uc_transact;
}
return 0;

View File

@@ -9,7 +9,7 @@
#include "common/bug.h"
#ifdef LOG_PREFIX
# undef LOG_PREFIX
#undef LOG_PREFIX
#endif
#define LOG_PREFIX "vdso: "
@@ -18,15 +18,15 @@ extern char *vdso_trampoline, *vdso_trampoline_end;
static inline void invalidate_caches(unsigned long at)
{
asm volatile("isync \n" \
"li 3,0 \n" \
"dcbf 3,%0 \n" \
"sync \n" \
"icbi 3,%0 \n" \
"isync \n" \
: /* no output */ \
: "r"(at) \
:"memory", "r3");
asm volatile("isync \n"
"li 3,0 \n"
"dcbf 3,%0 \n"
"sync \n"
"icbi 3,%0 \n"
"isync \n"
: /* no output */
: "r"(at)
: "memory", "r3");
}
/* This is the size of the trampoline call :
@@ -34,7 +34,7 @@ static inline void invalidate_caches(unsigned long at)
* bl trampoline
* <64 bit address>
*/
#define TRAMP_CALL_SIZE (2*sizeof(uint32_t) + sizeof(uint64_t))
#define TRAMP_CALL_SIZE (2 * sizeof(uint32_t) + sizeof(uint64_t))
/*
* put_trampoline does 2 things :
@@ -53,39 +53,35 @@ static inline void invalidate_caches(unsigned long at)
*/
static unsigned long put_trampoline(unsigned long at, struct vdso_symtable *sym)
{
int i,j;
int i, j;
unsigned long size;
unsigned long trampoline = 0;
/* First of all we have to find a place where to put the trampoline
* code.
*/
size = (unsigned long)&vdso_trampoline_end
- (unsigned long)&vdso_trampoline;
size = (unsigned long)&vdso_trampoline_end - (unsigned long)&vdso_trampoline;
for (i = 0; i < ARRAY_SIZE(sym->symbols); i++) {
if (vdso_symbol_empty(&sym->symbols[i]))
continue;
pr_debug("Checking '%s' at %lx\n", sym->symbols[i].name,
sym->symbols[i].offset);
pr_debug("Checking '%s' at %lx\n", sym->symbols[i].name, sym->symbols[i].offset);
/* find the nearest following symbol we are interested in */
for (j=0; j < ARRAY_SIZE(sym->symbols); j++) {
if (i==j || vdso_symbol_empty(&sym->symbols[j]))
for (j = 0; j < ARRAY_SIZE(sym->symbols); j++) {
if (i == j || vdso_symbol_empty(&sym->symbols[j]))
continue;
if (sym->symbols[j].offset <= sym->symbols[i].offset)
/* this symbol is above the current one */
continue;
if ((sym->symbols[i].offset+TRAMP_CALL_SIZE) >
sym->symbols[j].offset) {
if ((sym->symbols[i].offset + TRAMP_CALL_SIZE) > sym->symbols[j].offset) {
/* we have a major issue here since we cannot
* even put the trampoline call for this symbol
*/
pr_err("Can't handle small vDSO symbol %s\n",
sym->symbols[i].name);
pr_err("Can't handle small vDSO symbol %s\n", sym->symbols[i].name);
return 0;
}
@@ -93,8 +89,7 @@ static unsigned long put_trampoline(unsigned long at, struct vdso_symtable *sym)
/* no need to put it twice */
continue;
if ((sym->symbols[j].offset -
(sym->symbols[i].offset+TRAMP_CALL_SIZE)) <= size)
if ((sym->symbols[j].offset - (sym->symbols[i].offset + TRAMP_CALL_SIZE)) <= size)
/* not enough place */
continue;
@@ -102,10 +97,8 @@ static unsigned long put_trampoline(unsigned long at, struct vdso_symtable *sym)
trampoline = at + sym->symbols[i].offset;
trampoline += TRAMP_CALL_SIZE;
pr_debug("Putting vDSO trampoline in %s at %lx\n",
sym->symbols[i].name, trampoline);
memcpy((void *)trampoline, &vdso_trampoline,
size);
pr_debug("Putting vDSO trampoline in %s at %lx\n", sym->symbols[i].name, trampoline);
memcpy((void *)trampoline, &vdso_trampoline, size);
invalidate_caches(trampoline);
}
}
@@ -113,21 +106,19 @@ static unsigned long put_trampoline(unsigned long at, struct vdso_symtable *sym)
return trampoline;
}
static inline void put_trampoline_call(unsigned long at, unsigned long to,
unsigned long tr)
static inline void put_trampoline_call(unsigned long at, unsigned long to, unsigned long tr)
{
uint32_t *addr = (uint32_t *)at;
uint32_t *addr = (uint32_t *)at;
*addr++ = 0x7C0802a6; /* mflr r0 */
*addr++ = 0x48000001 | ((long)(tr-at-4) & 0x3fffffc); /* bl tr */
*(uint64_t *)addr = to; /* the address to read by the trampoline */
*addr++ = 0x7C0802a6; /* mflr r0 */
*addr++ = 0x48000001 | ((long)(tr - at - 4) & 0x3fffffc); /* bl tr */
*(uint64_t *)addr = to; /* the address to read by the trampoline */
invalidate_caches(at);
invalidate_caches(at);
}
int vdso_redirect_calls(unsigned long base_to, unsigned long base_from,
struct vdso_symtable *to, struct vdso_symtable *from,
bool __always_unused compat_vdso)
int vdso_redirect_calls(unsigned long base_to, unsigned long base_from, struct vdso_symtable *to,
struct vdso_symtable *from, bool __always_unused compat_vdso)
{
unsigned int i;
unsigned long trampoline;
@@ -140,14 +131,10 @@ int vdso_redirect_calls(unsigned long base_to, unsigned long base_from,
if (vdso_symbol_empty(&from->symbols[i]))
continue;
pr_debug("br: %lx/%lx -> %lx/%lx (index %d) '%s'\n",
base_from, from->symbols[i].offset,
base_to, to->symbols[i].offset, i,
from->symbols[i].name);
pr_debug("br: %lx/%lx -> %lx/%lx (index %d) '%s'\n", base_from, from->symbols[i].offset, base_to,
to->symbols[i].offset, i, from->symbols[i].name);
put_trampoline_call(base_from + from->symbols[i].offset,
base_to + to->symbols[i].offset,
trampoline);
put_trampoline_call(base_from + from->symbols[i].offset, base_to + to->symbols[i].offset, trampoline);
}
return 0;

View File

@@ -1,4 +1,4 @@
#undef LOG_PREFIX
#undef LOG_PREFIX
#define LOG_PREFIX "cpu: "
#include <sys/auxv.h>
@@ -18,22 +18,11 @@
static compel_cpuinfo_t rt_cpuinfo;
static const char *hwcap_str1[64] = {
"HWCAP_S390_ESAN3",
"HWCAP_S390_ZARCH",
"HWCAP_S390_STFLE",
"HWCAP_S390_MSA",
"HWCAP_S390_LDISP",
"HWCAP_S390_EIMM",
"HWCAP_S390_DFP",
"HWCAP_S390_HPAGE",
"HWCAP_S390_ETF3EH",
"HWCAP_S390_HIGH_GPRS",
"HWCAP_S390_TE",
"HWCAP_S390_VXRS",
"HWCAP_S390_VXRS_BCD",
"HWCAP_S390_VXRS_EXT",
"HWCAP_S390_ESAN3", "HWCAP_S390_ZARCH", "HWCAP_S390_STFLE", "HWCAP_S390_MSA", "HWCAP_S390_LDISP",
"HWCAP_S390_EIMM", "HWCAP_S390_DFP", "HWCAP_S390_HPAGE", "HWCAP_S390_ETF3EH", "HWCAP_S390_HIGH_GPRS",
"HWCAP_S390_TE", "HWCAP_S390_VXRS", "HWCAP_S390_VXRS_BCD", "HWCAP_S390_VXRS_EXT",
};
static const char *hwcap_str2[64] = { };
static const char *hwcap_str2[64] = {};
static const char **hwcap_str[2] = { hwcap_str1, hwcap_str2 };
@@ -73,7 +62,7 @@ int cpu_dump_cpuinfo(void)
img = open_image(CR_FD_CPUINFO, O_DUMP);
if (!img)
return -1;
return -1;
cpu_info.s390_entry = &cpu_s390_info_ptr;
cpu_info.n_s390_entry = 1;
@@ -124,11 +113,9 @@ int cpu_validate_cpuinfo(void)
if (rt_cpuinfo.hwcap[nr] & (1 << cap))
continue;
if (hwcap_str[nr][cap])
pr_err("CPU Feature %s not supported on host\n",
hwcap_str[nr][cap]);
pr_err("CPU Feature %s not supported on host\n", hwcap_str[nr][cap]);
else
pr_err("CPU Feature %d/%x not supported on host\n",
nr, 1 << cap);
pr_err("CPU Feature %d/%x not supported on host\n", nr, 1 << cap);
ret = -1;
}
}

View File

@@ -26,12 +26,12 @@
#include "pstree.h"
#include "image.h"
#define NT_PRFPREG 2
#define NT_S390_VXRS_LOW 0x309
#define NT_S390_VXRS_HIGH 0x30a
#define NT_S390_GS_CB 0x30b
#define NT_S390_GS_BC 0x30c
#define NT_S390_RI_CB 0x30d
#define NT_PRFPREG 2
#define NT_S390_VXRS_LOW 0x309
#define NT_S390_VXRS_HIGH 0x30a
#define NT_S390_GS_CB 0x30b
#define NT_S390_GS_BC 0x30c
#define NT_S390_RI_CB 0x30d
/*
* Print general purpose and access registers
@@ -41,8 +41,7 @@ static void print_core_gpregs(const char *msg, UserS390RegsEntry *gpregs)
int i;
pr_debug("%s: General purpose registers\n", msg);
pr_debug(" psw %016lx %016lx\n",
gpregs->psw_mask, gpregs->psw_addr);
pr_debug(" psw %016lx %016lx\n", gpregs->psw_mask, gpregs->psw_addr);
pr_debug(" orig_gpr2 %016lx\n", gpregs->orig_gpr2);
for (i = 0; i < 16; i++)
pr_debug(" g%02d %016lx\n", i, gpregs->gprs[i]);
@@ -69,8 +68,7 @@ static void print_core_vx_regs(CoreEntry *core)
for (i = 0; i < 16; i++)
pr_debug(" vx_low%02d %016lx\n", i, vxrs_low->regs[i]);
for (i = 0; i < 32; i += 2)
pr_debug(" vx_high%02d %016lx %016lx\n", i / 2,
vxrs_high->regs[i], vxrs_high->regs[i + 1]);
pr_debug(" vx_high%02d %016lx %016lx\n", i / 2, vxrs_high->regs[i], vxrs_high->regs[i + 1]);
}
/*
@@ -395,10 +393,8 @@ int restore_fpu(struct rt_sigframe *f, CoreEntry *core)
dst->fpregs.fpc = fpregs->fpc;
memcpy(dst->fpregs.fprs, fpregs->fprs, sizeof(dst->fpregs.fprs));
if (vxrs_low) {
memcpy(&dst_ext->vxrs_low, vxrs_low->regs,
sizeof(dst_ext->vxrs_low));
memcpy(&dst_ext->vxrs_high, vxrs_high->regs,
sizeof(dst_ext->vxrs_high));
memcpy(&dst_ext->vxrs_low, vxrs_low->regs, sizeof(dst_ext->vxrs_low));
memcpy(&dst_ext->vxrs_high, vxrs_high->regs, sizeof(dst_ext->vxrs_high));
}
return 0;
}
@@ -697,10 +693,8 @@ static int set_task_regs(pid_t pid, CoreEntry *core)
if (!cvxrs_high)
return -1;
fpregs.flags |= USER_FPREGS_VXRS;
memcpy(&fpregs.vxrs_low, cvxrs_low->regs,
sizeof(fpregs.vxrs_low));
memcpy(&fpregs.vxrs_high, cvxrs_high->regs,
sizeof(fpregs.vxrs_high));
memcpy(&fpregs.vxrs_low, cvxrs_low->regs, sizeof(fpregs.vxrs_low));
memcpy(&fpregs.vxrs_high, cvxrs_high->regs, sizeof(fpregs.vxrs_high));
if (set_vx_regs(pid, &fpregs) < 0)
return -1;
}
@@ -720,19 +714,15 @@ int arch_set_thread_regs(struct pstree_item *item, bool with_threads)
int i;
for_each_pstree_item(item) {
if (item->pid->state == TASK_DEAD ||
item->pid->state == TASK_ZOMBIE)
if (item->pid->state == TASK_DEAD || item->pid->state == TASK_ZOMBIE)
continue;
for (i = 0; i < item->nr_threads; i++) {
if (item->threads[i].state == TASK_DEAD ||
item->threads[i].state == TASK_ZOMBIE)
if (item->threads[i].state == TASK_DEAD || item->threads[i].state == TASK_ZOMBIE)
continue;
if (!with_threads && i > 0)
continue;
if (set_task_regs(item->threads[i].real,
item->core[i])) {
pr_perror("Not set registers for task %d",
item->threads[i].real);
if (set_task_regs(item->threads[i].real, item->core[i])) {
pr_perror("Not set registers for task %d", item->threads[i].real);
return -1;
}
}

View File

@@ -23,15 +23,14 @@ unsigned long sys_shmat(int shmid, const void *shmaddr, int shmflg)
unsigned long raddr;
int ret;
ret = sys_ipc(21 /*SHMAT */,
shmid, /* first */
shmflg, /* second */
(unsigned long)&raddr, /* third */
shmaddr, /* ptr */
0 /* fifth not used */);
ret = sys_ipc(21 /*SHMAT */, shmid, /* first */
shmflg, /* second */
(unsigned long)&raddr, /* third */
shmaddr, /* ptr */
0 /* fifth not used */);
if (ret)
raddr = (unsigned long) ret;
raddr = (unsigned long)ret;
return raddr;
}

View File

@@ -13,8 +13,7 @@
* - sigframe : Pointer to local signal frame
* - rsigframe: Pointer to remote signal frame of inferior
*/
int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe,
struct rt_sigframe *rsigframe)
int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe, struct rt_sigframe *rsigframe)
{
return 0;
}

View File

@@ -9,7 +9,7 @@
#include "common/bug.h"
#ifdef LOG_PREFIX
# undef LOG_PREFIX
#undef LOG_PREFIX
#endif
#define LOG_PREFIX "vdso: "
@@ -17,11 +17,11 @@
* Trampoline instruction sequence
*/
typedef struct {
u8 larl[6]; /* Load relative address of imm64 */
u8 lg[6]; /* Load %r1 with imm64 */
u8 br[2]; /* Branch to %r1 */
u64 addr; /* Jump address */
u32 guards; /* Guard bytes */
u8 larl[6]; /* Load relative address of imm64 */
u8 lg[6]; /* Load %r1 with imm64 */
u8 br[2]; /* Branch to %r1 */
u64 addr; /* Jump address */
u32 guards; /* Guard bytes */
} __packed jmp_t;
/*
@@ -29,21 +29,20 @@ typedef struct {
*/
jmp_t jmp = {
/* larl %r1,e (addr) */
.larl = {0xc0, 0x10, 0x00, 0x00, 0x00, 0x07},
.larl = { 0xc0, 0x10, 0x00, 0x00, 0x00, 0x07 },
/* lg %r1,0(%r1) */
.lg = {0xe3, 0x10, 0x10, 0x00, 0x00, 0x04},
.lg = { 0xe3, 0x10, 0x10, 0x00, 0x00, 0x04 },
/* br %r1 */
.br = {0x07, 0xf1},
.guards = 0xcccccccc,
.br = { 0x07, 0xf1 },
.guards = 0xcccccccc,
};
/*
* Insert trampoline code into old vdso entry points to
* jump to new vdso functions.
*/
int vdso_redirect_calls(unsigned long base_to, unsigned long base_from,
struct vdso_symtable *to, struct vdso_symtable *from,
bool __always_unused compat_vdso)
int vdso_redirect_calls(unsigned long base_to, unsigned long base_from, struct vdso_symtable *to,
struct vdso_symtable *from, bool __always_unused compat_vdso)
{
unsigned int i;
@@ -51,14 +50,11 @@ int vdso_redirect_calls(unsigned long base_to, unsigned long base_from,
if (vdso_symbol_empty(&from->symbols[i]))
continue;
pr_debug("jmp: %s: %lx/%lx -> %lx/%lx (index %d)\n",
from->symbols[i].name, base_from,
from->symbols[i].offset,
base_to, to->symbols[i].offset, i);
pr_debug("jmp: %s: %lx/%lx -> %lx/%lx (index %d)\n", from->symbols[i].name, base_from,
from->symbols[i].offset, base_to, to->symbols[i].offset, i);
jmp.addr = base_to + to->symbols[i].offset;
memcpy((void *)(base_from + from->symbols[i].offset), &jmp,
sizeof(jmp));
memcpy((void *)(base_from + from->symbols[i].offset), &jmp, sizeof(jmp));
}
return 0;

View File

@@ -23,7 +23,7 @@
#include "protobuf.h"
#include "images/cpuinfo.pb-c.h"
#undef LOG_PREFIX
#undef LOG_PREFIX
#define LOG_PREFIX "cpu: "
static compel_cpuinfo_t rt_cpu_info;
@@ -55,12 +55,9 @@ int cpu_init(void)
}
pr_debug("fpu:%d fxsr:%d xsave:%d xsaveopt:%d xsavec:%d xgetbv1:%d xsaves:%d\n",
!!compel_cpu_has_feature(X86_FEATURE_FPU),
!!compel_cpu_has_feature(X86_FEATURE_FXSR),
!!compel_cpu_has_feature(X86_FEATURE_OSXSAVE),
!!compel_cpu_has_feature(X86_FEATURE_XSAVEOPT),
!!compel_cpu_has_feature(X86_FEATURE_XSAVEC),
!!compel_cpu_has_feature(X86_FEATURE_XGETBV1),
!!compel_cpu_has_feature(X86_FEATURE_FPU), !!compel_cpu_has_feature(X86_FEATURE_FXSR),
!!compel_cpu_has_feature(X86_FEATURE_OSXSAVE), !!compel_cpu_has_feature(X86_FEATURE_XSAVEOPT),
!!compel_cpu_has_feature(X86_FEATURE_XSAVEC), !!compel_cpu_has_feature(X86_FEATURE_XGETBV1),
!!compel_cpu_has_feature(X86_FEATURE_XSAVES));
return cpu_has_unsupported_features() ? -1 : 0;
@@ -77,25 +74,24 @@ int cpu_dump_cpuinfo(void)
if (!img)
return -1;
cpu_info.x86_entry = &cpu_x86_info_ptr;
cpu_info.n_x86_entry = 1;
cpu_info.x86_entry = &cpu_x86_info_ptr;
cpu_info.n_x86_entry = 1;
cpu_x86_info.vendor_id = (rt_cpu_info.x86_vendor == X86_VENDOR_INTEL) ?
CPUINFO_X86_ENTRY__VENDOR__INTEL :
CPUINFO_X86_ENTRY__VENDOR__AMD;
cpu_x86_info.vendor_id = (rt_cpu_info.x86_vendor == X86_VENDOR_INTEL) ? CPUINFO_X86_ENTRY__VENDOR__INTEL :
CPUINFO_X86_ENTRY__VENDOR__AMD;
cpu_x86_info.cpu_family = rt_cpu_info.x86_family;
cpu_x86_info.model = rt_cpu_info.x86_model;
cpu_x86_info.stepping = rt_cpu_info.x86_mask;
cpu_x86_info.capability_ver = 2;
cpu_x86_info.n_capability = ARRAY_SIZE(rt_cpu_info.x86_capability);
cpu_x86_info.capability = (void *)rt_cpu_info.x86_capability;
cpu_x86_info.has_xfeatures_mask = true;
cpu_x86_info.xfeatures_mask = rt_cpu_info.xfeatures_mask;
cpu_x86_info.has_xsave_size = true;
cpu_x86_info.xsave_size = rt_cpu_info.xsave_size;
cpu_x86_info.has_xsave_size_max = true;
cpu_x86_info.xsave_size_max = rt_cpu_info.xsave_size_max;
cpu_x86_info.cpu_family = rt_cpu_info.x86_family;
cpu_x86_info.model = rt_cpu_info.x86_model;
cpu_x86_info.stepping = rt_cpu_info.x86_mask;
cpu_x86_info.capability_ver = 2;
cpu_x86_info.n_capability = ARRAY_SIZE(rt_cpu_info.x86_capability);
cpu_x86_info.capability = (void *)rt_cpu_info.x86_capability;
cpu_x86_info.has_xfeatures_mask = true;
cpu_x86_info.xfeatures_mask = rt_cpu_info.xfeatures_mask;
cpu_x86_info.has_xsave_size = true;
cpu_x86_info.xsave_size = rt_cpu_info.xsave_size;
cpu_x86_info.has_xsave_size_max = true;
cpu_x86_info.xsave_size_max = rt_cpu_info.xsave_size_max;
if (rt_cpu_info.x86_model_id[0])
cpu_x86_info.model_id = rt_cpu_info.x86_model_id;
@@ -109,102 +105,65 @@ int cpu_dump_cpuinfo(void)
return 0;
}
#define __ins_bit(__l, __v) (1u << ((__v) - 32u * (__l)))
#define __ins_bit(__l, __v) (1u << ((__v)-32u * (__l)))
static uint32_t x86_ins_capability_mask[NCAPINTS] = {
[CPUID_1_EDX] =
__ins_bit(CPUID_1_EDX, X86_FEATURE_FPU) |
__ins_bit(CPUID_1_EDX, X86_FEATURE_TSC) |
__ins_bit(CPUID_1_EDX, X86_FEATURE_CX8) |
__ins_bit(CPUID_1_EDX, X86_FEATURE_SEP) |
__ins_bit(CPUID_1_EDX, X86_FEATURE_CMOV) |
__ins_bit(CPUID_1_EDX, X86_FEATURE_CLFLUSH) |
__ins_bit(CPUID_1_EDX, X86_FEATURE_MMX) |
__ins_bit(CPUID_1_EDX, X86_FEATURE_FXSR) |
__ins_bit(CPUID_1_EDX, X86_FEATURE_XMM) |
__ins_bit(CPUID_1_EDX, X86_FEATURE_XMM2),
[CPUID_1_EDX] = __ins_bit(CPUID_1_EDX, X86_FEATURE_FPU) | __ins_bit(CPUID_1_EDX, X86_FEATURE_TSC) |
__ins_bit(CPUID_1_EDX, X86_FEATURE_CX8) | __ins_bit(CPUID_1_EDX, X86_FEATURE_SEP) |
__ins_bit(CPUID_1_EDX, X86_FEATURE_CMOV) | __ins_bit(CPUID_1_EDX, X86_FEATURE_CLFLUSH) |
__ins_bit(CPUID_1_EDX, X86_FEATURE_MMX) | __ins_bit(CPUID_1_EDX, X86_FEATURE_FXSR) |
__ins_bit(CPUID_1_EDX, X86_FEATURE_XMM) | __ins_bit(CPUID_1_EDX, X86_FEATURE_XMM2),
[CPUID_8000_0001_EDX] =
__ins_bit(CPUID_8000_0001_EDX, X86_FEATURE_SYSCALL) |
__ins_bit(CPUID_8000_0001_EDX, X86_FEATURE_MMXEXT) |
__ins_bit(CPUID_8000_0001_EDX, X86_FEATURE_RDTSCP) |
__ins_bit(CPUID_8000_0001_EDX, X86_FEATURE_3DNOWEXT) |
__ins_bit(CPUID_8000_0001_EDX, X86_FEATURE_3DNOW),
[CPUID_8000_0001_EDX] = __ins_bit(CPUID_8000_0001_EDX, X86_FEATURE_SYSCALL) |
__ins_bit(CPUID_8000_0001_EDX, X86_FEATURE_MMXEXT) |
__ins_bit(CPUID_8000_0001_EDX, X86_FEATURE_RDTSCP) |
__ins_bit(CPUID_8000_0001_EDX, X86_FEATURE_3DNOWEXT) |
__ins_bit(CPUID_8000_0001_EDX, X86_FEATURE_3DNOW),
[CPUID_LNX_1] =
__ins_bit(CPUID_LNX_1, X86_FEATURE_REP_GOOD) |
__ins_bit(CPUID_LNX_1, X86_FEATURE_NOPL),
[CPUID_LNX_1] = __ins_bit(CPUID_LNX_1, X86_FEATURE_REP_GOOD) | __ins_bit(CPUID_LNX_1, X86_FEATURE_NOPL),
[CPUID_1_ECX] =
__ins_bit(CPUID_1_ECX, X86_FEATURE_XMM3) |
__ins_bit(CPUID_1_ECX, X86_FEATURE_PCLMULQDQ) |
__ins_bit(CPUID_1_ECX, X86_FEATURE_MWAIT) |
__ins_bit(CPUID_1_ECX, X86_FEATURE_SSSE3) |
__ins_bit(CPUID_1_ECX, X86_FEATURE_CX16) |
__ins_bit(CPUID_1_ECX, X86_FEATURE_XMM4_1) |
__ins_bit(CPUID_1_ECX, X86_FEATURE_XMM4_2) |
__ins_bit(CPUID_1_ECX, X86_FEATURE_MOVBE) |
__ins_bit(CPUID_1_ECX, X86_FEATURE_POPCNT) |
__ins_bit(CPUID_1_ECX, X86_FEATURE_AES) |
__ins_bit(CPUID_1_ECX, X86_FEATURE_XSAVE) |
__ins_bit(CPUID_1_ECX, X86_FEATURE_OSXSAVE) |
__ins_bit(CPUID_1_ECX, X86_FEATURE_AVX) |
__ins_bit(CPUID_1_ECX, X86_FEATURE_F16C) |
__ins_bit(CPUID_1_ECX, X86_FEATURE_RDRAND),
[CPUID_1_ECX] = __ins_bit(CPUID_1_ECX, X86_FEATURE_XMM3) | __ins_bit(CPUID_1_ECX, X86_FEATURE_PCLMULQDQ) |
__ins_bit(CPUID_1_ECX, X86_FEATURE_MWAIT) | __ins_bit(CPUID_1_ECX, X86_FEATURE_SSSE3) |
__ins_bit(CPUID_1_ECX, X86_FEATURE_CX16) | __ins_bit(CPUID_1_ECX, X86_FEATURE_XMM4_1) |
__ins_bit(CPUID_1_ECX, X86_FEATURE_XMM4_2) | __ins_bit(CPUID_1_ECX, X86_FEATURE_MOVBE) |
__ins_bit(CPUID_1_ECX, X86_FEATURE_POPCNT) | __ins_bit(CPUID_1_ECX, X86_FEATURE_AES) |
__ins_bit(CPUID_1_ECX, X86_FEATURE_XSAVE) | __ins_bit(CPUID_1_ECX, X86_FEATURE_OSXSAVE) |
__ins_bit(CPUID_1_ECX, X86_FEATURE_AVX) | __ins_bit(CPUID_1_ECX, X86_FEATURE_F16C) |
__ins_bit(CPUID_1_ECX, X86_FEATURE_RDRAND),
[CPUID_8000_0001_ECX] =
__ins_bit(CPUID_8000_0001_ECX, X86_FEATURE_ABM) |
__ins_bit(CPUID_8000_0001_ECX, X86_FEATURE_SSE4A) |
__ins_bit(CPUID_8000_0001_ECX, X86_FEATURE_MISALIGNSSE) |
__ins_bit(CPUID_8000_0001_ECX, X86_FEATURE_3DNOWPREFETCH) |
__ins_bit(CPUID_8000_0001_ECX, X86_FEATURE_XOP) |
__ins_bit(CPUID_8000_0001_ECX, X86_FEATURE_FMA4) |
__ins_bit(CPUID_8000_0001_ECX, X86_FEATURE_ABM) | __ins_bit(CPUID_8000_0001_ECX, X86_FEATURE_SSE4A) |
__ins_bit(CPUID_8000_0001_ECX, X86_FEATURE_MISALIGNSSE) |
__ins_bit(CPUID_8000_0001_ECX, X86_FEATURE_3DNOWPREFETCH) |
__ins_bit(CPUID_8000_0001_ECX, X86_FEATURE_XOP) | __ins_bit(CPUID_8000_0001_ECX, X86_FEATURE_FMA4) |
__ins_bit(CPUID_8000_0001_ECX, X86_FEATURE_TBM),
[CPUID_7_0_EBX] =
__ins_bit(CPUID_7_0_EBX, X86_FEATURE_FSGSBASE) |
__ins_bit(CPUID_7_0_EBX, X86_FEATURE_BMI1) |
__ins_bit(CPUID_7_0_EBX, X86_FEATURE_HLE) |
__ins_bit(CPUID_7_0_EBX, X86_FEATURE_AVX2) |
__ins_bit(CPUID_7_0_EBX, X86_FEATURE_BMI2) |
__ins_bit(CPUID_7_0_EBX, X86_FEATURE_ERMS) |
__ins_bit(CPUID_7_0_EBX, X86_FEATURE_RTM) |
__ins_bit(CPUID_7_0_EBX, X86_FEATURE_MPX) |
__ins_bit(CPUID_7_0_EBX, X86_FEATURE_AVX512F) |
__ins_bit(CPUID_7_0_EBX, X86_FEATURE_AVX512DQ) |
__ins_bit(CPUID_7_0_EBX, X86_FEATURE_RDSEED) |
__ins_bit(CPUID_7_0_EBX, X86_FEATURE_ADX) |
__ins_bit(CPUID_7_0_EBX, X86_FEATURE_CLFLUSHOPT) |
__ins_bit(CPUID_7_0_EBX, X86_FEATURE_AVX512PF) |
__ins_bit(CPUID_7_0_EBX, X86_FEATURE_AVX512ER) |
__ins_bit(CPUID_7_0_EBX, X86_FEATURE_AVX512CD) |
__ins_bit(CPUID_7_0_EBX, X86_FEATURE_SHA_NI) |
__ins_bit(CPUID_7_0_EBX, X86_FEATURE_AVX512BW) |
__ins_bit(CPUID_7_0_EBX, X86_FEATURE_FSGSBASE) | __ins_bit(CPUID_7_0_EBX, X86_FEATURE_BMI1) |
__ins_bit(CPUID_7_0_EBX, X86_FEATURE_HLE) | __ins_bit(CPUID_7_0_EBX, X86_FEATURE_AVX2) |
__ins_bit(CPUID_7_0_EBX, X86_FEATURE_BMI2) | __ins_bit(CPUID_7_0_EBX, X86_FEATURE_ERMS) |
__ins_bit(CPUID_7_0_EBX, X86_FEATURE_RTM) | __ins_bit(CPUID_7_0_EBX, X86_FEATURE_MPX) |
__ins_bit(CPUID_7_0_EBX, X86_FEATURE_AVX512F) | __ins_bit(CPUID_7_0_EBX, X86_FEATURE_AVX512DQ) |
__ins_bit(CPUID_7_0_EBX, X86_FEATURE_RDSEED) | __ins_bit(CPUID_7_0_EBX, X86_FEATURE_ADX) |
__ins_bit(CPUID_7_0_EBX, X86_FEATURE_CLFLUSHOPT) | __ins_bit(CPUID_7_0_EBX, X86_FEATURE_AVX512PF) |
__ins_bit(CPUID_7_0_EBX, X86_FEATURE_AVX512ER) | __ins_bit(CPUID_7_0_EBX, X86_FEATURE_AVX512CD) |
__ins_bit(CPUID_7_0_EBX, X86_FEATURE_SHA_NI) | __ins_bit(CPUID_7_0_EBX, X86_FEATURE_AVX512BW) |
__ins_bit(CPUID_7_0_EBX, X86_FEATURE_AVX512VL),
[CPUID_D_1_EAX] =
__ins_bit(CPUID_D_1_EAX, X86_FEATURE_XSAVEOPT) |
__ins_bit(CPUID_D_1_EAX, X86_FEATURE_XSAVEC) |
__ins_bit(CPUID_D_1_EAX, X86_FEATURE_XGETBV1),
[CPUID_D_1_EAX] = __ins_bit(CPUID_D_1_EAX, X86_FEATURE_XSAVEOPT) |
__ins_bit(CPUID_D_1_EAX, X86_FEATURE_XSAVEC) | __ins_bit(CPUID_D_1_EAX, X86_FEATURE_XGETBV1),
[CPUID_7_0_ECX] =
__ins_bit(CPUID_7_0_ECX, X86_FEATURE_AVX512VBMI) |
__ins_bit(CPUID_7_0_ECX, X86_FEATURE_AVX512_VBMI2) |
__ins_bit(CPUID_7_0_ECX, X86_FEATURE_GFNI) |
__ins_bit(CPUID_7_0_ECX, X86_FEATURE_VAES) |
__ins_bit(CPUID_7_0_ECX, X86_FEATURE_VPCLMULQDQ) |
__ins_bit(CPUID_7_0_ECX, X86_FEATURE_AVX512_VNNI) |
__ins_bit(CPUID_7_0_ECX, X86_FEATURE_AVX512_BITALG) |
__ins_bit(CPUID_7_0_ECX, X86_FEATURE_TME) |
__ins_bit(CPUID_7_0_ECX, X86_FEATURE_AVX512_VPOPCNTDQ) |
__ins_bit(CPUID_7_0_ECX, X86_FEATURE_RDPID),
__ins_bit(CPUID_7_0_ECX, X86_FEATURE_AVX512VBMI) | __ins_bit(CPUID_7_0_ECX, X86_FEATURE_AVX512_VBMI2) |
__ins_bit(CPUID_7_0_ECX, X86_FEATURE_GFNI) | __ins_bit(CPUID_7_0_ECX, X86_FEATURE_VAES) |
__ins_bit(CPUID_7_0_ECX, X86_FEATURE_VPCLMULQDQ) | __ins_bit(CPUID_7_0_ECX, X86_FEATURE_AVX512_VNNI) |
__ins_bit(CPUID_7_0_ECX, X86_FEATURE_AVX512_BITALG) | __ins_bit(CPUID_7_0_ECX, X86_FEATURE_TME) |
__ins_bit(CPUID_7_0_ECX, X86_FEATURE_AVX512_VPOPCNTDQ) | __ins_bit(CPUID_7_0_ECX, X86_FEATURE_RDPID),
[CPUID_8000_0008_EBX] =
__ins_bit(CPUID_8000_0008_EBX, X86_FEATURE_CLZERO),
[CPUID_8000_0008_EBX] = __ins_bit(CPUID_8000_0008_EBX, X86_FEATURE_CLZERO),
[CPUID_7_0_EDX] =
__ins_bit(CPUID_7_0_EDX, X86_FEATURE_AVX512_4VNNIW) |
__ins_bit(CPUID_7_0_EDX, X86_FEATURE_AVX512_4FMAPS),
[CPUID_7_0_EDX] = __ins_bit(CPUID_7_0_EDX, X86_FEATURE_AVX512_4VNNIW) |
__ins_bit(CPUID_7_0_EDX, X86_FEATURE_AVX512_4FMAPS),
};
#undef __ins_bit
@@ -243,20 +202,14 @@ static int cpu_validate_features(compel_cpuinfo_t *cpu_info)
* rest of mismatches won't cause problems.
*/
#define __mismatch_fpu_bit(__bit) \
(test_bit(__bit, (void *)cpu_info->x86_capability) && \
!compel_cpu_has_feature(__bit))
if (__mismatch_fpu_bit(X86_FEATURE_FPU) ||
__mismatch_fpu_bit(X86_FEATURE_FXSR) ||
__mismatch_fpu_bit(X86_FEATURE_OSXSAVE) ||
__mismatch_fpu_bit(X86_FEATURE_XSAVES)) {
#define __mismatch_fpu_bit(__bit) (test_bit(__bit, (void *)cpu_info->x86_capability) && !compel_cpu_has_feature(__bit))
if (__mismatch_fpu_bit(X86_FEATURE_FPU) || __mismatch_fpu_bit(X86_FEATURE_FXSR) ||
__mismatch_fpu_bit(X86_FEATURE_OSXSAVE) || __mismatch_fpu_bit(X86_FEATURE_XSAVES)) {
pr_err("FPU feature required by image "
"is not supported on host "
"(fpu:%d fxsr:%d osxsave:%d xsaves:%d)\n",
__mismatch_fpu_bit(X86_FEATURE_FPU),
__mismatch_fpu_bit(X86_FEATURE_FXSR),
__mismatch_fpu_bit(X86_FEATURE_OSXSAVE),
__mismatch_fpu_bit(X86_FEATURE_XSAVES));
__mismatch_fpu_bit(X86_FEATURE_FPU), __mismatch_fpu_bit(X86_FEATURE_FXSR),
__mismatch_fpu_bit(X86_FEATURE_OSXSAVE), __mismatch_fpu_bit(X86_FEATURE_XSAVES));
return -1;
}
#undef __mismatch_fpu_bit
@@ -266,10 +219,8 @@ static int cpu_validate_features(compel_cpuinfo_t *cpu_info)
* the destination there are all the features which were on the
* source.
*/
if ((m = cpu_info->xfeatures_mask &
~rt_cpu_info.xfeatures_mask)) {
pr_err("CPU xfeatures has unsupported bits (%#"
PRIx64")\n", m);
if ((m = cpu_info->xfeatures_mask & ~rt_cpu_info.xfeatures_mask)) {
pr_err("CPU xfeatures has unsupported bits (%#" PRIx64 ")\n", m);
return -1;
}
@@ -281,13 +232,11 @@ static int cpu_validate_features(compel_cpuinfo_t *cpu_info)
* greedy feature mask causing programs to misbehave.
*/
if (cpu_info->xsave_size != rt_cpu_info.xsave_size) {
pr_err("CPU xsave size mismatch (%u/%u)\n",
cpu_info->xsave_size, rt_cpu_info.xsave_size);
pr_err("CPU xsave size mismatch (%u/%u)\n", cpu_info->xsave_size, rt_cpu_info.xsave_size);
return -1;
}
if (cpu_info->xsave_size_max != rt_cpu_info.xsave_size_max) {
pr_err("CPU xsave max size mismatch (%u/%u)\n",
cpu_info->xsave_size_max,
pr_err("CPU xsave max size mismatch (%u/%u)\n", cpu_info->xsave_size_max,
rt_cpu_info.xsave_size_max);
return -1;
}
@@ -305,8 +254,7 @@ static int cpu_validate_features(compel_cpuinfo_t *cpu_info)
* Strict capability mode. Everything must match.
*/
if (opts.cpu_cap & CPU_CAP_CPU) {
if (memcmp(cpu_info->x86_capability, rt_cpu_info.x86_capability,
sizeof(cpu_info->x86_capability))) {
if (memcmp(cpu_info->x86_capability, rt_cpu_info.x86_capability, sizeof(cpu_info->x86_capability))) {
pr_err("CPU capabilities do not match run time\n");
return -1;
}
@@ -316,8 +264,8 @@ static int cpu_validate_features(compel_cpuinfo_t *cpu_info)
}
static const struct {
const uint32_t capability_ver;
const uint32_t ncapints;
const uint32_t capability_ver;
const uint32_t ncapints;
} ncapints[] = {
{ .capability_ver = 1, .ncapints = NCAPINTS_V1 },
{ .capability_ver = 2, .ncapints = NCAPINTS_V2 },
@@ -328,14 +276,12 @@ static compel_cpuinfo_t *img_to_cpuinfo(CpuinfoX86Entry *img_x86_entry)
compel_cpuinfo_t *cpu_info;
size_t size, i;
BUILD_BUG_ON(sizeof(img_x86_entry->capability[0]) !=
sizeof(cpu_info->x86_capability[0]));
BUILD_BUG_ON(sizeof(img_x86_entry->capability[0]) != sizeof(cpu_info->x86_capability[0]));
BUILD_BUG_ON(ARRAY_SIZE(rt_cpu_info.x86_capability) != NCAPINTS);
if (img_x86_entry->vendor_id != CPUINFO_X86_ENTRY__VENDOR__INTEL &&
img_x86_entry->vendor_id != CPUINFO_X86_ENTRY__VENDOR__AMD) {
pr_err("Image carries unknown vendor %u\n",
(unsigned)img_x86_entry->vendor_id);
pr_err("Image carries unknown vendor %u\n", (unsigned)img_x86_entry->vendor_id);
return NULL;
}
@@ -343,8 +289,7 @@ static compel_cpuinfo_t *img_to_cpuinfo(CpuinfoX86Entry *img_x86_entry)
if (img_x86_entry->capability_ver == ncapints[i].capability_ver) {
if (img_x86_entry->n_capability != ncapints[i].ncapints) {
pr_err("Image carries %u words while %u expected\n",
(unsigned)img_x86_entry->n_capability,
(unsigned)ncapints[i].ncapints);
(unsigned)img_x86_entry->n_capability, (unsigned)ncapints[i].ncapints);
return NULL;
}
break;
@@ -352,8 +297,7 @@ static compel_cpuinfo_t *img_to_cpuinfo(CpuinfoX86Entry *img_x86_entry)
}
if (i >= ARRAY_SIZE(ncapints)) {
pr_err("Image carries unknown capability version %d\n",
(unsigned)img_x86_entry->capability_ver);
pr_err("Image carries unknown capability version %d\n", (unsigned)img_x86_entry->capability_ver);
return NULL;
}
@@ -368,21 +312,20 @@ static compel_cpuinfo_t *img_to_cpuinfo(CpuinfoX86Entry *img_x86_entry)
size = sizeof(img_x86_entry->capability[0]) * img_x86_entry->n_capability;
memcpy(cpu_info->x86_capability, img_x86_entry->capability, size);
if (img_x86_entry->capability_ver == 1) {
memcpy(&cpu_info->x86_capability[NCAPINTS_V1],
&rt_cpu_info.x86_capability[NCAPINTS_V1],
memcpy(&cpu_info->x86_capability[NCAPINTS_V1], &rt_cpu_info.x86_capability[NCAPINTS_V1],
(NCAPINTS_V2 - NCAPINTS_V1) * sizeof(rt_cpu_info.x86_capability[0]));
}
if (img_x86_entry->vendor_id == CPUINFO_X86_ENTRY__VENDOR__INTEL)
cpu_info->x86_vendor = X86_VENDOR_INTEL;
cpu_info->x86_vendor = X86_VENDOR_INTEL;
else
cpu_info->x86_vendor = X86_VENDOR_AMD;
cpu_info->x86_family = img_x86_entry->cpu_family;
cpu_info->x86_model = img_x86_entry->model;
cpu_info->x86_mask = img_x86_entry->stepping;
cpu_info->extended_cpuid_level = rt_cpu_info.extended_cpuid_level;
cpu_info->cpuid_level = rt_cpu_info.cpuid_level;
cpu_info->x86_power = rt_cpu_info.x86_power;
cpu_info->x86_vendor = X86_VENDOR_AMD;
cpu_info->x86_family = img_x86_entry->cpu_family;
cpu_info->x86_model = img_x86_entry->model;
cpu_info->x86_mask = img_x86_entry->stepping;
cpu_info->extended_cpuid_level = rt_cpu_info.extended_cpuid_level;
cpu_info->cpuid_level = rt_cpu_info.cpuid_level;
cpu_info->x86_power = rt_cpu_info.x86_power;
memcpy(cpu_info->x86_vendor_id, rt_cpu_info.x86_model_id, sizeof(cpu_info->x86_vendor_id));
strncpy(cpu_info->x86_model_id, img_x86_entry->model_id, sizeof(cpu_info->x86_model_id) - 1);

View File

@@ -13,30 +13,31 @@
#undef LOG_PREFIX
#define LOG_PREFIX "x86: "
#define XSAVE_PB_NELEMS(__s, __obj, __member) \
(sizeof(__s) / sizeof(*(__obj)->__member))
#define XSAVE_PB_NELEMS(__s, __obj, __member) (sizeof(__s) / sizeof(*(__obj)->__member))
int save_task_regs(void *x, user_regs_struct_t *regs, user_fpregs_struct_t *fpregs)
{
CoreEntry *core = x;
UserX86RegsEntry *gpregs = core->thread_info->gpregs;
UserX86RegsEntry *gpregs = core->thread_info->gpregs;
#define assign_reg(dst, src, e) do { dst->e = (__typeof__(dst->e))src.e; } while (0)
#define assign_array(dst, src, e) memcpy(dst->e, &src.e, sizeof(src.e))
#define assign_xsave(feature, xsave, member, area) \
do { \
if (compel_fpu_has_feature(feature)) { \
uint32_t off = compel_fpu_feature_offset(feature); \
void *from = &area[off]; \
size_t size = pb_repeated_size(xsave, member); \
size_t xsize = (size_t)compel_fpu_feature_size(feature); \
if (xsize != size) { \
pr_err("%s reported %zu bytes (expecting %zu)\n", \
# feature, xsize, size); \
return -1; \
} \
memcpy(xsave->member, from, size); \
} \
#define assign_reg(dst, src, e) \
do { \
dst->e = (__typeof__(dst->e))src.e; \
} while (0)
#define assign_array(dst, src, e) memcpy(dst->e, &src.e, sizeof(src.e))
#define assign_xsave(feature, xsave, member, area) \
do { \
if (compel_fpu_has_feature(feature)) { \
uint32_t off = compel_fpu_feature_offset(feature); \
void *from = &area[off]; \
size_t size = pb_repeated_size(xsave, member); \
size_t xsize = (size_t)compel_fpu_feature_size(feature); \
if (xsize != size) { \
pr_err("%s reported %zu bytes (expecting %zu)\n", #feature, xsize, size); \
return -1; \
} \
memcpy(xsave->member, from, size); \
} \
} while (0)
if (user_regs_native(regs)) {
@@ -119,13 +120,13 @@ int save_task_regs(void *x, user_regs_struct_t *regs, user_fpregs_struct_t *fpre
*/
assign_reg(xsave, fpregs->xsave_hdr, xstate_bv);
assign_xsave(XFEATURE_YMM, xsave, ymmh_space, extended_state_area);
assign_xsave(XFEATURE_BNDREGS, xsave, bndreg_state, extended_state_area);
assign_xsave(XFEATURE_BNDCSR, xsave, bndcsr_state, extended_state_area);
assign_xsave(XFEATURE_OPMASK, xsave, opmask_reg, extended_state_area);
assign_xsave(XFEATURE_ZMM_Hi256,xsave, zmm_upper, extended_state_area);
assign_xsave(XFEATURE_Hi16_ZMM, xsave, hi16_zmm, extended_state_area);
assign_xsave(XFEATURE_PKRU, xsave, pkru, extended_state_area);
assign_xsave(XFEATURE_YMM, xsave, ymmh_space, extended_state_area);
assign_xsave(XFEATURE_BNDREGS, xsave, bndreg_state, extended_state_area);
assign_xsave(XFEATURE_BNDCSR, xsave, bndcsr_state, extended_state_area);
assign_xsave(XFEATURE_OPMASK, xsave, opmask_reg, extended_state_area);
assign_xsave(XFEATURE_ZMM_Hi256, xsave, zmm_upper, extended_state_area);
assign_xsave(XFEATURE_Hi16_ZMM, xsave, hi16_zmm, extended_state_area);
assign_xsave(XFEATURE_PKRU, xsave, pkru, extended_state_area);
}
#undef assign_reg
@@ -139,7 +140,7 @@ static void alloc_tls(ThreadInfoX86 *ti, void **mempool)
{
int i;
ti->tls = xptr_pull_s(mempool, GDT_ENTRY_TLS_NUM*sizeof(UserDescT*));
ti->tls = xptr_pull_s(mempool, GDT_ENTRY_TLS_NUM * sizeof(UserDescT *));
ti->n_tls = GDT_ENTRY_TLS_NUM;
for (i = 0; i < GDT_ENTRY_TLS_NUM; i++) {
ti->tls[i] = xptr_pull(mempool, UserDescT);
@@ -150,50 +151,50 @@ static void alloc_tls(ThreadInfoX86 *ti, void **mempool)
static int alloc_xsave_extends(UserX86XsaveEntry *xsave)
{
if (compel_fpu_has_feature(XFEATURE_YMM)) {
xsave->n_ymmh_space = XSAVE_PB_NELEMS(struct ymmh_struct, xsave, ymmh_space);
xsave->ymmh_space = xzalloc(pb_repeated_size(xsave, ymmh_space));
xsave->n_ymmh_space = XSAVE_PB_NELEMS(struct ymmh_struct, xsave, ymmh_space);
xsave->ymmh_space = xzalloc(pb_repeated_size(xsave, ymmh_space));
if (!xsave->ymmh_space)
goto err;
}
if (compel_fpu_has_feature(XFEATURE_BNDREGS)) {
xsave->n_bndreg_state = XSAVE_PB_NELEMS(struct mpx_bndreg_state, xsave, bndreg_state);
xsave->bndreg_state = xzalloc(pb_repeated_size(xsave, bndreg_state));
xsave->n_bndreg_state = XSAVE_PB_NELEMS(struct mpx_bndreg_state, xsave, bndreg_state);
xsave->bndreg_state = xzalloc(pb_repeated_size(xsave, bndreg_state));
if (!xsave->bndreg_state)
goto err;
}
if (compel_fpu_has_feature(XFEATURE_BNDCSR)) {
xsave->n_bndcsr_state = XSAVE_PB_NELEMS(struct mpx_bndcsr_state, xsave, bndcsr_state);
xsave->bndcsr_state = xzalloc(pb_repeated_size(xsave, bndcsr_state));
xsave->n_bndcsr_state = XSAVE_PB_NELEMS(struct mpx_bndcsr_state, xsave, bndcsr_state);
xsave->bndcsr_state = xzalloc(pb_repeated_size(xsave, bndcsr_state));
if (!xsave->bndcsr_state)
goto err;
}
if (compel_fpu_has_feature(XFEATURE_OPMASK)) {
xsave->n_opmask_reg = XSAVE_PB_NELEMS(struct avx_512_opmask_state, xsave, opmask_reg);
xsave->opmask_reg = xzalloc(pb_repeated_size(xsave, opmask_reg));
xsave->n_opmask_reg = XSAVE_PB_NELEMS(struct avx_512_opmask_state, xsave, opmask_reg);
xsave->opmask_reg = xzalloc(pb_repeated_size(xsave, opmask_reg));
if (!xsave->opmask_reg)
goto err;
}
if (compel_fpu_has_feature(XFEATURE_ZMM_Hi256)) {
xsave->n_zmm_upper = XSAVE_PB_NELEMS(struct avx_512_zmm_uppers_state, xsave, zmm_upper);
xsave->zmm_upper = xzalloc(pb_repeated_size(xsave, zmm_upper));
xsave->n_zmm_upper = XSAVE_PB_NELEMS(struct avx_512_zmm_uppers_state, xsave, zmm_upper);
xsave->zmm_upper = xzalloc(pb_repeated_size(xsave, zmm_upper));
if (!xsave->zmm_upper)
goto err;
}
if (compel_fpu_has_feature(XFEATURE_Hi16_ZMM)) {
xsave->n_hi16_zmm = XSAVE_PB_NELEMS(struct avx_512_hi16_state, xsave, hi16_zmm);
xsave->hi16_zmm = xzalloc(pb_repeated_size(xsave, hi16_zmm));
xsave->n_hi16_zmm = XSAVE_PB_NELEMS(struct avx_512_hi16_state, xsave, hi16_zmm);
xsave->hi16_zmm = xzalloc(pb_repeated_size(xsave, hi16_zmm));
if (!xsave->hi16_zmm)
goto err;
}
if (compel_fpu_has_feature(XFEATURE_PKRU)) {
xsave->n_pkru = XSAVE_PB_NELEMS(struct pkru_state, xsave, pkru);
xsave->pkru = xzalloc(pb_repeated_size(xsave, pkru));
xsave->n_pkru = XSAVE_PB_NELEMS(struct pkru_state, xsave, pkru);
xsave->pkru = xzalloc(pb_repeated_size(xsave, pkru));
if (!xsave->pkru)
goto err;
}
@@ -210,12 +211,10 @@ int arch_alloc_thread_info(CoreEntry *core)
void *m;
ThreadInfoX86 *ti = NULL;
with_fpu = compel_cpu_has_feature(X86_FEATURE_FPU);
sz = sizeof(ThreadInfoX86) + sizeof(UserX86RegsEntry) +
GDT_ENTRY_TLS_NUM*sizeof(UserDescT) +
GDT_ENTRY_TLS_NUM*sizeof(UserDescT*);
sz = sizeof(ThreadInfoX86) + sizeof(UserX86RegsEntry) + GDT_ENTRY_TLS_NUM * sizeof(UserDescT) +
GDT_ENTRY_TLS_NUM * sizeof(UserDescT *);
if (with_fpu) {
sz += sizeof(UserX86FpregsEntry);
with_xsave = compel_cpu_has_feature(X86_FEATURE_OSXSAVE);
@@ -240,11 +239,11 @@ int arch_alloc_thread_info(CoreEntry *core)
user_x86_fpregs_entry__init(fpregs);
/* These are numbers from kernel */
fpregs->n_st_space = 32;
fpregs->n_xmm_space = 64;
fpregs->n_st_space = 32;
fpregs->n_xmm_space = 64;
fpregs->st_space = xzalloc(pb_repeated_size(fpregs, st_space));
fpregs->xmm_space = xzalloc(pb_repeated_size(fpregs, xmm_space));
fpregs->st_space = xzalloc(pb_repeated_size(fpregs, st_space));
fpregs->xmm_space = xzalloc(pb_repeated_size(fpregs, xmm_space));
if (!fpregs->st_space || !fpregs->xmm_space)
goto err;
@@ -293,16 +292,14 @@ static bool valid_xsave_frame(CoreEntry *core)
if (core->thread_info->fpregs->n_st_space < ARRAY_SIZE(x->i387.st_space)) {
pr_err("Corruption in FPU st_space area "
"(got %li but %li expected)\n",
(long)core->thread_info->fpregs->n_st_space,
(long)ARRAY_SIZE(x->i387.st_space));
(long)core->thread_info->fpregs->n_st_space, (long)ARRAY_SIZE(x->i387.st_space));
return false;
}
if (core->thread_info->fpregs->n_xmm_space < ARRAY_SIZE(x->i387.xmm_space)) {
pr_err("Corruption in FPU xmm_space area "
"(got %li but %li expected)\n",
(long)core->thread_info->fpregs->n_st_space,
(long)ARRAY_SIZE(x->i387.xmm_space));
(long)core->thread_info->fpregs->n_st_space, (long)ARRAY_SIZE(x->i387.xmm_space));
return false;
}
@@ -310,46 +307,52 @@ static bool valid_xsave_frame(CoreEntry *core)
if (xsave) {
size_t i;
struct {
const char *name;
size_t expected;
size_t obtained;
void *ptr;
const char *name;
size_t expected;
size_t obtained;
void *ptr;
} features[] = {
{
.name = __stringify_1(XFEATURE_YMM),
.expected = XSAVE_PB_NELEMS(struct ymmh_struct, xsave, ymmh_space),
.obtained = xsave->n_ymmh_space,
.ptr = xsave->ymmh_space,
}, {
.name = __stringify_1(XFEATURE_BNDREGS),
.expected = XSAVE_PB_NELEMS(struct mpx_bndreg_state, xsave, bndreg_state),
.obtained = xsave->n_bndreg_state,
.ptr = xsave->bndreg_state,
}, {
.name = __stringify_1(XFEATURE_BNDCSR),
.expected = XSAVE_PB_NELEMS(struct mpx_bndcsr_state, xsave, bndcsr_state),
.obtained = xsave->n_bndcsr_state,
.ptr = xsave->bndcsr_state,
}, {
.name = __stringify_1(XFEATURE_OPMASK),
.expected = XSAVE_PB_NELEMS(struct avx_512_opmask_state, xsave, opmask_reg),
.obtained = xsave->n_opmask_reg,
.ptr = xsave->opmask_reg,
}, {
.name = __stringify_1(XFEATURE_ZMM_Hi256),
.expected = XSAVE_PB_NELEMS(struct avx_512_zmm_uppers_state, xsave, zmm_upper),
.obtained = xsave->n_zmm_upper,
.ptr = xsave->zmm_upper,
}, {
.name = __stringify_1(XFEATURE_Hi16_ZMM),
.expected = XSAVE_PB_NELEMS(struct avx_512_hi16_state, xsave, hi16_zmm),
.obtained = xsave->n_hi16_zmm,
.ptr = xsave->hi16_zmm,
}, {
.name = __stringify_1(XFEATURE_PKRU),
.expected = XSAVE_PB_NELEMS(struct pkru_state, xsave, pkru),
.obtained = xsave->n_pkru,
.ptr = xsave->pkru,
.name = __stringify_1(XFEATURE_YMM),
.expected = XSAVE_PB_NELEMS(struct ymmh_struct, xsave, ymmh_space),
.obtained = xsave->n_ymmh_space,
.ptr = xsave->ymmh_space,
},
{
.name = __stringify_1(XFEATURE_BNDREGS),
.expected = XSAVE_PB_NELEMS(struct mpx_bndreg_state, xsave, bndreg_state),
.obtained = xsave->n_bndreg_state,
.ptr = xsave->bndreg_state,
},
{
.name = __stringify_1(XFEATURE_BNDCSR),
.expected = XSAVE_PB_NELEMS(struct mpx_bndcsr_state, xsave, bndcsr_state),
.obtained = xsave->n_bndcsr_state,
.ptr = xsave->bndcsr_state,
},
{
.name = __stringify_1(XFEATURE_OPMASK),
.expected = XSAVE_PB_NELEMS(struct avx_512_opmask_state, xsave, opmask_reg),
.obtained = xsave->n_opmask_reg,
.ptr = xsave->opmask_reg,
},
{
.name = __stringify_1(XFEATURE_ZMM_Hi256),
.expected = XSAVE_PB_NELEMS(struct avx_512_zmm_uppers_state, xsave, zmm_upper),
.obtained = xsave->n_zmm_upper,
.ptr = xsave->zmm_upper,
},
{
.name = __stringify_1(XFEATURE_Hi16_ZMM),
.expected = XSAVE_PB_NELEMS(struct avx_512_hi16_state, xsave, hi16_zmm),
.obtained = xsave->n_hi16_zmm,
.ptr = xsave->hi16_zmm,
},
{
.name = __stringify_1(XFEATURE_PKRU),
.expected = XSAVE_PB_NELEMS(struct pkru_state, xsave, pkru),
.obtained = xsave->n_pkru,
.ptr = xsave->pkru,
},
};
@@ -392,12 +395,11 @@ static void show_rt_xsave_frame(struct xsave_struct *x)
pr_debug("xsave runtime structure\n");
pr_debug("-----------------------\n");
pr_debug("cwd:%#x swd:%#x twd:%#x fop:%#x mxcsr:%#x mxcsr_mask:%#x\n",
(int)i387->cwd, (int)i387->swd, (int)i387->twd,
(int)i387->fop, (int)i387->mxcsr, (int)i387->mxcsr_mask);
pr_debug("cwd:%#x swd:%#x twd:%#x fop:%#x mxcsr:%#x mxcsr_mask:%#x\n", (int)i387->cwd, (int)i387->swd,
(int)i387->twd, (int)i387->fop, (int)i387->mxcsr, (int)i387->mxcsr_mask);
pr_debug("magic1:%#x extended_size:%u xstate_bv:%#lx xstate_size:%u\n",
fpx->magic1, fpx->extended_size, (long)fpx->xstate_bv, fpx->xstate_size);
pr_debug("magic1:%#x extended_size:%u xstate_bv:%#lx xstate_size:%u\n", fpx->magic1, fpx->extended_size,
(long)fpx->xstate_bv, fpx->xstate_size);
pr_debug("xstate_bv: %#lx\n", (long)xsave_hdr->xstate_bv);
pr_debug("-----------------------\n");
@@ -405,12 +407,9 @@ static void show_rt_xsave_frame(struct xsave_struct *x)
int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core)
{
fpu_state_t *fpu_state = core_is_compat(core) ?
&sigframe->compat.fpu_state :
&sigframe->native.fpu_state;
struct xsave_struct *x = core_is_compat(core) ?
(void *)&fpu_state->fpu_state_ia32.xsave :
(void *)&fpu_state->fpu_state_64.xsave;
fpu_state_t *fpu_state = core_is_compat(core) ? &sigframe->compat.fpu_state : &sigframe->native.fpu_state;
struct xsave_struct *x = core_is_compat(core) ? (void *)&fpu_state->fpu_state_ia32.xsave :
(void *)&fpu_state->fpu_state_64.xsave;
/*
* If no FPU information provided -- we're restoring
@@ -427,32 +426,33 @@ int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core)
fpu_state->has_fpu = true;
#define assign_reg(dst, src, e) do { dst.e = (__typeof__(dst.e))src->e; } while (0)
#define assign_array(dst, src, e) memcpy(dst.e, (src)->e, sizeof(dst.e))
#define assign_xsave(feature, xsave, member, area) \
do { \
if (compel_fpu_has_feature(feature)) { \
uint32_t off = compel_fpu_feature_offset(feature); \
void *to = &area[off]; \
void *from = xsave->member; \
size_t size = pb_repeated_size(xsave, member); \
size_t xsize = (size_t)compel_fpu_feature_size(feature); \
size_t xstate_size_next = off + xsize; \
if (xsize != size) { \
if (size) { \
pr_err("%s reported %zu bytes (expecting %zu)\n",\
# feature, xsize, size); \
return -1; \
} else { \
pr_debug("%s is not present in image, ignore\n",\
# feature); \
} \
} \
xstate_bv |= (1UL << feature); \
BUG_ON(xstate_size > xstate_size_next); \
xstate_size = xstate_size_next; \
memcpy(to, from, size); \
} \
#define assign_reg(dst, src, e) \
do { \
dst.e = (__typeof__(dst.e))src->e; \
} while (0)
#define assign_array(dst, src, e) memcpy(dst.e, (src)->e, sizeof(dst.e))
#define assign_xsave(feature, xsave, member, area) \
do { \
if (compel_fpu_has_feature(feature)) { \
uint32_t off = compel_fpu_feature_offset(feature); \
void *to = &area[off]; \
void *from = xsave->member; \
size_t size = pb_repeated_size(xsave, member); \
size_t xsize = (size_t)compel_fpu_feature_size(feature); \
size_t xstate_size_next = off + xsize; \
if (xsize != size) { \
if (size) { \
pr_err("%s reported %zu bytes (expecting %zu)\n", #feature, xsize, size); \
return -1; \
} else { \
pr_debug("%s is not present in image, ignore\n", #feature); \
} \
} \
xstate_bv |= (1UL << feature); \
BUG_ON(xstate_size > xstate_size_next); \
xstate_size = xstate_size_next; \
memcpy(to, from, size); \
} \
} while (0)
assign_reg(x->i387, core->thread_info->fpregs, cwd);
@@ -492,21 +492,21 @@ int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core)
* to the increasing offsets of XFEATURE_x
* inside memory layout (xstate_size calculation).
*/
assign_xsave(XFEATURE_YMM, xsave, ymmh_space, extended_state_area);
assign_xsave(XFEATURE_BNDREGS, xsave, bndreg_state, extended_state_area);
assign_xsave(XFEATURE_BNDCSR, xsave, bndcsr_state, extended_state_area);
assign_xsave(XFEATURE_OPMASK, xsave, opmask_reg, extended_state_area);
assign_xsave(XFEATURE_ZMM_Hi256,xsave, zmm_upper, extended_state_area);
assign_xsave(XFEATURE_Hi16_ZMM, xsave, hi16_zmm, extended_state_area);
assign_xsave(XFEATURE_PKRU, xsave, pkru, extended_state_area);
assign_xsave(XFEATURE_YMM, xsave, ymmh_space, extended_state_area);
assign_xsave(XFEATURE_BNDREGS, xsave, bndreg_state, extended_state_area);
assign_xsave(XFEATURE_BNDCSR, xsave, bndcsr_state, extended_state_area);
assign_xsave(XFEATURE_OPMASK, xsave, opmask_reg, extended_state_area);
assign_xsave(XFEATURE_ZMM_Hi256, xsave, zmm_upper, extended_state_area);
assign_xsave(XFEATURE_Hi16_ZMM, xsave, hi16_zmm, extended_state_area);
assign_xsave(XFEATURE_PKRU, xsave, pkru, extended_state_area);
}
x->xsave_hdr.xstate_bv = xstate_bv;
x->xsave_hdr.xstate_bv = xstate_bv;
fpx_sw->magic1 = FP_XSTATE_MAGIC1;
fpx_sw->xstate_bv = xstate_bv;
fpx_sw->xstate_size = xstate_size;
fpx_sw->extended_size = xstate_size + FP_XSTATE_MAGIC2_SIZE;
fpx_sw->magic1 = FP_XSTATE_MAGIC1;
fpx_sw->xstate_bv = xstate_bv;
fpx_sw->xstate_size = xstate_size;
fpx_sw->extended_size = xstate_size + FP_XSTATE_MAGIC2_SIZE;
/*
* This should be at the end of xsave frame.
@@ -524,7 +524,7 @@ int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core)
return 0;
}
#define CPREG32(d) f->compat.uc.uc_mcontext.d = r->d
#define CPREG32(d) f->compat.uc.uc_mcontext.d = r->d
static void restore_compat_gpregs(struct rt_sigframe *f, UserX86RegsEntry *r)
{
CPREG32(gs);
@@ -532,8 +532,15 @@ static void restore_compat_gpregs(struct rt_sigframe *f, UserX86RegsEntry *r)
CPREG32(es);
CPREG32(ds);
CPREG32(di); CPREG32(si); CPREG32(bp); CPREG32(sp); CPREG32(bx);
CPREG32(dx); CPREG32(cx); CPREG32(ip); CPREG32(ax);
CPREG32(di);
CPREG32(si);
CPREG32(bp);
CPREG32(sp);
CPREG32(bx);
CPREG32(dx);
CPREG32(cx);
CPREG32(ip);
CPREG32(ax);
CPREG32(cs);
CPREG32(ss);
CPREG32(flags);
@@ -542,7 +549,7 @@ static void restore_compat_gpregs(struct rt_sigframe *f, UserX86RegsEntry *r)
}
#undef CPREG32
#define CPREG64(d, s) f->native.uc.uc_mcontext.d = r->s
#define CPREG64(d, s) f->native.uc.uc_mcontext.d = r->s
static void restore_native_gpregs(struct rt_sigframe *f, UserX86RegsEntry *r)
{
CPREG64(rdi, di);
@@ -575,15 +582,15 @@ static void restore_native_gpregs(struct rt_sigframe *f, UserX86RegsEntry *r)
int restore_gpregs(struct rt_sigframe *f, UserX86RegsEntry *r)
{
switch (r->mode) {
case USER_X86_REGS_MODE__NATIVE:
restore_native_gpregs(f, r);
break;
case USER_X86_REGS_MODE__COMPAT:
restore_compat_gpregs(f, r);
break;
default:
pr_err("Can't prepare rt_sigframe: registers mode corrupted (%d)\n", r->mode);
return -1;
case USER_X86_REGS_MODE__NATIVE:
restore_native_gpregs(f, r);
break;
case USER_X86_REGS_MODE__COMPAT:
restore_compat_gpregs(f, r);
break;
default:
pr_err("Can't prepare rt_sigframe: registers mode corrupted (%d)\n", r->mode);
return -1;
}
return 0;
}
@@ -591,10 +598,10 @@ int restore_gpregs(struct rt_sigframe *f, UserX86RegsEntry *r)
static int get_robust_list32(pid_t pid, uintptr_t head, uintptr_t len)
{
struct syscall_args32 s = {
.nr = __NR32_get_robust_list,
.arg0 = pid,
.arg1 = (uint32_t)head,
.arg2 = (uint32_t)len,
.nr = __NR32_get_robust_list,
.arg0 = pid,
.arg1 = (uint32_t)head,
.arg2 = (uint32_t)len,
};
return do_full_int80(&s);
@@ -603,9 +610,9 @@ static int get_robust_list32(pid_t pid, uintptr_t head, uintptr_t len)
static int set_robust_list32(uint32_t head, uint32_t len)
{
struct syscall_args32 s = {
.nr = __NR32_set_robust_list,
.arg0 = head,
.arg1 = len,
.nr = __NR32_set_robust_list,
.arg0 = head,
.arg1 = len,
};
return do_full_int80(&s);
@@ -625,19 +632,18 @@ int get_task_futex_robust_list_compat(pid_t pid, ThreadCoreEntry *info)
if (ret == -ENOSYS) {
/* Check native get_task_futex_robust_list() for details. */
if (set_robust_list32(0, 0) == (uint32_t)-ENOSYS) {
info->futex_rla = 0;
info->futex_rla_len = 0;
info->futex_rla = 0;
info->futex_rla_len = 0;
ret = 0;
}
} else if (ret == 0) {
uint32_t *arg1 = (uint32_t*)mmap32;
uint32_t *arg1 = (uint32_t *)mmap32;
info->futex_rla = *arg1;
info->futex_rla_len = *(arg1 + 1);
info->futex_rla = *arg1;
info->futex_rla_len = *(arg1 + 1);
ret = 0;
}
free_compat_syscall_stack(mmap32);
return ret;
}

View File

@@ -58,22 +58,20 @@ int kdat_can_map_vdso(void)
return -1;
return WEXITSTATUS(stat);
}
#ifdef CONFIG_COMPAT
void *mmap_ia32(void *addr, size_t len, int prot,
int flags, int fildes, off_t off)
void *mmap_ia32(void *addr, size_t len, int prot, int flags, int fildes, off_t off)
{
struct syscall_args32 s;
s.nr = __NR32_mmap2;
s.arg0 = (uint32_t)(uintptr_t)addr;
s.arg1 = (uint32_t)len;
s.arg2 = prot;
s.arg3 = flags;
s.arg4 = fildes;
s.arg5 = (uint32_t)off;
s.nr = __NR32_mmap2;
s.arg0 = (uint32_t)(uintptr_t)addr;
s.arg1 = (uint32_t)len;
s.arg2 = prot;
s.arg3 = flags;
s.arg4 = fildes;
s.arg5 = (uint32_t)off;
return (void *)(uintptr_t)do_full_int80(&s);
}
@@ -101,7 +99,7 @@ static void mmap_bug_test(void)
void *map1, *map2;
int err;
map1 = mmap_ia32(0, PAGE_SIZE, PROT_NONE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
map1 = mmap_ia32(0, PAGE_SIZE, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
/* 32-bit error, not sign-extended - can't use IS_ERR_VALUE() here */
err = (uintptr_t)map1 % PAGE_SIZE;
if (err) {
@@ -114,7 +112,7 @@ static void mmap_bug_test(void)
exit(1);
}
map2 = mmap_ia32(0, PAGE_SIZE, PROT_NONE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
map2 = mmap_ia32(0, PAGE_SIZE, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
err = (uintptr_t)map2 % PAGE_SIZE;
if (err) {
pr_err("ia32 mmap() failed: %d\n", err);
@@ -200,7 +198,7 @@ static int kdat_x86_has_ptrace_fpu_xsave_bug_child(void *arg)
*/
int kdat_x86_has_ptrace_fpu_xsave_bug(void)
{
user_fpregs_struct_t xsave = { };
user_fpregs_struct_t xsave = {};
struct iovec iov;
char stack[PAGE_SIZE];
int flags = CLONE_VM | CLONE_FILES | CLONE_UNTRACED | SIGCHLD;
@@ -212,8 +210,7 @@ int kdat_x86_has_ptrace_fpu_xsave_bug(void)
if (!compel_cpu_has_feature(X86_FEATURE_OSXSAVE))
return 0;
child = clone(kdat_x86_has_ptrace_fpu_xsave_bug_child,
stack + ARRAY_SIZE(stack), flags, 0);
child = clone(kdat_x86_has_ptrace_fpu_xsave_bug_child, stack + ARRAY_SIZE(stack), flags, 0);
if (child < 0) {
pr_perror("%s(): failed to clone()", __func__);
return -1;

View File

@@ -17,8 +17,7 @@ int arch_map_vdso(unsigned long map_at, bool compatible)
{
int vdso_type = compatible ? ARCH_MAP_VDSO_32 : ARCH_MAP_VDSO_64;
pr_debug("Mapping %s vDSO at %lx\n",
compatible ? "compatible" : "native", map_at);
pr_debug("Mapping %s vDSO at %lx\n", compatible ? "compatible" : "native", map_at);
return sys_arch_prctl(vdso_type, map_at);
}
@@ -49,9 +48,9 @@ int restore_nonsigframe_gpregs(UserX86RegsEntry *r)
int set_compat_robust_list(uint32_t head_ptr, uint32_t len)
{
struct syscall_args32 s = {
.nr = __NR32_set_robust_list,
.arg0 = head_ptr,
.arg1 = len,
.nr = __NR32_set_robust_list,
.arg0 = head_ptr,
.arg1 = len,
};
return do_full_int80(&s);
@@ -95,18 +94,16 @@ void restore_tls(tls_t *ptls)
return;
memcpy(stack32, desc, sizeof(user_desc_t));
asm volatile (
" mov %1,%%eax \n"
" mov %2,%%ebx \n"
" int $0x80 \n"
" mov %%eax,%0 \n"
: "=g"(ret)
: "r"(__NR32_set_thread_area), "r"((uint32_t)(uintptr_t)stack32)
: "eax", "ebx", "r8", "r9", "r10", "r11", "memory");
asm volatile(" mov %1,%%eax \n"
" mov %2,%%ebx \n"
" int $0x80 \n"
" mov %%eax,%0 \n"
: "=g"(ret)
: "r"(__NR32_set_thread_area), "r"((uint32_t)(uintptr_t)stack32)
: "eax", "ebx", "r8", "r9", "r10", "r11", "memory");
if (ret)
pr_err("Failed to restore TLS descriptor %u in GDT: %d\n",
desc->entry_number, ret);
pr_err("Failed to restore TLS descriptor %u in GDT: %d\n", desc->entry_number, ret);
}
if (stack32)

View File

@@ -5,21 +5,21 @@
#include <compel/plugins/std/syscall-codes.h>
#ifdef CR_NOGLIBC
# include <compel/plugins/std/string.h>
#include <compel/plugins/std/string.h>
#endif
#include "cpu.h"
asm ( " .pushsection .text \n"
" .global restore_rt_sigaction \n"
" .code32 \n"
"restore_rt_sigaction: \n"
" mov %edx, %esi \n"
" mov $0, %edx \n"
" movl $"__stringify(__NR32_rt_sigaction)",%eax \n"
" int $0x80 \n"
" ret \n"
" .popsection \n"
" .code64");
asm(" .pushsection .text \n"
" .global restore_rt_sigaction \n"
" .code32 \n"
"restore_rt_sigaction: \n"
" mov %edx, %esi \n"
" mov $0, %edx \n"
" movl $" __stringify(__NR32_rt_sigaction) ",%eax \n"
" int $0x80 \n"
" ret \n"
" .popsection \n"
" .code64");
extern char restore_rt_sigaction;
/*
@@ -42,11 +42,11 @@ int arch_compat_rt_sigaction(void *stack32, int sig, rt_sigaction_t_compat *act)
* coping it on the bottom of the stack.
*/
memcpy(stack32, act, sizeof(rt_sigaction_t_compat));
arg.nr = __NR32_rt_sigaction;
arg.arg0 = sig;
arg.arg1 = (uint32_t)act_stack; /* act */
arg.arg2 = 0; /* oldact */
arg.arg3 = (uint32_t)sizeof(act->rt_sa_mask); /* sigsetsize */
arg.nr = __NR32_rt_sigaction;
arg.arg0 = sig;
arg.arg1 = (uint32_t)act_stack; /* act */
arg.arg2 = 0; /* oldact */
arg.arg3 = (uint32_t)sizeof(act->rt_sa_mask); /* sigsetsize */
return do_full_int80(&arg);
}

View File

@@ -6,34 +6,28 @@
#include "log.h"
int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe,
struct rt_sigframe *rsigframe)
int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe, struct rt_sigframe *rsigframe)
{
/*
* Use local sigframe to check native/compat type,
* but set address for rsigframe.
*/
fpu_state_t *fpu_state = (sigframe->is_native) ?
&rsigframe->native.fpu_state :
&rsigframe->compat.fpu_state;
fpu_state_t *fpu_state = (sigframe->is_native) ? &rsigframe->native.fpu_state : &rsigframe->compat.fpu_state;
if (sigframe->is_native) {
unsigned long addr = (unsigned long)(void *)&fpu_state->fpu_state_64.xsave;
if ((addr % 64ul)) {
pr_err("Unaligned address passed: %lx (native %d)\n",
addr, sigframe->is_native);
pr_err("Unaligned address passed: %lx (native %d)\n", addr, sigframe->is_native);
return -1;
}
sigframe->native.uc.uc_mcontext.fpstate = (uint64_t)addr;
} else if (!sigframe->is_native) {
unsigned long addr = (unsigned long)(void *)&fpu_state->fpu_state_ia32.xsave;
sigframe->compat.uc.uc_mcontext.fpstate =
(uint32_t)(unsigned long)(void *)&fpu_state->fpu_state_ia32;
sigframe->compat.uc.uc_mcontext.fpstate = (uint32_t)(unsigned long)(void *)&fpu_state->fpu_state_ia32;
if ((addr % 64ul)) {
pr_err("Unaligned address passed: %lx (native %d)\n",
addr, sigframe->is_native);
pr_err("Unaligned address passed: %lx (native %d)\n", addr, sigframe->is_native);
return -1;
}
}

View File

@@ -1,20 +1,19 @@
static struct syscall_exec_desc sc_exec_table_64[] = {
#include "sys-exec-tbl-64.c"
{ }, /* terminator */
{}, /* terminator */
};
#ifdef CONFIG_COMPAT
static struct syscall_exec_desc sc_exec_table_32[] = {
#include "sys-exec-tbl-32.c"
{ }, /* terminator */
{}, /* terminator */
};
#endif
struct syscall_exec_desc;
static inline struct syscall_exec_desc *
find_syscall_table(char *name, struct syscall_exec_desc *tbl)
static inline struct syscall_exec_desc *find_syscall_table(char *name, struct syscall_exec_desc *tbl)
{
int i;
@@ -27,7 +26,7 @@ find_syscall_table(char *name, struct syscall_exec_desc *tbl)
#define ARCH_HAS_FIND_SYSCALL
/* overwrite default to search in two tables above */
#ifdef CONFIG_COMPAT
struct syscall_exec_desc * find_syscall(char *name, struct parasite_ctl *ctl)
struct syscall_exec_desc *find_syscall(char *name, struct parasite_ctl *ctl)
{
if (compel_mode_native(ctl))
return find_syscall_table(name, sc_exec_table_64);
@@ -35,8 +34,7 @@ struct syscall_exec_desc * find_syscall(char *name, struct parasite_ctl *ctl)
return find_syscall_table(name, sc_exec_table_32);
}
#else
struct syscall_exec_desc *
find_syscall(char *name, __always_unused struct parasite_ctl *ctl)
struct syscall_exec_desc *find_syscall(char *name, __always_unused struct parasite_ctl *ctl)
{
return find_syscall_table(name, sc_exec_table_64);
}

View File

@@ -9,22 +9,22 @@
#include "common/bug.h"
#ifdef LOG_PREFIX
# undef LOG_PREFIX
#undef LOG_PREFIX
#endif
#define LOG_PREFIX "vdso: "
static void insert_trampoline32(uintptr_t from, uintptr_t to)
{
struct {
u8 movl;
u32 imm32;
u16 jmp_eax;
u32 guards;
u8 movl;
u32 imm32;
u16 jmp_eax;
u32 guards;
} __packed jmp = {
.movl = 0xb8,
.imm32 = (uint32_t)to,
.jmp_eax = 0xe0ff,
.guards = 0xcccccccc,
.movl = 0xb8,
.imm32 = (uint32_t)to,
.jmp_eax = 0xe0ff,
.guards = 0xcccccccc,
};
memcpy((void *)from, &jmp, sizeof(jmp));
@@ -33,23 +33,22 @@ static void insert_trampoline32(uintptr_t from, uintptr_t to)
static void insert_trampoline64(uintptr_t from, uintptr_t to)
{
struct {
u16 movabs;
u64 imm64;
u16 jmp_rax;
u32 guards;
u16 movabs;
u64 imm64;
u16 jmp_rax;
u32 guards;
} __packed jmp = {
.movabs = 0xb848,
.imm64 = to,
.jmp_rax = 0xe0ff,
.guards = 0xcccccccc,
.movabs = 0xb848,
.imm64 = to,
.jmp_rax = 0xe0ff,
.guards = 0xcccccccc,
};
memcpy((void *)from, &jmp, sizeof(jmp));
}
int vdso_redirect_calls(unsigned long base_to, unsigned long base_from,
struct vdso_symtable *sto, struct vdso_symtable *sfrom,
bool compat_vdso)
int vdso_redirect_calls(unsigned long base_to, unsigned long base_from, struct vdso_symtable *sto,
struct vdso_symtable *sfrom, bool compat_vdso)
{
unsigned int i;
@@ -59,9 +58,8 @@ int vdso_redirect_calls(unsigned long base_to, unsigned long base_from,
if (vdso_symbol_empty(&sfrom->symbols[i]))
continue;
pr_debug("jmp: %lx/%lx -> %lx/%lx (index %d)\n",
base_from, sfrom->symbols[i].offset,
base_to, sto->symbols[i].offset, i);
pr_debug("jmp: %lx/%lx -> %lx/%lx (index %d)\n", base_from, sfrom->symbols[i].offset, base_to,
sto->symbols[i].offset, i);
from = base_from + sfrom->symbols[i].offset;
to = base_to + sto->symbols[i].offset;

View File

@@ -18,13 +18,13 @@
#include "images/autofs.pb-c.h"
#define AUTOFS_OPT_UNKNOWN INT_MIN
#define AUTOFS_OPT_UNKNOWN INT_MIN
#define AUTOFS_MODE_DIRECT 0
#define AUTOFS_MODE_INDIRECT 1
#define AUTOFS_MODE_OFFSET 2
#define AUTOFS_MODE_DIRECT 0
#define AUTOFS_MODE_INDIRECT 1
#define AUTOFS_MODE_OFFSET 2
#define AUTOFS_CATATONIC_FD -1
#define AUTOFS_CATATONIC_FD -1
static int autofs_mnt_open(const char *mnt_path, dev_t devid);
@@ -111,8 +111,7 @@ free:
return ret;
}
static int autofs_check_fd_stat(struct stat *stat, int prgp, int fd,
long ino, int *mode)
static int autofs_check_fd_stat(struct stat *stat, int prgp, int fd, long ino, int *mode)
{
struct fdinfo_common fdinfo;
@@ -209,13 +208,15 @@ static int autofs_find_read_fd(int pgrp, long pipe_ino)
/* We need to find read end and make sure, that it's empty */
if (autofs_find_pipe_read_end(pgrp, pipe_ino, &read_fd) < 0) {
pr_err("Failed to find read pipe fd (ino %ld) "
"in process %d\n", pipe_ino, pgrp);
"in process %d\n",
pipe_ino, pgrp);
return -1;
}
if (read_fd == -1) {
pr_err("Master %d doesn't have a read end of the pipe with "
"inode %ld opened\n", pgrp, pipe_ino);
"inode %ld opened\n",
pgrp, pipe_ino);
pr_err("Abandoned mount or control was delegated to child?\n");
return -ENOENT;
}
@@ -226,8 +227,7 @@ static int autofs_find_read_fd(int pgrp, long pipe_ino)
return -1;
if (fd_has_data(fd)) {
pr_err("Process %d autofs pipe fd %d is not empty.\n", pgrp,
read_fd);
pr_err("Process %d autofs pipe fd %d is not empty.\n", pgrp, read_fd);
pr_err("Try again later.\n");
return -1;
}
@@ -348,7 +348,7 @@ static int autofs_revisit_options(struct mount_info *pm)
char *token;
/* Removing '/n' */
str[strlen(str)-1] = '\0';
str[strlen(str) - 1] = '\0';
while ((token = strsep(&str, " ")) != NULL) {
if (mnt_id == -1) {
@@ -427,16 +427,15 @@ static int access_autofs_mount(struct mount_info *pm)
pid = fork();
switch (pid) {
case -1:
pr_err("failed to fork\n");
goto close_autofs_mnt;
case 0:
/* We don't care about results.
case -1:
pr_err("failed to fork\n");
goto close_autofs_mnt;
case 0:
/* We don't care about results.
* All we need is to "touch" */
/* coverity[check_return] */
openat(autofs_mnt, mnt_path, O_RDONLY|O_NONBLOCK|O_DIRECTORY);
_exit(0);
/* coverity[check_return] */
openat(autofs_mnt, mnt_path, O_RDONLY | O_NONBLOCK | O_DIRECTORY);
_exit(0);
}
/* Here we also don't care about results */
waitpid(pid, &status, 0);
@@ -499,24 +498,21 @@ static int autofs_create_entry(struct mount_info *pm, AutofsEntry *entry)
* options, then we can read them again and dump it.
*/
if (access_autofs_mount(pm)) {
pr_err("failed to access autofs %s\n",
pm->mountpoint + 1);
pr_err("failed to access autofs %s\n", pm->mountpoint + 1);
return -1;
}
if (parse_options(pm->options, entry, &pipe_ino))
return -1;
if (entry->fd == AUTOFS_CATATONIC_FD)
return 0;
pr_err("Autofs %d is alive, but unreachable.\n",
pm->mnt_id);
pr_err("Autofs %d is alive, but unreachable.\n", pm->mnt_id);
return -1;
}
/* Let' check whether write end is still open */
found = autofs_kernel_pipe_alive(entry->pgrp, entry->fd, pipe_ino);
if (found < 0) {
pr_err("Failed to check fd %d in process %d\n",
entry->fd, entry->pgrp);
pr_err("Failed to check fd %d in process %d\n", entry->fd, entry->pgrp);
return -1;
}
/* Write end is absent. we need to carry read end to restore. */
@@ -528,8 +524,7 @@ static int autofs_create_entry(struct mount_info *pm, AutofsEntry *entry)
/* We need to get virtual pgrp to restore mount */
virt_pgrp = pid_to_virt(entry->pgrp);
if (!virt_pgrp) {
pr_err("failed to find pstree item with pid %d\n",
entry->pgrp);
pr_err("failed to find pstree item with pid %d\n", entry->pgrp);
pr_err("Non-catatonic mount without master?\n");
return -1;
}
@@ -551,7 +546,6 @@ static int autofs_dump_entry(struct mount_info *pm, AutofsEntry *entry)
return ret;
}
int autofs_dump(struct mount_info *pm)
{
AutofsEntry *entry;
@@ -582,8 +576,7 @@ typedef struct autofs_info_s {
struct pprep_head ph;
} autofs_info_t;
static int dup_pipe_info(struct pipe_info *pi, int flags,
struct file_desc_ops *ops)
static int dup_pipe_info(struct pipe_info *pi, int flags, struct file_desc_ops *ops)
{
struct pipe_info *new;
PipeEntry *pe;
@@ -609,9 +602,7 @@ static int dup_pipe_info(struct pipe_info *pi, int flags,
return 0;
}
static int autofs_dup_pipe(struct pstree_item *task,
struct fdinfo_list_entry *ple,
int new_fd)
static int autofs_dup_pipe(struct pstree_item *task, struct fdinfo_list_entry *ple, int new_fd)
{
struct pipe_info *pi = container_of(ple->desc, struct pipe_info, d);
unsigned flags = O_WRONLY;
@@ -619,23 +610,19 @@ static int autofs_dup_pipe(struct pstree_item *task,
new_fd = find_unused_fd(task, new_fd);
if (dup_pipe_info(pi, flags, pi->d.ops) < 0) {
pr_err("Failed to dup pipe entry ID %#x PIPE_ID %#x\n",
pi->pe->id, pi->pe->pipe_id);
pr_err("Failed to dup pipe entry ID %#x PIPE_ID %#x\n", pi->pe->id, pi->pe->pipe_id);
return -1;
}
if (dup_fle(task, ple, new_fd, flags) < 0) {
pr_err("Failed to add fd %d to process %d\n",
new_fd, vpid(task));
pr_err("Failed to add fd %d to process %d\n", new_fd, vpid(task));
return -1;
}
pr_info("autofs: added pipe fd %d, flags %#x to %d\n",
new_fd, flags, vpid(task));
pr_info("autofs: added pipe fd %d, flags %#x to %d\n", new_fd, flags, vpid(task));
return new_fd;
}
static int autofs_ioctl(const char *path, int fd, int cmd, const void *param)
{
int err;
@@ -649,7 +636,7 @@ static int autofs_ioctl(const char *path, int fd, int cmd, const void *param)
static int autofs_dev_ioctl(int cmd, struct autofs_dev_ioctl *param)
{
char *path = "/dev/"AUTOFS_DEVICE_NAME;
char *path = "/dev/" AUTOFS_DEVICE_NAME;
int fd, err;
fd = open(path, O_RDONLY);
@@ -670,8 +657,7 @@ static int autofs_mnt_make_catatonic(const char *mnt_path, int mnt_fd)
return autofs_ioctl(mnt_path, mnt_fd, AUTOFS_IOC_CATATONIC, NULL);
}
static int autofs_mnt_set_timeout(time_t timeout,
const char *mnt_path, int mnt_fd)
static int autofs_mnt_set_timeout(time_t timeout, const char *mnt_path, int mnt_fd)
{
pr_info("%s: set timeout %ld for %s\n", __func__, timeout, mnt_path);
return autofs_ioctl(mnt_path, mnt_fd, AUTOFS_IOC_SETTIMEOUT, &timeout);
@@ -685,8 +671,7 @@ static int autofs_mnt_set_pipefd(const autofs_info_t *i, int mnt_fd)
if (i->entry->fd == AUTOFS_CATATONIC_FD)
return 0;
pr_info("%s: set pipe fd %d (pgrp %d) for mount %s\n", __func__,
i->entry->fd, getpgrp(), i->mnt_path);
pr_info("%s: set pipe fd %d (pgrp %d) for mount %s\n", __func__, i->entry->fd, getpgrp(), i->mnt_path);
init_autofs_dev_ioctl(&param);
param.ioctlfd = mnt_fd;
@@ -699,8 +684,7 @@ static int autofs_mnt_close(const char *mnt_path, int mnt_fd)
{
struct autofs_dev_ioctl param;
pr_info("%s: closing fd %d for mount %s\n", __func__, mnt_fd,
mnt_path);
pr_info("%s: closing fd %d for mount %s\n", __func__, mnt_fd, mnt_path);
init_autofs_dev_ioctl(&param);
param.ioctlfd = mnt_fd;
@@ -730,8 +714,7 @@ static int autofs_mnt_open(const char *mnt_path, dev_t devid)
fd = param->ioctlfd;
free(param);
if (err < 0) {
pr_err("Failed to get %s fd (devid: %ld)\n",
mnt_path, (long)devid);
pr_err("Failed to get %s fd (devid: %ld)\n", mnt_path, (long)devid);
return -1;
}
return fd;
@@ -746,8 +729,7 @@ static int autofs_create_dentries(const struct mount_info *mi, char *mnt_path)
basename = strrchr(c->mountpoint, '/');
if (!basename) {
pr_info("%s: mount path \"%s\" doesn't have '/'\n",
__func__, c->mountpoint);
pr_info("%s: mount path \"%s\" doesn't have '/'\n", __func__, c->mountpoint);
return -1;
}
path = xsprintf("%s%s", mnt_path, basename);
@@ -763,8 +745,7 @@ static int autofs_create_dentries(const struct mount_info *mi, char *mnt_path)
return 0;
}
static int autofs_populate_mount(const struct mount_info *mi,
const AutofsEntry *entry)
static int autofs_populate_mount(const struct mount_info *mi, const AutofsEntry *entry)
{
if (entry->mode != AUTOFS_MODE_INDIRECT)
return 0;
@@ -772,13 +753,11 @@ static int autofs_populate_mount(const struct mount_info *mi,
return autofs_create_dentries(mi, mi->mountpoint);
}
static int autofs_post_mount(const char *mnt_path, dev_t mnt_dev,
time_t timeout)
static int autofs_post_mount(const char *mnt_path, dev_t mnt_dev, time_t timeout)
{
int mnt_fd;
pr_info("%s: set timeout for %s and make it catatonic\n",
__func__, mnt_path);
pr_info("%s: set timeout for %s and make it catatonic\n", __func__, mnt_path);
mnt_fd = autofs_mnt_open(mnt_path, mnt_dev);
if (mnt_fd < 0) {
@@ -787,8 +766,7 @@ static int autofs_post_mount(const char *mnt_path, dev_t mnt_dev,
}
if (autofs_mnt_set_timeout(timeout, mnt_path, mnt_fd)) {
pr_err("Failed to set timeout %ld for %s\n",
timeout, mnt_path);
pr_err("Failed to set timeout %ld for %s\n", timeout, mnt_path);
return -1;
}
@@ -830,23 +808,19 @@ static int autofs_post_open(struct file_desc *d, int fd)
return -1;
}
pr_info("autofs mount %s owner restored: pgrp=%d, fd=%d\n",
i->mnt_path, getpgrp(), i->entry->fd);
pr_info("autofs mount %s owner restored: pgrp=%d, fd=%d\n", i->mnt_path, getpgrp(), i->entry->fd);
if (i->entry->has_read_fd) {
pr_info("%s: pid %d, closing write end %d\n", __func__,
getpid(), i->entry->fd);
pr_info("%s: pid %d, closing write end %d\n", __func__, getpid(), i->entry->fd);
close(i->entry->fd);
}
pr_info("%s: pid %d, closing artificial pipe end %d\n", __func__,
getpid(), fd);
pr_info("%s: pid %d, closing artificial pipe end %d\n", __func__, getpid(), fd);
close(fd);
return 0;
}
static autofs_info_t *autofs_create_info(const struct mount_info *mi,
const struct file_desc *desc,
static autofs_info_t *autofs_create_info(const struct mount_info *mi, const struct file_desc *desc,
const autofs_info_t *info)
{
autofs_info_t *i;
@@ -876,8 +850,7 @@ static autofs_info_t *autofs_create_info(const struct mount_info *mi,
return i;
}
static struct fdinfo_list_entry *autofs_pipe_le(struct pstree_item *master,
AutofsEntry *entry)
static struct fdinfo_list_entry *autofs_pipe_le(struct pstree_item *master, AutofsEntry *entry)
{
struct fdinfo_list_entry *ple;
int pipe_fd = entry->fd;
@@ -887,13 +860,11 @@ static struct fdinfo_list_entry *autofs_pipe_le(struct pstree_item *master,
ple = find_used_fd(master, pipe_fd);
if (!ple) {
pr_err("Failed to find pipe fd %d in process %d\n",
pipe_fd, vpid(master));
pr_err("Failed to find pipe fd %d in process %d\n", pipe_fd, vpid(master));
return NULL;
}
if (ple->fe->type != FD_TYPES__PIPE) {
pr_err("Fd %d in process %d is not a pipe: %d\n", pipe_fd,
vpid(master), ple->fe->type);
pr_err("Fd %d in process %d is not a pipe: %d\n", pipe_fd, vpid(master), ple->fe->type);
return NULL;
}
return ple;
@@ -915,8 +886,7 @@ static int autofs_open_pipefd(struct file_desc *d, int *new_fd)
return autofs_post_open(d, fle->fe->fd);
}
static int autofs_create_pipe(struct pstree_item *task, autofs_info_t *i,
struct fdinfo_list_entry *ple)
static int autofs_create_pipe(struct pstree_item *task, autofs_info_t *i, struct fdinfo_list_entry *ple)
{
struct pipe_info *pi = container_of(ple->desc, struct pipe_info, d);
int fd = -1;
@@ -953,8 +923,7 @@ static int autofs_create_pipe(struct pstree_item *task, autofs_info_t *i,
return -1;
fe->type = FD_TYPES__AUTOFS_PIPE;
pr_info("autofs: adding pipe fd %d, flags %#x to %d (with post_open)\n",
fe->fd, fe->flags, vpid(task));
pr_info("autofs: adding pipe fd %d, flags %#x to %d (with post_open)\n", fe->fd, fe->flags, vpid(task));
return collect_fd(vpid(task), fe, rsti(task), false);
}
@@ -985,8 +954,7 @@ static int autofs_add_mount_info(struct pprep_head *ph)
entry->fd = autofs_dup_pipe(master, ple, entry->fd);
if (entry->fd < 0) {
pr_err("Failed to find free fd in process %d\n",
vpid(master));
pr_err("Failed to find free fd in process %d\n", vpid(master));
return -1;
}
}
@@ -1025,8 +993,7 @@ static int autofs_restore_entry(struct mount_info *mi, AutofsEntry **entry)
return 0;
}
int autofs_mount(struct mount_info *mi, const char *source, const
char *filesystemtype, unsigned long mountflags)
int autofs_mount(struct mount_info *mi, const char *source, const char *filesystemtype, unsigned long mountflags)
{
AutofsEntry *entry;
autofs_info_t *info;
@@ -1048,8 +1015,7 @@ int autofs_mount(struct mount_info *mi, const char *source, const
if (entry->mode == AUTOFS_MODE_OFFSET)
mode = "offset";
opts = xsprintf("fd=%d,pgrp=%d,minproto=%d,maxproto=%d,%s",
control_pipe[1], getpgrp(), entry->minproto,
opts = xsprintf("fd=%d,pgrp=%d,minproto=%d,maxproto=%d,%s", control_pipe[1], getpgrp(), entry->minproto,
entry->maxproto, mode);
if (opts && entry->has_uid)
opts = xstrcat(opts, ",uid=%d", entry->uid);
@@ -1060,8 +1026,7 @@ int autofs_mount(struct mount_info *mi, const char *source, const
goto close_pipe;
}
pr_info("autofs: mounting to %s with options: \"%s\"\n",
mi->mountpoint, opts);
pr_info("autofs: mounting to %s with options: \"%s\"\n", mi->mountpoint, opts);
if (mount(source, mi->mountpoint, filesystemtype, mountflags, opts) < 0) {
pr_perror("Failed to mount autofs to %s", mi->mountpoint);
@@ -1118,4 +1083,3 @@ umount:
pr_perror("Failed to umount %s", mi->mountpoint);
goto close_pipe;
}

View File

@@ -16,14 +16,14 @@
#include "xmalloc.h"
#include "page.h"
#undef LOG_PREFIX
#undef LOG_PREFIX
#define LOG_PREFIX "bfd: "
/*
* Kernel doesn't produce more than one page of
* date per one read call on proc files.
*/
#define BUFSIZE (PAGE_SIZE)
#define BUFSIZE (PAGE_SIZE)
struct bfd_buf {
char *mem;
@@ -32,7 +32,7 @@ struct bfd_buf {
static LIST_HEAD(bufs);
#define BUFBATCH (16)
#define BUFBATCH (16)
static int buf_get(struct xbuf *xb)
{
@@ -42,8 +42,7 @@ static int buf_get(struct xbuf *xb)
void *mem;
int i;
mem = mmap(NULL, BUFBATCH * BUFSIZE, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
mem = mmap(NULL, BUFBATCH * BUFSIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
if (mem == MAP_FAILED) {
pr_perror("No buf");
return -1;

View File

@@ -1,17 +1,12 @@
#include "common/bitsperlong.h"
#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
#define BITMAP_FIRST_WORD_MASK(start) (~0ul << ((start) % BITS_PER_LONG))
#define BITMAP_LAST_WORD_MASK(nbits) \
( \
((nbits) % BITS_PER_LONG) ? \
(1ul << ((nbits) % BITS_PER_LONG)) - 1 : ~0ul \
)
#define BITMAP_LAST_WORD_MASK(nbits) (((nbits) % BITS_PER_LONG) ? (1ul << ((nbits) % BITS_PER_LONG)) - 1 : ~0ul)
#define small_const_nbits(nbits) \
(__builtin_constant_p(nbits) && (nbits) <= BITS_PER_LONG)
#define small_const_nbits(nbits) (__builtin_constant_p(nbits) && (nbits) <= BITS_PER_LONG)
void bitmap_set(unsigned long *map, int start, int nr)
{

View File

@@ -19,8 +19,8 @@ int is_bpfmap_link(char *link)
static void pr_info_bpfmap(char *action, BpfmapFileEntry *bpf)
{
pr_info("%sbpfmap: id %#08x map_id %#08x map_type %d flags %"PRIx32"\n",
action, bpf->id, bpf->map_id, bpf->map_type, bpf->map_flags);
pr_info("%sbpfmap: id %#08x map_id %#08x map_type %d flags %" PRIx32 "\n", action, bpf->id, bpf->map_id,
bpf->map_type, bpf->map_flags);
}
struct bpfmap_data_rst *bpfmap_data_hash_table[BPFMAP_DATA_TABLE_SIZE];
@@ -31,8 +31,7 @@ static int bpfmap_data_read(struct cr_img *img, struct bpfmap_data_rst *r)
if (!bytes)
return 0;
r->data = mmap(NULL, bytes, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, 0, 0);
r->data = mmap(NULL, bytes, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
if (r->data == MAP_FAILED) {
pr_perror("Can't map mem for bpfmap buffers");
return -1;
@@ -41,8 +40,8 @@ static int bpfmap_data_read(struct cr_img *img, struct bpfmap_data_rst *r)
return read_img_buf(img, r->data, bytes);
}
int do_collect_bpfmap_data(struct bpfmap_data_rst *r, ProtobufCMessage *msg,
struct cr_img *img, struct bpfmap_data_rst **bpf_hash_table)
int do_collect_bpfmap_data(struct bpfmap_data_rst *r, ProtobufCMessage *msg, struct cr_img *img,
struct bpfmap_data_rst **bpf_hash_table)
{
int ret;
int table_index;
@@ -67,14 +66,9 @@ int restore_bpfmap_data(int map_fd, uint32_t map_id, struct bpfmap_data_rst **bp
void *keys = NULL;
void *values = NULL;
unsigned int count;
DECLARE_LIBBPF_OPTS(bpf_map_batch_opts, opts,
.elem_flags = 0,
.flags = 0,
);
for (map_data = bpf_hash_table[map_id & BPFMAP_DATA_HASH_MASK]; map_data != NULL;
map_data = map_data->next) {
DECLARE_LIBBPF_OPTS(bpf_map_batch_opts, opts, .elem_flags = 0, .flags = 0, );
for (map_data = bpf_hash_table[map_id & BPFMAP_DATA_HASH_MASK]; map_data != NULL; map_data = map_data->next) {
if (map_data->bde->map_id == map_id)
break;
}
@@ -87,16 +81,14 @@ int restore_bpfmap_data(int map_fd, uint32_t map_id, struct bpfmap_data_rst **bp
bde = map_data->bde;
count = bde->count;
keys = mmap(NULL, bde->keys_bytes, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, 0, 0);
keys = mmap(NULL, bde->keys_bytes, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
if (keys == MAP_FAILED) {
pr_perror("Can't map memory for BPF map keys");
goto err;
}
memcpy(keys, map_data->data, bde->keys_bytes);
values = mmap(NULL, bde->values_bytes, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, 0, 0);
values = mmap(NULL, bde->values_bytes, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
if (values == MAP_FAILED) {
pr_perror("Can't map memory for BPF map values");
goto err;
@@ -157,10 +149,7 @@ int dump_one_bpfmap_data(BpfmapFileEntry *bpf, int lfd, const struct fd_parms *p
void *keys = NULL, *values = NULL;
void *in_batch = NULL, *out_batch = NULL;
BpfmapDataEntry bde = BPFMAP_DATA_ENTRY__INIT;
DECLARE_LIBBPF_OPTS(bpf_map_batch_opts, opts,
.elem_flags = 0,
.flags = 0,
);
DECLARE_LIBBPF_OPTS(bpf_map_batch_opts, opts, .elem_flags = 0, .flags = 0, );
int ret;
key_size = bpf->key_size;
@@ -168,22 +157,19 @@ int dump_one_bpfmap_data(BpfmapFileEntry *bpf, int lfd, const struct fd_parms *p
max_entries = bpf->max_entries;
count = max_entries;
keys = mmap(NULL, key_size * max_entries, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, 0, 0);
keys = mmap(NULL, key_size * max_entries, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
if (keys == MAP_FAILED) {
pr_perror("Can't map memory for BPF map keys");
goto err;
}
values = mmap(NULL, value_size * max_entries, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, 0, 0);
values = mmap(NULL, value_size * max_entries, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
if (values == MAP_FAILED) {
pr_perror("Can't map memory for BPF map values");
goto err;
}
out_batch = mmap(NULL, key_size, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, 0, 0);
out_batch = mmap(NULL, key_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
if (out_batch == MAP_FAILED) {
pr_perror("Can't map memory for BPF map out_batch");
goto err;
@@ -244,38 +230,36 @@ static int dump_one_bpfmap(int lfd, u32 id, const struct fd_parms *p)
}
switch (bpf.map_type) {
case BPF_MAP_TYPE_HASH:
case BPF_MAP_TYPE_ARRAY:
bpf.id = id;
bpf.flags = p->flags;
bpf.fown = (FownEntry *)&p->fown;
bpf.map_name = xstrdup(map_info.name);
bpf.ifindex = map_info.ifindex;
case BPF_MAP_TYPE_HASH:
case BPF_MAP_TYPE_ARRAY:
bpf.id = id;
bpf.flags = p->flags;
bpf.fown = (FownEntry *)&p->fown;
bpf.map_name = xstrdup(map_info.name);
bpf.ifindex = map_info.ifindex;
fe.type = FD_TYPES__BPFMAP;
fe.id = bpf.id;
fe.bpf = &bpf;
fe.type = FD_TYPES__BPFMAP;
fe.id = bpf.id;
fe.bpf = &bpf;
pr_info_bpfmap("Dumping ", &bpf);
if (pb_write_one(img_from_set(glob_imgset, CR_FD_FILES), &fe, PB_FILE))
return -1;
pr_info_bpfmap("Dumping data for ", &bpf);
ret = dump_one_bpfmap_data(&bpf, lfd, p);
break;
pr_info_bpfmap("Dumping ", &bpf);
if (pb_write_one(img_from_set(glob_imgset, CR_FD_FILES), &fe, PB_FILE))
return -1;
pr_info_bpfmap("Dumping data for ", &bpf);
ret = dump_one_bpfmap_data(&bpf, lfd, p);
break;
default:
pr_err("CRIU does not currently support dumping BPF map type %u!\n", bpf.map_type);
ret = -1;
default:
pr_err("CRIU does not currently support dumping BPF map type %u!\n", bpf.map_type);
ret = -1;
}
return ret;
}
const struct fdtype_ops bpfmap_dump_ops = {
.type = FD_TYPES__BPFMAP,
.dump = dump_one_bpfmap,
.type = FD_TYPES__BPFMAP,
.dump = dump_one_bpfmap,
};
static int bpfmap_open(struct file_desc *d, int *new_fd)

View File

@@ -20,7 +20,7 @@
#include "log.h"
#include "common/bug.h"
#undef LOG_PREFIX
#undef LOG_PREFIX
#define LOG_PREFIX "cg-prop: "
enum {
@@ -36,14 +36,14 @@ static const char *____criu_global_props____[] = {
};
cgp_t cgp_global = {
.name = "____criu_global_props____",
.nr_props = ARRAY_SIZE(____criu_global_props____),
.props = ____criu_global_props____,
.name = "____criu_global_props____",
.nr_props = ARRAY_SIZE(____criu_global_props____),
.props = ____criu_global_props____,
};
typedef struct {
struct list_head list;
cgp_t cgp;
struct list_head list;
cgp_t cgp;
} cgp_list_entry_t;
static LIST_HEAD(cgp_list);
@@ -91,9 +91,7 @@ static int cgp_handle_props(cgp_list_entry_t **p, int strategy)
if (strcmp(t->cgp.name, s->cgp.name))
continue;
pr_debug("%s \"%s\" controller properties\n",
strategy == CGP_MERGE ?
"Merging" : "Replacing",
pr_debug("%s \"%s\" controller properties\n", strategy == CGP_MERGE ? "Merging" : "Replacing",
s->cgp.name);
if (strategy == CGP_MERGE) {
@@ -258,21 +256,18 @@ static int cgp_parse_stream(char *stream, size_t len)
}
if (!eat_symbols(&stream, &len, ":\n - ", 5, true)) {
pr_err("Expected \':\\n - \' sequence controller's %s stream\n",
cgp_entry->cgp.name);
pr_err("Expected \':\\n - \' sequence controller's %s stream\n", cgp_entry->cgp.name);
goto err_parse;
}
if (!eat_word(&stream, &len, "\"strategy\":", 11, true)) {
pr_err("Expected \'strategy:\' keyword in controller's %s stream\n",
cgp_entry->cgp.name);
pr_err("Expected \'strategy:\' keyword in controller's %s stream\n", cgp_entry->cgp.name);
goto err_parse;
}
p = get_quoted(&stream, &len, true);
if (!p) {
pr_err("Expected strategy in controller's %s stream\n",
cgp_entry->cgp.name);
pr_err("Expected strategy in controller's %s stream\n", cgp_entry->cgp.name);
goto err_parse;
};
@@ -281,8 +276,7 @@ static int cgp_parse_stream(char *stream, size_t len)
} else if (!strcmp(p, "replace")) {
strategy = CGP_REPLACE;
} else {
pr_err("Unknown strategy \"%s\" in controller's %s stream\n",
p, cgp_entry->cgp.name);
pr_err("Unknown strategy \"%s\" in controller's %s stream\n", p, cgp_entry->cgp.name);
xfree(p);
goto err_parse;
}
@@ -291,34 +285,28 @@ static int cgp_parse_stream(char *stream, size_t len)
xfree(p);
if (!eat_symbols(&stream, &len, "\n - ", 4, true)) {
pr_err("Expected \':\\n - \' sequence controller's %s stream\n",
cgp_entry->cgp.name);
pr_err("Expected \':\\n - \' sequence controller's %s stream\n", cgp_entry->cgp.name);
goto err_parse;
}
if (!eat_word(&stream, &len, "\"properties\":", 13, true)) {
pr_err("Expected \"properties:\" keyword in controller's %s stream\n",
cgp_entry->cgp.name);
pr_err("Expected \"properties:\" keyword in controller's %s stream\n", cgp_entry->cgp.name);
goto err_parse;
}
if (!eat_symbol(&stream, &len, '[', true)) {
pr_err("Expected \'[\' sequence controller's %s properties stream\n",
cgp_entry->cgp.name);
pr_err("Expected \'[\' sequence controller's %s properties stream\n", cgp_entry->cgp.name);
goto err_parse;
}
while ((p = get_quoted(&stream, &len, true))) {
if (!p) {
pr_err("Expected property name for controller %s\n",
cgp_entry->cgp.name);
pr_err("Expected property name for controller %s\n", cgp_entry->cgp.name);
goto err_parse;
}
if (xrealloc_safe(&cgp_entry->cgp.props,
(cgp_entry->cgp.nr_props + 1) * sizeof(char *))) {
pr_err("Can't allocate property for controller %s\n",
cgp_entry->cgp.name);
if (xrealloc_safe(&cgp_entry->cgp.props, (cgp_entry->cgp.nr_props + 1) * sizeof(char *))) {
pr_err("Can't allocate property for controller %s\n", cgp_entry->cgp.name);
xfree(p);
goto err_parse;
}
@@ -331,8 +319,7 @@ static int cgp_parse_stream(char *stream, size_t len)
stream++, len--;
break;
}
pr_err("Expected ']' in controller's %s stream\n",
cgp_entry->cgp.name);
pr_err("Expected ']' in controller's %s stream\n", cgp_entry->cgp.name);
goto err_parse;
}
}
@@ -343,8 +330,7 @@ static int cgp_parse_stream(char *stream, size_t len)
}
if (!eat_symbol(&stream, &len, '\n', true) && len) {
pr_err("Expected \'\\n\' symbol in controller's %s stream\n",
cgp_entry->cgp.name);
pr_err("Expected \'\\n\' symbol in controller's %s stream\n", cgp_entry->cgp.name);
goto err_parse;
}
@@ -402,96 +388,94 @@ err:
static int cgp_parse_builtins(void)
{
static const char predefined_stream[] =
"\"cpu\":\n"
" - \"strategy\": \"replace\"\n"
" - \"properties\": "
"[ "
"\"cpu.shares\", "
"\"cpu.cfs_period_us\", "
"\"cpu.cfs_quota_us\", "
"\"cpu.rt_period_us\", "
"\"cpu.rt_runtime_us\" "
"]\n"
/* limit_in_bytes and memsw.limit_in_bytes must be set in this order */
"\"memory\":\n"
" - \"strategy\": \"replace\"\n"
" - \"properties\": "
"[ "
"\"memory.limit_in_bytes\", "
"\"memory.memsw.limit_in_bytes\", "
"\"memory.swappiness\", "
"\"memory.soft_limit_in_bytes\", "
"\"memory.move_charge_at_immigrate\", "
"\"memory.oom_control\", "
"\"memory.use_hierarchy\", "
"\"memory.kmem.limit_in_bytes\", "
"\"memory.kmem.tcp.limit_in_bytes\" "
"]\n"
/*
static const char predefined_stream[] = "\"cpu\":\n"
" - \"strategy\": \"replace\"\n"
" - \"properties\": "
"[ "
"\"cpu.shares\", "
"\"cpu.cfs_period_us\", "
"\"cpu.cfs_quota_us\", "
"\"cpu.rt_period_us\", "
"\"cpu.rt_runtime_us\" "
"]\n"
/* limit_in_bytes and memsw.limit_in_bytes must be set in this order */
"\"memory\":\n"
" - \"strategy\": \"replace\"\n"
" - \"properties\": "
"[ "
"\"memory.limit_in_bytes\", "
"\"memory.memsw.limit_in_bytes\", "
"\"memory.swappiness\", "
"\"memory.soft_limit_in_bytes\", "
"\"memory.move_charge_at_immigrate\", "
"\"memory.oom_control\", "
"\"memory.use_hierarchy\", "
"\"memory.kmem.limit_in_bytes\", "
"\"memory.kmem.tcp.limit_in_bytes\" "
"]\n"
/*
* cpuset.cpus and cpuset.mems must be set before the process moves
* into its cgroup; they are "initialized" below to whatever the root
* values are in copy_special_cg_props so as not to cause ENOSPC when
* values are restored via this code.
*/
"\"cpuset\":\n"
" - \"strategy\": \"replace\"\n"
" - \"properties\": "
"[ "
"\"cpuset.cpus\", "
"\"cpuset.mems\", "
"\"cpuset.memory_migrate\", "
"\"cpuset.cpu_exclusive\", "
"\"cpuset.mem_exclusive\", "
"\"cpuset.mem_hardwall\", "
"\"cpuset.memory_spread_page\", "
"\"cpuset.memory_spread_slab\", "
"\"cpuset.sched_load_balance\", "
"\"cpuset.sched_relax_domain_level\" "
"]\n"
"\"blkio\":\n"
" - \"strategy\": \"replace\"\n"
" - \"properties\": "
"[ "
"\"blkio.weight\" "
"]\n"
"\"freezer\":\n"
" - \"strategy\": \"replace\"\n"
" - \"properties\": "
"[ "
"]\n"
"\"perf_event\":\n"
" - \"strategy\": \"replace\"\n"
" - \"properties\": "
"[ "
"]\n"
"\"net_cls\":\n"
" - \"strategy\": \"replace\"\n"
" - \"properties\": "
"[ "
"\"net_cls.classid\" "
"]\n"
"\"net_prio\":\n"
" - \"strategy\": \"replace\"\n"
" - \"properties\": "
"[ "
"\"net_prio.ifpriomap\" "
"]\n"
"\"pids\":\n"
" - \"strategy\": \"replace\"\n"
" - \"properties\": "
"[ "
"\"pids.max\" "
"]\n"
"\"devices\":\n"
" - \"strategy\": \"replace\"\n"
" - \"properties\": "
"[ "
"\"devices.list\" "
"]\n";
"\"cpuset\":\n"
" - \"strategy\": \"replace\"\n"
" - \"properties\": "
"[ "
"\"cpuset.cpus\", "
"\"cpuset.mems\", "
"\"cpuset.memory_migrate\", "
"\"cpuset.cpu_exclusive\", "
"\"cpuset.mem_exclusive\", "
"\"cpuset.mem_hardwall\", "
"\"cpuset.memory_spread_page\", "
"\"cpuset.memory_spread_slab\", "
"\"cpuset.sched_load_balance\", "
"\"cpuset.sched_relax_domain_level\" "
"]\n"
"\"blkio\":\n"
" - \"strategy\": \"replace\"\n"
" - \"properties\": "
"[ "
"\"blkio.weight\" "
"]\n"
"\"freezer\":\n"
" - \"strategy\": \"replace\"\n"
" - \"properties\": "
"[ "
"]\n"
"\"perf_event\":\n"
" - \"strategy\": \"replace\"\n"
" - \"properties\": "
"[ "
"]\n"
"\"net_cls\":\n"
" - \"strategy\": \"replace\"\n"
" - \"properties\": "
"[ "
"\"net_cls.classid\" "
"]\n"
"\"net_prio\":\n"
" - \"strategy\": \"replace\"\n"
" - \"properties\": "
"[ "
"\"net_prio.ifpriomap\" "
"]\n"
"\"pids\":\n"
" - \"strategy\": \"replace\"\n"
" - \"properties\": "
"[ "
"\"pids.max\" "
"]\n"
"\"devices\":\n"
" - \"strategy\": \"replace\"\n"
" - \"properties\": "
"[ "
"\"devices.list\" "
"]\n";
return cgp_parse_stream((void *)predefined_stream,
strlen(predefined_stream));
return cgp_parse_stream((void *)predefined_stream, strlen(predefined_stream));
}
int cgp_init(char *stream, size_t len, char *path)

View File

@@ -1,4 +1,4 @@
#define LOG_PREFIX "cg: "
#define LOG_PREFIX "cg: "
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
@@ -36,10 +36,10 @@
*/
struct cg_set {
u32 id;
struct list_head l;
unsigned int n_ctls;
struct list_head ctls;
u32 id;
struct list_head l;
unsigned int n_ctls;
struct list_head ctls;
};
static LIST_HEAD(cg_sets);
@@ -66,8 +66,8 @@ static CgSetEntry *find_rst_set_by_id(u32 id)
return NULL;
}
#define CGCMP_MATCH 1 /* check for exact match */
#define CGCMP_ISSUB 2 /* check set is subset of ctls */
#define CGCMP_MATCH 1 /* check for exact match */
#define CGCMP_ISSUB 2 /* check set is subset of ctls */
static bool cg_set_compare(struct cg_set *set, struct list_head *ctls, int what)
{
@@ -189,8 +189,7 @@ int parse_cg_info(void)
/* Check that co-mounted controllers from /proc/cgroups (e.g. cpu and cpuacct)
* are contained in a comma separated string (e.g. from /proc/self/cgroup or
* mount options). */
static bool cgroup_contains(char **controllers,
unsigned int n_controllers, char *name, u64 *mask)
static bool cgroup_contains(char **controllers, unsigned int n_controllers, char *name, u64 *mask)
{
unsigned int i;
bool all_match = true;
@@ -230,12 +229,12 @@ static bool cgroup_contains(char **controllers,
/* This is for use in add_cgroup() as additional arguments for the ftw()
* callback */
static struct cg_controller *current_controller;
static unsigned int path_pref_len;
static struct cg_controller *current_controller;
static unsigned int path_pref_len;
#define EXACT_MATCH 0
#define PARENT_MATCH 1
#define NO_MATCH 2
#define EXACT_MATCH 0
#define PARENT_MATCH 1
#define NO_MATCH 2
static int find_dir(const char *path, struct list_head *dirs, struct cgroup_dir **rdir)
{
@@ -253,7 +252,6 @@ static int find_dir(const char *path, struct list_head *dirs, struct cgroup_dir
return PARENT_MATCH;
}
return ret;
}
}
@@ -431,8 +429,7 @@ static int dump_cg_props_array(const char *fpath, struct cgroup_dir *ncd, const
return 0;
}
static int add_cgroup_properties(const char *fpath, struct cgroup_dir *ncd,
struct cg_controller *controller)
static int add_cgroup_properties(const char *fpath, struct cgroup_dir *ncd, struct cg_controller *controller)
{
int i;
@@ -527,7 +524,7 @@ static int add_freezer_state(struct cg_controller *controller)
{
struct cgroup_dir *it;
/* There is one more case, that cgroup namespaces might
/* There is one more case, that cgroup namespaces might
* generate "multiple" heads if nothing is actually in the
* root freezer cgroup, e.g. --freeze-cgroup=/lxc/foo and all
* tasks in either /lxc/foo/a or /lxc/foo/b.
@@ -570,12 +567,11 @@ static int __new_open_cgroupfs(struct cg_ctl *cc)
}
if (strstartswith(cc->name, namestr)) {
if (sys_fsconfig(fsfd, FSCONFIG_SET_STRING,
"name", cc->name + strlen(namestr), 0)) {
if (sys_fsconfig(fsfd, FSCONFIG_SET_STRING, "name", cc->name + strlen(namestr), 0)) {
pr_perror("Unable to configure the cgroup (%s) file system", cc->name);
goto err;
}
} else if (cc->name[0] != 0) { /* cgroup v1 */
} else if (cc->name[0] != 0) { /* cgroup v1 */
char *saveptr = NULL, *buf = strdupa(cc->name);
name = strtok_r(buf, ",", &saveptr);
while (name) {
@@ -723,8 +719,7 @@ static int collect_cgroups(struct list_head *ctls)
if (ret < 0)
return ret;
if (opts.freeze_cgroup && !strcmp(cc->name, "freezer") &&
add_freezer_state(current_controller))
if (opts.freeze_cgroup && !strcmp(cc->name, "freezer") && add_freezer_state(current_controller))
return -1;
}
@@ -776,7 +771,8 @@ int dump_task_cgroup(struct pstree_item *item, u32 *cg_id, struct parasite_dump_
continue;
if (strlen(stray->path) < root->cgns_prefix) {
pr_err("cg %s shorter than path prefix %d?\n", stray->path, root->cgns_prefix);
pr_err("cg %s shorter than path prefix %d?\n", stray->path,
root->cgns_prefix);
return -1;
}
@@ -790,8 +786,7 @@ int dump_task_cgroup(struct pstree_item *item, u32 *cg_id, struct parasite_dump_
return 0;
}
static int dump_cg_dir_props(struct list_head *props, size_t n_props,
CgroupPropEntry ***ents)
static int dump_cg_dir_props(struct list_head *props, size_t n_props, CgroupPropEntry ***ents)
{
struct cgroup_prop *prop_cur;
CgroupPropEntry *cpe;
@@ -876,8 +871,7 @@ static int dump_cg_dirs(struct list_head *dirs, size_t n_dirs, CgroupDirEntry **
cde->n_properties = cur->n_properties;
if (cde->n_properties > 0) {
if (dump_cg_dir_props(&cur->properties,
cde->n_properties, &cde->properties) < 0) {
if (dump_cg_dir_props(&cur->properties, cde->n_properties, &cde->properties) < 0) {
xfree(*ents);
return -1;
}
@@ -931,7 +925,6 @@ static void free_sets(CgroupEntry *cg, unsigned nr)
xfree(cg->sets);
}
static int dump_sets(CgroupEntry *cg)
{
struct cg_set *set;
@@ -1024,8 +1017,7 @@ err:
return ret;
}
static int ctrl_dir_and_opt(CgControllerEntry *ctl, char *dir, int ds,
char *opt, int os)
static int ctrl_dir_and_opt(CgControllerEntry *ctl, char *dir, int ds, char *opt, int os)
{
int i, doff = 0, ooff = 0;
bool none_opt = false;
@@ -1062,14 +1054,8 @@ static int ctrl_dir_and_opt(CgControllerEntry *ctl, char *dir, int ds,
* it. We restore these properties as soon as the cgroup is created.
*/
static const char *special_props[] = {
"cpuset.cpus",
"cpuset.mems",
"devices.list",
"memory.kmem.limit_in_bytes",
"memory.swappiness",
"memory.oom_control",
"memory.use_hierarchy",
NULL,
"cpuset.cpus", "cpuset.mems", "devices.list", "memory.kmem.limit_in_bytes",
"memory.swappiness", "memory.oom_control", "memory.use_hierarchy", NULL,
};
bool is_special_property(const char *prop)
@@ -1165,7 +1151,6 @@ static int prepare_cgns(CgSetEntry *se)
do_unshare = true;
}
}
if (do_unshare && unshare(CLONE_NEWCGROUP) < 0) {
@@ -1294,13 +1279,12 @@ static int restore_perms(int fd, const char *path, CgroupPerms *perms)
* allowed to chmod some cgroup props (e.g. the read only ones), so we
* don't want to try if the perms already match.
*/
if (sb.st_mode != (mode_t) perms->mode && fchmod(fd, perms->mode) < 0) {
if (sb.st_mode != (mode_t)perms->mode && fchmod(fd, perms->mode) < 0) {
pr_perror("chmod of %s failed", path);
return -1;
}
if ((sb.st_uid != perms->uid || sb.st_gid != perms->gid) &&
fchown(fd, perms->uid, perms->gid)) {
if ((sb.st_uid != perms->uid || sb.st_gid != perms->gid) && fchown(fd, perms->uid, perms->gid)) {
pr_perror("chown of %s failed", path);
return -1;
}
@@ -1309,8 +1293,8 @@ static int restore_perms(int fd, const char *path, CgroupPerms *perms)
return 0;
}
static int restore_cgroup_prop(const CgroupPropEntry *cg_prop_entry_p,
char *path, int off, bool split_lines, bool skip_fails)
static int restore_cgroup_prop(const CgroupPropEntry *cg_prop_entry_p, char *path, int off, bool split_lines,
bool skip_fails)
{
int cg, fd, ret = -1;
CgroupPerms *perms = cg_prop_entry_p->perms;
@@ -1358,7 +1342,7 @@ static int restore_cgroup_prop(const CgroupPropEntry *cg_prop_entry_p,
goto out;
}
line = next_line + 1;
} while(*next_line != '\0');
} while (*next_line != '\0');
} else {
size_t len = strlen(cg_prop_entry_p->value);
@@ -1389,8 +1373,7 @@ int restore_freezer_state(void)
return 0;
freezer_path_len = strlen(freezer_path);
return restore_cgroup_prop(freezer_state_entry, freezer_path,
freezer_path_len, false, false);
return restore_cgroup_prop(freezer_state_entry, freezer_path, freezer_path_len, false, false);
}
static void add_freezer_state_for_restore(CgroupPropEntry *entry, char *path, size_t path_len)
@@ -1455,9 +1438,9 @@ static int filter_ifpriomap(char *out, char *line)
strncpy(out, line, len + 1);
out += len + 1;
written = true;
next:
next:
line = next_line + 1;
} while(*next_line != '\0');
} while (*next_line != '\0');
if (written)
*(out - 1) = '\0';
@@ -1486,8 +1469,7 @@ out:
return ret;
}
static int prepare_cgroup_dir_properties(char *path, int off, CgroupDirEntry **ents,
unsigned int n_ents)
static int prepare_cgroup_dir_properties(char *path, int off, CgroupDirEntry **ents, unsigned int n_ents)
{
unsigned int i, j;
@@ -1528,7 +1510,7 @@ static int prepare_cgroup_dir_properties(char *path, int off, CgroupDirEntry **e
if (restore_cgroup_prop(p, path, off2, false, false) < 0)
return -1;
}
skip:
skip:
if (prepare_cgroup_dir_properties(path, off2, e->children, e->n_children) < 0)
return -1;
}
@@ -1655,8 +1637,8 @@ static int prepare_dir_perms(int cg, char *path, CgroupPerms *perms)
return ret;
}
static int prepare_cgroup_dirs(char **controllers, int n_controllers, char *paux, size_t off,
CgroupDirEntry **ents, size_t n_ents)
static int prepare_cgroup_dirs(char **controllers, int n_controllers, char *paux, size_t off, CgroupDirEntry **ents,
size_t n_ents)
{
size_t i, j;
CgroupDirEntry *e;
@@ -1689,9 +1671,8 @@ static int prepare_cgroup_dirs(char **controllers, int n_controllers, char *paux
return -1;
for (j = 0; j < n_controllers; j++) {
if (!strcmp(controllers[j], "cpuset")
|| !strcmp(controllers[j], "memory")
|| !strcmp(controllers[j], "devices")) {
if (!strcmp(controllers[j], "cpuset") || !strcmp(controllers[j], "memory") ||
!strcmp(controllers[j], "devices")) {
if (restore_special_props(paux, off2, e) < 0) {
pr_err("Restoring special cpuset props failed!\n");
return -1;
@@ -1715,13 +1696,11 @@ static int prepare_cgroup_dirs(char **controllers, int n_controllers, char *paux
}
}
if (!(opts.manage_cgroups & CG_MODE_NONE) &&
prepare_dir_perms(cg, paux, e->dir_perms) < 0)
if (!(opts.manage_cgroups & CG_MODE_NONE) && prepare_dir_perms(cg, paux, e->dir_perms) < 0)
return -1;
}
if (prepare_cgroup_dirs(controllers, n_controllers, paux, off2,
e->children, e->n_children) < 0)
if (prepare_cgroup_dirs(controllers, n_controllers, paux, off2, e->children, e->n_children) < 0)
return -1;
}
@@ -1754,8 +1733,7 @@ static int prepare_cgroup_sfd(CgroupEntry *ce)
if (!opts.manage_cgroups)
return 0;
pr_info("Preparing cgroups yard (cgroups restore mode %#x)\n",
opts.manage_cgroups);
pr_info("Preparing cgroups yard (cgroups restore mode %#x)\n", opts.manage_cgroups);
if (opts.cgroup_yard) {
off = sprintf(paux, "%s", opts.cgroup_yard);
@@ -1803,9 +1781,7 @@ static int prepare_cgroup_sfd(CgroupEntry *ce)
return -1;
}
ctl_off += ctrl_dir_and_opt(ctrl,
paux + ctl_off, sizeof(paux) - ctl_off,
opt, sizeof(opt));
ctl_off += ctrl_dir_and_opt(ctrl, paux + ctl_off, sizeof(paux) - ctl_off, opt, sizeof(opt));
/* Create controller if not yet present */
if (access(paux, F_OK)) {
@@ -1831,16 +1807,14 @@ static int prepare_cgroup_sfd(CgroupEntry *ce)
yard = paux + strlen(cg_yard) + 1;
yard_off = ctl_off - (strlen(cg_yard) + 1);
if (opts.manage_cgroups &&
prepare_cgroup_dirs(ctrl->cnames, ctrl->n_cnames, yard, yard_off,
ctrl->dirs, ctrl->n_dirs))
prepare_cgroup_dirs(ctrl->cnames, ctrl->n_cnames, yard, yard_off, ctrl->dirs, ctrl->n_dirs))
return -1;
}
return 0;
}
static int rewrite_cgsets(CgroupEntry *cge, char **controllers, int n_controllers,
char **dir_name, char *newroot)
static int rewrite_cgsets(CgroupEntry *cge, char **controllers, int n_controllers, char **dir_name, char *newroot)
{
size_t dirlen = strlen(*dir_name);
char *dir = *dir_name;
@@ -1877,7 +1851,7 @@ static int rewrite_cgsets(CgroupEntry *cge, char **controllers, int n_controller
* "/" is matching to be renamed.
*/
if (!(cgroup_contains(controllers, n_controllers, cg->name, NULL) &&
strstartswith(cg->path + 1, dir)))
strstartswith(cg->path + 1, dir)))
continue;
if (cg->has_cgns_prefix && cg->cgns_prefix) {
@@ -1905,8 +1879,7 @@ static int rewrite_cgsets(CgroupEntry *cge, char **controllers, int n_controller
* root but make sure the rest of path is
* untouched.
*/
cg->path = xsprintf("%s%s", newroot,
cg->path + dirlen + 1);
cg->path = xsprintf("%s%s", newroot, cg->path + dirlen + 1);
if (!cg->path) {
cg->path = prev;
xfree(dirnew);
@@ -1943,12 +1916,10 @@ static int rewrite_cgroup_roots(CgroupEntry *cge)
unsigned old_mask = ctrl_mask;
/* coverity[check_return] */
cgroup_contains(ctrl->cnames, ctrl->n_cnames,
o->controller, &ctrl_mask);
cgroup_contains(ctrl->cnames, ctrl->n_cnames, o->controller, &ctrl_mask);
if (old_mask != ctrl_mask) {
if (newroot && strcmp(newroot, o->newroot)) {
pr_err("CG paths mismatch: %s %s\n",
newroot, o->newroot);
pr_err("CG paths mismatch: %s %s\n", newroot, o->newroot);
return -1;
}
newroot = o->newroot;

View File

@@ -46,8 +46,7 @@ int clone_noasan(int (*fn)(void *), int flags, void *arg)
return clone(fn, stack_ptr, flags, arg);
}
int clone3_with_pid_noasan(int (*fn)(void *), void *arg, int flags,
int exit_signal, pid_t pid)
int clone3_with_pid_noasan(int (*fn)(void *), void *arg, int flags, int exit_signal, pid_t pid)
{
struct _clone_args c_args = {};

View File

@@ -131,7 +131,7 @@ int parse_statement(int i, char *line, char **configuration)
/* We got "" as value */
configuration[i] = xstrdup("");
if (unlikely(!configuration[i])) {
xfree(configuration[i -1]);
xfree(configuration[i - 1]);
return -1;
}
offset = 0;
@@ -152,7 +152,7 @@ int parse_statement(int i, char *line, char **configuration)
found_second_quote = true;
configuration[i] = xzalloc(quote_offset - offset + 1);
if (unlikely(!configuration[i])) {
xfree(configuration[i -1]);
xfree(configuration[i - 1]);
return -1;
}
memcpy(configuration[i], quote_start, quote_offset - offset);
@@ -185,7 +185,7 @@ int parse_statement(int i, char *line, char **configuration)
} else {
/* Does not start with a quote. */
if (unlikely(asprintf(&configuration[i], "%s", input + offset) == -1)) {
xfree(configuration[i -1]);
xfree(configuration[i - 1]);
return -1;
}
@@ -249,10 +249,10 @@ out:
}
/* Parse a configuration file */
static char ** parse_config(char *filepath)
static char **parse_config(char *filepath)
{
#define DEFAULT_CONFIG_SIZE 10
FILE* configfile = fopen(filepath, "r");
#define DEFAULT_CONFIG_SIZE 10
FILE *configfile = fopen(filepath, "r");
int config_size = DEFAULT_CONFIG_SIZE;
int i = 1;
size_t line_size = 0;
@@ -315,8 +315,7 @@ static char ** parse_config(char *filepath)
return configuration;
}
static int next_config(char **argv, char ***_argv, bool no_default_config,
int state, char *cfg_file)
static int next_config(char **argv, char ***_argv, bool no_default_config, int state, char *cfg_file)
{
char local_filepath[PATH_MAX + 1];
char *home_dir = NULL;
@@ -325,52 +324,51 @@ static int next_config(char **argv, char ***_argv, bool no_default_config,
if (state >= PARSING_LAST)
return 0;
switch(state) {
case PARSING_GLOBAL_CONF:
if (no_default_config)
break;
*_argv = parse_config(GLOBAL_CONFIG_DIR DEFAULT_CONFIG_FILENAME);
switch (state) {
case PARSING_GLOBAL_CONF:
if (no_default_config)
break;
case PARSING_USER_CONF:
if (no_default_config)
break;
home_dir = getenv("HOME");
if (!home_dir) {
pr_info("Unable to get $HOME directory, local configuration file will not be used.\n");
} else {
snprintf(local_filepath, PATH_MAX, "%s/%s%s",
home_dir, USER_CONFIG_DIR, DEFAULT_CONFIG_FILENAME);
*_argv = parse_config(local_filepath);
}
*_argv = parse_config(GLOBAL_CONFIG_DIR DEFAULT_CONFIG_FILENAME);
break;
case PARSING_USER_CONF:
if (no_default_config)
break;
case PARSING_ENV_CONF:
cfg_from_env = getenv("CRIU_CONFIG_FILE");
if (!cfg_from_env)
break;
*_argv = parse_config(cfg_from_env);
home_dir = getenv("HOME");
if (!home_dir) {
pr_info("Unable to get $HOME directory, local configuration file will not be used.\n");
} else {
snprintf(local_filepath, PATH_MAX, "%s/%s%s", home_dir, USER_CONFIG_DIR,
DEFAULT_CONFIG_FILENAME);
*_argv = parse_config(local_filepath);
}
break;
case PARSING_ENV_CONF:
cfg_from_env = getenv("CRIU_CONFIG_FILE");
if (!cfg_from_env)
break;
case PARSING_CMDLINE_CONF:
if (!cfg_file)
break;
*_argv = parse_config(cfg_file);
*_argv = parse_config(cfg_from_env);
break;
case PARSING_CMDLINE_CONF:
if (!cfg_file)
break;
case PARSING_ARGV:
*_argv = argv;
break;
case PARSING_RPC_CONF:
if (!rpc_cfg_file)
break;
*_argv = parse_config(rpc_cfg_file);
break;
default:
*_argv = parse_config(cfg_file);
break;
case PARSING_ARGV:
*_argv = argv;
break;
case PARSING_RPC_CONF:
if (!rpc_cfg_file)
break;
*_argv = parse_config(rpc_cfg_file);
break;
default:
break;
}
return ++state;
}
static int pre_parse(int argc, char **argv, bool *usage_error, bool *no_default_config,
char **cfg_file)
static int pre_parse(int argc, char **argv, bool *usage_error, bool *no_default_config, char **cfg_file)
{
int i;
/*
@@ -447,12 +445,12 @@ static int parse_cpu_cap(struct cr_options *opts, const char *optarg)
{
bool inverse = false;
#define ____cpu_set_cap(__opts, __cap, __inverse) \
do { \
if ((__inverse)) \
(__opts)->cpu_cap &= ~(__cap); \
else \
(__opts)->cpu_cap |= (__cap); \
#define ____cpu_set_cap(__opts, __cap, __inverse) \
do { \
if ((__inverse)) \
(__opts)->cpu_cap &= ~(__cap); \
else \
(__opts)->cpu_cap |= (__cap); \
} while (0)
if (!optarg) {
@@ -594,8 +592,7 @@ Esyntax:
* correct, '1' if something failed and '2' if the CRIU help text should
* be displayed.
*/
int parse_options(int argc, char **argv, bool *usage_error,
bool *has_exec_cmd, int state)
int parse_options(int argc, char **argv, bool *usage_error, bool *has_exec_cmd, int state)
{
int ret;
int opt = -1;
@@ -605,99 +602,99 @@ int parse_options(int argc, char **argv, bool *usage_error,
char **_argv = NULL;
int _argc = 0;
#define BOOL_OPT(OPT_NAME, SAVE_TO) \
{OPT_NAME, no_argument, SAVE_TO, true},\
{"no-" OPT_NAME, no_argument, SAVE_TO, false}
#define BOOL_OPT(OPT_NAME, SAVE_TO) \
{ OPT_NAME, no_argument, SAVE_TO, true }, \
{ \
"no-" OPT_NAME, no_argument, SAVE_TO, false \
}
static const char short_opts[] = "dSsRt:hD:o:v::x::Vr:jJ:lW:L:M:";
static struct option long_opts[] = {
{ "tree", required_argument, 0, 't' },
{ "leave-stopped", no_argument, 0, 's' },
{ "leave-running", no_argument, 0, 'R' },
{ "tree", required_argument, 0, 't' },
{ "leave-stopped", no_argument, 0, 's' },
{ "leave-running", no_argument, 0, 'R' },
BOOL_OPT("restore-detached", &opts.restore_detach),
BOOL_OPT("restore-sibling", &opts.restore_sibling),
BOOL_OPT("daemon", &opts.restore_detach),
{ "images-dir", required_argument, 0, 'D' },
{ "work-dir", required_argument, 0, 'W' },
{ "log-file", required_argument, 0, 'o' },
{ "join-ns", required_argument, 0, 'J' },
{ "root", required_argument, 0, 'r' },
{ USK_EXT_PARAM, optional_argument, 0, 'x' },
{ "help", no_argument, 0, 'h' },
{ "images-dir", required_argument, 0, 'D' },
{ "work-dir", required_argument, 0, 'W' },
{ "log-file", required_argument, 0, 'o' },
{ "join-ns", required_argument, 0, 'J' },
{ "root", required_argument, 0, 'r' },
{ USK_EXT_PARAM, optional_argument, 0, 'x' },
{ "help", no_argument, 0, 'h' },
BOOL_OPT(SK_EST_PARAM, &opts.tcp_established_ok),
{ "close", required_argument, 0, 1043 },
{ "close", required_argument, 0, 1043 },
BOOL_OPT("log-pid", &opts.log_file_per_pid),
{ "version", no_argument, 0, 'V' },
{ "version", no_argument, 0, 'V' },
BOOL_OPT("evasive-devices", &opts.evasive_devices),
{ "pidfile", required_argument, 0, 1046 },
{ "veth-pair", required_argument, 0, 1047 },
{ "action-script", required_argument, 0, 1049 },
{ "pidfile", required_argument, 0, 1046 },
{ "veth-pair", required_argument, 0, 1047 },
{ "action-script", required_argument, 0, 1049 },
BOOL_OPT(LREMAP_PARAM, &opts.link_remap_ok),
BOOL_OPT(OPT_SHELL_JOB, &opts.shell_job),
BOOL_OPT(OPT_FILE_LOCKS, &opts.handle_file_locks),
BOOL_OPT("page-server", &opts.use_page_server),
{ "address", required_argument, 0, 1051 },
{ "port", required_argument, 0, 1052 },
{ "prev-images-dir", required_argument, 0, 1053 },
{ "ms", no_argument, 0, 1054 },
{ "address", required_argument, 0, 1051 },
{ "port", required_argument, 0, 1052 },
{ "prev-images-dir", required_argument, 0, 1053 },
{ "ms", no_argument, 0, 1054 },
BOOL_OPT("track-mem", &opts.track_mem),
BOOL_OPT("auto-dedup", &opts.auto_dedup),
{ "libdir", required_argument, 0, 'L' },
{ "cpu-cap", optional_argument, 0, 1057 },
{ "libdir", required_argument, 0, 'L' },
{ "cpu-cap", optional_argument, 0, 1057 },
BOOL_OPT("force-irmap", &opts.force_irmap),
{ "ext-mount-map", required_argument, 0, 'M' },
{ "exec-cmd", no_argument, 0, 1059 },
{ "manage-cgroups", optional_argument, 0, 1060 },
{ "cgroup-root", required_argument, 0, 1061 },
{ "inherit-fd", required_argument, 0, 1062 },
{ "feature", required_argument, 0, 1063 },
{ "skip-mnt", required_argument, 0, 1064 },
{ "enable-fs", required_argument, 0, 1065 },
{ "enable-external-sharing", no_argument, &opts.enable_external_sharing, true },
{ "enable-external-masters", no_argument, &opts.enable_external_masters, true },
{ "freeze-cgroup", required_argument, 0, 1068 },
{ "ghost-limit", required_argument, 0, 1069 },
{ "irmap-scan-path", required_argument, 0, 1070 },
{ "lsm-profile", required_argument, 0, 1071 },
{ "timeout", required_argument, 0, 1072 },
{ "external", required_argument, 0, 1073 },
{ "empty-ns", required_argument, 0, 1074 },
{ "lazy-pages", no_argument, 0, 1076 },
{ "ext-mount-map", required_argument, 0, 'M' },
{ "exec-cmd", no_argument, 0, 1059 },
{ "manage-cgroups", optional_argument, 0, 1060 },
{ "cgroup-root", required_argument, 0, 1061 },
{ "inherit-fd", required_argument, 0, 1062 },
{ "feature", required_argument, 0, 1063 },
{ "skip-mnt", required_argument, 0, 1064 },
{ "enable-fs", required_argument, 0, 1065 },
{ "enable-external-sharing", no_argument, &opts.enable_external_sharing, true },
{ "enable-external-masters", no_argument, &opts.enable_external_masters, true },
{ "freeze-cgroup", required_argument, 0, 1068 },
{ "ghost-limit", required_argument, 0, 1069 },
{ "irmap-scan-path", required_argument, 0, 1070 },
{ "lsm-profile", required_argument, 0, 1071 },
{ "timeout", required_argument, 0, 1072 },
{ "external", required_argument, 0, 1073 },
{ "empty-ns", required_argument, 0, 1074 },
{ "lazy-pages", no_argument, 0, 1076 },
BOOL_OPT("extra", &opts.check_extra_features),
BOOL_OPT("experimental", &opts.check_experimental_features),
{ "all", no_argument, 0, 1079 },
{ "cgroup-props", required_argument, 0, 1080 },
{ "cgroup-props-file", required_argument, 0, 1081 },
{ "cgroup-dump-controller", required_argument, 0, 1082 },
{ "all", no_argument, 0, 1079 },
{ "cgroup-props", required_argument, 0, 1080 },
{ "cgroup-props-file", required_argument, 0, 1081 },
{ "cgroup-dump-controller", required_argument, 0, 1082 },
BOOL_OPT(SK_INFLIGHT_PARAM, &opts.tcp_skip_in_flight),
BOOL_OPT("deprecated", &opts.deprecated_ok),
BOOL_OPT("display-stats", &opts.display_stats),
BOOL_OPT("weak-sysctls", &opts.weak_sysctls),
{ "status-fd", required_argument, 0, 1088 },
{ "status-fd", required_argument, 0, 1088 },
BOOL_OPT(SK_CLOSE_PARAM, &opts.tcp_close),
{ "verbosity", optional_argument, 0, 'v' },
{ "ps-socket", required_argument, 0, 1091},
{ "verbosity", optional_argument, 0, 'v' },
{ "ps-socket", required_argument, 0, 1091 },
BOOL_OPT("stream", &opts.stream),
{ "config", required_argument, 0, 1089},
{ "no-default-config", no_argument, 0, 1090},
{ "tls-cacert", required_argument, 0, 1092},
{ "tls-cacrl", required_argument, 0, 1093},
{ "tls-cert", required_argument, 0, 1094},
{ "tls-key", required_argument, 0, 1095},
{ "config", required_argument, 0, 1089 },
{ "no-default-config", no_argument, 0, 1090 },
{ "tls-cacert", required_argument, 0, 1092 },
{ "tls-cacrl", required_argument, 0, 1093 },
{ "tls-cert", required_argument, 0, 1094 },
{ "tls-key", required_argument, 0, 1095 },
BOOL_OPT("tls", &opts.tls),
{"tls-no-cn-verify", no_argument, &opts.tls_no_cn_verify, true},
{ "cgroup-yard", required_argument, 0, 1096 },
{ "pre-dump-mode", required_argument, 0, 1097},
{ "file-validation", required_argument, 0, 1098 },
{ "lsm-mount-context", required_argument, 0, 1099 },
{ },
{ "tls-no-cn-verify", no_argument, &opts.tls_no_cn_verify, true },
{ "cgroup-yard", required_argument, 0, 1096 },
{ "pre-dump-mode", required_argument, 0, 1097 },
{ "file-validation", required_argument, 0, 1098 },
{ "lsm-mount-context", required_argument, 0, 1099 },
{},
};
#undef BOOL_OPT
ret = pre_parse(argc, argv, usage_error, &no_default_config,
&cfg_file);
ret = pre_parse(argc, argv, usage_error, &no_default_config, &cfg_file);
if (ret)
return 2;
@@ -709,7 +706,7 @@ int parse_options(int argc, char **argv, bool *usage_error,
/* Do not free any memory if it points to argv */
if (state != PARSING_ARGV + 1) {
int i;
for (i=1; i < _argc; i++) {
for (i = 1; i < _argc; i++) {
free(_argv[i]);
}
free(_argv);
@@ -809,21 +806,19 @@ int parse_options(int argc, char **argv, bool *usage_error,
case 1046:
SET_CHAR_OPTS(pidfile, optarg);
break;
case 1047:
{
char *aux;
case 1047: {
char *aux;
aux = strchr(optarg, '=');
if (aux == NULL)
goto bad_arg;
aux = strchr(optarg, '=');
if (aux == NULL)
goto bad_arg;
*aux = '\0';
if (veth_pair_add(optarg, aux + 1)) {
pr_err("Failed to add veth pair: %s, %s.\n", optarg, aux + 1);
return 1;
}
*aux = '\0';
if (veth_pair_add(optarg, aux + 1)) {
pr_err("Failed to add veth pair: %s, %s.\n", optarg, aux + 1);
return 1;
}
break;
} break;
case 1049:
if (add_script(optarg)) {
pr_err("Failed to add action-script: %s.\n", optarg);
@@ -868,33 +863,31 @@ int parse_options(int argc, char **argv, bool *usage_error,
if (parse_manage_cgroups(&opts, optarg))
return 2;
break;
case 1061:
{
char *path, *ctl;
case 1061: {
char *path, *ctl;
path = strchr(optarg, ':');
if (path) {
*path = '\0';
path++;
ctl = optarg;
} else {
path = optarg;
ctl = NULL;
}
if (new_cg_root_add(ctl, path))
return -1;
path = strchr(optarg, ':');
if (path) {
*path = '\0';
path++;
ctl = optarg;
} else {
path = optarg;
ctl = NULL;
}
break;
if (new_cg_root_add(ctl, path))
return -1;
} break;
case 1062:
if (inherit_fd_parse(optarg) < 0)
return 1;
break;
case 1063:
ret = check_add_feature(optarg);
if (ret < 0) /* invalid kernel feature name */
if (ret < 0) /* invalid kernel feature name */
return 1;
if (ret > 0) /* list kernel features and exit */
if (ret > 0) /* list kernel features and exit */
return 0;
break;
case 1064:
@@ -931,26 +924,25 @@ int parse_options(int argc, char **argv, bool *usage_error,
case 1076:
opts.lazy_pages = true;
break;
case 'M':
{
char *aux;
case 'M': {
char *aux;
if (strcmp(optarg, "auto") == 0) {
opts.autodetect_ext_mounts = true;
break;
}
aux = strchr(optarg, ':');
if (aux == NULL)
goto bad_arg;
*aux = '\0';
if (ext_mount_add(optarg, aux + 1)) {
pr_err("Could not add external mount when initializing config: %s, %s\n", optarg, aux + 1);
return 1;
}
if (strcmp(optarg, "auto") == 0) {
opts.autodetect_ext_mounts = true;
break;
}
break;
aux = strchr(optarg, ':');
if (aux == NULL)
goto bad_arg;
*aux = '\0';
if (ext_mount_add(optarg, aux + 1)) {
pr_err("Could not add external mount when initializing config: %s, %s\n", optarg,
aux + 1);
return 1;
}
} break;
case 1073:
if (add_external(optarg)) {
pr_err("Could not add external resource when initializing config: %s\n", optarg);
@@ -961,8 +953,7 @@ int parse_options(int argc, char **argv, bool *usage_error,
if (!strcmp("net", optarg))
opts.empty_ns |= CLONE_NEWNET;
else {
pr_err("Unsupported empty namespace: %s\n",
optarg);
pr_err("Unsupported empty namespace: %s\n", optarg);
return 1;
}
break;
@@ -1040,11 +1031,9 @@ int parse_options(int argc, char **argv, bool *usage_error,
bad_arg:
if (idx < 0) /* short option */
pr_err("invalid argument for -%c: %s\n",
opt, optarg);
pr_err("invalid argument for -%c: %s\n", opt, optarg);
else /* long option */
pr_err("invalid argument for --%s: %s\n",
long_opts[idx].name, optarg);
pr_err("invalid argument for --%s: %s\n", long_opts[idx].name, optarg);
return 1;
}
@@ -1079,7 +1068,7 @@ int check_options(void)
"combination with --ps-socket is obsolete\n");
if (opts.ps_socket <= STDERR_FILENO && opts.daemon_mode) {
pr_err("Standard file descriptors will be closed"
" in daemon mode\n");
" in daemon mode\n");
return 1;
}
}

View File

@@ -63,9 +63,8 @@ static int check_tty(void)
if (ARRAY_SIZE(t.c_cc) < TERMIOS_NCC) {
pr_err("struct termios has %d @c_cc while "
"at least %d expected.\n",
(int)ARRAY_SIZE(t.c_cc),
TERMIOS_NCC);
"at least %d expected.\n",
(int)ARRAY_SIZE(t.c_cc), TERMIOS_NCC);
goto out;
}
@@ -293,8 +292,7 @@ static int check_fdinfo_eventfd(void)
}
if (fe.counter != cnt) {
pr_err("Counter mismatch (or not met) %d want %d\n",
(int)fe.counter, cnt);
pr_err("Counter mismatch (or not met) %d want %d\n", (int)fe.counter, cnt);
return -1;
}
@@ -468,7 +466,7 @@ err:
}
#ifndef SO_GET_FILTER
#define SO_GET_FILTER SO_ATTACH_FILTER
#define SO_GET_FILTER SO_ATTACH_FILTER
#endif
static int check_so_gets(void)
@@ -612,9 +610,9 @@ static int check_ptrace_peeksiginfo(void)
}
struct special_mapping {
const char *name;
void *addr;
size_t size;
const char *name;
void *addr;
size_t size;
};
static int parse_special_maps(struct special_mapping *vmas, size_t nr)
@@ -632,8 +630,7 @@ static int parse_special_maps(struct special_mapping *vmas, size_t nr)
int r, tail;
size_t i;
r = sscanf(buf, "%lx-%lx %*s %*s %*s %*s %n\n",
&start, &end, &tail);
r = sscanf(buf, "%lx-%lx %*s %*s %*s %*s %n\n", &start, &end, &tail);
if (r != 2) {
fclose(maps);
pr_err("Bad maps format %d.%d (%s)\n", r, tail, buf + tail);
@@ -674,8 +671,7 @@ static void dummy_sighandler(int sig)
* And we definitely mremap() support by the fact that those special_mappings
* are subjects for ASLR. (See #288 as a reference)
*/
static void check_special_mapping_mremap_child(struct special_mapping *vmas,
size_t nr)
static void check_special_mapping_mremap_child(struct special_mapping *vmas, size_t nr)
{
size_t i, parking_size = 0;
void *parking_lot;
@@ -691,8 +687,7 @@ static void check_special_mapping_mremap_child(struct special_mapping *vmas,
exit(1);
}
parking_lot = mmap(NULL, parking_size, PROT_NONE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
parking_lot = mmap(NULL, parking_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (parking_lot == MAP_FAILED) {
pr_perror("mmap(%zu) failed", parking_size);
exit(1);
@@ -704,10 +699,8 @@ static void check_special_mapping_mremap_child(struct special_mapping *vmas,
if (vmas[i].addr == MAP_FAILED)
continue;
ret = syscall(__NR_mremap, (unsigned long)vmas[i].addr,
vmas[i].size, vmas[i].size,
MREMAP_FIXED | MREMAP_MAYMOVE,
(unsigned long)parking_lot);
ret = syscall(__NR_mremap, (unsigned long)vmas[i].addr, vmas[i].size, vmas[i].size,
MREMAP_FIXED | MREMAP_MAYMOVE, (unsigned long)parking_lot);
if (ret != (unsigned long)parking_lot)
syscall(__NR_exit, 1);
parking_lot += vmas[i].size;
@@ -807,19 +800,19 @@ static int check_ptrace_suspend_seccomp(void)
static int setup_seccomp_filter(void)
{
struct sock_filter filter[] = {
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct seccomp_data, nr)),
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(struct seccomp_data, nr)),
/* Allow all syscalls except ptrace */
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ptrace, 0, 1),
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL),
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, __NR_ptrace, 0, 1),
BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_KILL),
BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ALLOW),
};
struct sock_fprog bpf_prog = {
.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
.len = (unsigned short)(sizeof(filter) / sizeof(filter[0])),
.filter = filter,
};
if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, (long) &bpf_prog, 0, 0) < 0)
if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, (long)&bpf_prog, 0, 0) < 0)
return -1;
return 0;
@@ -912,7 +905,7 @@ static int check_aio_remap(void)
return -1;
}
len = get_ring_len((unsigned long) ctx);
len = get_ring_len((unsigned long)ctx);
if (!len)
return -1;
@@ -956,7 +949,8 @@ struct clone_arg {
char stack_ptr[0];
};
static int clone_cb(void *_arg) {
static int clone_cb(void *_arg)
{
exit(0);
}
@@ -1016,8 +1010,7 @@ static int check_autofs(void)
ret = -1;
options = xsprintf("fd=%d,pgrp=%d,minproto=5,maxproto=5,direct",
pfd[1], getpgrp());
options = xsprintf("fd=%d,pgrp=%d,minproto=5,maxproto=5,direct", pfd[1], getpgrp());
if (!options) {
pr_err("failed to allocate autofs options\n");
goto close_pipe;
@@ -1129,7 +1122,7 @@ static int kerndat_tcp_repair_window(void)
pr_perror("Unable to set TCP_REPAIR_WINDOW");
goto err;
}
now:
now:
val = 0;
} else
val = 1;
@@ -1327,8 +1320,8 @@ static int check_newifindex(void)
static int check_net_diag_raw(void)
{
check_sock_diag();
return (socket_test_collect_bit(AF_INET, IPPROTO_RAW) &&
socket_test_collect_bit(AF_INET6, IPPROTO_RAW)) ? 0 : -1;
return (socket_test_collect_bit(AF_INET, IPPROTO_RAW) && socket_test_collect_bit(AF_INET6, IPPROTO_RAW)) ? 0 :
-1;
}
static int check_pidfd_store(void)
@@ -1371,17 +1364,19 @@ static int (*chk_feature)(void);
* We fail if any feature in category 1 is missing but tolerate failures
* in the other categories. Currently, there is nothing in category 3.
*/
#define CHECK_GOOD "Looks good."
#define CHECK_BAD "Does not look good."
#define CHECK_MAYBE "Looks good but some kernel features are missing\n" \
"which, depending on your process tree, may cause\n" \
"dump or restore failure."
#define CHECK_CAT1(fn) do { \
if ((ret = fn) != 0) { \
pr_warn("%s\n", CHECK_BAD); \
return ret; \
} \
} while (0)
#define CHECK_GOOD "Looks good."
#define CHECK_BAD "Does not look good."
#define CHECK_MAYBE \
"Looks good but some kernel features are missing\n" \
"which, depending on your process tree, may cause\n" \
"dump or restore failure."
#define CHECK_CAT1(fn) \
do { \
if ((ret = fn) != 0) { \
pr_warn("%s\n", CHECK_BAD); \
return ret; \
} \
} while (0)
int cr_check(void)
{
struct ns_id *ns;
@@ -1566,17 +1561,17 @@ static struct feature_list feature_list[] = {
{ "compat_cr", check_compat_cr },
{ "uffd", check_uffd },
{ "uffd-noncoop", check_uffd_noncoop },
{ "can_map_vdso", check_can_map_vdso},
{ "can_map_vdso", check_can_map_vdso },
{ "sk_ns", check_sk_netns },
{ "sk_unix_file", check_sk_unix_file },
{ "net_diag_raw", check_net_diag_raw },
{ "nsid", check_nsid },
{ "link_nsid", check_link_nsid},
{ "kcmp_epoll", check_kcmp_epoll},
{ "timens", check_time_namespace},
{ "external_net_ns", check_external_net_ns},
{ "clone3_set_tid", check_clone3_set_tid},
{ "newifindex", check_newifindex},
{ "link_nsid", check_link_nsid },
{ "kcmp_epoll", check_kcmp_epoll },
{ "timens", check_time_namespace },
{ "external_net_ns", check_external_net_ns },
{ "clone3_set_tid", check_clone3_set_tid },
{ "newifindex", check_newifindex },
{ "nftables", check_nftables_cr },
{ "has_ipt_legacy", check_ipt_legacy },
{ "pidfd_store", check_pidfd_store },

View File

@@ -14,7 +14,7 @@ int cr_dedup(void)
{
int close_ret, ret = 0;
unsigned long img_id;
DIR * dirp;
DIR *dirp;
struct dirent *ent;
dirp = opendir(CR_PARENT_LINK);
@@ -71,7 +71,7 @@ static int cr_dedup_one_pagemap(unsigned long img_id, int flags)
{
int ret;
struct page_read pr;
struct page_read * prp;
struct page_read *prp;
flags |= PR_MOD;
ret = open_page_read(img_id, &pr, flags);
@@ -87,11 +87,9 @@ static int cr_dedup_one_pagemap(unsigned long img_id, int flags)
if (ret <= 0)
goto exit;
pr_debug("dedup iovec base=%"PRIx64", len=%lu\n",
pr.pe->vaddr, pagemap_len(pr.pe));
pr_debug("dedup iovec base=%" PRIx64 ", len=%lu\n", pr.pe->vaddr, pagemap_len(pr.pe));
if (!pagemap_in_parent(pr.pe)) {
ret = dedup_one_iovec(prp, pr.pe->vaddr,
pagemap_len(pr.pe));
ret = dedup_one_iovec(prp, pr.pe->vaddr, pagemap_len(pr.pe));
if (ret)
goto exit;
}

View File

@@ -15,7 +15,6 @@
#include <sys/time.h>
#include <sys/wait.h>
#include <sched.h>
#include <sys/resource.h>
@@ -93,13 +92,12 @@
* with_threads = true : The register sets of the tasks with all their threads
* are restored
*/
int __attribute__((weak)) arch_set_thread_regs(struct pstree_item *item,
bool with_threads)
int __attribute__((weak)) arch_set_thread_regs(struct pstree_item *item, bool with_threads)
{
return 0;
}
#define PERSONALITY_LENGTH 9
#define PERSONALITY_LENGTH 9
static char loc_buf[PERSONALITY_LENGTH];
void free_mappings(struct vm_area_list *vma_area_list)
@@ -115,8 +113,7 @@ void free_mappings(struct vm_area_list *vma_area_list)
vm_area_list_init(vma_area_list);
}
int collect_mappings(pid_t pid, struct vm_area_list *vma_area_list,
dump_filemap_t dump_file)
int collect_mappings(pid_t pid, struct vm_area_list *vma_area_list, dump_filemap_t dump_file)
{
int ret = -1;
@@ -128,8 +125,7 @@ int collect_mappings(pid_t pid, struct vm_area_list *vma_area_list,
if (ret < 0)
goto err;
pr_info("Collected, longest area occupies %lu pages\n",
vma_area_list->nr_priv_pages_longest);
pr_info("Collected, longest area occupies %lu pages\n", vma_area_list->nr_priv_pages_longest);
pr_info_vma_list(&vma_area_list->h);
pr_info("----------------------------------------\n");
@@ -325,8 +321,7 @@ static int dump_task_fs(pid_t pid, struct parasite_dump_misc *misc, struct cr_im
close(fd);
pr_info("Dumping task cwd id %#x root id %#x\n",
fe.cwd_id, fe.root_id);
pr_info("Dumping task cwd id %#x root id %#x\n", fe.cwd_id, fe.root_id);
return pb_write_one(img_from_set(imgset, CR_FD_FS), &fe, PB_FS);
}
@@ -340,7 +335,7 @@ static int dump_task_rlimits(int pid, TaskRlimitsEntry *rls)
{
int res;
for (res = 0; res <rls->n_rlimits ; res++) {
for (res = 0; res < rls->n_rlimits; res++) {
struct rlimit64 lim;
if (syscall(__NR_prlimit64, pid, res, NULL, &lim)) {
@@ -412,8 +407,7 @@ static int dump_filemap(struct vma_area *vma_area, int fd)
if (vma_area->aufs_rpath) {
struct fd_link aufs_link;
strlcpy(aufs_link.name, vma_area->aufs_rpath,
sizeof(aufs_link.name));
strlcpy(aufs_link.name, vma_area->aufs_rpath, sizeof(aufs_link.name));
aufs_link.len = strlen(aufs_link.name);
p.link = &aufs_link;
}
@@ -434,8 +428,7 @@ static int check_sysvipc_map_dump(pid_t pid, VmaEntry *vma)
if (root_ns_mask & CLONE_NEWIPC)
return 0;
pr_err("Task %d with SysVIPC shmem map @%"PRIx64" doesn't live in IPC ns\n",
pid, vma->start);
pr_err("Task %d with SysVIPC shmem map @%" PRIx64 " doesn't live in IPC ns\n", pid, vma->start);
return -1;
}
@@ -467,10 +460,8 @@ err:
return ret;
}
static int dump_task_mm(pid_t pid, const struct proc_pid_stat *stat,
const struct parasite_dump_misc *misc,
const struct vm_area_list *vma_area_list,
const struct cr_imgset *imgset)
static int dump_task_mm(pid_t pid, const struct proc_pid_stat *stat, const struct parasite_dump_misc *misc,
const struct vm_area_list *vma_area_list, const struct cr_imgset *imgset)
{
MmEntry mme = MM_ENTRY__INIT;
struct vma_area *vma_area;
@@ -578,8 +569,8 @@ static int get_task_futex_robust_list(pid_t pid, ThreadCoreEntry *info)
goto err;
}
info->futex_rla = encode_pointer(head);
info->futex_rla_len = (u32)len;
info->futex_rla = encode_pointer(head);
info->futex_rla_len = (u32)len;
return 0;
@@ -713,8 +704,7 @@ int dump_thread_core(int pid, CoreEntry *core, const struct parasite_dump_thread
ret = dump_sched_info(pid, tc);
if (!ret) {
core_put_tls(core, ti->tls);
CORE_THREAD_ARCH_INFO(core)->clear_tid_addr =
encode_pointer(ti->tid_addr);
CORE_THREAD_ARCH_INFO(core)->clear_tid_addr = encode_pointer(ti->tid_addr);
BUG_ON(!tc->sas);
copy_sas(tc->sas, &ti->sas);
if (ti->pdeath_sig) {
@@ -731,11 +721,8 @@ int dump_thread_core(int pid, CoreEntry *core, const struct parasite_dump_thread
return ret;
}
static int dump_task_core_all(struct parasite_ctl *ctl,
struct pstree_item *item,
const struct proc_pid_stat *stat,
const struct cr_imgset *cr_imgset,
const struct parasite_dump_misc *misc)
static int dump_task_core_all(struct parasite_ctl *ctl, struct pstree_item *item, const struct proc_pid_stat *stat,
const struct cr_imgset *cr_imgset, const struct parasite_dump_misc *misc)
{
struct cr_img *img;
CoreEntry *core = item->core[0];
@@ -805,7 +792,9 @@ static int collect_pstree_ids_predump(void)
struct {
struct pstree_item i;
struct dmp_info d;
} crt = { .i.pid = &pid, };
} crt = {
.i.pid = &pid,
};
/*
* This thing is normally done inside
@@ -845,8 +834,7 @@ static int collect_file_locks(void)
return parse_file_locks();
}
static int dump_task_thread(struct parasite_ctl *parasite_ctl,
const struct pstree_item *item, int id)
static int dump_task_thread(struct parasite_ctl *parasite_ctl, const struct pstree_item *item, int id)
{
struct parasite_thread_ctl *tctl = dmpi(item)->thread_ctls[id];
struct pid *tid = &item->threads[id];
@@ -878,8 +866,7 @@ err:
return ret;
}
static int dump_one_zombie(const struct pstree_item *item,
const struct proc_pid_stat *pps)
static int dump_one_zombie(const struct pstree_item *item, const struct proc_pid_stat *pps)
{
CoreEntry *core;
int ret = -1;
@@ -904,7 +891,7 @@ err:
return ret;
}
#define SI_BATCH 32
#define SI_BATCH 32
static int dump_signal_queue(pid_t tid, SignalQueueEntry **sqe, bool group)
{
@@ -961,8 +948,7 @@ static int dump_signal_queue(pid_t tid, SignalQueueEntry **sqe, bool group)
break;
}
for (si_pos = queue->n_signals - nr;
si_pos < queue->n_signals; si_pos++) {
for (si_pos = queue->n_signals - nr; si_pos < queue->n_signals; si_pos++) {
SiginfoEntry *se;
se = xmalloc(sizeof(*se));
@@ -1014,8 +1000,7 @@ static int dump_task_signals(pid_t pid, struct pstree_item *item)
static struct proc_pid_stat pps_buf;
static int dump_task_threads(struct parasite_ctl *parasite_ctl,
const struct pstree_item *item)
static int dump_task_threads(struct parasite_ctl *parasite_ctl, const struct pstree_item *item)
{
int i;
@@ -1348,12 +1333,10 @@ static int dump_one_task(struct pstree_item *item, InventoryEntry *parent_ie)
item->sid = misc.sid;
item->pgid = misc.pgid;
pr_info("sid=%d pgid=%d pid=%d\n",
item->sid, item->pgid, vpid(item));
pr_info("sid=%d pgid=%d pid=%d\n", item->sid, item->pgid, vpid(item));
if (item->sid == 0) {
pr_err("A session leader of %d(%d) is outside of its pid namespace\n",
item->pid->real, vpid(item));
pr_err("A session leader of %d(%d) is outside of its pid namespace\n", item->pid->real, vpid(item));
goto err_cure;
}
@@ -1469,13 +1452,13 @@ err_cure_imgset:
static int alarm_attempts = 0;
bool alarm_timeouted(void) {
bool alarm_timeouted(void)
{
return alarm_attempts > 0;
}
static void alarm_handler(int signo)
{
pr_err("Timeout reached. Try to interrupt: %d\n", alarm_attempts);
if (alarm_attempts++ < 5) {
alarm(1);
@@ -1489,8 +1472,7 @@ static void alarm_handler(int signo)
static int setup_alarm_handler(void)
{
struct sigaction sa = {
.sa_handler = alarm_handler,
.sa_flags = 0, /* Don't restart syscalls */
.sa_handler = alarm_handler, .sa_flags = 0, /* Don't restart syscalls */
};
sigemptyset(&sa.sa_mask);
@@ -1552,8 +1534,7 @@ static int cr_pre_dump_finish(int status)
if (opts.pre_dump_mode == PRE_DUMP_READ) {
timing_stop(TIME_MEMWRITE);
ret = page_xfer_predump_pages(item->pid->real,
&xfer, mem_pp);
ret = page_xfer_predump_pages(item->pid->real, &xfer, mem_pp);
} else {
ret = page_xfer_dump_pages(&xfer, mem_pp);
}
@@ -1772,9 +1753,7 @@ static int cr_dump_finish(int ret)
if (arch_set_thread_regs(root_item, true) < 0)
return -1;
pstree_switch_state(root_item,
(ret || post_dump_ret) ?
TASK_ALIVE : opts.final_state);
pstree_switch_state(root_item, (ret || post_dump_ret) ? TASK_ALIVE : opts.final_state);
timing_stop(TIME_FROZEN);
free_pstree(root_item);
seccomp_free_entries();
@@ -1792,7 +1771,7 @@ static int cr_dump_finish(int ret)
write_stats(DUMP_STATS);
pr_info("Dumping finished successfully\n");
}
return post_dump_ret ? : (ret != 0);
return post_dump_ret ?: (ret != 0);
}
int cr_dump_tasks(pid_t pid)
@@ -1842,10 +1821,7 @@ int cr_dump_tasks(pid_t pid)
if (vdso_init_dump())
goto err;
if (cgp_init(opts.cgroup_props,
opts.cgroup_props ?
strlen(opts.cgroup_props) : 0,
opts.cgroup_props_file))
if (cgp_init(opts.cgroup_props, opts.cgroup_props ? strlen(opts.cgroup_props) : 0, opts.cgroup_props_file))
goto err;
if (parse_cg_info())

View File

@@ -18,7 +18,6 @@
#include <sys/prctl.h>
#include <sched.h>
#include "types.h"
#include <compel/ptrace.h>
#include "common/compiler.h"
@@ -98,16 +97,16 @@
#include "cr-errno.h"
#ifndef arch_export_restore_thread
#define arch_export_restore_thread __export_restore_thread
#define arch_export_restore_thread __export_restore_thread
#endif
#ifndef arch_export_restore_task
#define arch_export_restore_task __export_restore_task
#define arch_export_restore_task __export_restore_task
#endif
#ifndef arch_export_unmap
#define arch_export_unmap __export_unmap
#define arch_export_unmap_compat __export_unmap_compat
#define arch_export_unmap __export_unmap
#define arch_export_unmap_compat __export_unmap_compat
#endif
struct pstree_item *current;
@@ -202,16 +201,14 @@ static int restore_wait_other_tasks(void)
static inline void __restore_switch_stage_nw(int next_stage)
{
futex_set(&task_entries->nr_in_progress,
stage_participants(next_stage));
futex_set(&task_entries->nr_in_progress, stage_participants(next_stage));
futex_set(&task_entries->start, next_stage);
}
static inline void __restore_switch_stage(int next_stage)
{
if (next_stage != CR_STATE_COMPLETE)
futex_set(&task_entries->nr_in_progress,
stage_participants(next_stage));
futex_set(&task_entries->nr_in_progress, stage_participants(next_stage));
futex_set_and_wake(&task_entries->start, next_stage);
}
@@ -266,34 +263,17 @@ static int crtools_prepare_shared(void)
*/
static struct collect_image_info *cinfos[] = {
&file_locks_cinfo,
&pipe_data_cinfo,
&fifo_data_cinfo,
&sk_queues_cinfo,
&file_locks_cinfo, &pipe_data_cinfo, &fifo_data_cinfo, &sk_queues_cinfo,
#ifdef CONFIG_HAS_LIBBPF
&bpfmap_data_cinfo,
#endif
};
static struct collect_image_info *cinfos_files[] = {
&unix_sk_cinfo,
&fifo_cinfo,
&pipe_cinfo,
&nsfile_cinfo,
&packet_sk_cinfo,
&netlink_sk_cinfo,
&eventfd_cinfo,
&epoll_cinfo,
&epoll_tfd_cinfo,
&signalfd_cinfo,
&tunfile_cinfo,
&timerfd_cinfo,
&inotify_cinfo,
&inotify_mark_cinfo,
&fanotify_cinfo,
&fanotify_mark_cinfo,
&ext_file_cinfo,
&memfd_cinfo,
&unix_sk_cinfo, &fifo_cinfo, &pipe_cinfo, &nsfile_cinfo, &packet_sk_cinfo,
&netlink_sk_cinfo, &eventfd_cinfo, &epoll_cinfo, &epoll_tfd_cinfo, &signalfd_cinfo,
&tunfile_cinfo, &timerfd_cinfo, &inotify_cinfo, &inotify_mark_cinfo, &fanotify_cinfo,
&fanotify_mark_cinfo, &ext_file_cinfo, &memfd_cinfo,
};
/* These images are required to restore namespaces */
@@ -337,8 +317,7 @@ static int root_prepare_shared(void)
if (collect_images(cinfos, ARRAY_SIZE(cinfos)))
return -1;
if (!files_collected() &&
collect_images(cinfos_files, ARRAY_SIZE(cinfos_files)))
if (!files_collected() && collect_images(cinfos_files, ARRAY_SIZE(cinfos_files)))
return -1;
for_each_pstree_item(pi) {
@@ -451,9 +430,8 @@ static bool sa_inherited(int sig, rt_sigaction_t *sa)
if (pa->rt_sa_mask.sig[i] != sa->rt_sa_mask.sig[i])
return false;
return pa->rt_sa_handler == sa->rt_sa_handler &&
pa->rt_sa_flags == sa->rt_sa_flags &&
pa->rt_sa_restorer == sa->rt_sa_restorer;
return pa->rt_sa_handler == sa->rt_sa_handler && pa->rt_sa_flags == sa->rt_sa_flags &&
pa->rt_sa_restorer == sa->rt_sa_restorer;
}
static int restore_native_sigaction(int sig, SaEntry *e)
@@ -466,7 +444,7 @@ static int restore_native_sigaction(int sig, SaEntry *e)
ASSIGN_TYPED(act.rt_sa_restorer, decode_pointer(e->restorer));
#ifdef CONFIG_MIPS
e->has_mask_extended = 1;
BUILD_BUG_ON(sizeof(e->mask)* 2 != sizeof(act.rt_sa_mask.sig));
BUILD_BUG_ON(sizeof(e->mask) * 2 != sizeof(act.rt_sa_mask.sig));
memcpy(&(act.rt_sa_mask.sig[0]), &e->mask, sizeof(act.rt_sa_mask.sig[0]));
memcpy(&(act.rt_sa_mask.sig[1]), &e->mask_extended, sizeof(act.rt_sa_mask.sig[1]));
@@ -522,9 +500,8 @@ static bool sa_compat_inherited(int sig, rt_sigaction_t_compat *sa)
if (pa->rt_sa_mask.sig[i] != sa->rt_sa_mask.sig[i])
return false;
return pa->rt_sa_handler == sa->rt_sa_handler &&
pa->rt_sa_flags == sa->rt_sa_flags &&
pa->rt_sa_restorer == sa->rt_sa_restorer;
return pa->rt_sa_handler == sa->rt_sa_handler && pa->rt_sa_flags == sa->rt_sa_flags &&
pa->rt_sa_restorer == sa->rt_sa_restorer;
}
static int restore_compat_sigaction(int sig, SaEntry *e)
@@ -576,8 +553,7 @@ static int prepare_sigactions_from_core(TaskCoreEntry *tc)
int sig, i;
if (tc->n_sigactions != SIGMAX - 2) {
pr_err("Bad number of sigactions in the image (%d, want %d)\n",
(int)tc->n_sigactions, SIGMAX - 2);
pr_err("Bad number of sigactions in the image (%d, want %d)\n", (int)tc->n_sigactions, SIGMAX - 2);
return -1;
}
@@ -661,8 +637,7 @@ static int prepare_sigactions_from_image(void)
rst++;
}
pr_info("Restored %d/%d sigacts\n", rst,
SIGMAX - 3 /* KILL, STOP and CHLD */);
pr_info("Restored %d/%d sigacts\n", rst, SIGMAX - 3 /* KILL, STOP and CHLD */);
close_image(img);
return ret;
@@ -722,8 +697,7 @@ static int collect_child_pids(int state, unsigned int *n)
if (current == root_item) {
for_each_pstree_item(pi) {
if (pi->pid->state != TASK_HELPER &&
pi->pid->state != TASK_DEAD)
if (pi->pid->state != TASK_HELPER && pi->pid->state != TASK_DEAD)
continue;
if (__collect_child_pids(pi, state, n))
return -1;
@@ -801,7 +775,7 @@ static int open_cores(int pid, CoreEntry *leader_core)
int i, tpid;
CoreEntry **cores = NULL;
cores = xmalloc(sizeof(*cores)*current->nr_threads);
cores = xmalloc(sizeof(*cores) * current->nr_threads);
if (!cores)
goto err;
@@ -867,8 +841,7 @@ static int prepare_proc_misc(pid_t pid, TaskCoreEntry *tc, struct task_restore_a
args->child_subreaper = tc->child_subreaper;
/* loginuid value is critical to restore */
if (kdat.luid == LUID_FULL && tc->has_loginuid &&
tc->loginuid != INVALID_UID) {
if (kdat.luid == LUID_FULL && tc->has_loginuid && tc->loginuid != INVALID_UID) {
ret = prepare_loginuid(tc->loginuid);
if (ret < 0) {
pr_err("Setting loginuid for %d task failed\n", pid);
@@ -894,8 +867,7 @@ static int restore_one_alive_task(int pid, CoreEntry *core)
rst_mem_switch_to_private();
args_len = round_up(sizeof(*ta) + sizeof(struct thread_restore_args) *
current->nr_threads, page_size());
args_len = round_up(sizeof(*ta) + sizeof(struct thread_restore_args) * current->nr_threads, page_size());
ta = mmap(NULL, args_len, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
if (!ta)
return -1;
@@ -996,33 +968,12 @@ static void zombie_prepare_signals(void)
sigaction(sig, &act, NULL);
}
#define SIG_FATAL_MASK ( \
(1 << SIGHUP) |\
(1 << SIGINT) |\
(1 << SIGQUIT) |\
(1 << SIGILL) |\
(1 << SIGTRAP) |\
(1 << SIGABRT) |\
(1 << SIGIOT) |\
(1 << SIGBUS) |\
(1 << SIGFPE) |\
(1 << SIGKILL) |\
(1 << SIGUSR1) |\
(1 << SIGSEGV) |\
(1 << SIGUSR2) |\
(1 << SIGPIPE) |\
(1 << SIGALRM) |\
(1 << SIGTERM) |\
(1 << SIGXCPU) |\
(1 << SIGXFSZ) |\
(1 << SIGVTALRM)|\
(1 << SIGPROF) |\
(1 << SIGPOLL) |\
(1 << SIGIO) |\
(1 << SIGSYS) |\
(1 << SIGSTKFLT)|\
(1 << SIGPWR) \
)
#define SIG_FATAL_MASK \
((1 << SIGHUP) | (1 << SIGINT) | (1 << SIGQUIT) | (1 << SIGILL) | (1 << SIGTRAP) | (1 << SIGABRT) | \
(1 << SIGIOT) | (1 << SIGBUS) | (1 << SIGFPE) | (1 << SIGKILL) | (1 << SIGUSR1) | (1 << SIGSEGV) | \
(1 << SIGUSR2) | (1 << SIGPIPE) | (1 << SIGALRM) | (1 << SIGTERM) | (1 << SIGXCPU) | (1 << SIGXFSZ) | \
(1 << SIGVTALRM) | (1 << SIGPROF) | (1 << SIGPOLL) | (1 << SIGIO) | (1 << SIGSYS) | (1 << SIGSTKFLT) | \
(1 << SIGPWR))
static inline int sig_fatal(int sig)
{
@@ -1111,8 +1062,7 @@ static int setup_newborn_fds(struct pstree_item *me)
if (clone_service_fd(me))
return -1;
if (!me->parent ||
(rsti(me->parent)->fdt && !(rsti(me)->clone_flags & CLONE_FILES))) {
if (!me->parent || (rsti(me->parent)->fdt && !(rsti(me)->clone_flags & CLONE_FILES))) {
/*
* When our parent has shared fd table, some of the table owners
* may be already created. Files, they open, will be inherited
@@ -1295,8 +1245,7 @@ struct cr_clone_arg {
CoreEntry *core;
};
static void maybe_clone_parent(struct pstree_item *item,
struct cr_clone_arg *ca)
static void maybe_clone_parent(struct pstree_item *item, struct cr_clone_arg *ca)
{
/*
* zdtm runs in kernel 3.11, which has the problem described below. We
@@ -1353,8 +1302,7 @@ static int set_next_pid(void *arg)
len = snprintf(buf, sizeof(buf), "%d", *pid - 1);
if (write(fd, buf, len) != len) {
pr_perror("Failed to write %s to /proc/%s",
buf, LAST_PID_PATH);
pr_perror("Failed to write %s to /proc/%s", buf, LAST_PID_PATH);
close(fd);
return -1;
}
@@ -1466,18 +1414,16 @@ static inline int fork_with_pid(struct pstree_item *item)
} else {
if (!external_pidns) {
if (pid != INIT_PID) {
pr_err("First PID in a PID namespace needs to be %d and not %d\n",
pid, INIT_PID);
pr_err("First PID in a PID namespace needs to be %d and not %d\n", pid, INIT_PID);
return -1;
}
}
}
if (kdat.has_clone3_set_tid) {
ret = clone3_with_pid_noasan(restore_task_with_children,
&ca, (ca.clone_flags &
~(CLONE_NEWNET | CLONE_NEWCGROUP | CLONE_NEWTIME)),
SIGCHLD, pid);
ret = clone3_with_pid_noasan(restore_task_with_children, &ca,
(ca.clone_flags & ~(CLONE_NEWNET | CLONE_NEWCGROUP | CLONE_NEWTIME)),
SIGCHLD, pid);
} else {
/*
* Some kernel modules, such as network packet generator
@@ -1493,9 +1439,7 @@ static inline int fork_with_pid(struct pstree_item *item)
*/
close_pid_proc();
ret = clone_noasan(restore_task_with_children,
(ca.clone_flags &
~(CLONE_NEWNET | CLONE_NEWCGROUP | CLONE_NEWTIME)) | SIGCHLD,
&ca);
(ca.clone_flags & ~(CLONE_NEWNET | CLONE_NEWCGROUP | CLONE_NEWTIME)) | SIGCHLD, &ca);
}
if (ret < 0) {
@@ -1505,11 +1449,9 @@ static inline int fork_with_pid(struct pstree_item *item)
goto err_unlock;
}
if (item == root_item) {
item->pid->real = ret;
pr_debug("PID: real %d virt %d\n",
item->pid->real, vpid(item));
pr_debug("PID: real %d virt %d\n", item->pid->real, vpid(item));
}
err_unlock:
@@ -1644,8 +1586,7 @@ static void restore_sid(void)
/* Skip the root task if it's not init */
if (current == root_item && vpid(root_item) != INIT_PID)
return;
pr_err("Requested sid %d doesn't match inherited %d\n",
current->sid, sid);
pr_err("Requested sid %d doesn't match inherited %d\n", current->sid, sid);
exit(1);
}
}
@@ -1804,8 +1745,7 @@ static int restore_task_with_children(void *_arg)
buf[ret] = '\0';
current->pid->real = atoi(buf);
pr_debug("PID: real %d virt %d\n",
current->pid->real, vpid(current));
pr_debug("PID: real %d virt %d\n", current->pid->real, vpid(current));
}
pid = getpid();
@@ -1993,7 +1933,6 @@ static int attach_to_tasks(bool root_seized)
return -1;
}
if (wait4(pid, &status, __WALL, NULL) != pid) {
pr_perror("waitpid(%d) failed", pid);
return -1;
@@ -2009,7 +1948,7 @@ static int attach_to_tasks(bool root_seized)
if (rsti(item)->has_seccomp && ptrace_suspend_seccomp(pid) < 0)
pr_err("failed to suspend seccomp, restore will probably fail...\n");
if (ptrace(PTRACE_CONT, pid, NULL, NULL) ) {
if (ptrace(PTRACE_CONT, pid, NULL, NULL)) {
pr_perror("Unable to resume %d", pid);
return -1;
}
@@ -2049,8 +1988,7 @@ static int catch_tasks(bool root_seized, enum trace_flags *flag)
return -1;
}
ret = compel_stop_pie(pid, rsti(item)->breakpoint,
flag, fault_injected(FI_NO_BREAKPOINTS));
ret = compel_stop_pie(pid, rsti(item)->breakpoint, flag, fault_injected(FI_NO_BREAKPOINTS));
if (ret < 0)
return -1;
}
@@ -2100,8 +2038,7 @@ static void finalize_restore(void)
xfree(ctl);
if ((item->pid->state == TASK_STOPPED) ||
(opts.final_state == TASK_STOPPED))
if ((item->pid->state == TASK_STOPPED) || (opts.final_state == TASK_STOPPED))
kill(item->pid->real, SIGSTOP);
}
}
@@ -2249,9 +2186,9 @@ static int restore_root_task(struct pstree_item *init)
if (vpid(init) == INIT_PID) {
if (!(root_ns_mask & CLONE_NEWPID)) {
pr_err("This process tree can only be restored "
"in a new pid namespace.\n"
"criu should be re-executed with the "
"\"--namespace pid\" option.\n");
"in a new pid namespace.\n"
"criu should be re-executed with the "
"\"--namespace pid\" option.\n");
return -1;
}
} else if (root_ns_mask & CLONE_NEWPID) {
@@ -2437,8 +2374,7 @@ skip_ns_bouncing:
__restore_switch_stage(CR_STATE_COMPLETE);
ret = compel_stop_on_syscall(task_entries->nr_threads,
__NR(rt_sigreturn, 0), __NR(rt_sigreturn, 1), flag);
ret = compel_stop_on_syscall(task_entries->nr_threads, __NR(rt_sigreturn, 0), __NR(rt_sigreturn, 1), flag);
if (ret) {
pr_err("Can't stop all tasks on rt_sigreturn\n");
goto out_kill_network_unlocked;
@@ -2491,8 +2427,7 @@ out_kill:
kill(root_item->pid->real, SIGKILL);
if (waitpid(root_item->pid->real, &status, 0) < 0)
pr_warn("Unable to wait %d: %s\n",
root_item->pid->real, strerror(errno));
pr_warn("Unable to wait %d: %s\n", root_item->pid->real, strerror(errno));
} else {
struct pstree_item *pi;
@@ -2608,8 +2543,7 @@ err:
return ret;
}
static long restorer_get_vma_hint(struct list_head *tgt_vma_list,
struct list_head *self_vma_list, long vma_len)
static long restorer_get_vma_hint(struct list_head *tgt_vma_list, struct list_head *self_vma_list, long vma_len)
{
struct vma_area *t_vma, *s_vma;
long prev_vma_end = 0;
@@ -2693,9 +2627,8 @@ static inline int decode_itimer(char *n, ItimerEntry *ie, struct itimerval *val)
return -1;
}
pr_info("Restored %s timer to %ld.%ld -> %ld.%ld\n", n,
val->it_value.tv_sec, val->it_value.tv_usec,
val->it_interval.tv_sec, val->it_interval.tv_usec);
pr_info("Restored %s timer to %ld.%ld -> %ld.%ld\n", n, val->it_value.tv_sec, val->it_value.tv_usec,
val->it_interval.tv_sec, val->it_interval.tv_usec);
return 0;
}
@@ -2765,8 +2698,7 @@ static inline int timespec_valid(struct timespec *ts)
return (ts->tv_sec >= 0) && ((unsigned long)ts->tv_nsec < NSEC_PER_SEC);
}
static inline int decode_posix_timer(PosixTimerEntry *pte,
struct restore_posix_timer *pt)
static inline int decode_posix_timer(PosixTimerEntry *pte, struct restore_posix_timer *pt)
{
pt->val.it_interval.tv_sec = pte->isec;
pt->val.it_interval.tv_nsec = pte->insec;
@@ -2822,9 +2754,7 @@ static void sort_posix_timers(struct task_restore_args *ta)
if (ta->posix_timers_n > 0) {
tmem = rst_mem_remap_ptr((unsigned long)ta->posix_timers, RM_PRIVATE);
qsort(tmem, ta->posix_timers_n,
sizeof(struct restore_posix_timer),
cmp_posix_timer_proc_id);
qsort(tmem, ta->posix_timers_n, sizeof(struct restore_posix_timer), cmp_posix_timer_proc_id);
}
}
@@ -2901,8 +2831,8 @@ out:
static inline int verify_cap_size(CredsEntry *ce)
{
return ((ce->n_cap_inh == CR_CAP_SIZE) && (ce->n_cap_eff == CR_CAP_SIZE) &&
(ce->n_cap_prm == CR_CAP_SIZE) && (ce->n_cap_bnd == CR_CAP_SIZE));
return ((ce->n_cap_inh == CR_CAP_SIZE) && (ce->n_cap_eff == CR_CAP_SIZE) && (ce->n_cap_prm == CR_CAP_SIZE) &&
(ce->n_cap_bnd == CR_CAP_SIZE));
}
static int prepare_mm(pid_t pid, struct task_restore_args *args)
@@ -2919,7 +2849,7 @@ static int prepare_mm(pid_t pid, struct task_restore_args *args)
goto out;
}
args->mm_saved_auxv_size = mm->n_mm_saved_auxv*sizeof(auxv_t);
args->mm_saved_auxv_size = mm->n_mm_saved_auxv * sizeof(auxv_t);
for (i = 0; i < mm->n_mm_saved_auxv; ++i) {
args->mm_saved_auxv[i] = (auxv_t)mm->mm_saved_auxv[i];
}
@@ -2965,9 +2895,7 @@ static int prepare_restorer_blob(void)
*/
restorer_len = round_up(pbd.hdr.args_off, page_size());
restorer = mmap(NULL, restorer_len,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
restorer = mmap(NULL, restorer_len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
if (restorer == MAP_FAILED) {
pr_perror("Can't map restorer code");
return -1;
@@ -2983,8 +2911,7 @@ static int remap_restorer_blob(void *addr)
struct parasite_blob_desc pbd;
void *mem;
mem = mremap(restorer, restorer_len, restorer_len,
MREMAP_FIXED | MREMAP_MAYMOVE, addr);
mem = mremap(restorer, restorer_len, restorer_len, MREMAP_FIXED | MREMAP_MAYMOVE, addr);
if (mem != addr) {
pr_perror("Can't remap restorer blob");
return -1;
@@ -3033,8 +2960,7 @@ static int prep_sched_info(struct rst_sched_param *sp, ThreadCoreEntry *tc)
sp->prio = tc->sched_prio;
if (!validate_sched_parm(sp)) {
pr_err("Inconsistent sched params received (%d.%d.%d)\n",
sp->policy, sp->nice, sp->prio);
pr_err("Inconsistent sched params received (%d.%d.%d)\n", sp->policy, sp->nice, sp->prio);
return -1;
}
@@ -3076,16 +3002,14 @@ static int prepare_rlimits_from_fd(int pid, struct task_restore_args *ta)
r = rst_mem_alloc(sizeof(*r), RM_PRIVATE);
if (!r) {
pr_err("Can't allocate memory for resource %d\n",
ta->rlims_n);
pr_err("Can't allocate memory for resource %d\n", ta->rlims_n);
return -1;
}
r->rlim_cur = decode_rlim(re->cur);
r->rlim_max = decode_rlim(re->max);
if (r->rlim_cur > r->rlim_max) {
pr_err("Can't restore cur > max for %d.%d\n",
pid, ta->rlims_n);
pr_err("Can't restore cur > max for %d.%d\n", pid, ta->rlims_n);
r->rlim_cur = r->rlim_max;
}
@@ -3134,7 +3058,7 @@ static int signal_to_mem(SiginfoEntry *sie)
{
siginfo_t *info, *t;
info = (siginfo_t *) sie->siginfo.data;
info = (siginfo_t *)sie->siginfo.data;
t = rst_mem_alloc(sizeof(siginfo_t), RM_PRIVATE);
if (!t)
return -1;
@@ -3177,7 +3101,7 @@ static int open_signal_image(int type, pid_t pid, unsigned int *nr)
close_image(img);
return ret ? : 0;
return ret ?: 0;
}
static int prepare_one_signal_queue(SignalQueueEntry *sqe, unsigned int *nr)
@@ -3205,7 +3129,7 @@ static int prepare_signals(int pid, struct task_restore_args *ta, CoreEntry *lea
goto out;
/* Prepare shared signals */
if (!leader_core->tc->signals_s)/*backward compatibility*/
if (!leader_core->tc->signals_s) /*backward compatibility*/
ret = open_signal_image(CR_FD_SIGNAL, pid, &ta->siginfo_n);
else
ret = prepare_one_signal_queue(leader_core->tc->signals_s, &ta->siginfo_n);
@@ -3214,12 +3138,10 @@ static int prepare_signals(int pid, struct task_restore_args *ta, CoreEntry *lea
goto out;
for (i = 0; i < current->nr_threads; i++) {
if (!current->core[i]->thread_core->signals_p)/*backward compatibility*/
ret = open_signal_image(CR_FD_PSIGNAL,
current->threads[i].ns[0].virt, &siginfo_priv_nr[i]);
if (!current->core[i]->thread_core->signals_p) /*backward compatibility*/
ret = open_signal_image(CR_FD_PSIGNAL, current->threads[i].ns[0].virt, &siginfo_priv_nr[i]);
else
ret = prepare_one_signal_queue(current->core[i]->thread_core->signals_p,
&siginfo_priv_nr[i]);
ret = prepare_one_signal_queue(current->core[i]->thread_core->signals_p, &siginfo_priv_nr[i]);
if (ret < 0)
goto out;
}
@@ -3228,10 +3150,11 @@ out:
}
extern void __gcov_flush(void) __attribute__((weak));
void __gcov_flush(void) {}
void __gcov_flush(void)
{
}
static void rst_reloc_creds(struct thread_restore_args *thread_args,
unsigned long *creds_pos_next)
static void rst_reloc_creds(struct thread_restore_args *thread_args, unsigned long *creds_pos_next)
{
struct thread_creds_args *args;
@@ -3251,11 +3174,11 @@ static void rst_reloc_creds(struct thread_restore_args *thread_args,
thread_args->creds_args = args;
}
static bool groups_match(gid_t* groups, int n_groups)
static bool groups_match(gid_t *groups, int n_groups)
{
int n, len;
bool ret;
gid_t* gids;
gid_t *gids;
n = getgroups(0, NULL);
if (n == -1) {
@@ -3285,16 +3208,14 @@ static bool groups_match(gid_t* groups, int n_groups)
return ret;
}
static struct thread_creds_args *
rst_prep_creds_args(CredsEntry *ce, unsigned long *prev_pos)
static struct thread_creds_args *rst_prep_creds_args(CredsEntry *ce, unsigned long *prev_pos)
{
unsigned long this_pos;
struct thread_creds_args *args;
if (!verify_cap_size(ce)) {
pr_err("Caps size mismatch %d %d %d %d\n",
(int)ce->n_cap_inh, (int)ce->n_cap_eff,
(int)ce->n_cap_prm, (int)ce->n_cap_bnd);
pr_err("Caps size mismatch %d %d %d %d\n", (int)ce->n_cap_inh, (int)ce->n_cap_eff, (int)ce->n_cap_prm,
(int)ce->n_cap_bnd);
return ERR_PTR(-EINVAL);
}
@@ -3537,8 +3458,7 @@ static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, uns
/* Wait when all tasks restored all files */
if (restore_wait_other_tasks())
goto err_nv;
if (root_ns_mask & CLONE_NEWNS &&
remount_readonly_mounts())
if (root_ns_mask & CLONE_NEWNS && remount_readonly_mounts())
goto err_nv;
}
@@ -3556,8 +3476,7 @@ static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, uns
memzone_size = round_up(sizeof(struct restore_mem_zone) * current->nr_threads, page_size());
task_args->bootstrap_len = restorer_len + memzone_size + alen + rst_mem_size;
BUG_ON(task_args->bootstrap_len & (PAGE_SIZE - 1));
pr_info("%d threads require %ldK of memory\n",
current->nr_threads, KBYTES(task_args->bootstrap_len));
pr_info("%d threads require %ldK of memory\n", current->nr_threads, KBYTES(task_args->bootstrap_len));
if (core_is_compat(core))
vdso_maps_rt = vdso_maps_compat;
@@ -3585,16 +3504,13 @@ static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, uns
* or inited from scratch).
*/
mem = (void *)restorer_get_vma_hint(&vmas->h, &self_vmas.h,
task_args->bootstrap_len);
mem = (void *)restorer_get_vma_hint(&vmas->h, &self_vmas.h, task_args->bootstrap_len);
if (mem == (void *)-1) {
pr_err("No suitable area for task_restore bootstrap (%ldK)\n",
task_args->bootstrap_len);
pr_err("No suitable area for task_restore bootstrap (%ldK)\n", task_args->bootstrap_len);
goto err;
}
pr_info("Found bootstrap VMA hint at: %p (needs ~%ldK)\n",
mem, KBYTES(task_args->bootstrap_len));
pr_info("Found bootstrap VMA hint at: %p (needs ~%ldK)\n", mem, KBYTES(task_args->bootstrap_len));
ret = remap_restorer_blob(mem);
if (ret < 0)
@@ -3604,16 +3520,15 @@ static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, uns
* Prepare a memory map for restorer. Note a thread space
* might be completely unused so it's here just for convenience.
*/
task_args->clone_restore_fn = restorer_sym(mem, arch_export_restore_thread);
restore_task_exec_start = restorer_sym(mem, arch_export_restore_task);
rsti(current)->munmap_restorer = restorer_munmap_addr(core, mem);
task_args->clone_restore_fn = restorer_sym(mem, arch_export_restore_thread);
restore_task_exec_start = restorer_sym(mem, arch_export_restore_task);
rsti(current)->munmap_restorer = restorer_munmap_addr(core, mem);
task_args->bootstrap_start = mem;
mem += restorer_len;
/* VMA we need for stacks and sigframes for threads */
if (mmap(mem, memzone_size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, 0, 0) != mem) {
if (mmap(mem, memzone_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, 0, 0) != mem) {
pr_perror("Can't mmap section for restore code");
goto err;
}
@@ -3623,7 +3538,7 @@ static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, uns
mem += memzone_size;
/* New home for task_restore_args and thread_restore_args */
task_args = mremap(task_args, alen, alen, MREMAP_MAYMOVE|MREMAP_FIXED, mem);
task_args = mremap(task_args, alen, alen, MREMAP_MAYMOVE | MREMAP_FIXED, mem);
if (task_args != mem) {
pr_perror("Can't move task args");
goto err;
@@ -3699,10 +3614,10 @@ static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, uns
BUG_ON(core->mtype != CORE_ENTRY__MARCH);
task_args->logfd = log_get_fd();
task_args->loglevel = log_get_loglevel();
task_args->logfd = log_get_fd();
task_args->loglevel = log_get_loglevel();
log_get_logstart(&task_args->logstart);
task_args->sigchld_act = sigchld_act;
task_args->sigchld_act = sigchld_act;
strncpy(task_args->comm, core->tc->comm, TASK_COMM_LEN - 1);
task_args->comm[TASK_COMM_LEN - 1] = 0;
@@ -3750,27 +3665,25 @@ static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, uns
}
if ((tcore->tc || tcore->ids) && thread_args[i].pid != pid) {
pr_err("Thread has optional fields present %d\n",
thread_args[i].pid);
pr_err("Thread has optional fields present %d\n", thread_args[i].pid);
ret = -1;
}
if (ret < 0) {
pr_err("Can't read core data for thread %d\n",
thread_args[i].pid);
pr_err("Can't read core data for thread %d\n", thread_args[i].pid);
goto err;
}
thread_args[i].ta = task_args;
thread_args[i].gpregs = *CORE_THREAD_ARCH_INFO(tcore)->gpregs;
thread_args[i].clear_tid_addr = CORE_THREAD_ARCH_INFO(tcore)->clear_tid_addr;
thread_args[i].ta = task_args;
thread_args[i].gpregs = *CORE_THREAD_ARCH_INFO(tcore)->gpregs;
thread_args[i].clear_tid_addr = CORE_THREAD_ARCH_INFO(tcore)->clear_tid_addr;
core_get_tls(tcore, &thread_args[i].tls);
rst_reloc_creds(&thread_args[i], &creds_pos_next);
thread_args[i].futex_rla = tcore->thread_core->futex_rla;
thread_args[i].futex_rla_len = tcore->thread_core->futex_rla_len;
thread_args[i].pdeath_sig = tcore->thread_core->pdeath_sig;
thread_args[i].futex_rla = tcore->thread_core->futex_rla;
thread_args[i].futex_rla_len = tcore->thread_core->futex_rla_len;
thread_args[i].pdeath_sig = tcore->thread_core->pdeath_sig;
if (tcore->thread_core->pdeath_sig > _KNSIG) {
pr_err("Pdeath signal is too big\n");
goto err;
@@ -3802,9 +3715,7 @@ static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, uns
if (thread_args[i].pid != pid)
core_entry__free_unpacked(tcore, NULL);
pr_info("Thread %4d stack %8p rt_sigframe %8p\n",
i, mz[i].stack, mz[i].rt_sigframe);
pr_info("Thread %4d stack %8p rt_sigframe %8p\n", i, mz[i].stack, mz[i].rt_sigframe);
}
/*
@@ -3829,17 +3740,17 @@ static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, uns
/*
* Now prepare run-time data for threads restore.
*/
task_args->nr_threads = current->nr_threads;
task_args->thread_args = thread_args;
task_args->nr_threads = current->nr_threads;
task_args->thread_args = thread_args;
task_args->auto_dedup = opts.auto_dedup;
task_args->auto_dedup = opts.auto_dedup;
/*
* In the restorer we need to know if it is SELinux or not. For SELinux
* we must change the process context before creating threads. For
* Apparmor we can change each thread after they have been created.
*/
task_args->lsm_type = kdat.lsm;
task_args->lsm_type = kdat.lsm;
/*
* Make root and cwd restore _that_ late not to break any
@@ -3866,9 +3777,7 @@ static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, uns
"task_args->nr_threads: %d\n"
"task_args->clone_restore_fn: %p\n"
"task_args->thread_args: %p\n",
task_args, task_args->t->pid,
task_args->nr_threads,
task_args->clone_restore_fn,
task_args, task_args->t->pid, task_args->nr_threads, task_args->clone_restore_fn,
task_args->thread_args);
/*

View File

@@ -491,14 +491,14 @@ static int setup_opts_from_req(int sk, CriuOpts *req)
if (req->has_pre_dump_mode) {
switch (req->pre_dump_mode) {
case CRIU_PRE_DUMP_MODE__SPLICE:
opts.pre_dump_mode = PRE_DUMP_SPLICE;
break;
case CRIU_PRE_DUMP_MODE__VM_READ:
opts.pre_dump_mode = PRE_DUMP_READ;
break;
default:
goto err;
case CRIU_PRE_DUMP_MODE__SPLICE:
opts.pre_dump_mode = PRE_DUMP_SPLICE;
break;
case CRIU_PRE_DUMP_MODE__VM_READ:
opts.pre_dump_mode = PRE_DUMP_READ;
break;
default:
goto err;
}
}
@@ -553,8 +553,7 @@ static int setup_opts_from_req(int sk, CriuOpts *req)
goto err;
for (i = 0; i < req->n_cg_root; i++) {
if (new_cg_root_add(req->cg_root[i]->ctrl,
req->cg_root[i]->path))
if (new_cg_root_add(req->cg_root[i]->ctrl, req->cg_root[i]->path))
goto err;
}
@@ -698,7 +697,6 @@ static int setup_opts_from_req(int sk, CriuOpts *req)
if (req->orphan_pts_master)
opts.orphan_pts_master = true;
/* Evaluate additional configuration file a second time to overwrite
* all RPC settings. */
if (req->config_file) {
@@ -744,7 +742,7 @@ static int dump_using_req(int sk, CriuOpts *req)
exit:
free_pidfd_store();
pidfd_store_err:
if (req->leave_running || !self_dump || !success) {
if (req->leave_running || !self_dump || !success) {
if (send_criu_dump_resp(sk, success, false) == -1) {
pr_perror("Can't send response");
success = false;
@@ -776,8 +774,7 @@ static int restore_using_req(int sk, CriuOpts *req)
success = true;
exit:
if (send_criu_restore_resp(sk, success,
root_item ? root_item->pid->real : -1) == -1) {
if (send_criu_restore_resp(sk, success, root_item ? root_item->pid->real : -1) == -1) {
pr_perror("Can't send response");
success = false;
}
@@ -861,9 +858,9 @@ static int pre_dump_using_req(int sk, CriuOpts *req)
goto cout;
ret = 0;
cout:
cout:
free_pidfd_store();
pidfd_store_err:
pidfd_store_err:
exit(ret);
}
@@ -947,7 +944,7 @@ static int start_page_server_req(int sk, CriuOpts *req, bool daemon_mode)
}
ret = 0;
out_ch:
out_ch:
if (daemon_mode && ret < 0 && pid > 0)
kill(pid, SIGKILL);
close(start_pipe[1]);
@@ -1012,8 +1009,7 @@ static int chk_keepopen_req(CriuReq *msg)
if (msg->type == CRIU_REQ_TYPE__PAGE_SERVER_CHLD)
/* This just fork()-s so no leaks */
return 0;
else if (msg->type == CRIU_REQ_TYPE__CPUINFO_DUMP ||
msg->type == CRIU_REQ_TYPE__CPUINFO_CHECK)
else if (msg->type == CRIU_REQ_TYPE__CPUINFO_DUMP || msg->type == CRIU_REQ_TYPE__CPUINFO_CHECK)
return 0;
else if (msg->type == CRIU_REQ_TYPE__FEATURE_CHECK)
return 0;
@@ -1027,7 +1023,7 @@ static int chk_keepopen_req(CriuReq *msg)
* Return the version information, depending on the information
* available in version.h
*/
static int handle_version(int sk, CriuReq * msg)
static int handle_version(int sk, CriuReq *msg)
{
CriuResp resp = CRIU_RESP__INIT;
CriuVersion version = CRIU_VERSION__INIT;
@@ -1065,7 +1061,7 @@ static int handle_version(int sk, CriuReq * msg)
* For each feature which has been requested in msg->features
* the corresponding parameter will be set in resp.features.
*/
static int handle_feature_check(int sk, CriuReq * msg)
static int handle_feature_check(int sk, CriuReq *msg)
{
CriuResp resp = CRIU_RESP__INIT;
CriuFeatures feat = CRIU_FEATURES__INIT;
@@ -1092,16 +1088,13 @@ static int handle_feature_check(int sk, CriuReq * msg)
setproctitle("feature-check --rpc");
if ((msg->features->has_mem_track == 1) &&
(msg->features->mem_track == true))
if ((msg->features->has_mem_track == 1) && (msg->features->mem_track == true))
feat.mem_track = kdat.has_dirty_track;
if ((msg->features->has_lazy_pages == 1) &&
(msg->features->lazy_pages == true))
if ((msg->features->has_lazy_pages == 1) && (msg->features->lazy_pages == true))
feat.lazy_pages = kdat.has_uffd && uffd_noncooperative();
if ((msg->features->has_pidfd_store == 1) &&
(msg->features->pidfd_store == true))
if ((msg->features->has_pidfd_store == 1) && (msg->features->pidfd_store == true))
feat.pidfd_store = kdat.has_pidfd_getfd && kdat.has_pidfd_open;
resp.features = &feat;
@@ -1179,16 +1172,14 @@ static int handle_cpuinfo(int sk, CriuReq *msg)
if (setup_opts_from_req(sk, msg->opts))
goto cout;
setproctitle("cpuinfo %s --rpc -D %s",
msg->type == CRIU_REQ_TYPE__CPUINFO_DUMP ?
"dump" : "check",
setproctitle("cpuinfo %s --rpc -D %s", msg->type == CRIU_REQ_TYPE__CPUINFO_DUMP ? "dump" : "check",
images_dir);
if (msg->type == CRIU_REQ_TYPE__CPUINFO_DUMP)
ret = cpuinfo_dump();
else
ret = cpuinfo_check();
cout:
cout:
exit(ret);
}
@@ -1255,7 +1246,7 @@ more:
ret = start_page_server_req(sk, msg->opts, false);
break;
case CRIU_REQ_TYPE__WAIT_PID:
ret = handle_wait_pid(sk, msg->pid);
ret = handle_wait_pid(sk, msg->pid);
break;
case CRIU_REQ_TYPE__CPUINFO_DUMP:
case CRIU_REQ_TYPE__CPUINFO_CHECK:
@@ -1304,11 +1295,10 @@ static void reap_worker(int signo)
}
if (WIFEXITED(status))
pr_info("Worker(pid %d) exited with %d\n",
pid, WEXITSTATUS(status));
pr_info("Worker(pid %d) exited with %d\n", pid, WEXITSTATUS(status));
else if (WIFSIGNALED(status))
pr_info("Worker(pid %d) was killed by %d: %s\n", pid,
WTERMSIG(status), strsignal(WTERMSIG(status)));
pr_info("Worker(pid %d) was killed by %d: %s\n", pid, WTERMSIG(status),
strsignal(WTERMSIG(status)));
}
}
@@ -1318,8 +1308,8 @@ static int setup_sigchld_handler(void)
sigemptyset(&action.sa_mask);
sigaddset(&action.sa_mask, SIGCHLD);
action.sa_handler = reap_worker;
action.sa_flags = SA_RESTART;
action.sa_handler = reap_worker;
action.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &action, NULL)) {
pr_perror("Can't setup SIGCHLD handler");
@@ -1335,8 +1325,8 @@ static int restore_sigchld_handler(void)
sigemptyset(&action.sa_mask);
sigaddset(&action.sa_mask, SIGCHLD);
action.sa_handler = SIG_DFL;
action.sa_flags = SA_RESTART;
action.sa_handler = SIG_DFL;
action.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &action, NULL)) {
pr_perror("Can't restore SIGCHLD handler");
@@ -1373,17 +1363,14 @@ int cr_service(bool daemon_mode)
SET_CHAR_OPTS(addr, CR_DEFAULT_SERVICE_ADDRESS);
}
strncpy(server_addr.sun_path, opts.addr,
sizeof(server_addr.sun_path) - 1);
strncpy(server_addr.sun_path, opts.addr, sizeof(server_addr.sun_path) - 1);
server_addr_len = strlen(server_addr.sun_path)
+ sizeof(server_addr.sun_family);
server_addr_len = strlen(server_addr.sun_path) + sizeof(server_addr.sun_family);
client_addr_len = sizeof(client_addr);
unlink(server_addr.sun_path);
if (bind(server_fd, (struct sockaddr *) &server_addr,
server_addr_len) == -1) {
if (bind(server_fd, (struct sockaddr *)&server_addr, server_addr_len) == -1) {
pr_perror("Can't bind");
goto err;
}

View File

@@ -56,8 +56,7 @@ void flush_early_log_to_stderr(void)
static int image_dir_mode(char *argv[], int optind)
{
if (!strcmp(argv[optind], "dump") ||
!strcmp(argv[optind], "pre-dump") ||
if (!strcmp(argv[optind], "dump") || !strcmp(argv[optind], "pre-dump") ||
(!strcmp(argv[optind], "cpuinfo") && !strcmp(argv[optind + 1], "dump")))
return O_DUMP;
@@ -79,8 +78,7 @@ int main(int argc, char *argv[], char *envp[])
BUILD_BUG_ON(CTL_32 != SYSCTL_TYPE__CTL_32);
BUILD_BUG_ON(__CTL_STR != SYSCTL_TYPE__CTL_STR);
/* We use it for fd overlap handling in clone_service_fd() */
BUG_ON(get_service_fd(SERVICE_FD_MIN+1) <
get_service_fd(SERVICE_FD_MAX-1));
BUG_ON(get_service_fd(SERVICE_FD_MIN + 1) < get_service_fd(SERVICE_FD_MAX - 1));
if (fault_injection_init()) {
pr_err("Failed to initialize fault injection when initializing crtools.\n");
@@ -95,7 +93,6 @@ int main(int argc, char *argv[], char *envp[])
init_opts();
ret = parse_options(argc, argv, &usage_error, &has_exec_cmd, state);
if (ret == 1)
@@ -110,7 +107,7 @@ int main(int argc, char *argv[], char *envp[])
log_set_loglevel(opts.log_level);
if (optind < argc && !strcmp(argv[optind], "swrk")) {
if (argc != optind+2) {
if (argc != optind + 2) {
fprintf(stderr, "Usage: criu swrk <fd>\n");
return 1;
}
@@ -121,7 +118,7 @@ int main(int argc, char *argv[], char *envp[])
* corresponding lib call change.
*/
opts.swrk_restore = true;
return cr_service_work(atoi(argv[optind+1]));
return cr_service_work(atoi(argv[optind + 1]));
}
if (check_options())
@@ -159,8 +156,7 @@ int main(int argc, char *argv[], char *envp[])
} else {
/* No subcommands except for cpuinfo and restore --exec-cmd */
if (strcmp(argv[optind], "cpuinfo") && has_sub_command) {
pr_err("excessive parameter%s for command %s\n",
(argc - optind) > 2 ? "s" : "", argv[optind]);
pr_err("excessive parameter%s for command %s\n", (argc - optind) > 2 ? "s" : "", argv[optind]);
goto usage;
}
}
@@ -198,10 +194,8 @@ int main(int argc, char *argv[], char *envp[])
* When a process group becomes an orphan,
* its processes are sent a SIGHUP signal
*/
if (!strcmp(argv[optind], "restore") &&
opts.restore_detach &&
opts.final_state == TASK_STOPPED &&
opts.shell_job)
if (!strcmp(argv[optind], "restore") && opts.restore_detach && opts.final_state == TASK_STOPPED &&
opts.shell_job)
pr_warn("Stopped and detached shell job will get SIGHUP from OS.\n");
if (chdir(opts.work_dir)) {
@@ -305,26 +299,25 @@ int main(int argc, char *argv[], char *envp[])
pr_err("unknown command: %s\n", argv[optind]);
usage:
pr_msg("\n"
"Usage:\n"
" criu dump|pre-dump -t PID [<options>]\n"
" criu restore [<options>]\n"
" criu check [--feature FEAT]\n"
" criu page-server\n"
" criu service [<options>]\n"
" criu dedup\n"
" criu lazy-pages -D DIR [<options>]\n"
"\n"
"Commands:\n"
" dump checkpoint a process/tree identified by pid\n"
" pre-dump pre-dump task(s) minimizing their frozen time\n"
" restore restore a process/tree\n"
" check checks whether the kernel support is up-to-date\n"
" page-server launch page server\n"
" service launch service\n"
" dedup remove duplicates in memory dump\n"
" cpuinfo dump writes cpu information into image file\n"
" cpuinfo check validates cpu information read from image file\n"
);
"Usage:\n"
" criu dump|pre-dump -t PID [<options>]\n"
" criu restore [<options>]\n"
" criu check [--feature FEAT]\n"
" criu page-server\n"
" criu service [<options>]\n"
" criu dedup\n"
" criu lazy-pages -D DIR [<options>]\n"
"\n"
"Commands:\n"
" dump checkpoint a process/tree identified by pid\n"
" pre-dump pre-dump task(s) minimizing their frozen time\n"
" restore restore a process/tree\n"
" check checks whether the kernel support is up-to-date\n"
" page-server launch page server\n"
" service launch service\n"
" dedup remove duplicates in memory dump\n"
" cpuinfo dump writes cpu information into image file\n"
" cpuinfo check validates cpu information read from image file\n");
if (usage_error) {
pr_msg("\nTry -h|--help for more info\n");
@@ -333,178 +326,175 @@ usage:
pr_msg("\n"
"Most of the true / false long options (the ones without arguments) can be\n"
"prefixed with --no- to negate the option (example: --display-stats and\n"
"--no-display-stats).\n"
"\n"
"Dump/Restore options:\n"
"\n"
"* Generic:\n"
" -t|--tree PID checkpoint a process tree identified by PID\n"
" -d|--restore-detached detach after restore\n"
" -S|--restore-sibling restore root task as sibling\n"
" -s|--leave-stopped leave tasks in stopped state after checkpoint\n"
" -R|--leave-running leave tasks in running state after checkpoint\n"
" -D|--images-dir DIR directory for image files\n"
" --pidfile FILE write root task, service or page-server pid to FILE\n"
" -W|--work-dir DIR directory to cd and write logs/pidfiles/stats to\n"
" (if not specified, value of --images-dir is used)\n"
" --cpu-cap [CAP] CPU capabilities to write/check. CAP is comma-separated\n"
" list of: cpu, fpu, all, ins, none. To disable\n"
" a capability, use ^CAP. Empty argument implies all\n"
" --exec-cmd execute the command specified after '--' on successful\n"
" restore making it the parent of the restored process\n"
" --freeze-cgroup use cgroup freezer to collect processes\n"
" --weak-sysctls skip restoring sysctls that are not available\n"
" --lazy-pages restore pages on demand\n"
" this requires running a second instance of criu\n"
" in lazy-pages mode: 'criu lazy-pages -D DIR'\n"
" --lazy-pages and lazy-pages mode require userfaultfd\n"
" --stream dump/restore images using criu-image-streamer\n"
"\n"
"* External resources support:\n"
" --external RES dump objects from this list as external resources:\n"
" Formats of RES on dump:\n"
" tty[rdev:dev]\n"
" file[mnt_id:inode]\n"
" dev[major/minor]:NAME\n"
" unix[ino]\n"
" mnt[MOUNTPOINT]:COOKIE\n"
" mnt[]{:AUTO_OPTIONS}\n"
" Formats of RES on restore:\n"
" dev[NAME]:DEVPATH\n"
" veth[IFNAME]:OUTNAME{@BRIDGE}\n"
" macvlan[IFNAME]:OUTNAME\n"
" mnt[COOKIE]:ROOT\n"
" netdev[IFNAME]:ORIGNAME\n"
"\n"
"* Special resources support:\n"
" --" SK_EST_PARAM " checkpoint/restore established TCP connections\n"
" --" SK_INFLIGHT_PARAM " skip (ignore) in-flight TCP connections\n"
" --" SK_CLOSE_PARAM " don't dump the state of, or block, established tcp\n"
" connections, and restore them in closed state.\n"
" -r|--root PATH change the root filesystem (when run in mount namespace)\n"
" --evasive-devices use any path to a device file if the original one\n"
" is inaccessible\n"
" --link-remap allow one to link unlinked files back when possible\n"
" --ghost-limit size limit max size of deleted file contents inside image\n"
" --action-script FILE add an external action script\n"
" -j|--" OPT_SHELL_JOB " allow one to dump and restore shell jobs\n"
" -l|--" OPT_FILE_LOCKS " handle file locks, for safety, only used for container\n"
" -L|--libdir path to a plugin directory (by default " CR_PLUGIN_DEFAULT ")\n"
" --force-irmap force resolving names for inotify/fsnotify watches\n"
" --irmap-scan-path FILE\n"
" add a path the irmap hints to scan\n"
" --manage-cgroups [m] dump/restore process' cgroups; argument can be one of\n"
" 'none', 'props', 'soft' (default), 'full', 'strict'\n"
" or 'ignore'\n"
" --cgroup-root [controller:]/newroot\n"
" on dump: change the root for the controller that will\n"
" be dumped. By default, only the paths with tasks in\n"
" them and below will be dumped.\n"
" on restore: change the root cgroup the controller will\n"
" be installed into. No controller means that root is the\n"
" default for all controllers not specified\n"
" --cgroup-props STRING\n"
" define cgroup controllers and properties\n"
" to be checkpointed, which are described\n"
" via STRING using simplified YAML format\n"
" --cgroup-props-file FILE\n"
" same as --cgroup-props, but taking description\n"
" from the path specified\n"
" --cgroup-dump-controller NAME\n"
" define cgroup controller to be dumped\n"
" and skip anything else present in system\n"
" --cgroup-yard PATH\n"
" instead of trying to mount cgroups in CRIU, provide\n"
" a path to a directory with already created cgroup yard.\n"
" Useful if you don't want to grant CAP_SYS_ADMIN to CRIU\n"
" --lsm-profile TYPE:NAME\n"
" Specify an LSM profile to be used during restore.\n"
" The type can be either 'apparmor' or 'selinux'.\n"
" --lsm-mount-context CTX\n"
" Specify a mount context to be used during restore.\n"
" Only mounts with an existing context will have their\n"
" mount context replaced with CTX.\n"
" --skip-mnt PATH ignore this mountpoint when dumping the mount namespace\n"
" --enable-fs FSNAMES a comma separated list of filesystem names or \"all\"\n"
" force criu to (try to) dump/restore these filesystem's\n"
" mountpoints even if fs is not supported\n"
" --inherit-fd fd[NUM]:RES\n"
" Inherit file descriptors, treating fd NUM as being\n"
" already opened via an existing RES, which can be:\n"
" tty[rdev:dev]\n"
" pipe[inode]\n"
" socket[inode]\n"
" file[mnt_id:inode]\n"
" /memfd:name\n"
" path/to/file\n"
" --empty-ns net Create a namespace, but don't restore its properties\n"
" (assuming it will be restored by action scripts)\n"
" -J|--join-ns NS:{PID|NS_FILE}[,OPTIONS]\n"
" Join existing namespace and restore process in it.\n"
" Namespace can be specified as either pid or file path.\n"
" OPTIONS can be used to specify parameters for userns:\n"
" user:PID,UID,GID\n"
" --file-validation METHOD\n"
" pass the validation method to be used; argument\n"
" can be 'filesize' or 'buildid' (default).\n"
"\n"
"Check options:\n"
" Without options, \"criu check\" checks availability of absolutely required\n"
" kernel features, critical for performing dump and restore.\n"
" --extra add check for extra kernel features\n"
" --experimental add check for experimental kernel features\n"
" --all same as --extra --experimental\n"
" --feature FEAT only check a particular feature, one of:"
);
"Most of the true / false long options (the ones without arguments) can be\n"
"prefixed with --no- to negate the option (example: --display-stats and\n"
"--no-display-stats).\n"
"\n"
"Dump/Restore options:\n"
"\n"
"* Generic:\n"
" -t|--tree PID checkpoint a process tree identified by PID\n"
" -d|--restore-detached detach after restore\n"
" -S|--restore-sibling restore root task as sibling\n"
" -s|--leave-stopped leave tasks in stopped state after checkpoint\n"
" -R|--leave-running leave tasks in running state after checkpoint\n"
" -D|--images-dir DIR directory for image files\n"
" --pidfile FILE write root task, service or page-server pid to FILE\n"
" -W|--work-dir DIR directory to cd and write logs/pidfiles/stats to\n"
" (if not specified, value of --images-dir is used)\n"
" --cpu-cap [CAP] CPU capabilities to write/check. CAP is comma-separated\n"
" list of: cpu, fpu, all, ins, none. To disable\n"
" a capability, use ^CAP. Empty argument implies all\n"
" --exec-cmd execute the command specified after '--' on successful\n"
" restore making it the parent of the restored process\n"
" --freeze-cgroup use cgroup freezer to collect processes\n"
" --weak-sysctls skip restoring sysctls that are not available\n"
" --lazy-pages restore pages on demand\n"
" this requires running a second instance of criu\n"
" in lazy-pages mode: 'criu lazy-pages -D DIR'\n"
" --lazy-pages and lazy-pages mode require userfaultfd\n"
" --stream dump/restore images using criu-image-streamer\n"
"\n"
"* External resources support:\n"
" --external RES dump objects from this list as external resources:\n"
" Formats of RES on dump:\n"
" tty[rdev:dev]\n"
" file[mnt_id:inode]\n"
" dev[major/minor]:NAME\n"
" unix[ino]\n"
" mnt[MOUNTPOINT]:COOKIE\n"
" mnt[]{:AUTO_OPTIONS}\n"
" Formats of RES on restore:\n"
" dev[NAME]:DEVPATH\n"
" veth[IFNAME]:OUTNAME{@BRIDGE}\n"
" macvlan[IFNAME]:OUTNAME\n"
" mnt[COOKIE]:ROOT\n"
" netdev[IFNAME]:ORIGNAME\n"
"\n"
"* Special resources support:\n"
" --" SK_EST_PARAM " checkpoint/restore established TCP connections\n"
" --" SK_INFLIGHT_PARAM " skip (ignore) in-flight TCP connections\n"
" --" SK_CLOSE_PARAM " don't dump the state of, or block, established tcp\n"
" connections, and restore them in closed state.\n"
" -r|--root PATH change the root filesystem (when run in mount namespace)\n"
" --evasive-devices use any path to a device file if the original one\n"
" is inaccessible\n"
" --link-remap allow one to link unlinked files back when possible\n"
" --ghost-limit size limit max size of deleted file contents inside image\n"
" --action-script FILE add an external action script\n"
" -j|--" OPT_SHELL_JOB " allow one to dump and restore shell jobs\n"
" -l|--" OPT_FILE_LOCKS " handle file locks, for safety, only used for container\n"
" -L|--libdir path to a plugin directory (by default " CR_PLUGIN_DEFAULT ")\n"
" --force-irmap force resolving names for inotify/fsnotify watches\n"
" --irmap-scan-path FILE\n"
" add a path the irmap hints to scan\n"
" --manage-cgroups [m] dump/restore process' cgroups; argument can be one of\n"
" 'none', 'props', 'soft' (default), 'full', 'strict'\n"
" or 'ignore'\n"
" --cgroup-root [controller:]/newroot\n"
" on dump: change the root for the controller that will\n"
" be dumped. By default, only the paths with tasks in\n"
" them and below will be dumped.\n"
" on restore: change the root cgroup the controller will\n"
" be installed into. No controller means that root is the\n"
" default for all controllers not specified\n"
" --cgroup-props STRING\n"
" define cgroup controllers and properties\n"
" to be checkpointed, which are described\n"
" via STRING using simplified YAML format\n"
" --cgroup-props-file FILE\n"
" same as --cgroup-props, but taking description\n"
" from the path specified\n"
" --cgroup-dump-controller NAME\n"
" define cgroup controller to be dumped\n"
" and skip anything else present in system\n"
" --cgroup-yard PATH\n"
" instead of trying to mount cgroups in CRIU, provide\n"
" a path to a directory with already created cgroup yard.\n"
" Useful if you don't want to grant CAP_SYS_ADMIN to CRIU\n"
" --lsm-profile TYPE:NAME\n"
" Specify an LSM profile to be used during restore.\n"
" The type can be either 'apparmor' or 'selinux'.\n"
" --lsm-mount-context CTX\n"
" Specify a mount context to be used during restore.\n"
" Only mounts with an existing context will have their\n"
" mount context replaced with CTX.\n"
" --skip-mnt PATH ignore this mountpoint when dumping the mount namespace\n"
" --enable-fs FSNAMES a comma separated list of filesystem names or \"all\"\n"
" force criu to (try to) dump/restore these filesystem's\n"
" mountpoints even if fs is not supported\n"
" --inherit-fd fd[NUM]:RES\n"
" Inherit file descriptors, treating fd NUM as being\n"
" already opened via an existing RES, which can be:\n"
" tty[rdev:dev]\n"
" pipe[inode]\n"
" socket[inode]\n"
" file[mnt_id:inode]\n"
" /memfd:name\n"
" path/to/file\n"
" --empty-ns net Create a namespace, but don't restore its properties\n"
" (assuming it will be restored by action scripts)\n"
" -J|--join-ns NS:{PID|NS_FILE}[,OPTIONS]\n"
" Join existing namespace and restore process in it.\n"
" Namespace can be specified as either pid or file path.\n"
" OPTIONS can be used to specify parameters for userns:\n"
" user:PID,UID,GID\n"
" --file-validation METHOD\n"
" pass the validation method to be used; argument\n"
" can be 'filesize' or 'buildid' (default).\n"
"\n"
"Check options:\n"
" Without options, \"criu check\" checks availability of absolutely required\n"
" kernel features, critical for performing dump and restore.\n"
" --extra add check for extra kernel features\n"
" --experimental add check for experimental kernel features\n"
" --all same as --extra --experimental\n"
" --feature FEAT only check a particular feature, one of:");
pr_check_features(" ", ", ", 80);
pr_msg(
"\n"
"* Logging:\n"
" -o|--log-file FILE log file name\n"
" --log-pid enable per-process logging to separate FILE.pid files\n"
" -v[v...]|--verbosity increase verbosity (can use multiple v)\n"
" -vNUM|--verbosity=NUM set verbosity to NUM (higher level means more output):\n"
" -v1 - only errors and messages\n"
" -v2 - also warnings (default level)\n"
" -v3 - also information messages and timestamps\n"
" -v4 - lots of debug\n"
" --display-stats print out dump/restore stats\n"
"\n"
"* Memory dumping options:\n"
" --track-mem turn on memory changes tracker in kernel\n"
" --prev-images-dir DIR path to images from previous dump (relative to -D)\n"
" --page-server send pages to page server (see options below as well)\n"
" --auto-dedup when used on dump it will deduplicate \"old\" data in\n"
" pages images of previous dump\n"
" when used on restore, as soon as page is restored, it\n"
" will be punched from the image\n"
" --pre-dump-mode splice - parasite based pre-dumping (default)\n"
" read - process_vm_readv syscall based pre-dumping\n"
"\n"
"Page/Service server options:\n"
" --address ADDR address of server or service\n"
" --port PORT port of page server\n"
" --ps-socket FD use specified FD as page server socket\n"
" -d|--daemon run in the background after creating socket\n"
" --status-fd FD write \\0 to the FD and close it once process is ready\n"
" to handle requests\n"
" --tls-cacert FILE trust certificates signed only by this CA\n"
" --tls-cacrl FILE path to CA certificate revocation list file\n"
" --tls-cert FILE path to TLS certificate file\n"
" --tls-key FILE path to TLS private key file\n"
" --tls use TLS to secure remote connection\n"
" --tls-no-cn-verify do not verify common name in server certificate\n"
"\n"
"Configuration file options:\n"
" --config FILEPATH pass a specific configuration file\n"
" --no-default-config forbid usage of default configuration files\n"
"\n"
"Other options:\n"
" -h|--help show this text\n"
" -V|--version show version\n"
);
pr_msg("\n"
"* Logging:\n"
" -o|--log-file FILE log file name\n"
" --log-pid enable per-process logging to separate FILE.pid files\n"
" -v[v...]|--verbosity increase verbosity (can use multiple v)\n"
" -vNUM|--verbosity=NUM set verbosity to NUM (higher level means more output):\n"
" -v1 - only errors and messages\n"
" -v2 - also warnings (default level)\n"
" -v3 - also information messages and timestamps\n"
" -v4 - lots of debug\n"
" --display-stats print out dump/restore stats\n"
"\n"
"* Memory dumping options:\n"
" --track-mem turn on memory changes tracker in kernel\n"
" --prev-images-dir DIR path to images from previous dump (relative to -D)\n"
" --page-server send pages to page server (see options below as well)\n"
" --auto-dedup when used on dump it will deduplicate \"old\" data in\n"
" pages images of previous dump\n"
" when used on restore, as soon as page is restored, it\n"
" will be punched from the image\n"
" --pre-dump-mode splice - parasite based pre-dumping (default)\n"
" read - process_vm_readv syscall based pre-dumping\n"
"\n"
"Page/Service server options:\n"
" --address ADDR address of server or service\n"
" --port PORT port of page server\n"
" --ps-socket FD use specified FD as page server socket\n"
" -d|--daemon run in the background after creating socket\n"
" --status-fd FD write \\0 to the FD and close it once process is ready\n"
" to handle requests\n"
" --tls-cacert FILE trust certificates signed only by this CA\n"
" --tls-cacrl FILE path to CA certificate revocation list file\n"
" --tls-cert FILE path to TLS certificate file\n"
" --tls-key FILE path to TLS private key file\n"
" --tls use TLS to secure remote connection\n"
" --tls-no-cn-verify do not verify common name in server certificate\n"
"\n"
"Configuration file options:\n"
" --config FILEPATH pass a specific configuration file\n"
" --no-default-config forbid usage of default configuration files\n"
"\n"
"Other options:\n"
" -h|--help show this text\n"
" -V|--version show version\n");
return 0;

View File

@@ -22,12 +22,12 @@
#include "protobuf.h"
#include "images/eventfd.pb-c.h"
#undef LOG_PREFIX
#undef LOG_PREFIX
#define LOG_PREFIX "eventfd: "
struct eventfd_file_info {
EventfdFileEntry *efe;
struct file_desc d;
EventfdFileEntry *efe;
struct file_desc d;
};
/* Checks if file descriptor @lfd is eventfd */
@@ -38,8 +38,7 @@ int is_eventfd_link(char *link)
static void pr_info_eventfd(char *action, EventfdFileEntry *efe)
{
pr_info("%s: id %#08x flags %#04x counter %#016"PRIx64"\n",
action, efe->id, efe->flags, efe->counter);
pr_info("%s: id %#08x flags %#04x counter %#016" PRIx64 "\n", action, efe->id, efe->flags, efe->counter);
}
static int dump_one_eventfd(int lfd, u32 id, const struct fd_parms *p)
@@ -63,8 +62,8 @@ static int dump_one_eventfd(int lfd, u32 id, const struct fd_parms *p)
}
const struct fdtype_ops eventfd_dump_ops = {
.type = FD_TYPES__EVENTFD,
.dump = dump_one_eventfd,
.type = FD_TYPES__EVENTFD,
.dump = dump_one_eventfd,
};
static int eventfd_open(struct file_desc *d, int *new_fd)
@@ -76,14 +75,12 @@ static int eventfd_open(struct file_desc *d, int *new_fd)
tmp = eventfd(info->efe->counter, 0);
if (tmp < 0) {
pr_perror("Can't create eventfd %#08x",
info->efe->id);
pr_perror("Can't create eventfd %#08x", info->efe->id);
return -1;
}
if (rst_file_params(tmp, info->efe->fown, info->efe->flags)) {
pr_perror("Can't restore params on eventfd %#08x",
info->efe->id);
pr_perror("Can't restore params on eventfd %#08x", info->efe->id);
goto err_close;
}

View File

@@ -30,33 +30,33 @@
#include "protobuf.h"
#include "images/eventpoll.pb-c.h"
#undef LOG_PREFIX
#undef LOG_PREFIX
#define LOG_PREFIX "epoll: "
static LIST_HEAD(dinfo_list);
typedef struct {
uint32_t tfd;
uint32_t off;
uint32_t idx;
uint32_t tfd;
uint32_t off;
uint32_t idx;
} toff_t;
struct eventpoll_dinfo {
struct list_head list;
struct list_head list;
FileEntry *fe;
EventpollFileEntry *e;
FileEntry *fe;
EventpollFileEntry *e;
toff_t *toff;
FownEntry fown;
toff_t *toff;
FownEntry fown;
pid_t pid;
int efd;
pid_t pid;
int efd;
};
struct eventpoll_file_info {
EventpollFileEntry *efe;
struct file_desc d;
EventpollFileEntry *efe;
struct file_desc d;
};
/* Checks if file descriptor @lfd is eventfd */
@@ -67,8 +67,8 @@ int is_eventpoll_link(char *link)
static void pr_info_eventpoll_tfd(char *action, uint32_t id, EventpollTfdEntry *e)
{
pr_info("%seventpoll-tfd: id %#08x tfd %8d events %#08x data %#016"PRIx64"\n",
action, id, e->tfd, e->events, e->data);
pr_info("%seventpoll-tfd: id %#08x tfd %8d events %#08x data %#016" PRIx64 "\n", action, id, e->tfd, e->events,
e->data);
}
static void pr_info_eventpoll(char *action, EventpollFileEntry *e)
@@ -90,16 +90,16 @@ static int queue_dinfo(FileEntry **fe, EventpollFileEntry **e, toff_t **toff, co
INIT_LIST_HEAD(&dinfo->list);
dinfo->fe = *fe;
dinfo->e = *e;
dinfo->toff = *toff;
dinfo->e->fown = &dinfo->fown;
dinfo->pid = p->pid;
dinfo->efd = p->fd;
dinfo->fe = *fe;
dinfo->e = *e;
dinfo->toff = *toff;
dinfo->e->fown = &dinfo->fown;
dinfo->pid = p->pid;
dinfo->efd = p->fd;
*fe = NULL;
*e = NULL;
*toff = NULL;
*fe = NULL;
*e = NULL;
*toff = NULL;
list_add_tail(&dinfo->list, &dinfo_list);
return 0;
@@ -133,31 +133,29 @@ int flush_eventpoll_dinfo_queue(void)
for (i = 0; i < e->n_tfd; i++) {
EventpollTfdEntry *tfde = e->tfd[i];
struct kid_elem ke = {
.pid = dinfo->pid,
.genid = make_gen_id(tfde->dev,
tfde->inode,
tfde->pos),
.idx = tfde->tfd,
.pid = dinfo->pid,
.genid = make_gen_id(tfde->dev, tfde->inode, tfde->pos),
.idx = tfde->tfd,
};
kcmp_epoll_slot_t slot = {
.efd = dinfo->efd,
.tfd = tfde->tfd,
.toff = dinfo->toff[i].off,
.efd = dinfo->efd,
.tfd = tfde->tfd,
.toff = dinfo->toff[i].off,
};
struct kid_elem *t = kid_lookup_epoll_tfd(&fd_tree, &ke, &slot);
if (!t) {
pr_debug("kid_lookup_epoll: no match pid %d efd %d tfd %d toff %u\n",
dinfo->pid, dinfo->efd, tfde->tfd, dinfo->toff[i].off);
pr_debug("kid_lookup_epoll: no match pid %d efd %d tfd %d toff %u\n", dinfo->pid,
dinfo->efd, tfde->tfd, dinfo->toff[i].off);
goto err;
}
pr_debug("kid_lookup_epoll: rbsearch match pid %d efd %d tfd %d toff %u -> %d\n",
dinfo->pid, dinfo->efd, tfde->tfd, dinfo->toff[i].off, t->idx);
pr_debug("kid_lookup_epoll: rbsearch match pid %d efd %d tfd %d toff %u -> %d\n", dinfo->pid,
dinfo->efd, tfde->tfd, dinfo->toff[i].off, t->idx);
/* Make sure the pid matches */
if (t->pid != dinfo->pid) {
pr_debug("kid_lookup_epoll: pid mismatch %d %d efd %d tfd %d toff %u\n",
dinfo->pid, t->pid, dinfo->efd, tfde->tfd, dinfo->toff[i].off);
pr_debug("kid_lookup_epoll: pid mismatch %d %d efd %d tfd %d toff %u\n", dinfo->pid,
t->pid, dinfo->efd, tfde->tfd, dinfo->toff[i].off);
goto err;
}
@@ -218,13 +216,12 @@ static int toff_cmp_idx(const void *a, const void *b)
* fds in fd_parms are sorted so we can use binary search
* for better performance.
*/
static int find_tfd_bsearch(pid_t pid, int efd, int fds[], size_t nr_fds,
int tfd, unsigned int toff)
static int find_tfd_bsearch(pid_t pid, int efd, int fds[], size_t nr_fds, int tfd, unsigned int toff)
{
kcmp_epoll_slot_t slot = {
.efd = efd,
.tfd = tfd,
.toff = toff,
.efd = efd,
.tfd = tfd,
.toff = toff,
};
int *tfd_found;
@@ -243,14 +240,13 @@ static int find_tfd_bsearch(pid_t pid, int efd, int fds[], size_t nr_fds,
return tfd;
}
} else {
pr_debug("find_tfd_bsearch (kcmp-no): bsearch match pid %d efd %d tfd %d toff %u\n",
pid, efd, tfd, toff);
pr_debug("find_tfd_bsearch (kcmp-no): bsearch match pid %d efd %d tfd %d toff %u\n", pid, efd,
tfd, toff);
return tfd;
}
}
pr_debug("find_tfd_bsearch: no match pid %d efd %d tfd %d toff %u\n",
pid, efd, tfd, toff);
pr_debug("find_tfd_bsearch: no match pid %d efd %d tfd %d toff %u\n", pid, efd, tfd, toff);
return -1;
}
@@ -272,16 +268,16 @@ static int dump_one_eventpoll(int lfd, u32 id, const struct fd_parms *p)
goto out;
file_entry__init(fe);
e->id = id;
e->flags = p->flags;
e->fown = (FownEntry *)&p->fown;
e->id = id;
e->flags = p->flags;
e->fown = (FownEntry *)&p->fown;
if (parse_fdinfo(lfd, FD_TYPES__EVENTPOLL, e))
goto out;
fe->type = FD_TYPES__EVENTPOLL;
fe->id = e->id;
fe->epfd = e;
fe->type = FD_TYPES__EVENTPOLL;
fe->id = e->id;
fe->epfd = e;
/*
* In regular case there is no so many dup'ed
@@ -293,9 +289,9 @@ static int dump_one_eventpoll(int lfd, u32 id, const struct fd_parms *p)
if (!toff)
goto out;
for (i = 0; i < e->n_tfd; i++) {
toff[i].idx = i;
toff[i].tfd = e->tfd[i]->tfd;
toff[i].off = 0;
toff[i].idx = i;
toff[i].tfd = e->tfd[i]->tfd;
toff[i].off = 0;
}
qsort(toff, e->n_tfd, sizeof(*toff), toff_cmp);
@@ -317,14 +313,13 @@ static int dump_one_eventpoll(int lfd, u32 id, const struct fd_parms *p)
*/
if (p->dfds) {
for (i = 0; i < e->n_tfd; i++) {
int tfd = find_tfd_bsearch(p->pid, p->fd, p->dfds->fds,
p->dfds->nr_fds, e->tfd[i]->tfd, toff[i].off);
int tfd = find_tfd_bsearch(p->pid, p->fd, p->dfds->fds, p->dfds->nr_fds, e->tfd[i]->tfd,
toff[i].off);
if (tfd == -1) {
if (kdat.has_kcmp_epoll_tfd) {
ret = queue_dinfo(&fe, &e, &toff, p);
} else {
pr_err("Escaped/closed fd descriptor %d on pid %d\n",
e->tfd[i]->tfd, p->pid);
pr_err("Escaped/closed fd descriptor %d on pid %d\n", e->tfd[i]->tfd, p->pid);
}
goto out;
}
@@ -352,8 +347,8 @@ out:
}
const struct fdtype_ops eventpoll_dump_ops = {
.type = FD_TYPES__EVENTPOLL,
.dump = dump_one_eventpoll,
.type = FD_TYPES__EVENTPOLL,
.dump = dump_one_eventpoll,
};
static int eventpoll_post_open(struct file_desc *d, int fd);
@@ -373,14 +368,12 @@ static int eventpoll_open(struct file_desc *d, int *new_fd)
tmp = epoll_create(1);
if (tmp < 0) {
pr_perror("Can't create epoll %#08x",
info->efe->id);
pr_perror("Can't create epoll %#08x", info->efe->id);
return -1;
}
if (rst_file_params(tmp, info->efe->fown, info->efe->flags)) {
pr_perror("Can't restore file params on epoll %#08x",
info->efe->id);
pr_perror("Can't restore file params on epoll %#08x", info->efe->id);
goto err_close;
}
@@ -418,8 +411,8 @@ static int eventpoll_retore_tfd(int fd, int id, EventpollTfdEntry *tdefe)
pr_info_eventpoll_tfd("Restore ", id, tdefe);
event.events = tdefe->events;
event.data.u64 = tdefe->data;
event.events = tdefe->events;
event.data.u64 = tdefe->data;
if (epoll_ctl(fd, EPOLL_CTL_ADD, tdefe->tfd, &event)) {
pr_perror("Can't add event on %#08x", id);
return -1;
@@ -448,8 +441,8 @@ static int eventpoll_post_open(struct file_desc *d, int fd)
}
static struct file_desc_ops desc_ops = {
.type = FD_TYPES__EVENTPOLL,
.open = eventpoll_open,
.type = FD_TYPES__EVENTPOLL,
.open = eventpoll_open,
};
static int collect_one_epoll_tfd(void *o, ProtobufCMessage *msg, struct cr_img *i)
@@ -484,10 +477,10 @@ static int collect_one_epoll_tfd(void *o, ProtobufCMessage *msg, struct cr_img *
}
struct collect_image_info epoll_tfd_cinfo = {
.fd_type = CR_FD_EVENTPOLL_TFD,
.pb_type = PB_EVENTPOLL_TFD,
.collect = collect_one_epoll_tfd,
.flags = COLLECT_NOFREE,
.fd_type = CR_FD_EVENTPOLL_TFD,
.pb_type = PB_EVENTPOLL_TFD,
.collect = collect_one_epoll_tfd,
.flags = COLLECT_NOFREE,
};
static int collect_one_epoll(void *o, ProtobufCMessage *msg, struct cr_img *i)
@@ -500,8 +493,8 @@ static int collect_one_epoll(void *o, ProtobufCMessage *msg, struct cr_img *i)
}
struct collect_image_info epoll_cinfo = {
.fd_type = CR_FD_EVENTPOLL_FILE,
.pb_type = PB_EVENTPOLL_FILE,
.priv_size = sizeof(struct eventpoll_file_info),
.collect = collect_one_epoll,
.fd_type = CR_FD_EVENTPOLL_FILE,
.pb_type = PB_EVENTPOLL_FILE,
.priv_size = sizeof(struct eventpoll_file_info),
.collect = collect_one_epoll,
};

View File

@@ -16,7 +16,7 @@
static struct fdstore_desc {
int next_id;
mutex_t lock; /* to protect a peek offset */
} *desc;
} * desc;
int fdstore_init(void)
{
@@ -54,7 +54,7 @@ int fdstore_init(void)
}
addr.sun_family = AF_UNIX;
addrlen = snprintf(addr.sun_path, sizeof(addr.sun_path), "X/criu-fdstore-%"PRIx64, st.st_ino);
addrlen = snprintf(addr.sun_path, sizeof(addr.sun_path), "X/criu-fdstore-%" PRIx64, st.st_ino);
addrlen += sizeof(addr.sun_family);
addr.sun_path[0] = 0;
@@ -66,12 +66,12 @@ int fdstore_init(void)
* a queue and remember its sequence number. Then we can set SO_PEEK_OFF
* to get a file descriptor without dequeuing it.
*/
if (bind(sk, (struct sockaddr *) &addr, addrlen)) {
if (bind(sk, (struct sockaddr *)&addr, addrlen)) {
pr_perror("Unable to bind a socket");
close(sk);
return -1;
}
if (connect(sk, (struct sockaddr *) &addr, addrlen)) {
if (connect(sk, (struct sockaddr *)&addr, addrlen)) {
pr_perror("Unable to connect a socket");
close(sk);
return -1;

View File

@@ -30,14 +30,16 @@
*/
struct fifo_info {
struct list_head list;
struct file_desc d;
FifoEntry *fe;
bool restore_data;
struct list_head list;
struct file_desc d;
FifoEntry *fe;
bool restore_data;
};
static LIST_HEAD(fifo_head);
static struct pipe_data_dump pd_fifo = { .img_type = CR_FD_FIFO_DATA, };
static struct pipe_data_dump pd_fifo = {
.img_type = CR_FD_FIFO_DATA,
};
static int dump_one_fifo(int lfd, u32 id, const struct fd_parms *p)
{
@@ -56,13 +58,12 @@ static int dump_one_fifo(int lfd, u32 id, const struct fd_parms *p)
if (dump_one_reg_file(lfd, rf_id, p))
return -1;
pr_info("Dumping fifo %d with id %#x pipe_id %#x\n",
lfd, id, pipe_id(p));
pr_info("Dumping fifo %d with id %#x pipe_id %#x\n", lfd, id, pipe_id(p));
e.id = id;
e.pipe_id = pipe_id(p);
e.has_regf_id = true;
e.regf_id = rf_id;
e.id = id;
e.pipe_id = pipe_id(p);
e.has_regf_id = true;
e.regf_id = rf_id;
fe.type = FD_TYPES__FIFO;
fe.id = e.id;
@@ -75,8 +76,8 @@ static int dump_one_fifo(int lfd, u32 id, const struct fd_parms *p)
}
const struct fdtype_ops fifo_dump_ops = {
.type = FD_TYPES__FIFO,
.dump = dump_one_fifo,
.type = FD_TYPES__FIFO,
.dump = dump_one_fifo,
};
static struct pipe_data_rst *pd_hash_fifo[PIPE_DATA_HASH_SIZE];
@@ -105,8 +106,7 @@ static int do_open_fifo(int ns_root_fd, struct reg_file_info *rfi, void *arg)
}
if (info->restore_data)
if (restore_pipe_data(CR_FD_FIFO_DATA, fake_fifo,
info->fe->pipe_id, pd_hash_fifo)) {
if (restore_pipe_data(CR_FD_FIFO_DATA, fake_fifo, info->fe->pipe_id, pd_hash_fifo)) {
close(new_fifo);
new_fifo = -1;
}
@@ -122,8 +122,7 @@ static int open_fifo_fd(struct file_desc *d, int *new_fd)
struct file_desc *reg_d;
int fd;
reg_d = collect_special_file(info->fe->has_regf_id ?
info->fe->regf_id : info->fe->id);
reg_d = collect_special_file(info->fe->has_regf_id ? info->fe->regf_id : info->fe->id);
if (!reg_d)
return -1;
@@ -135,8 +134,8 @@ static int open_fifo_fd(struct file_desc *d, int *new_fd)
}
static struct file_desc_ops fifo_desc_ops = {
.type = FD_TYPES__FIFO,
.open = open_fifo_fd,
.type = FD_TYPES__FIFO,
.open = open_fifo_fd,
};
static int collect_one_fifo(void *o, ProtobufCMessage *base, struct cr_img *i)
@@ -144,8 +143,7 @@ static int collect_one_fifo(void *o, ProtobufCMessage *base, struct cr_img *i)
struct fifo_info *info = o, *f;
info->fe = pb_msg(base, FifoEntry);
pr_info("Collected fifo entry ID %#x PIPE ID %#x\n",
info->fe->id, info->fe->pipe_id);
pr_info("Collected fifo entry ID %#x PIPE ID %#x\n", info->fe->id, info->fe->pipe_id);
/* check who will restore the fifo data */
list_for_each_entry(f, &fifo_head, list)
@@ -161,7 +159,6 @@ static int collect_one_fifo(void *o, ProtobufCMessage *base, struct cr_img *i)
}
return file_desc_add(&info->d, info->fe->id, &fifo_desc_ops);
}
struct collect_image_info fifo_cinfo = {

View File

@@ -21,9 +21,9 @@
DECLARE_KCMP_TREE(fd_tree, KCMP_FILE);
#define FDID_BITS 5
#define FDID_SIZE (1 << FDID_BITS)
#define FDID_MASK (FDID_SIZE - 1)
#define FDID_BITS 5
#define FDID_SIZE (1 << FDID_BITS)
#define FDID_MASK (FDID_SIZE - 1)
static inline int fdid_hashfn(unsigned int s_dev, unsigned long i_ino)
{
@@ -63,11 +63,8 @@ static struct fd_id *fd_id_cache_lookup(struct fd_parms *p)
struct stat *st = &p->stat;
struct fd_id *fi;
for (fi = fd_id_cache[fdid_hashfn(st->st_dev, st->st_ino)];
fi; fi = fi->n)
if (fi->dev == st->st_dev &&
fi->ino == st->st_ino &&
fi->mnt_id == p->mnt_id)
for (fi = fd_id_cache[fdid_hashfn(st->st_dev, st->st_ino)]; fi; fi = fi->n)
if (fi->dev == st->st_dev && fi->ino == st->st_ino && fi->mnt_id == p->mnt_id)
return fi;
return NULL;

View File

@@ -76,11 +76,10 @@ void free_file_locks(void)
static int dump_one_file_lock(FileLockEntry *fle)
{
pr_info("LOCK flag: %d,type: %d,pid: %d,fd: %d,start: %8"PRIx64",len: %8"PRIx64"\n",
fle->flag, fle->type, fle->pid, fle->fd, fle->start, fle->len);
pr_info("LOCK flag: %d,type: %d,pid: %d,fd: %d,start: %8" PRIx64 ",len: %8" PRIx64 "\n", fle->flag, fle->type,
fle->pid, fle->fd, fle->start, fle->len);
return pb_write_one(img_from_set(glob_imgset, CR_FD_FILE_LOCKS),
fle, PB_FILE_LOCK);
return pb_write_one(img_from_set(glob_imgset, CR_FD_FILE_LOCKS), fle, PB_FILE_LOCK);
}
static void fill_flock_entry(FileLockEntry *fle, int fl_kind, int fl_ltype)
@@ -91,17 +90,16 @@ static void fill_flock_entry(FileLockEntry *fle, int fl_kind, int fl_ltype)
int dump_file_locks(void)
{
FileLockEntry fle;
FileLockEntry fle;
struct file_lock *fl;
int ret = 0;
int ret = 0;
pr_info("Dumping file-locks\n");
list_for_each_entry(fl, &file_lock_list, list) {
if (fl->real_owner == -1) {
if (fl->fl_kind == FL_POSIX) {
pr_err("Unresolved lock found pid %d ino %ld\n",
fl->fl_owner, fl->i_no);
pr_err("Unresolved lock found pid %d ino %ld\n", fl->fl_owner, fl->i_no);
return -1;
}
@@ -110,7 +108,7 @@ int dump_file_locks(void)
if (!opts.handle_file_locks) {
pr_err("Some file locks are hold by dumping tasks! "
"You can try --" OPT_FILE_LOCKS " to dump them.\n");
"You can try --" OPT_FILE_LOCKS " to dump them.\n");
return -1;
}
@@ -154,7 +152,7 @@ static int lock_btrfs_file_match(pid_t pid, int fd, struct file_lock *fl, struct
link[ret] = 0;
ns = lookup_nsid_by_mnt_id(p->mnt_id);
return phys_stat_dev_match(p->stat.st_dev, phys_dev, ns, link);
return phys_stat_dev_match(p->stat.st_dev, phys_dev, ns, link);
}
static inline int lock_file_match(pid_t pid, int fd, struct file_lock *fl, struct fd_parms *p)
@@ -224,11 +222,7 @@ static int lock_ofd_check_fd(int lfd, struct file_lock *fl)
{
int ret;
struct flock lck = {
.l_whence = SEEK_SET,
.l_type = F_WRLCK,
.l_start = fl->start
};
struct flock lck = { .l_whence = SEEK_SET, .l_type = F_WRLCK, .l_start = fl->start };
if (strcmp(fl->end, "EOF")) {
unsigned long end;
@@ -366,7 +360,7 @@ int note_file_lock(struct pid *pid, int fd, int lfd, struct fd_parms *p)
if (!opts.handle_file_locks) {
pr_err("Some file locks are hold by dumping tasks!"
"You can try --" OPT_FILE_LOCKS " to dump them.\n");
"You can try --" OPT_FILE_LOCKS " to dump them.\n");
return -1;
}
@@ -380,8 +374,7 @@ int note_file_lock(struct pid *pid, int fd, int lfd, struct fd_parms *p)
} else if (fl->fl_kind == FL_LEASE) {
if (fl->owners_fd >= 0)
continue;
if (fl->fl_owner != pid->real &&
fl->real_owner != -1)
if (fl->fl_owner != pid->real && fl->real_owner != -1)
continue;
ret = lease_check_fd(lfd, p->flags, fl);
@@ -399,8 +392,7 @@ int note_file_lock(struct pid *pid, int fd, int lfd, struct fd_parms *p)
* anyway.
*/
if (fl->fl_owner != pid->real &&
fl->real_owner != -1)
if (fl->fl_owner != pid->real && fl->real_owner != -1)
continue;
pr_debug("Checking lock holder %d:%d\n", pid->real, fd);
@@ -419,9 +411,7 @@ int note_file_lock(struct pid *pid, int fd, int lfd, struct fd_parms *p)
fl->real_owner = pid->ns[0].virt;
fl->owners_fd = fd;
pr_info("Found lock entry %d.%d %d vs %d\n",
pid->real, pid->ns[0].virt, fd,
fl->fl_owner);
pr_info("Found lock entry %d.%d %d vs %d\n", pid->real, pid->ns[0].virt, fd, fl->fl_owner);
}
return 0;
@@ -450,8 +440,7 @@ int correct_file_leases_type(struct pid *pid, int fd, int lfd)
if (fl->fl_holder != pid->real || fl->owners_fd != fd)
continue;
if (fl->fl_kind == FL_LEASE &&
(fl->fl_ltype & LEASE_BREAKING)) {
if (fl->fl_kind == FL_LEASE && (fl->fl_ltype & LEASE_BREAKING)) {
/*
* Set lease type to actual 'target lease type'
* instead of 'READ' returned by procfs.
@@ -538,8 +527,7 @@ static int restore_lease_prebreaking_state(int fd, int fd_type)
return set_file_lease(fd, lease_type);
}
static struct fdinfo_list_entry *find_fd_unordered(struct pstree_item *task,
int fd)
static struct fdinfo_list_entry *find_fd_unordered(struct pstree_item *task, int fd)
{
struct list_head *head = &rsti(task)->fds;
struct fdinfo_list_entry *fle;
@@ -592,9 +580,8 @@ static int restore_file_lease(FileLockEntry *fle)
pr_perror("Can't get file i/o signum");
return -1;
}
if (sigemptyset(&blockmask) ||
sigaddset(&blockmask, signum) ||
sigprocmask(SIG_BLOCK, &blockmask, &oldmask)) {
if (sigemptyset(&blockmask) || sigaddset(&blockmask, signum) ||
sigprocmask(SIG_BLOCK, &blockmask, &oldmask)) {
pr_perror("Can't block file i/o signal");
return -1;
}
@@ -633,8 +620,8 @@ static int restore_file_lock(FileLockEntry *fle)
goto err;
}
pr_info("(flock)flag: %d, type: %d, cmd: %d, pid: %d, fd: %d\n",
fle->flag, fle->type, cmd, fle->pid, fle->fd);
pr_info("(flock)flag: %d, type: %d, cmd: %d, pid: %d, fd: %d\n", fle->flag, fle->type, cmd, fle->pid,
fle->fd);
ret = flock(fle->fd, cmd);
if (ret < 0) {
@@ -646,15 +633,14 @@ static int restore_file_lock(FileLockEntry *fle)
memset(&flk, 0, sizeof(flk));
flk.l_whence = SEEK_SET;
flk.l_start = fle->start;
flk.l_len = fle->len;
flk.l_pid = fle->pid;
flk.l_type = fle->type;
flk.l_start = fle->start;
flk.l_len = fle->len;
flk.l_pid = fle->pid;
flk.l_type = fle->type;
pr_info("(posix)flag: %d, type: %d, pid: %d, fd: %d, "
"start: %8"PRIx64", len: %8"PRIx64"\n",
fle->flag, fle->type, fle->pid, fle->fd,
fle->start, fle->len);
"start: %8" PRIx64 ", len: %8" PRIx64 "\n",
fle->flag, fle->type, fle->pid, fle->fd, fle->start, fle->len);
ret = fcntl(fle->fd, F_SETLKW, &flk);
if (ret < 0) {
@@ -663,17 +649,12 @@ static int restore_file_lock(FileLockEntry *fle)
}
} else if (fle->flag & FL_OFD) {
struct flock flk = {
.l_whence = SEEK_SET,
.l_start = fle->start,
.l_len = fle->len,
.l_pid = 0,
.l_type = fle->type
.l_whence = SEEK_SET, .l_start = fle->start, .l_len = fle->len, .l_pid = 0, .l_type = fle->type
};
pr_info("(ofd)flag: %d, type: %d, pid: %d, fd: %d, "
"start: %8"PRIx64", len: %8"PRIx64"\n",
fle->flag, fle->type, fle->pid, fle->fd,
fle->start, fle->len);
"start: %8" PRIx64 ", len: %8" PRIx64 "\n",
fle->flag, fle->type, fle->pid, fle->fd, fle->start, fle->len);
ret = fcntl(fle->fd, F_OFD_SETLK, &flk);
if (ret < 0) {
@@ -682,9 +663,8 @@ static int restore_file_lock(FileLockEntry *fle)
}
} else if (fle->flag & FL_LEASE) {
pr_info("(lease)flag: %d, type: %d, pid: %d, fd: %d, "
"start: %8"PRIx64", len: %8"PRIx64"\n",
fle->flag, fle->type, fle->pid, fle->fd,
fle->start, fle->len);
"start: %8" PRIx64 ", len: %8" PRIx64 "\n",
fle->flag, fle->type, fle->pid, fle->fd, fle->start, fle->len);
ret = restore_file_lease(fle);
if (ret < 0)
goto err;
@@ -720,5 +700,4 @@ int prepare_file_locks(int pid)
return 0;
return restore_file_locks(pid);
}

View File

@@ -20,8 +20,8 @@ static int dump_one_ext_file(int lfd, u32 id, const struct fd_parms *p)
if (ret < 0)
return ret;
xfe.id = id;
xfe.fown = (FownEntry *)&p->fown;
xfe.id = id;
xfe.fown = (FownEntry *)&p->fown;
fe.type = FD_TYPES__EXT;
fe.id = xfe.id;
@@ -32,13 +32,13 @@ static int dump_one_ext_file(int lfd, u32 id, const struct fd_parms *p)
}
const struct fdtype_ops ext_dump_ops = {
.type = FD_TYPES__EXT,
.dump = dump_one_ext_file,
.type = FD_TYPES__EXT,
.dump = dump_one_ext_file,
};
struct ext_file_info {
struct file_desc d;
ExtFileEntry *xfe;
struct file_desc d;
ExtFileEntry *xfe;
};
static int open_fd(struct file_desc *d, int *new_fd)
@@ -83,8 +83,7 @@ struct collect_image_info ext_file_cinfo = {
.collect = collect_one_ext,
};
int dump_unsupp_fd(struct fd_parms *p, int lfd,
char *more, char *info, FdinfoEntry *e)
int dump_unsupp_fd(struct fd_parms *p, int lfd, char *more, char *info, FdinfoEntry *e)
{
int ret;
@@ -92,7 +91,6 @@ int dump_unsupp_fd(struct fd_parms *p, int lfd,
if (ret == 0)
return 0;
if (ret == -ENOTSUP)
pr_err("Can't dump file %d of that type [%o] (%s %s)\n",
p->fd, p->stat.st_mode, more, info);
pr_err("Can't dump file %d of that type [%o] (%s %s)\n", p->fd, p->stat.st_mode, more, info);
return -1;
}

View File

@@ -15,12 +15,12 @@
#include <elf.h>
#ifndef SEEK_DATA
#define SEEK_DATA 3
#define SEEK_HOLE 4
#define SEEK_DATA 3
#define SEEK_HOLE 4
#endif
/* Stolen from kernel/fs/nfs/unlink.c */
#define SILLYNAME_PREF ".nfs"
#define SILLYNAME_PREF ".nfs"
#define SILLYNAME_SUFF_LEN (((unsigned)sizeof(u64) << 1) + ((unsigned)sizeof(unsigned int) << 1))
/*
@@ -63,13 +63,13 @@ int setfsgid(gid_t fsuid);
* us. Any brave soul to implement link unlinked file back?
*/
struct ghost_file {
struct list_head list;
u32 id;
struct list_head list;
u32 id;
u32 dev;
u32 ino;
u32 dev;
u32 ino;
struct file_remap remap;
struct file_remap remap;
};
static u32 ghost_file_ids = 1;
@@ -102,9 +102,9 @@ static LIST_HEAD(remaps);
* we keep all data in memory.
*/
struct link_remap_rlb {
struct list_head list;
struct ns_id *mnt_ns;
char *path;
struct list_head list;
struct ns_id *mnt_ns;
char *path;
};
static int note_link_remap(char *path, struct ns_id *nsid)
@@ -158,7 +158,7 @@ static int trim_last_parent(char *path)
return 0;
}
#define BUFSIZE (4096)
#define BUFSIZE (4096)
static int copy_chunk_from_file(int fd, int img, off_t off, size_t len)
{
@@ -369,7 +369,7 @@ static int create_ghost(struct ghost_file *gf, GhostFileEntry *gfe, struct cr_im
}
/* Add a '/' only if we have no at the end */
if (path[root_len-1] != '/') {
if (path[root_len - 1] != '/') {
path[root_len++] = '/';
path[root_len] = '\0';
}
@@ -429,14 +429,12 @@ err:
return ret;
}
static inline void ghost_path(char *path, int plen,
struct reg_file_info *rfi, RemapFilePathEntry *rpe)
static inline void ghost_path(char *path, int plen, struct reg_file_info *rfi, RemapFilePathEntry *rpe)
{
snprintf(path, plen, "%s.cr.%x.ghost", rfi->path, rpe->remap_id);
}
static int collect_remap_ghost(struct reg_file_info *rfi,
RemapFilePathEntry *rpe)
static int collect_remap_ghost(struct reg_file_info *rfi, RemapFilePathEntry *rpe)
{
struct ghost_file *gf;
@@ -476,8 +474,7 @@ gf_found:
return 0;
}
static int open_remap_ghost(struct reg_file_info *rfi,
RemapFilePathEntry *rpe)
static int open_remap_ghost(struct reg_file_info *rfi, RemapFilePathEntry *rpe)
{
struct ghost_file *gf = container_of(rfi->remap, struct ghost_file, remap);
GhostFileEntry *gfe = NULL;
@@ -527,8 +524,7 @@ err:
return -1;
}
static int collect_remap_linked(struct reg_file_info *rfi,
RemapFilePathEntry *rpe)
static int collect_remap_linked(struct reg_file_info *rfi, RemapFilePathEntry *rpe)
{
struct file_remap *rm;
struct file_desc *rdesc;
@@ -575,8 +571,7 @@ static int open_remap_linked(struct reg_file_info *rfi)
return 0;
}
static int collect_remap_dead_process(struct reg_file_info *rfi,
RemapFilePathEntry *rfe)
static int collect_remap_dead_process(struct reg_file_info *rfi, RemapFilePathEntry *rfe)
{
struct pstree_item *helper;
@@ -589,7 +584,6 @@ static int collect_remap_dead_process(struct reg_file_info *rfi,
return 0;
}
helper->sid = root_item->sid;
helper->pgid = root_item->pgid;
helper->pid->ns[0].virt = rfe->remap_id;
@@ -777,7 +771,7 @@ static struct collect_image_info remap_cinfo = {
};
/* Tiny files don't need to generate chunks in ghost image. */
#define GHOST_CHUNKS_THRESH (3 * 4096)
#define GHOST_CHUNKS_THRESH (3 * 4096)
static int dump_ghost_file(int _fd, u32 id, const struct stat *st, dev_t phys_dev)
{
@@ -841,8 +835,8 @@ static int dump_ghost_file(int _fd, u32 id, const struct stat *st, dev_t phys_de
pathbuf[ret] = 0;
if (ret != st->st_size) {
pr_err("Buffer for readlinkat is too small: ret %zd, st_size %"PRId64", buf %u %s\n",
ret, st->st_size, PATH_MAX, pathbuf);
pr_err("Buffer for readlinkat is too small: ret %zd, st_size %" PRId64 ", buf %u %s\n", ret,
st->st_size, PATH_MAX, pathbuf);
goto err_out;
}
@@ -893,8 +887,7 @@ struct file_remap *lookup_ghost_remap(u32 dev, u32 ino)
return NULL;
}
static int dump_ghost_remap(char *path, const struct stat *st,
int lfd, u32 id, struct ns_id *nsid)
static int dump_ghost_remap(char *path, const struct stat *st, int lfd, u32 id, struct ns_id *nsid)
{
struct ghost_file *gf;
RemapFilePathEntry rpe = REMAP_FILE_PATH_ENTRY__INIT;
@@ -903,8 +896,7 @@ static int dump_ghost_remap(char *path, const struct stat *st,
pr_info("Dumping ghost file for fd %d id %#x\n", lfd, id);
if (st->st_size > opts.ghost_limit) {
pr_err("Can't dump ghost file %s of %"PRIu64" size, increase limit\n",
path, st->st_size);
pr_err("Can't dump ghost file %s of %" PRIu64 " size, increase limit\n", path, st->st_size);
return -1;
}
@@ -934,8 +926,7 @@ dump_entry:
rpe.has_remap_type = true;
rpe.remap_type = REMAP_TYPE__GHOST;
return pb_write_one(img_from_set(glob_imgset, CR_FD_REMAP_FPATH),
&rpe, PB_REMAP_FPATH);
return pb_write_one(img_from_set(glob_imgset, CR_FD_REMAP_FPATH), &rpe, PB_REMAP_FPATH);
}
static void __rollback_link_remaps(bool do_unlink)
@@ -958,13 +949,17 @@ static void __rollback_link_remaps(bool do_unlink)
}
}
void delete_link_remaps(void) { __rollback_link_remaps(true); }
void free_link_remaps(void) { __rollback_link_remaps(false); }
void delete_link_remaps(void)
{
__rollback_link_remaps(true);
}
void free_link_remaps(void)
{
__rollback_link_remaps(false);
}
static int linkat_hard(int odir, char *opath, int ndir, char *npath, uid_t uid, gid_t gid, int flags);
static int create_link_remap(char *path, int len, int lfd,
u32 *idp, struct ns_id *nsid,
const struct stat *st)
static int create_link_remap(char *path, int len, int lfd, u32 *idp, struct ns_id *nsid, const struct stat *st)
{
char link_name[PATH_MAX], *tmp;
FileEntry fe = FILE_ENTRY__INIT;
@@ -975,7 +970,8 @@ static int create_link_remap(char *path, int len, int lfd,
if (!opts.link_remap_ok) {
pr_err("Can't create link remap for %s. "
"Use " LREMAP_PARAM " option.\n", path);
"Use " LREMAP_PARAM " option.\n",
path);
return -1;
}
@@ -997,11 +993,11 @@ static int create_link_remap(char *path, int len, int lfd,
}
fd_id_generate_special(NULL, idp);
rfe.id = *idp;
rfe.flags = 0;
rfe.pos = 0;
rfe.fown = &fwn;
rfe.name = link_name + 1;
rfe.id = *idp;
rfe.flags = 0;
rfe.pos = 0;
rfe.fown = &fwn;
rfe.name = link_name + 1;
/* Any 'unique' name works here actually. Remap works by reg-file ids. */
snprintf(tmp + 1, sizeof(link_name) - (size_t)(tmp - link_name - 1), "link_remap.%d", rfe.id);
@@ -1009,8 +1005,7 @@ static int create_link_remap(char *path, int len, int lfd,
mntns_root = mntns_get_root_fd(nsid);
again:
ret = linkat_hard(lfd, "", mntns_root, link_name,
st->st_uid, st->st_gid, AT_EMPTY_PATH);
ret = linkat_hard(lfd, "", mntns_root, link_name, st->st_uid, st->st_gid, AT_EMPTY_PATH);
if (ret < 0 && errno == ENOENT) {
/* Use grand parent, if parent directory does not exist. */
if (trim_last_parent(link_name) < 0) {
@@ -1033,8 +1028,7 @@ again:
return pb_write_one(img_from_set(glob_imgset, CR_FD_FILES), &fe, PB_FILE);
}
static int dump_linked_remap(char *path, int len, const struct stat *ost,
int lfd, u32 id, struct ns_id *nsid)
static int dump_linked_remap(char *path, int len, const struct stat *ost, int lfd, u32 id, struct ns_id *nsid)
{
u32 lid;
RemapFilePathEntry rpe = REMAP_FILE_PATH_ENTRY__INIT;
@@ -1047,8 +1041,7 @@ static int dump_linked_remap(char *path, int len, const struct stat *ost,
rpe.has_remap_type = true;
rpe.remap_type = REMAP_TYPE__LINKED;
return pb_write_one(img_from_set(glob_imgset, CR_FD_REMAP_FPATH),
&rpe, PB_REMAP_FPATH);
return pb_write_one(img_from_set(glob_imgset, CR_FD_REMAP_FPATH), &rpe, PB_REMAP_FPATH);
}
static pid_t *dead_pids;
@@ -1071,7 +1064,7 @@ int dead_pid_conflict(void)
continue;
pr_err("Conflict with a dead task with the same PID as of this thread (virt %d, real %d).\n",
node->ns[0].virt, node->real);
node->ns[0].virt, node->real);
return -1;
}
@@ -1112,8 +1105,7 @@ static int dump_dead_process_remap(pid_t pid, u32 id)
rpe.has_remap_type = true;
rpe.remap_type = REMAP_TYPE__PROCFS;
return pb_write_one(img_from_set(glob_imgset, CR_FD_REMAP_FPATH),
&rpe, PB_REMAP_FPATH);
return pb_write_one(img_from_set(glob_imgset, CR_FD_REMAP_FPATH), &rpe, PB_REMAP_FPATH);
}
static bool is_sillyrename_name(char *name)
@@ -1150,8 +1142,7 @@ static inline bool nfs_silly_rename(char *rpath, const struct fd_parms *parms)
return (parms->fs_type == NFS_SUPER_MAGIC) && is_sillyrename_name(rpath);
}
static int check_path_remap(struct fd_link *link, const struct fd_parms *parms,
int lfd, u32 id, struct ns_id *nsid)
static int check_path_remap(struct fd_link *link, const struct fd_parms *parms, int lfd, u32 id, struct ns_id *nsid)
{
char *rpath = link->name;
int plen = link->len;
@@ -1269,8 +1260,7 @@ static int check_path_remap(struct fd_link *link, const struct fd_parms *parms,
if (errno == ENOENT) {
link_strip_deleted(link);
return dump_linked_remap(rpath + 1, plen - 1,
ost, lfd, id, nsid);
return dump_linked_remap(rpath + 1, plen - 1, ost, lfd, id, nsid);
}
pr_perror("Can't stat path");
@@ -1278,8 +1268,7 @@ static int check_path_remap(struct fd_link *link, const struct fd_parms *parms,
}
if ((pst.st_ino != ost->st_ino) || (pst.st_dev != ost->st_dev)) {
if (opts.evasive_devices &&
(S_ISCHR(ost->st_mode) || S_ISBLK(ost->st_mode)) &&
if (opts.evasive_devices && (S_ISCHR(ost->st_mode) || S_ISBLK(ost->st_mode)) &&
pst.st_rdev == ost->st_rdev)
return 0;
/*
@@ -1292,9 +1281,8 @@ static int check_path_remap(struct fd_link *link, const struct fd_parms *parms,
* have the "(deleted)" suffix in proc and name conflict
* is unlikely :)
*/
pr_err("Unaccessible path opened %u:%u, need %u:%u\n",
(int)pst.st_dev, (int)pst.st_ino,
(int)ost->st_dev, (int)ost->st_ino);
pr_err("Unaccessible path opened %u:%u, need %u:%u\n", (int)pst.st_dev, (int)pst.st_ino,
(int)ost->st_dev, (int)ost->st_ino);
return -1;
}
@@ -1308,8 +1296,7 @@ static int check_path_remap(struct fd_link *link, const struct fd_parms *parms,
static bool should_check_size(int flags)
{
/* Skip size if file has O_APPEND and O_WRONLY flags (e.g. log file). */
if (((flags & O_ACCMODE) == O_WRONLY) &&
(flags & O_APPEND))
if (((flags & O_ACCMODE) == O_WRONLY) && (flags & O_APPEND))
return false;
return true;
@@ -1320,15 +1307,14 @@ static bool should_check_size(int flags)
* Returns the number of bytes of the build-id if it could
* be obtained, else -1.
*/
static int get_build_id_32(Elf32_Ehdr *file_header, unsigned char **build_id,
const int fd, size_t mapped_size)
static int get_build_id_32(Elf32_Ehdr *file_header, unsigned char **build_id, const int fd, size_t mapped_size)
{
int size, num_iterations;
size_t file_header_end;
Elf32_Phdr *program_header, *program_header_end;
Elf32_Nhdr *note_header_end, *note_header = NULL;
file_header_end = (size_t) file_header + mapped_size;
file_header_end = (size_t)file_header + mapped_size;
if (sizeof(Elf32_Ehdr) > mapped_size)
return -1;
@@ -1341,11 +1327,11 @@ static int get_build_id_32(Elf32_Ehdr *file_header, unsigned char **build_id,
return -1;
}
program_header = (Elf32_Phdr *) (file_header->e_phoff + (char *) file_header);
if (program_header <= (Elf32_Phdr *) file_header)
program_header = (Elf32_Phdr *)(file_header->e_phoff + (char *)file_header);
if (program_header <= (Elf32_Phdr *)file_header)
return -1;
program_header_end = (Elf32_Phdr *) (file_header_end - sizeof(Elf32_Phdr));
program_header_end = (Elf32_Phdr *)(file_header_end - sizeof(Elf32_Phdr));
/*
* If the file has a build-id, it will be in the PT_NOTE program header
@@ -1357,21 +1343,19 @@ static int get_build_id_32(Elf32_Ehdr *file_header, unsigned char **build_id,
if (program_header->p_type != PT_NOTE)
continue;
note_header = (Elf32_Nhdr *) (program_header->p_offset + (char *) file_header);
if (note_header <= (Elf32_Nhdr *) file_header) {
note_header = (Elf32_Nhdr *)(program_header->p_offset + (char *)file_header);
if (note_header <= (Elf32_Nhdr *)file_header) {
note_header = NULL;
continue;
}
note_header_end = (Elf32_Nhdr *) min_t(char*,
(char *) note_header + program_header->p_filesz,
(char *) (file_header_end - sizeof(Elf32_Nhdr)));
note_header_end = (Elf32_Nhdr *)min_t(char *, (char *)note_header + program_header->p_filesz,
(char *)(file_header_end - sizeof(Elf32_Nhdr)));
/* The note type for the build-id is NT_GNU_BUILD_ID. */
while (note_header <= note_header_end && note_header->n_type != NT_GNU_BUILD_ID)
note_header = (Elf32_Nhdr *) ((char *) note_header + sizeof(Elf32_Nhdr) +
ALIGN(note_header->n_namesz, 4) +
ALIGN(note_header->n_descsz, 4));
note_header = (Elf32_Nhdr *)((char *)note_header + sizeof(Elf32_Nhdr) +
ALIGN(note_header->n_namesz, 4) + ALIGN(note_header->n_descsz, 4));
if (note_header > note_header_end) {
note_header = NULL;
@@ -1395,17 +1379,16 @@ static int get_build_id_32(Elf32_Ehdr *file_header, unsigned char **build_id,
}
size = note_header->n_descsz;
note_header = (Elf32_Nhdr *) ((char *) note_header + sizeof(Elf32_Nhdr) +
ALIGN(note_header->n_namesz, 4));
note_header_end = (Elf32_Nhdr *) (file_header_end - size);
if (note_header <= (Elf32_Nhdr *) file_header || note_header > note_header_end)
note_header = (Elf32_Nhdr *)((char *)note_header + sizeof(Elf32_Nhdr) + ALIGN(note_header->n_namesz, 4));
note_header_end = (Elf32_Nhdr *)(file_header_end - size);
if (note_header <= (Elf32_Nhdr *)file_header || note_header > note_header_end)
return -1;
*build_id = (unsigned char *) xmalloc(size);
*build_id = (unsigned char *)xmalloc(size);
if (!*build_id)
return -1;
memcpy(*build_id, (void *) note_header, size);
memcpy(*build_id, (void *)note_header, size);
return size;
}
@@ -1414,15 +1397,14 @@ static int get_build_id_32(Elf32_Ehdr *file_header, unsigned char **build_id,
* Returns the number of bytes of the build-id if it could
* be obtained, else -1.
*/
static int get_build_id_64(Elf64_Ehdr *file_header, unsigned char **build_id,
const int fd, size_t mapped_size)
static int get_build_id_64(Elf64_Ehdr *file_header, unsigned char **build_id, const int fd, size_t mapped_size)
{
int size, num_iterations;
size_t file_header_end;
Elf64_Phdr *program_header, *program_header_end;
Elf64_Nhdr *note_header_end, *note_header = NULL;
file_header_end = (size_t) file_header + mapped_size;
file_header_end = (size_t)file_header + mapped_size;
if (sizeof(Elf64_Ehdr) > mapped_size)
return -1;
@@ -1435,11 +1417,11 @@ static int get_build_id_64(Elf64_Ehdr *file_header, unsigned char **build_id,
return -1;
}
program_header = (Elf64_Phdr *) (file_header->e_phoff + (char *) file_header);
if (program_header <= (Elf64_Phdr *) file_header)
program_header = (Elf64_Phdr *)(file_header->e_phoff + (char *)file_header);
if (program_header <= (Elf64_Phdr *)file_header)
return -1;
program_header_end = (Elf64_Phdr *) (file_header_end - sizeof(Elf64_Phdr));
program_header_end = (Elf64_Phdr *)(file_header_end - sizeof(Elf64_Phdr));
/*
* If the file has a build-id, it will be in the PT_NOTE program header
@@ -1451,21 +1433,19 @@ static int get_build_id_64(Elf64_Ehdr *file_header, unsigned char **build_id,
if (program_header->p_type != PT_NOTE)
continue;
note_header = (Elf64_Nhdr *) (program_header->p_offset + (char *) file_header);
if (note_header <= (Elf64_Nhdr *) file_header) {
note_header = (Elf64_Nhdr *)(program_header->p_offset + (char *)file_header);
if (note_header <= (Elf64_Nhdr *)file_header) {
note_header = NULL;
continue;
}
note_header_end = (Elf64_Nhdr *) min_t(char*,
(char *) note_header + program_header->p_filesz,
(char *) (file_header_end - sizeof(Elf64_Nhdr)));
note_header_end = (Elf64_Nhdr *)min_t(char *, (char *)note_header + program_header->p_filesz,
(char *)(file_header_end - sizeof(Elf64_Nhdr)));
/* The note type for the build-id is NT_GNU_BUILD_ID. */
while (note_header <= note_header_end && note_header->n_type != NT_GNU_BUILD_ID)
note_header = (Elf64_Nhdr *) ((char *) note_header + sizeof(Elf64_Nhdr) +
ALIGN(note_header->n_namesz, 4) +
ALIGN(note_header->n_descsz, 4));
note_header = (Elf64_Nhdr *)((char *)note_header + sizeof(Elf64_Nhdr) +
ALIGN(note_header->n_namesz, 4) + ALIGN(note_header->n_descsz, 4));
if (note_header > note_header_end) {
note_header = NULL;
@@ -1489,17 +1469,16 @@ static int get_build_id_64(Elf64_Ehdr *file_header, unsigned char **build_id,
}
size = note_header->n_descsz;
note_header = (Elf64_Nhdr *) ((char *) note_header + sizeof(Elf64_Nhdr) +
ALIGN(note_header->n_namesz, 4));
note_header_end = (Elf64_Nhdr *) (file_header_end - size);
if (note_header <= (Elf64_Nhdr *) file_header || note_header > note_header_end)
note_header = (Elf64_Nhdr *)((char *)note_header + sizeof(Elf64_Nhdr) + ALIGN(note_header->n_namesz, 4));
note_header_end = (Elf64_Nhdr *)(file_header_end - size);
if (note_header <= (Elf64_Nhdr *)file_header || note_header > note_header_end)
return -1;
*build_id = (unsigned char *) xmalloc(size);
*build_id = (unsigned char *)xmalloc(size);
if (!*build_id)
return -1;
memcpy(*build_id, (void *) note_header, size);
memcpy(*build_id, (void *)note_header, size);
return size;
}
@@ -1509,15 +1488,14 @@ static int get_build_id_64(Elf64_Ehdr *file_header, unsigned char **build_id,
* Returns the number of bytes of the build-id if it could be
* obtained, else -1.
*/
static int get_build_id(const int fd, const struct stat *fd_status,
unsigned char **build_id)
static int get_build_id(const int fd, const struct stat *fd_status, unsigned char **build_id)
{
char buf[SELFMAG+1];
char buf[SELFMAG + 1];
void *start_addr;
size_t mapped_size;
int ret = -1;
if (read(fd, buf, SELFMAG+1) != SELFMAG+1)
if (read(fd, buf, SELFMAG + 1) != SELFMAG + 1)
return -1;
/*
@@ -1555,8 +1533,7 @@ static int get_build_id(const int fd, const struct stat *fd_status,
* Returns 1 if the build-id of the file could be stored, -1 if there was an error
* or 0 if the build-id could not be obtained.
*/
static int store_validation_data_build_id(RegFileEntry *rfe, int lfd,
const struct fd_parms *p)
static int store_validation_data_build_id(RegFileEntry *rfe, int lfd, const struct fd_parms *p)
{
unsigned char *build_id = NULL;
int build_id_size, allocated_size;
@@ -1567,13 +1544,13 @@ static int store_validation_data_build_id(RegFileEntry *rfe, int lfd,
* four (SELFMAG) bytes which should correspond to the ELF magic number
* and the next byte which indicates whether the file is 32-bit or 64-bit.
*/
if (p->stat.st_size < SELFMAG+1)
if (p->stat.st_size < SELFMAG + 1)
return 0;
fd = open_proc(PROC_SELF, "fd/%d", lfd);
if (fd < 0) {
pr_err("Build-ID (For validation) could not be obtained for file %s because can't open the file\n",
rfe->name);
rfe->name);
return -1;
}
@@ -1585,14 +1562,13 @@ static int store_validation_data_build_id(RegFileEntry *rfe, int lfd,
allocated_size = round_up(build_id_size, sizeof(uint32_t));
rfe->build_id = xzalloc(allocated_size);
if (!rfe->build_id) {
pr_warn("Build-ID (For validation) could not be set for file %s\n",
rfe->name);
pr_warn("Build-ID (For validation) could not be set for file %s\n", rfe->name);
xfree(build_id);
return -1;
}
rfe->n_build_id = allocated_size / sizeof(uint32_t);
memcpy(rfe->build_id, (void *) build_id, build_id_size);
memcpy(rfe->build_id, (void *)build_id, build_id_size);
xfree(build_id);
return 1;
@@ -1604,8 +1580,7 @@ static int store_validation_data_build_id(RegFileEntry *rfe, int lfd,
* being restored.
* Returns true if atleast some metadata was stored, if there was an error it returns false.
*/
static bool store_validation_data(RegFileEntry *rfe,
const struct fd_parms *p, int lfd)
static bool store_validation_data(RegFileEntry *rfe, const struct fd_parms *p, int lfd)
{
int result = 1;
@@ -1619,8 +1594,7 @@ static bool store_validation_data(RegFileEntry *rfe,
return false;
if (!result)
pr_info("Only file size could be stored for validation for file %s\n",
rfe->name);
pr_info("Only file size could be stored for validation for file %s\n", rfe->name);
return true;
}
@@ -1641,9 +1615,7 @@ int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p)
} else
link = p->link;
snprintf(ext_id, sizeof(ext_id), "file[%x:%"PRIx64"]", p->mnt_id, p->stat.st_ino);
snprintf(ext_id, sizeof(ext_id), "file[%x:%" PRIx64 "]", p->mnt_id, p->stat.st_ino);
if (external_lookup_id(ext_id)) {
/* the first symbol will be cut on restore to get an relative path*/
rfe.name = xstrdup(ext_id);
@@ -1654,8 +1626,7 @@ int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p)
mi = lookup_mnt_id(p->mnt_id);
if (mi == NULL) {
pr_err("Can't lookup mount=%d for fd=%d path=%s\n",
p->mnt_id, p->fd, link->name + 1);
pr_err("Can't lookup mount=%d for fd=%d path=%s\n", p->mnt_id, p->fd, link->name + 1);
return -1;
}
@@ -1669,8 +1640,7 @@ int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p)
rfe.has_mnt_id = true;
}
pr_info("Dumping path for %d fd via self %d [%s]\n",
p->fd, lfd, &link->name[1]);
pr_info("Dumping path for %d fd via self %d [%s]\n", p->fd, lfd, &link->name[1]);
/*
* The regular path we can handle should start with slash.
@@ -1682,17 +1652,16 @@ int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p)
if (check_path_remap(link, p, lfd, id, mi->nsid))
return -1;
rfe.name = &link->name[1];
rfe.name = &link->name[1];
ext:
rfe.id = id;
rfe.flags = p->flags;
rfe.pos = p->pos;
rfe.fown = (FownEntry *)&p->fown;
rfe.has_mode = true;
rfe.mode = p->stat.st_mode;
rfe.id = id;
rfe.flags = p->flags;
rfe.pos = p->pos;
rfe.fown = (FownEntry *)&p->fown;
rfe.has_mode = true;
rfe.mode = p->stat.st_mode;
if (S_ISREG(p->stat.st_mode) && should_check_size(rfe.flags) &&
!store_validation_data(&rfe, p, lfd))
if (S_ISREG(p->stat.st_mode) && should_check_size(rfe.flags) && !store_validation_data(&rfe, p, lfd))
return -1;
fe.type = FD_TYPES__REG;
@@ -1709,13 +1678,11 @@ ext:
}
const struct fdtype_ops regfile_dump_ops = {
.type = FD_TYPES__REG,
.dump = dump_one_reg_file,
.type = FD_TYPES__REG,
.dump = dump_one_reg_file,
};
static void convert_path_from_another_mp(char *src, char *dst, int dlen,
struct mount_info *smi,
struct mount_info *dmi)
static void convert_path_from_another_mp(char *src, char *dst, int dlen, struct mount_info *smi, struct mount_info *dmi)
{
int off;
@@ -1732,10 +1699,7 @@ static void convert_path_from_another_mp(char *src, char *dst, int dlen,
* Absolute path to the mount point + difference between source
* and destination roots + path relative to the mountpoint.
*/
snprintf(dst, dlen, "./%s/%s/%s",
dmi->ns_mountpoint + 1,
smi->root + strlen(dmi->root),
src + off);
snprintf(dst, dlen, "./%s/%s/%s", dmi->ns_mountpoint + 1, smi->root + strlen(dmi->root), src + off);
}
static int linkat_hard(int odir, char *opath, int ndir, char *npath, uid_t uid, gid_t gid, int flags)
@@ -1749,7 +1713,7 @@ static int linkat_hard(int odir, char *opath, int ndir, char *npath, uid_t uid,
if (ret == 0)
return 0;
if (!( (errno == EPERM || errno == EOVERFLOW) && (root_ns_mask & CLONE_NEWUSER) )) {
if (!((errno == EPERM || errno == EOVERFLOW) && (root_ns_mask & CLONE_NEWUSER))) {
errno_save = errno;
pr_warn("Can't link %s -> %s\n", opath, npath);
errno = errno_save;
@@ -1964,8 +1928,7 @@ out_root:
if (*level < 0)
return -1;
if (linkat_hard(mntns_root, rpath, mntns_root, path,
rfi->remap->uid, rfi->remap->gid, 0) < 0) {
if (linkat_hard(mntns_root, rpath, mntns_root, path, rfi->remap->uid, rfi->remap->gid, 0) < 0) {
int errno_saved = errno;
rm_parent_dirs(mntns_root, path, *level);
errno = errno_saved;
@@ -1981,8 +1944,7 @@ out_root:
* while dumping, -1 if there is a mismatch or 0 if the build-id has not been
* stored or could not be obtained.
*/
static int validate_with_build_id(const int fd, const struct stat *fd_status,
const struct reg_file_info *rfi)
static int validate_with_build_id(const int fd, const struct stat *fd_status, const struct reg_file_info *rfi)
{
unsigned char *build_id;
int build_id_size;
@@ -2000,8 +1962,7 @@ static int validate_with_build_id(const int fd, const struct stat *fd_status,
if (round_up(build_id_size, sizeof(uint32_t)) != rfi->rfe->n_build_id * sizeof(uint32_t)) {
pr_err("File %s has bad build-ID length %d (expect %d)\n", rfi->path,
round_up(build_id_size, sizeof(uint32_t)),
(int) (rfi->rfe->n_build_id * sizeof(uint32_t)));
round_up(build_id_size, sizeof(uint32_t)), (int)(rfi->rfe->n_build_id * sizeof(uint32_t)));
xfree(build_id);
return -1;
}
@@ -2024,14 +1985,13 @@ static int validate_with_build_id(const int fd, const struct stat *fd_status,
* Returns true if the metadata of the file matches the metadata stored while
* dumping else returns false.
*/
static bool validate_file(const int fd, const struct stat *fd_status,
const struct reg_file_info *rfi)
static bool validate_file(const int fd, const struct stat *fd_status, const struct reg_file_info *rfi)
{
int result = 1;
if (rfi->rfe->has_size && (fd_status->st_size != rfi->rfe->size)) {
pr_err("File %s has bad size %"PRIu64" (expect %"PRIu64")\n",
rfi->path, fd_status->st_size, rfi->rfe->size);
pr_err("File %s has bad size %" PRIu64 " (expect %" PRIu64 ")\n", rfi->path, fd_status->st_size,
rfi->rfe->size);
return false;
}
@@ -2042,13 +2002,11 @@ static bool validate_file(const int fd, const struct stat *fd_status,
return false;
if (!result)
pr_info("File %s could only be validated with file size\n",
rfi->path);
pr_info("File %s could only be validated with file size\n", rfi->path);
return true;
}
int open_path(struct file_desc *d,
int(*open_cb)(int mntns_root, struct reg_file_info *, void *), void *arg)
int open_path(struct file_desc *d, int (*open_cb)(int mntns_root, struct reg_file_info *, void *), void *arg)
{
int tmp, mntns_root, level = 0;
struct reg_file_info *rfi;
@@ -2095,8 +2053,7 @@ int open_path(struct file_desc *d,
static char tmp_path[PATH_MAX];
if (errno != EEXIST) {
pr_perror("Can't link %s -> %s",
rfi->remap->rpath, rfi->path);
pr_perror("Can't link %s -> %s", rfi->remap->rpath, rfi->path);
return -1;
}
@@ -2132,8 +2089,7 @@ ext:
}
close_safe(&inh_fd);
if ((rfi->rfe->has_size || rfi->rfe->has_mode) &&
!rfi->size_mode_checked) {
if ((rfi->rfe->has_size || rfi->rfe->has_mode) && !rfi->size_mode_checked) {
struct stat st;
if (fstat(tmp, &st) < 0) {
@@ -2145,9 +2101,7 @@ ext:
return -1;
if (rfi->rfe->has_mode && (st.st_mode != rfi->rfe->mode)) {
pr_err("File %s has bad mode 0%o (expect 0%o)\n",
rfi->path, (int)st.st_mode,
rfi->rfe->mode);
pr_err("File %s has bad mode 0%o (expect 0%o)\n", rfi->path, (int)st.st_mode, rfi->rfe->mode);
return -1;
}
@@ -2211,8 +2165,7 @@ static int do_open_reg(int ns_root_fd, struct reg_file_info *rfi, void *arg)
* just ignore positioning at all.
*/
if (!(rfi->rfe->flags & O_PATH)) {
if (rfi->rfe->pos != -1ULL &&
lseek(fd, rfi->rfe->pos, SEEK_SET) < 0) {
if (rfi->rfe->pos != -1ULL && lseek(fd, rfi->rfe->pos, SEEK_SET) < 0) {
pr_perror("Can't restore file pos");
close(fd);
return -1;
@@ -2282,10 +2235,10 @@ static struct filemap_ctx ctx;
void filemap_ctx_init(bool auto_close)
{
ctx.desc = NULL; /* to fail the first comparison in open_ */
ctx.fd = -1; /* not to close random fd in _fini */
ctx.vma = NULL; /* not to put spurious VMA_CLOSE in _fini */
/* flags may remain any */
ctx.desc = NULL; /* to fail the first comparison in open_ */
ctx.fd = -1; /* not to close random fd in _fini */
ctx.vma = NULL; /* not to put spurious VMA_CLOSE in _fini */
/* flags may remain any */
ctx.close = auto_close;
}
@@ -2341,8 +2294,7 @@ int collect_filemap(struct vma_area *vma)
if (!vma->e->has_fdflags) {
/* Make a wild guess for the fdflags */
vma->e->has_fdflags = true;
if ((vma->e->prot & PROT_WRITE) &&
vma_area_is(vma, VMA_FILE_SHARED))
if ((vma->e->prot & PROT_WRITE) && vma_area_is(vma, VMA_FILE_SHARED))
vma->e->fdflags = O_RDWR;
else
vma->e->fdflags = O_RDONLY;

View File

@@ -57,7 +57,7 @@
#include "plugin.h"
#define FDESC_HASH_SIZE 64
#define FDESC_HASH_SIZE 64
static struct hlist_head file_desc_hash[FDESC_HASH_SIZE];
/* file_desc's, which fle is not owned by a process, that is able to open them */
static LIST_HEAD(fake_master_head);
@@ -78,8 +78,8 @@ void file_desc_init(struct file_desc *d, u32 id, struct file_desc_ops *ops)
INIT_LIST_HEAD(&d->fake_master_list);
INIT_HLIST_NODE(&d->hash);
d->id = id;
d->ops = ops;
d->id = id;
d->ops = ops;
}
int file_desc_add(struct file_desc *d, u32 id, struct file_desc_ops *ops)
@@ -100,8 +100,7 @@ struct file_desc *find_file_desc_raw(int type, u32 id)
chain = &file_desc_hash[id % FDESC_HASH_SIZE];
hlist_for_each_entry(d, chain, hash)
if ((d->id == id) &&
(d->ops->type == type || type == FD_TYPES__UND))
if ((d->id == id) && (d->ops->type == type || type == FD_TYPES__UND))
/*
* Warning -- old CRIU might generate matching IDs
* for different file types! So any code that uses
@@ -219,8 +218,7 @@ struct fdinfo_list_entry *try_file_master(struct file_desc *d)
if (list_empty(&d->fd_info_head))
return NULL;
return list_first_entry(&d->fd_info_head,
struct fdinfo_list_entry, desc_list);
return list_first_entry(&d->fd_info_head, struct fdinfo_list_entry, desc_list);
}
struct fdinfo_list_entry *file_master(struct file_desc *d)
@@ -229,8 +227,7 @@ struct fdinfo_list_entry *file_master(struct file_desc *d)
fle = try_file_master(d);
if (!fle) {
pr_err("Empty list on file desc id %#x(%d)\n", d->id,
d->ops ? d->ops->type : -1);
pr_err("Empty list on file desc id %#x(%d)\n", d->id, d->ops ? d->ops->type : -1);
BUG();
}
@@ -319,16 +316,13 @@ uint32_t make_gen_id(uint32_t st_dev, uint32_t st_ino, uint64_t pos)
return st_dev ^ st_ino ^ pos_hi ^ pos_low;
}
int do_dump_gen_file(struct fd_parms *p, int lfd,
const struct fdtype_ops *ops, FdinfoEntry *e)
int do_dump_gen_file(struct fd_parms *p, int lfd, const struct fdtype_ops *ops, FdinfoEntry *e)
{
int ret = -1;
e->type = ops->type;
e->id = make_gen_id((uint32_t)p->stat.st_dev,
(uint32_t)p->stat.st_ino,
(uint64_t)p->pos);
e->fd = p->fd;
e->type = ops->type;
e->id = make_gen_id((uint32_t)p->stat.st_dev, (uint32_t)p->stat.st_ino, (uint64_t)p->pos);
e->fd = p->fd;
e->flags = p->fd_flags;
ret = fd_id_generate(p->pid, e, p);
@@ -361,8 +355,7 @@ int fill_fdlink(int lfd, const struct fd_parms *p, struct fd_link *link)
return 0;
}
static int fill_fd_params(struct pid *owner_pid, int fd, int lfd,
struct fd_opts *opts, struct fd_parms *p)
static int fill_fd_params(struct pid *owner_pid, int fd, int lfd, struct fd_opts *opts, struct fd_parms *p)
{
int ret;
struct statfs fsbuf;
@@ -381,24 +374,24 @@ static int fill_fd_params(struct pid *owner_pid, int fd, int lfd,
if (parse_fdinfo_pid(owner_pid->real, fd, FD_TYPES__UND, &fdinfo))
return -1;
p->fs_type = fsbuf.f_type;
p->fd = fd;
p->pos = fdinfo.pos;
p->fs_type = fsbuf.f_type;
p->fd = fd;
p->pos = fdinfo.pos;
/*
* The kernel artificially adds the O_CLOEXEC flag on the file pointer
* flags by looking at the flags on the file descriptor (see kernel
* code fs/proc/fd.c). FD_CLOEXEC is a file descriptor property, which
* is saved in fd_flags.
*/
p->flags = fdinfo.flags & ~O_CLOEXEC;
p->mnt_id = fdinfo.mnt_id;
p->pid = owner_pid->real;
p->fd_flags = opts->flags;
p->flags = fdinfo.flags & ~O_CLOEXEC;
p->mnt_id = fdinfo.mnt_id;
p->pid = owner_pid->real;
p->fd_flags = opts->flags;
fown_entry__init(&p->fown);
pr_info("%d fdinfo %d: pos: %#16"PRIx64" flags: %16o/%#x\n",
owner_pid->real, fd, p->pos, p->flags, (int)p->fd_flags);
pr_info("%d fdinfo %d: pos: %#16" PRIx64 " flags: %16o/%#x\n", owner_pid->real, fd, p->pos, p->flags,
(int)p->fd_flags);
if (p->flags & O_PATH)
ret = 0;
@@ -413,10 +406,10 @@ static int fill_fd_params(struct pid *owner_pid, int fd, int lfd,
if (opts->fown.pid == 0)
return 0;
p->fown.pid = opts->fown.pid;
p->fown.pid = opts->fown.pid;
p->fown.pid_type = opts->fown.pid_type;
p->fown.uid = opts->fown.uid;
p->fown.euid = opts->fown.euid;
p->fown.uid = opts->fown.uid;
p->fown.euid = opts->fown.euid;
return 0;
}
@@ -489,9 +482,8 @@ static int dump_chrdev(struct fd_parms *p, int lfd, FdinfoEntry *e)
return err;
}
static int dump_one_file(struct pid *pid, int fd, int lfd, struct fd_opts *opts,
struct parasite_ctl *ctl, FdinfoEntry *e,
struct parasite_drain_fd *dfds)
static int dump_one_file(struct pid *pid, int fd, int lfd, struct fd_opts *opts, struct parasite_ctl *ctl,
FdinfoEntry *e, struct parasite_drain_fd *dfds)
{
struct fd_parms p = FD_PARMS_INIT;
const struct fdtype_ops *ops;
@@ -550,8 +542,7 @@ static int dump_one_file(struct pid *pid, int fd, int lfd, struct fd_opts *opts,
return do_dump_gen_file(&p, lfd, ops, e);
}
if (S_ISREG(p.stat.st_mode) || S_ISDIR(p.stat.st_mode) ||
S_ISLNK(p.stat.st_mode)) {
if (S_ISREG(p.stat.st_mode) || S_ISDIR(p.stat.st_mode) || S_ISLNK(p.stat.st_mode)) {
if (fill_fdlink(lfd, &p, &link))
return -1;
@@ -606,14 +597,13 @@ int dump_my_file(int lfd, u32 *id, int *type)
return 0;
}
int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item,
struct parasite_drain_fd *dfds)
int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item, struct parasite_drain_fd *dfds)
{
int *lfds = NULL;
struct cr_img *img = NULL;
struct fd_opts *opts = NULL;
int i, ret = -1;
int off, nr_fds = min((int) PARASITE_MAX_FDS, dfds->nr_fds);
int off, nr_fds = min((int)PARASITE_MAX_FDS, dfds->nr_fds);
pr_info("\n");
pr_info("Dumping opened files (pid: %d)\n", item->pid->real);
@@ -636,16 +626,14 @@ int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item,
if (nr_fds + off > dfds->nr_fds)
nr_fds = dfds->nr_fds - off;
ret = parasite_drain_fds_seized(ctl, dfds, nr_fds,
off, lfds, opts);
ret = parasite_drain_fds_seized(ctl, dfds, nr_fds, off, lfds, opts);
if (ret)
goto err;
for (i = 0; i < nr_fds; i++) {
FdinfoEntry e = FDINFO_ENTRY__INIT;
ret = dump_one_file(item->pid, dfds->fds[i + off],
lfds[i], opts + i, ctl, &e, dfds);
ret = dump_one_file(item->pid, dfds->fds[i + off], lfds[i], opts + i, ctl, &e, dfds);
if (ret)
break;
@@ -810,8 +798,7 @@ static void __collect_desc_fle(struct fdinfo_list_entry *new_le, struct file_des
list_add(&new_le->desc_list, &le->desc_list);
}
static void collect_desc_fle(struct fdinfo_list_entry *new_le,
struct file_desc *fdesc, bool force_master)
static void collect_desc_fle(struct fdinfo_list_entry *new_le, struct file_desc *fdesc, bool force_master)
{
new_le->desc = fdesc;
@@ -823,9 +810,8 @@ static void collect_desc_fle(struct fdinfo_list_entry *new_le,
}
}
struct fdinfo_list_entry *collect_fd_to(int pid, FdinfoEntry *e,
struct rst_info *rst_info, struct file_desc *fdesc,
bool fake, bool force_master)
struct fdinfo_list_entry *collect_fd_to(int pid, FdinfoEntry *e, struct rst_info *rst_info, struct file_desc *fdesc,
bool fake, bool force_master)
{
struct fdinfo_list_entry *new_le;
@@ -843,8 +829,7 @@ int collect_fd(int pid, FdinfoEntry *e, struct rst_info *rst_info, bool fake)
{
struct file_desc *fdesc;
pr_info("Collect fdinfo pid=%d fd=%d id=%#x\n",
pid, e->fd, e->id);
pr_info("Collect fdinfo pid=%d fd=%d id=%#x\n", pid, e->fd, e->id);
fdesc = find_file_desc(e);
if (fdesc == NULL) {
@@ -868,15 +853,14 @@ FdinfoEntry *dup_fdinfo(FdinfoEntry *old, int fd, unsigned flags)
fdinfo_entry__init(e);
e->id = old->id;
e->type = old->type;
e->fd = fd;
e->flags = flags;
e->id = old->id;
e->type = old->type;
e->fd = fd;
e->flags = flags;
return e;
}
int dup_fle(struct pstree_item *task, struct fdinfo_list_entry *ple,
int fd, unsigned flags)
int dup_fle(struct pstree_item *task, struct fdinfo_list_entry *ple, int fd, unsigned flags)
{
FdinfoEntry *e;
@@ -952,7 +936,8 @@ int set_fd_flags(int fd, int flags)
if (ret != flags) {
pr_err("fcntl call on fd %d (flags %#o) succeeded, "
"but some flags were dropped: %#o\n", fd, flags, ret);
"but some flags were dropped: %#o\n",
fd, flags, ret);
return -1;
}
return 0;
@@ -1134,7 +1119,7 @@ static int open_fd(struct fdinfo_list_entry *fle)
flem = file_master(d);
if (fle != flem) {
BUG_ON (fle->stage != FLE_INITIALIZED);
BUG_ON(fle->stage != FLE_INITIALIZED);
ret = receive_fd(fle);
if (ret != 0)
return ret;
@@ -1212,8 +1197,7 @@ static int open_fdinfos(struct pstree_item *me)
BUG_ON(st == FLE_RESTORED);
ret = open_fd(fle);
if (ret == -1) {
pr_err("Unable to open fd=%d id=%#x\n",
fle->fe->fd, fle->fe->id);
pr_err("Unable to open fd=%d id=%#x\n", fle->fe->fd, fle->fe->id);
goto splice;
}
if (st != fle->stage || ret == 0)
@@ -1231,7 +1215,7 @@ static int open_fdinfos(struct pstree_item *me)
list_add(&fle->ps_list, &fake);
}
if (ret == 1)
again = true;
again = true;
}
if (!progress && again)
wait_fds_event();
@@ -1501,8 +1485,8 @@ int shared_fdt_prepare(struct pstree_item *item)
struct inherit_fd {
struct list_head inh_list;
char *inh_id; /* file identifier */
int inh_fd; /* criu's descriptor to inherit */
char *inh_id; /* file identifier */
int inh_fd; /* criu's descriptor to inherit */
int inh_fd_id;
};
@@ -1541,8 +1525,7 @@ int inherit_fd_parse(char *optarg)
if (dbg) {
n = strlen(cp);
if (write(fd, cp, n) != n) {
pr_err("Can't write debug message %s to inherit fd %d\n",
cp, fd);
pr_err("Can't write debug message %s to inherit fd %d\n", cp, fd);
return -1;
}
return 0;
@@ -1586,8 +1569,7 @@ void inherit_fd_log(void)
struct inherit_fd *inh;
list_for_each_entry(inh, &opts.inherit_fds, inh_list) {
pr_info("File %s will be restored from inherit fd %d\n",
inh->inh_id, inh->inh_fd);
pr_info("File %s will be restored from inherit fd %d\n", inh->inh_id, inh->inh_fd);
}
}
@@ -1617,8 +1599,7 @@ int inherit_fd_lookup_id(char *id)
list_for_each_entry(inh, &opts.inherit_fds, inh_list) {
if (!strcmp(inh->inh_id, id)) {
ret = fdstore_get(inh->inh_fd_id);
pr_debug("Found id %s (fd %d) in inherit fd list\n",
id, ret);
pr_debug("Found id %s (fd %d) in inherit fd list\n", id, ret);
break;
}
}
@@ -1643,7 +1624,8 @@ bool inherited_fd(struct file_desc *d, int *fd_p)
*fd_p = i_fd;
pr_info("File %s will be restored from fd %d dumped "
"from inherit fd %d\n", id_str, *fd_p, i_fd);
"from inherit fd %d\n",
id_str, *fd_p, i_fd);
return true;
}
@@ -1673,8 +1655,7 @@ out:
return ret;
}
static int collect_one_file_entry(FileEntry *fe, u_int32_t id, ProtobufCMessage *base,
struct collect_image_info *cinfo)
static int collect_one_file_entry(FileEntry *fe, u_int32_t id, ProtobufCMessage *base, struct collect_image_info *cinfo)
{
if (fe->id != id) {
pr_err("ID mismatch %u != %u\n", fe->id, id);

View File

@@ -44,7 +44,6 @@ static int binfmt_misc_parse_or_collect(struct mount_info *pm)
{
opts.has_binfmt_misc = true;
return 0;
}
static int binfmt_misc_virtual(struct mount_info *pm)
@@ -78,13 +77,13 @@ static int parse_binfmt_misc_entry(struct bfd *f, BinfmtMiscEntry *bme)
continue;
}
#define DUP_EQUAL_AS(key, member) \
if (!strncmp(str, key, strlen(key))) { \
bme->member = xstrdup(str + strlen(key)); \
if (!bme->member) \
return -1; \
continue; \
}
#define DUP_EQUAL_AS(key, member) \
if (!strncmp(str, key, strlen(key))) { \
bme->member = xstrdup(str + strlen(key)); \
if (!bme->member) \
return -1; \
continue; \
}
DUP_EQUAL_AS("interpreter ", interpreter)
DUP_EQUAL_AS("flags: ", flags)
DUP_EQUAL_AS("extension .", extension)
@@ -130,7 +129,6 @@ err:
free(bme.mask);
bclose(&f);
return ret;
}
static int binfmt_misc_dump(struct mount_info *pm)
@@ -192,7 +190,7 @@ out:
static int write_binfmt_misc_entry(char *mp, char *buf, BinfmtMiscEntry *bme)
{
int fd, len, ret = -1;
char path[PATH_MAX+1];
char path[PATH_MAX + 1];
snprintf(path, PATH_MAX, "%s/register", mp);
@@ -243,9 +241,9 @@ static int make_bfmtm_magic_str(char *buf, BinfmtMiscEntry *bme)
* dump them without changes. But for registering a new entry
* it expects every byte is prepended with \x, i.e. \x61\x62\x63.
*/
len = strlen(bme->name) + 3 /* offset < 128 */ + 2 * strlen(bme->magic)
+ (bme->mask ? 2 * strlen(bme->mask) : 0) + strlen(bme->interpreter)
+ (bme->flags ? strlen(bme->flags) : 0) + strlen(":::::::");
len = strlen(bme->name) + 3 /* offset < 128 */ + 2 * strlen(bme->magic) +
(bme->mask ? 2 * strlen(bme->mask) : 0) + strlen(bme->interpreter) +
(bme->flags ? strlen(bme->flags) : 0) + strlen(":::::::");
if ((len > BINFMT_MISC_STR - 1) || bme->offset > 128)
return -1;
@@ -264,7 +262,7 @@ static int make_bfmtm_magic_str(char *buf, BinfmtMiscEntry *bme)
buf += sprintf(buf, "\\x%c%c", bme->mask[i], bme->mask[i + 1]);
}
sprintf(buf, ":%s:%s", bme->interpreter, bme->flags ? : "\0");
sprintf(buf, ":%s:%s", bme->interpreter, bme->flags ?: "\0");
return 1;
}
@@ -281,9 +279,8 @@ static int binfmt_misc_restore_bme(struct mount_info *mi, BinfmtMiscEntry *bme,
ret = make_bfmtm_magic_str(buf, bme);
} else if (bme->extension) {
/* :name:E::extension::interpreter:flags */
ret = snprintf(buf, BINFMT_MISC_STR, ":%s:E::%s::%s:%s",
bme->name, bme->extension, bme->interpreter,
bme->flags ? : "\0");
ret = snprintf(buf, BINFMT_MISC_STR, ":%s:E::%s::%s:%s", bme->name, bme->extension, bme->interpreter,
bme->flags ?: "\0");
if (ret >= BINFMT_MISC_STR) /* output truncated */
ret = -1;
} else
@@ -374,8 +371,8 @@ int collect_binfmt_misc(void)
return collect_image(&binfmt_misc_cinfo);
}
#else
#define binfmt_misc_dump NULL
#define binfmt_misc_restore NULL
#define binfmt_misc_dump NULL
#define binfmt_misc_restore NULL
#define binfmt_misc_parse_or_collect NULL
#endif
@@ -419,17 +416,11 @@ static int tmpfs_dump(struct mount_info *pm)
if (root_ns_mask & CLONE_NEWUSER)
userns_pid = root_item->pid->real;
ret = cr_system_userns(fd, img_raw_fd(img), -1, "tar", (char *[])
{ "tar", "--create",
"--gzip",
"--no-unquote",
"--no-wildcards",
"--one-file-system",
"--check-links",
"--preserve-permissions",
"--sparse",
"--numeric-owner",
"--directory", "/proc/self/fd/0", ".", NULL }, 0, userns_pid);
ret = cr_system_userns(fd, img_raw_fd(img), -1, "tar",
(char *[]){ "tar", "--create", "--gzip", "--no-unquote", "--no-wildcards",
"--one-file-system", "--check-links", "--preserve-permissions", "--sparse",
"--numeric-owner", "--directory", "/proc/self/fd/0", ".", NULL },
0, userns_pid);
if (ret)
pr_err("Can't dump tmpfs content\n");
@@ -460,9 +451,9 @@ static int tmpfs_restore(struct mount_info *pm)
}
ret = cr_system(img_raw_fd(img), -1, -1, "tar",
(char *[]) {"tar", "--extract", "--gzip",
"--no-unquote", "--no-wildcards",
"--directory", pm->mountpoint, NULL}, 0);
(char *[]){ "tar", "--extract", "--gzip", "--no-unquote", "--no-wildcards", "--directory",
pm->mountpoint, NULL },
0);
close_image(img);
if (ret) {
@@ -556,8 +547,7 @@ static int fusectl_dump(struct mount_info *pm)
}
for (it = mntinfo; it; it = it->next) {
if (it->fstype->code == FSTYPE__FUSE &&
id == kdev_minor(it->s_dev) && !it->external) {
if (it->fstype->code == FSTYPE__FUSE && id == kdev_minor(it->s_dev) && !it->external) {
pr_err("%s is a fuse mount but not external\n", it->mountpoint);
goto out;
}
@@ -588,8 +578,7 @@ static int tracefs_parse(struct mount_info *pm)
static bool cgroup_sb_equal(struct mount_info *a, struct mount_info *b)
{
if (a->private && b->private &&
strcmp(a->private, b->private))
if (a->private && b->private && strcmp(a->private, b->private))
return false;
if (strcmp(a->options, b->options))
return false;
@@ -670,8 +659,7 @@ static int dump_empty_fs(struct mount_info *pm)
*/
static int always_fail(struct mount_info *pm)
{
pr_err("failed to dump fs %s (%s): always fail\n", pm->mountpoint,
pm->fstype->name);
pr_err("failed to dump fs %s (%s): always fail\n", pm->mountpoint, pm->fstype->name);
return -1;
}
@@ -679,92 +667,113 @@ static struct fstype fstypes[] = {
{
.name = "unsupported",
.code = FSTYPE__UNSUPPORTED,
}, {
},
{
.name = "auto_cr",
.code = FSTYPE__AUTO,
}, {
},
{
.name = "proc",
.code = FSTYPE__PROC,
}, {
},
{
.name = "sysfs",
.code = FSTYPE__SYSFS,
}, {
},
{
.name = "devtmpfs",
.code = FSTYPE__DEVTMPFS,
.dump = devtmpfs_dump,
.restore = devtmpfs_restore,
}, {
},
{
.name = "binfmt_misc",
.parse = binfmt_misc_parse_or_collect,
.collect = binfmt_misc_parse_or_collect,
.code = FSTYPE__BINFMT_MISC,
.dump = binfmt_misc_dump,
.restore = binfmt_misc_restore,
}, {
},
{
.name = "tmpfs",
.code = FSTYPE__TMPFS,
.dump = tmpfs_dump,
.restore = tmpfs_restore,
}, {
},
{
.name = "devpts",
.parse = devpts_parse,
.code = FSTYPE__DEVPTS,
.restore = devpts_restore,
.check_bindmount = devpts_check_bindmount,
}, {
},
{
.name = "simfs",
.code = FSTYPE__SIMFS,
}, {
},
{
.name = "btrfs",
.code = FSTYPE__UNSUPPORTED,
.sb_equal = btrfs_sb_equal,
}, {
},
{
.name = "pstore",
.dump = dump_empty_fs,
.code = FSTYPE__PSTORE,
}, {
},
{
.name = "mqueue",
.dump = dump_empty_fs,
.code = FSTYPE__MQUEUE,
}, {
},
{
.name = "securityfs",
.code = FSTYPE__SECURITYFS,
}, {
},
{
.name = "fusectl",
.dump = fusectl_dump,
.code = FSTYPE__FUSECTL,
}, {
},
{
.name = "debugfs",
.code = FSTYPE__DEBUGFS,
.parse = debugfs_parse,
}, {
},
{
.name = "tracefs",
.code = FSTYPE__TRACEFS,
.parse = tracefs_parse,
}, {
},
{
.name = "cgroup",
.code = FSTYPE__CGROUP,
.parse = cgroup_parse,
.sb_equal = cgroup_sb_equal,
}, {
},
{
.name = "cgroup2",
.code = FSTYPE__CGROUP2,
.parse = cgroup_parse,
.sb_equal = cgroup_sb_equal,
}, {
},
{
.name = "aufs",
.code = FSTYPE__AUFS,
.parse = aufs_parse,
}, {
},
{
.name = "fuse",
.code = FSTYPE__FUSE,
.dump = always_fail,
.restore = always_fail,
}, {
},
{
.name = "overlay",
.code = FSTYPE__OVERLAYFS,
.parse = overlayfs_parse,
}, {
},
{
.name = "autofs",
.code = FSTYPE__AUTOFS,
.parse = autofs_parse,
@@ -773,7 +782,10 @@ static struct fstype fstypes[] = {
},
};
struct fstype *fstype_auto(void) { return &fstypes[1]; }
struct fstype *fstype_auto(void)
{
return &fstypes[1];
}
static char fsauto_all[] = "all";
static char *fsauto_names;
@@ -871,4 +883,3 @@ struct fstype *decode_fstype(u32 fst)
uns:
return &fstypes[0];
}

View File

@@ -46,26 +46,26 @@
#include "images/fsnotify.pb-c.h"
#include "images/mnt.pb-c.h"
#undef LOG_PREFIX
#undef LOG_PREFIX
#define LOG_PREFIX "fsnotify: "
struct fsnotify_mark_info {
struct list_head list;
struct list_head list;
union {
InotifyWdEntry *iwe;
FanotifyMarkEntry *fme;
InotifyWdEntry *iwe;
FanotifyMarkEntry *fme;
};
struct pprep_head prep; /* XXX union with remap */
struct file_remap *remap;
struct pprep_head prep; /* XXX union with remap */
struct file_remap *remap;
};
struct fsnotify_file_info {
union {
InotifyFileEntry *ife;
FanotifyFileEntry *ffe;
InotifyFileEntry *ife;
FanotifyFileEntry *ffe;
};
struct list_head marks;
struct file_desc d;
struct list_head marks;
struct file_desc d;
};
/* File handle */
@@ -91,12 +91,10 @@ static void decode_handle(fh_t *handle, FhEntry *img)
{
memzero(handle, sizeof(*handle));
handle->type = img->type;
handle->bytes = img->bytes;
handle->type = img->type;
handle->bytes = img->bytes;
memcpy(handle->__handle, img->handle,
min(pb_repeated_size(img, handle),
sizeof(handle->__handle)));
memcpy(handle->__handle, img->handle, min(pb_repeated_size(img, handle), sizeof(handle->__handle)));
}
static int open_by_handle(void *arg, int fd, int pid)
@@ -104,11 +102,7 @@ static int open_by_handle(void *arg, int fd, int pid)
return syscall(__NR_open_by_handle_at, fd, arg, O_PATH);
}
enum {
ERR_NO_MOUNT = -1,
ERR_NO_PATH_IN_MOUNT = -2,
ERR_GENERIC = -3
};
enum { ERR_NO_MOUNT = -1, ERR_NO_PATH_IN_MOUNT = -2, ERR_GENERIC = -3 };
static char *alloc_openable(unsigned int s_dev, unsigned long i_ino, FhEntry *f_handle)
{
@@ -139,13 +133,12 @@ static char *alloc_openable(unsigned int s_dev, unsigned long i_ino, FhEntry *f_
continue;
mntfd = __open_mountpoint(m, -1);
pr_debug("\t\tTrying via mntid %d root %s ns_mountpoint @%s (%d)\n",
m->mnt_id, m->root, m->ns_mountpoint, mntfd);
pr_debug("\t\tTrying via mntid %d root %s ns_mountpoint @%s (%d)\n", m->mnt_id, m->root,
m->ns_mountpoint, mntfd);
if (mntfd < 0)
continue;
fd = userns_call(open_by_handle, UNS_FDOUT, &handle,
sizeof(handle), mntfd);
fd = userns_call(open_by_handle, UNS_FDOUT, &handle, sizeof(handle), mntfd);
close(mntfd);
if (fd < 0)
continue;
@@ -176,9 +169,8 @@ static char *alloc_openable(unsigned int s_dev, unsigned long i_ino, FhEntry *f_
}
close(openable_fd);
pr_debug("\t\t\topenable (inode %s) as %s\n",
st.st_ino == i_ino ?
"match" : "don't match", __path);
pr_debug("\t\t\topenable (inode %s) as %s\n", st.st_ino == i_ino ? "match" : "don't match",
__path);
if (st.st_ino == i_ino) {
path = xstrdup(buf);
@@ -200,8 +192,7 @@ err:
return ERR_PTR(ERR_NO_MOUNT);
}
static int open_handle(unsigned int s_dev, unsigned long i_ino,
FhEntry *f_handle)
static int open_handle(unsigned int s_dev, unsigned long i_ino, FhEntry *f_handle)
{
struct mount_info *m;
int mntfd, fd = -1;
@@ -209,8 +200,7 @@ static int open_handle(unsigned int s_dev, unsigned long i_ino,
decode_handle(&handle, f_handle);
pr_debug("Opening fhandle %x:%llx...\n",
s_dev, (unsigned long long)handle.__handle[0]);
pr_debug("Opening fhandle %x:%llx...\n", s_dev, (unsigned long long)handle.__handle[0]);
for (m = mntinfo; m; m = m->next) {
if (m->s_dev != s_dev || !mnt_is_dir(m))
@@ -233,8 +223,7 @@ out:
return fd;
}
int check_open_handle(unsigned int s_dev, unsigned long i_ino,
FhEntry *f_handle)
int check_open_handle(unsigned int s_dev, unsigned long i_ino, FhEntry *f_handle)
{
char *path, *irmap_path;
struct mount_info *mi;
@@ -270,10 +259,9 @@ int check_open_handle(unsigned int s_dev, unsigned long i_ino,
goto err;
}
if ((mi->fstype->code == FSTYPE__TMPFS) ||
(mi->fstype->code == FSTYPE__DEVTMPFS)) {
pr_err("Can't find suitable path for handle (dev %#x ino %#lx): %d\n",
s_dev, i_ino, (int)PTR_ERR(path));
if ((mi->fstype->code == FSTYPE__TMPFS) || (mi->fstype->code == FSTYPE__DEVTMPFS)) {
pr_err("Can't find suitable path for handle (dev %#x ino %#lx): %d\n", s_dev, i_ino,
(int)PTR_ERR(path));
goto err;
}
@@ -310,11 +298,9 @@ err:
static int check_one_wd(InotifyWdEntry *we)
{
pr_info("wd: wd %#08x s_dev %#08x i_ino %#16"PRIx64" mask %#08x\n",
we->wd, we->s_dev, we->i_ino, we->mask);
pr_info("\t[fhandle] bytes %#08x type %#08x __handle %#016"PRIx64":%#016"PRIx64"\n",
we->f_handle->bytes, we->f_handle->type,
we->f_handle->handle[0], we->f_handle->handle[1]);
pr_info("wd: wd %#08x s_dev %#08x i_ino %#16" PRIx64 " mask %#08x\n", we->wd, we->s_dev, we->i_ino, we->mask);
pr_info("\t[fhandle] bytes %#08x type %#08x __handle %#016" PRIx64 ":%#016" PRIx64 "\n", we->f_handle->bytes,
we->f_handle->type, we->f_handle->handle[0], we->f_handle->handle[1]);
if (we->mask & KERNEL_FS_EVENT_ON_CHILD)
pr_warn_once("\t\tDetected FS_EVENT_ON_CHILD bit "
@@ -387,23 +373,21 @@ static int pre_dump_one_inotify(int pid, int lfd)
}
const struct fdtype_ops inotify_dump_ops = {
.type = FD_TYPES__INOTIFY,
.dump = dump_one_inotify,
.pre_dump = pre_dump_one_inotify,
.type = FD_TYPES__INOTIFY,
.dump = dump_one_inotify,
.pre_dump = pre_dump_one_inotify,
};
static int check_one_mark(FanotifyMarkEntry *fme)
{
if (fme->type == MARK_TYPE__INODE) {
BUG_ON(!fme->ie);
pr_info("mark: s_dev %#08x i_ino %#016"PRIx64" mask %#08x\n",
fme->s_dev, fme->ie->i_ino, fme->mask);
pr_info("mark: s_dev %#08x i_ino %#016" PRIx64 " mask %#08x\n", fme->s_dev, fme->ie->i_ino, fme->mask);
pr_info("\t[fhandle] bytes %#08x type %#08x __handle %#016"PRIx64":%#016"PRIx64"\n",
fme->ie->f_handle->bytes, fme->ie->f_handle->type,
fme->ie->f_handle->handle[0], fme->ie->f_handle->handle[1]);
pr_info("\t[fhandle] bytes %#08x type %#08x __handle %#016" PRIx64 ":%#016" PRIx64 "\n",
fme->ie->f_handle->bytes, fme->ie->f_handle->type, fme->ie->f_handle->handle[0],
fme->ie->f_handle->handle[1]);
if (check_open_handle(fme->s_dev, fme->ie->i_ino, fme->ie->f_handle))
return -1;
@@ -423,9 +407,7 @@ static int check_one_mark(FanotifyMarkEntry *fme)
fme->me->path = m->mountpoint + 1;
fme->s_dev = m->s_dev;
pr_info("mark: s_dev %#08x mnt_id %#08x mask %#08x\n",
fme->s_dev, fme->me->mnt_id, fme->mask);
pr_info("mark: s_dev %#08x mnt_id %#08x mask %#08x\n", fme->s_dev, fme->me->mnt_id, fme->mask);
}
return 0;
@@ -480,9 +462,7 @@ static int pre_dump_one_fanotify(int pid, int lfd)
for (i = 0; i < fe.n_mark; i++) {
FanotifyMarkEntry *me = fe.mark[i];
if (me->type == MARK_TYPE__INODE &&
irmap_queue_cache(me->s_dev, me->ie->i_ino,
me->ie->f_handle))
if (me->type == MARK_TYPE__INODE && irmap_queue_cache(me->s_dev, me->ie->i_ino, me->ie->f_handle))
return -1;
xfree(me);
@@ -492,13 +472,12 @@ static int pre_dump_one_fanotify(int pid, int lfd)
}
const struct fdtype_ops fanotify_dump_ops = {
.type = FD_TYPES__FANOTIFY,
.dump = dump_one_fanotify,
.pre_dump = pre_dump_one_fanotify,
.type = FD_TYPES__FANOTIFY,
.dump = dump_one_fanotify,
.pre_dump = pre_dump_one_fanotify,
};
static char *get_mark_path(const char *who, struct file_remap *remap,
FhEntry *f_handle, unsigned long i_ino,
static char *get_mark_path(const char *who, struct file_remap *remap, FhEntry *f_handle, unsigned long i_ino,
unsigned int s_dev, char *buf, int *target)
{
char *path = NULL;
@@ -508,11 +487,10 @@ static char *get_mark_path(const char *who, struct file_remap *remap,
mntns_root = mntns_get_root_by_mnt_id(remap->rmnt_id);
pr_debug("\t\tRestore %s watch for %#08x:%#016lx (via %s)\n",
who, s_dev, i_ino, remap->rpath);
pr_debug("\t\tRestore %s watch for %#08x:%#016lx (via %s)\n", who, s_dev, i_ino, remap->rpath);
*target = openat(mntns_root, remap->rpath, O_PATH);
} else if (f_handle->path) {
int mntns_root;
int mntns_root;
char *path = ".";
uint32_t mnt_id = f_handle->has_mnt_id ? f_handle->mnt_id : -1;
@@ -550,8 +528,7 @@ static char *get_mark_path(const char *who, struct file_remap *remap,
if (read_fd_link(*target, link, sizeof(link)) < 0)
link[0] = '\0';
pr_debug("\t\tRestore %s watch for %#08x:%#016lx (via %s -> %s)\n",
who, s_dev, i_ino, path, link);
pr_debug("\t\tRestore %s watch for %#08x:%#016lx (via %s -> %s)\n", who, s_dev, i_ino, path, link);
}
err:
return path;
@@ -564,15 +541,13 @@ static int restore_one_inotify(int inotify_fd, struct fsnotify_mark_info *info)
char buf[PSFDS], *path;
uint32_t mask;
path = get_mark_path("inotify", info->remap, iwe->f_handle,
iwe->i_ino, iwe->s_dev, buf, &target);
path = get_mark_path("inotify", info->remap, iwe->f_handle, iwe->i_ino, iwe->s_dev, buf, &target);
if (!path)
goto err;
mask = iwe->mask & IN_ALL_EVENTS;
if (iwe->mask & ~IN_ALL_EVENTS) {
pr_info("\t\tfilter event mask %#x -> %#x\n",
iwe->mask, mask);
pr_info("\t\tfilter event mask %#x -> %#x\n", iwe->mask, mask);
}
if (kdat.has_inotify_setnextwd) {
@@ -643,9 +618,8 @@ static int restore_one_fanotify(int fd, struct fsnotify_mark_info *mark)
snprintf(buf, sizeof(buf), "/proc/self/fd/%d", target);
path = buf;
} else if (fme->type == MARK_TYPE__INODE) {
path = get_mark_path("fanotify", mark->remap,
fme->ie->f_handle, fme->ie->i_ino,
fme->s_dev, buf, &target);
path = get_mark_path("fanotify", mark->remap, fme->ie->f_handle, fme->ie->i_ino, fme->s_dev, buf,
&target);
if (!path)
goto err;
} else {
@@ -658,18 +632,16 @@ static int restore_one_fanotify(int fd, struct fsnotify_mark_info *mark)
if (mark->fme->mask) {
ret = fanotify_mark(fd, flags, fme->mask, AT_FDCWD, path);
if (ret) {
pr_err("Adding fanotify mask 0x%x on 0x%x/%s failed (%d)\n",
fme->mask, fme->id, path, ret);
pr_err("Adding fanotify mask 0x%x on 0x%x/%s failed (%d)\n", fme->mask, fme->id, path, ret);
goto err;
}
}
if (fme->ignored_mask) {
ret = fanotify_mark(fd, flags | FAN_MARK_IGNORED_MASK,
fme->ignored_mask, AT_FDCWD, path);
ret = fanotify_mark(fd, flags | FAN_MARK_IGNORED_MASK, fme->ignored_mask, AT_FDCWD, path);
if (ret) {
pr_err("Adding fanotify ignored-mask 0x%x on 0x%x/%s failed (%d)\n",
fme->ignored_mask, fme->id, path, ret);
pr_err("Adding fanotify ignored-mask 0x%x on 0x%x/%s failed (%d)\n", fme->ignored_mask, fme->id,
path, ret);
goto err;
}
}
@@ -791,8 +763,7 @@ static int __collect_inotify_mark(struct fsnotify_file_info *p, struct fsnotify_
return 0;
}
static int __collect_fanotify_mark(struct fsnotify_file_info *p,
struct fsnotify_mark_info *mark)
static int __collect_fanotify_mark(struct fsnotify_file_info *p, struct fsnotify_mark_info *mark)
{
list_add(&mark->list, &p->marks);
if (mark->fme->type == MARK_TYPE__INODE) {
@@ -830,10 +801,10 @@ static int collect_one_inotify(void *o, ProtobufCMessage *msg, struct cr_img *im
}
struct collect_image_info inotify_cinfo = {
.fd_type = CR_FD_INOTIFY_FILE,
.pb_type = PB_INOTIFY_FILE,
.priv_size = sizeof(struct fsnotify_file_info),
.collect = collect_one_inotify,
.fd_type = CR_FD_INOTIFY_FILE,
.pb_type = PB_INOTIFY_FILE,
.priv_size = sizeof(struct fsnotify_file_info),
.collect = collect_one_inotify,
};
static int collect_one_fanotify(void *o, ProtobufCMessage *msg, struct cr_img *img)
@@ -864,10 +835,10 @@ static int collect_one_fanotify(void *o, ProtobufCMessage *msg, struct cr_img *i
}
struct collect_image_info fanotify_cinfo = {
.fd_type = CR_FD_FANOTIFY_FILE,
.pb_type = PB_FANOTIFY_FILE,
.priv_size = sizeof(struct fsnotify_file_info),
.collect = collect_one_fanotify,
.fd_type = CR_FD_FANOTIFY_FILE,
.pb_type = PB_FANOTIFY_FILE,
.priv_size = sizeof(struct fsnotify_file_info),
.collect = collect_one_fanotify,
};
static int collect_one_inotify_mark(void *o, ProtobufCMessage *msg, struct cr_img *i)
@@ -902,10 +873,10 @@ static int collect_one_inotify_mark(void *o, ProtobufCMessage *msg, struct cr_im
}
struct collect_image_info inotify_mark_cinfo = {
.fd_type = CR_FD_INOTIFY_WD,
.pb_type = PB_INOTIFY_WD,
.priv_size = sizeof(struct fsnotify_mark_info),
.collect = collect_one_inotify_mark,
.fd_type = CR_FD_INOTIFY_WD,
.pb_type = PB_INOTIFY_WD,
.priv_size = sizeof(struct fsnotify_mark_info),
.collect = collect_one_inotify_mark,
};
static int collect_one_fanotify_mark(void *o, ProtobufCMessage *msg, struct cr_img *i)
@@ -930,8 +901,8 @@ static int collect_one_fanotify_mark(void *o, ProtobufCMessage *msg, struct cr_i
}
struct collect_image_info fanotify_mark_cinfo = {
.fd_type = CR_FD_FANOTIFY_MARK,
.pb_type = PB_FANOTIFY_MARK,
.priv_size = sizeof(struct fsnotify_mark_info),
.collect = collect_one_fanotify_mark,
.fd_type = CR_FD_FANOTIFY_MARK,
.pb_type = PB_FANOTIFY_MARK,
.priv_size = sizeof(struct fsnotify_mark_info),
.collect = collect_one_fanotify_mark,
};

View File

@@ -11,17 +11,17 @@
* for more details.
*/
#define FD_ENTRY(_name, _fmt) \
[CR_FD_##_name] = { \
.fmt = _fmt ".img", \
.magic = _name##_MAGIC, \
#define FD_ENTRY(_name, _fmt) \
[CR_FD_##_name] = { \
.fmt = _fmt ".img", \
.magic = _name##_MAGIC, \
}
#define FD_ENTRY_F(_name, _fmt, _f) \
[CR_FD_##_name] = { \
.fmt = _fmt ".img", \
.magic = _name##_MAGIC, \
.oflags = _f, \
#define FD_ENTRY_F(_name, _fmt, _f) \
[CR_FD_##_name] = { \
.fmt = _fmt ".img", \
.magic = _name##_MAGIC, \
.oflags = _f, \
}
struct cr_fd_desc_tmpl imgset_template[CR_FD_MAX] = {

View File

@@ -274,8 +274,7 @@ void close_cr_imgset(struct cr_imgset **cr_imgset)
*cr_imgset = NULL;
}
struct cr_imgset *cr_imgset_open_range(int pid, int from, int to,
unsigned long flags)
struct cr_imgset *cr_imgset_open_range(int pid, int from, int to, unsigned long flags)
{
struct cr_imgset *imgset;
unsigned int i;
@@ -403,10 +402,10 @@ static int img_write_magic(struct cr_img *img, int oflags, int type)
}
struct openat_args {
char path[PATH_MAX];
int flags;
int err;
int mode;
char path[PATH_MAX];
int flags;
int err;
int mode;
};
static int userns_openat(void *arg, int dfd, int pid)
@@ -430,8 +429,7 @@ static int do_open_image(struct cr_img *img, int dfd, int type, unsigned long of
if (opts.stream && !(oflags & O_FORCE_LOCAL)) {
ret = img_streamer_open(path, flags);
errno = EIO; /* errno value is meaningless, only the ret value is meaningful */
} else if (root_ns_mask & CLONE_NEWUSER &&
type == CR_FD_PAGES && oflags & O_RDWR) {
} else if (root_ns_mask & CLONE_NEWUSER && type == CR_FD_PAGES && oflags & O_RDWR) {
/*
* For pages images dedup we need to open images read-write on
* restore, that may require proper capabilities, so we ask
@@ -574,7 +572,7 @@ int open_image_dir(char *dir, int mode)
if (opts.img_parent[0] == '/')
pr_warn("Absolute paths for parent links "
"may not work on restore!\n");
"may not work on restore!\n");
}
return 0;

View File

@@ -21,7 +21,7 @@
* (e.g., streamer is in capture more, while CRIU is in restore mode).
*/
#define IMG_STREAMER_CAPTURE_SOCKET_NAME "streamer-capture.sock"
#define IMG_STREAMER_SERVE_SOCKET_NAME "streamer-serve.sock"
#define IMG_STREAMER_SERVE_SOCKET_NAME "streamer-serve.sock"
/* All requests go through the same socket connection. We must synchronize */
static mutex_t *img_streamer_fd_lock;
@@ -32,9 +32,13 @@ static int img_streamer_mode;
static const char *socket_name_for_mode(int mode)
{
switch (mode) {
case O_DUMP: return IMG_STREAMER_CAPTURE_SOCKET_NAME;
case O_RSTR: return IMG_STREAMER_SERVE_SOCKET_NAME;
default: BUG(); return NULL;
case O_DUMP:
return IMG_STREAMER_CAPTURE_SOCKET_NAME;
case O_RSTR:
return IMG_STREAMER_SERVE_SOCKET_NAME;
default:
BUG();
return NULL;
}
}
@@ -57,8 +61,7 @@ int img_streamer_init(const char *image_dir, int mode)
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s",
image_dir, socket_name_for_mode(mode));
snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s", image_dir, socket_name_for_mode(mode));
if (connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
pr_perror("Unable to connect to image streamer socket: %s", addr.sun_path);
@@ -132,15 +135,13 @@ static int send_file_request(char *filename)
{
ImgStreamerRequestEntry req = IMG_STREAMER_REQUEST_ENTRY__INIT;
req.filename = filename;
return pb_write_one_fd(get_service_fd(IMG_STREAMER_FD_OFF),
&req, PB_IMG_STREAMER_REQUEST);
return pb_write_one_fd(get_service_fd(IMG_STREAMER_FD_OFF), &req, PB_IMG_STREAMER_REQUEST);
}
static int recv_file_reply(bool *exists)
{
ImgStreamerReplyEntry *reply;
int ret = pb_read_one_fd(get_service_fd(IMG_STREAMER_FD_OFF),
(void **)&reply, PB_IMG_STREAMER_REPLY);
int ret = pb_read_one_fd(get_service_fd(IMG_STREAMER_FD_OFF), (void **)&reply, PB_IMG_STREAMER_REPLY);
if (ret < 0)
return ret;
@@ -155,8 +156,8 @@ static int recv_file_reply(bool *exists)
* image streamer, greatly improving performance.
* Transfer rates of up to 15GB/s can be seen with this technique.
*/
#define READ_PIPE 0 /* index of the read pipe returned by pipe() */
#define WRITE_PIPE 1
#define READ_PIPE 0 /* index of the read pipe returned by pipe() */
#define WRITE_PIPE 1
static int establish_streamer_file_pipe(void)
{
/*
@@ -174,8 +175,7 @@ static int establish_streamer_file_pipe(void)
return -1;
}
if (send_fd(get_service_fd(IMG_STREAMER_FD_OFF),
NULL, 0, fds[streamer_pipe_direction]) < 0)
if (send_fd(get_service_fd(IMG_STREAMER_FD_OFF), NULL, 0, fds[streamer_pipe_direction]) < 0)
close(fds[criu_pipe_direction]);
else
ret = fds[criu_pipe_direction];

View File

@@ -22,26 +22,25 @@
#include "images/ipc-sem.pb-c.h"
#include "images/ipc-msg.pb-c.h"
#if defined (__GLIBC__) && __GLIBC__ >= 2
#if defined(__GLIBC__) && __GLIBC__ >= 2
#define KEY __key
#else
#define KEY key
#endif
#ifndef MSGMAX
#define MSGMAX 8192
#define MSGMAX 8192
#endif
#ifndef MSG_COPY
#define MSG_COPY 040000
#define MSG_COPY 040000
#endif
static void pr_ipc_desc_entry(const IpcDescEntry *desc)
{
pr_info("id: %-10d key: %#08x uid: %-10d gid: %-10d "
"cuid: %-10d cgid: %-10d mode: %-10o ",
desc->id, desc->key, desc->uid, desc->gid,
desc->cuid, desc->cgid, desc->mode);
"cuid: %-10d cgid: %-10d mode: %-10o ",
desc->id, desc->key, desc->uid, desc->gid, desc->cuid, desc->cgid, desc->mode);
}
static void fill_ipc_desc(int id, IpcDescEntry *desc, const struct ipc_perm *ipcp)
@@ -62,7 +61,7 @@ static void pr_ipc_sem_array(int nr, u16 *values)
pr_info("\n");
}
#define pr_info_ipc_sem_array(nr, values) pr_ipc_sem_array(nr, values)
#define pr_info_ipc_sem_array(nr, values) pr_ipc_sem_array(nr, values)
static void pr_info_ipc_sem_entry(const IpcSemEntry *sem)
{
@@ -160,8 +159,7 @@ static int dump_ipc_sem(struct cr_img *img)
static void pr_info_ipc_msg(int nr, const IpcMsg *msg)
{
pr_info(" %-5d: type: %-20"PRId64" size: %-10d\n",
nr++, msg->mtype, msg->msize);
pr_info(" %-5d: type: %-20" PRId64 " size: %-10d\n", nr++, msg->mtype, msg->msize);
}
static void pr_info_ipc_msg_entry(const IpcMsgEntry *msg)
@@ -170,8 +168,7 @@ static void pr_info_ipc_msg_entry(const IpcMsgEntry *msg)
pr_info("qbytes: %-10d qnum: %-10d\n", msg->qbytes, msg->qnum);
}
static int dump_ipc_msg_queue_messages(struct cr_img *img, const IpcMsgEntry *msq,
unsigned int msg_nr)
static int dump_ipc_msg_queue_messages(struct cr_img *img, const IpcMsgEntry *msq, unsigned int msg_nr)
{
struct msgbuf *message = NULL;
unsigned int msgmax;
@@ -287,7 +284,7 @@ static int dump_ipc_msg(struct cr_img *img)
static void pr_info_ipc_shm(const IpcShmEntry *shm)
{
pr_ipc_desc_entry(shm->desc);
pr_info("size: %-10"PRIu64"\n", shm->size);
pr_info("size: %-10" PRIu64 "\n", shm->size);
}
#define NR_MANDATORY_IPC_SYSCTLS 9
@@ -295,24 +292,24 @@ static void pr_info_ipc_shm(const IpcShmEntry *shm)
static int ipc_sysctl_req(IpcVarEntry *e, int op)
{
struct sysctl_req req[] = {
{ "kernel/sem", e->sem_ctls, CTL_U32A(e->n_sem_ctls) },
{ "kernel/msgmax", &e->msg_ctlmax, CTL_U32 },
{ "kernel/msgmnb", &e->msg_ctlmnb, CTL_U32 },
{ "kernel/auto_msgmni", &e->auto_msgmni, CTL_U32 },
{ "kernel/msgmni", &e->msg_ctlmni, CTL_U32 },
{ "kernel/shmmax", &e->shm_ctlmax, CTL_U64 },
{ "kernel/shmall", &e->shm_ctlall, CTL_U64 },
{ "kernel/shmmni", &e->shm_ctlmni, CTL_U32 },
{ "kernel/shm_rmid_forced", &e->shm_rmid_forced, CTL_U32 },
{ "kernel/sem", e->sem_ctls, CTL_U32A(e->n_sem_ctls) },
{ "kernel/msgmax", &e->msg_ctlmax, CTL_U32 },
{ "kernel/msgmnb", &e->msg_ctlmnb, CTL_U32 },
{ "kernel/auto_msgmni", &e->auto_msgmni, CTL_U32 },
{ "kernel/msgmni", &e->msg_ctlmni, CTL_U32 },
{ "kernel/shmmax", &e->shm_ctlmax, CTL_U64 },
{ "kernel/shmall", &e->shm_ctlall, CTL_U64 },
{ "kernel/shmmni", &e->shm_ctlmni, CTL_U32 },
{ "kernel/shm_rmid_forced", &e->shm_rmid_forced, CTL_U32 },
/* We have 9 mandatory sysctls above and 8 optional below */
{ "fs/mqueue/queues_max", &e->mq_queues_max, CTL_U32 },
{ "fs/mqueue/msg_max", &e->mq_msg_max, CTL_U32 },
{ "fs/mqueue/msgsize_max", &e->mq_msgsize_max, CTL_U32 },
{ "fs/mqueue/msg_default", &e->mq_msg_default, CTL_U32 },
{ "fs/mqueue/msgsize_default", &e->mq_msgsize_default, CTL_U32 },
{ "kernel/msg_next_id", &e->msg_next_id, CTL_U32 },
{ "kernel/sem_next_id", &e->sem_next_id, CTL_U32 },
{ "kernel/shm_next_id", &e->shm_next_id, CTL_U32 },
{ "fs/mqueue/queues_max", &e->mq_queues_max, CTL_U32 },
{ "fs/mqueue/msg_max", &e->mq_msg_max, CTL_U32 },
{ "fs/mqueue/msgsize_max", &e->mq_msgsize_max, CTL_U32 },
{ "fs/mqueue/msg_default", &e->mq_msg_default, CTL_U32 },
{ "fs/mqueue/msgsize_default", &e->mq_msgsize_default, CTL_U32 },
{ "kernel/msg_next_id", &e->msg_next_id, CTL_U32 },
{ "kernel/sem_next_id", &e->sem_next_id, CTL_U32 },
{ "kernel/shm_next_id", &e->shm_next_id, CTL_U32 },
};
int nr = NR_MANDATORY_IPC_SYSCTLS;
@@ -408,8 +405,7 @@ static int dump_ipc_shm(struct cr_img *img)
slot++;
}
if (slot != info.used_ids) {
pr_err("Failed to collect %d (only %d succeeded)\n",
info.used_ids, slot);
pr_err("Failed to collect %d (only %d succeeded)\n", info.used_ids, slot);
return -EFAULT;
}
return 0;
@@ -420,8 +416,8 @@ static int dump_ipc_var(struct cr_img *img)
IpcVarEntry var = IPC_VAR_ENTRY__INIT;
int ret = -1;
var.n_sem_ctls = 4;
var.sem_ctls = xmalloc(pb_repeated_size(&var, sem_ctls));
var.n_sem_ctls = 4;
var.sem_ctls = xmalloc(pb_repeated_size(&var, sem_ctls));
if (!var.sem_ctls)
goto err;
var.has_mq_msg_default = true;
@@ -543,16 +539,14 @@ static int prepare_ipc_sem_desc(struct cr_img *img, const IpcSemEntry *sem)
return ret;
}
id = semget(sem->desc->key, sem->nsems,
sem->desc->mode | IPC_CREAT | IPC_EXCL);
id = semget(sem->desc->key, sem->nsems, sem->desc->mode | IPC_CREAT | IPC_EXCL);
if (id == -1) {
pr_perror("Failed to create sem set");
return -errno;
}
if (id != sem->desc->id) {
pr_err("Failed to restore sem id (%d instead of %d)\n",
id, sem->desc->id);
pr_err("Failed to restore sem id (%d instead of %d)\n", id, sem->desc->id);
return -EFAULT;
}
@@ -639,8 +633,7 @@ static int prepare_ipc_msg_queue_messages(struct cr_img *img, const IpcMsgEntry
if (msg->msize > MSGMAX) {
ret = -1;
pr_err("Unsupported message size: %d (MAX: %d)\n",
msg->msize, MSGMAX);
pr_err("Unsupported message size: %d (MAX: %d)\n", msg->msize, MSGMAX);
break;
}
@@ -686,8 +679,7 @@ static int prepare_ipc_msg_queue(struct cr_img *img, const IpcMsgEntry *msq)
}
if (id != msq->desc->id) {
pr_err("Failed to restore msg id (%d instead of %d)\n",
id, msq->desc->id);
pr_err("Failed to restore msg id (%d instead of %d)\n", id, msq->desc->id);
return -EFAULT;
}
@@ -821,16 +813,14 @@ static int prepare_ipc_shm_seg(struct cr_img *img, const IpcShmEntry *shm)
return ret;
}
id = shmget(shm->desc->key, shm->size,
shm->desc->mode | IPC_CREAT | IPC_EXCL);
id = shmget(shm->desc->key, shm->size, shm->desc->mode | IPC_CREAT | IPC_EXCL);
if (id == -1) {
pr_perror("Failed to create shm set");
return -errno;
}
if (id != shm->desc->id) {
pr_err("Failed to restore shm id (%d instead of %d)\n",
id, shm->desc->id);
pr_err("Failed to restore shm id (%d instead of %d)\n", id, shm->desc->id);
return -EFAULT;
}

Some files were not shown because too many files have changed in this diff Show More