2016-09-27 18:12:25 +03:00
|
|
|
#ifndef __COMPEL_INFECT_H__
|
|
|
|
#define __COMPEL_INFECT_H__
|
2016-09-28 13:55:21 +03:00
|
|
|
|
2016-10-31 15:06:48 +03:00
|
|
|
#include <stdbool.h>
|
|
|
|
|
|
|
|
#include <compel/asm/sigframe.h>
|
|
|
|
#include <compel/asm/infect-types.h>
|
2016-10-27 19:01:21 +03:00
|
|
|
#include <compel/ksigset.h>
|
2016-11-04 00:30:00 +03:00
|
|
|
#include <compel/compel.h>
|
2016-09-28 13:55:21 +03:00
|
|
|
|
2016-10-31 15:06:48 +03:00
|
|
|
#include "common/compiler.h"
|
|
|
|
|
2016-10-27 11:22:42 +03:00
|
|
|
#define PARASITE_START_AREA_MIN (4096)
|
|
|
|
|
2016-11-21 21:26:19 +03:00
|
|
|
extern int compel_interrupt_task(int pid);
|
2016-09-27 20:16:07 +03:00
|
|
|
|
|
|
|
struct seize_task_status {
|
|
|
|
char state;
|
|
|
|
int ppid;
|
|
|
|
unsigned long long sigpnd;
|
|
|
|
unsigned long long shdpnd;
|
|
|
|
int seccomp_mode;
|
|
|
|
};
|
|
|
|
|
|
|
|
extern int compel_wait_task(int pid, int ppid,
|
|
|
|
int (*get_status)(int pid, struct seize_task_status *),
|
|
|
|
struct seize_task_status *st);
|
2016-11-25 16:20:31 +03:00
|
|
|
|
|
|
|
extern int compel_stop_task(int pid);
|
2016-11-25 16:20:45 +03:00
|
|
|
extern int compel_resume_task(pid_t pid, int orig_state, int state);
|
2016-09-27 20:16:07 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* FIXME -- these should be mapped to pid.h's
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define TASK_ALIVE 0x1
|
|
|
|
#define TASK_DEAD 0x2
|
|
|
|
#define TASK_STOPPED 0x3
|
|
|
|
#define TASK_ZOMBIE 0x6
|
|
|
|
|
2016-09-28 11:29:01 +03:00
|
|
|
struct parasite_ctl;
|
2016-11-14 16:05:36 +03:00
|
|
|
struct parasite_thread_ctl;
|
2016-11-14 16:05:08 +03:00
|
|
|
|
2016-09-28 11:50:25 +03:00
|
|
|
extern struct parasite_ctl *compel_prepare(int pid);
|
2016-11-21 21:26:13 +03:00
|
|
|
extern struct parasite_ctl *compel_prepare_noctx(int pid);
|
2016-09-28 11:29:01 +03:00
|
|
|
extern int compel_infect(struct parasite_ctl *ctl, unsigned long nr_threads, unsigned long args_size);
|
2016-11-14 16:05:08 +03:00
|
|
|
extern struct parasite_thread_ctl *compel_prepare_thread(struct parasite_ctl *ctl, int pid);
|
|
|
|
extern void compel_release_thread(struct parasite_thread_ctl *);
|
2016-09-28 11:29:01 +03:00
|
|
|
|
2016-09-28 12:01:01 +03:00
|
|
|
extern int compel_stop_daemon(struct parasite_ctl *ctl);
|
|
|
|
extern int compel_cure_remote(struct parasite_ctl *ctl);
|
|
|
|
extern int compel_cure_local(struct parasite_ctl *ctl);
|
|
|
|
extern int compel_cure(struct parasite_ctl *ctl);
|
2016-09-28 12:12:09 +03:00
|
|
|
|
|
|
|
#define PARASITE_ARG_SIZE_MIN ( 1 << 12)
|
|
|
|
|
|
|
|
#define compel_parasite_args(ctl, type) \
|
|
|
|
({ \
|
|
|
|
void *___ret; \
|
|
|
|
BUILD_BUG_ON(sizeof(type) > PARASITE_ARG_SIZE_MIN); \
|
|
|
|
___ret = compel_parasite_args_p(ctl); \
|
|
|
|
___ret; \
|
|
|
|
})
|
|
|
|
|
|
|
|
extern void *compel_parasite_args_p(struct parasite_ctl *ctl);
|
|
|
|
extern void *compel_parasite_args_s(struct parasite_ctl *ctl, int args_size);
|
2016-09-28 13:55:21 +03:00
|
|
|
|
|
|
|
extern int compel_execute_syscall(struct parasite_ctl *ctl,
|
|
|
|
user_regs_struct_t *regs, const char *code_syscall);
|
2016-11-14 16:05:49 +03:00
|
|
|
extern int compel_run_in_thread(struct parasite_thread_ctl *tctl, unsigned int cmd);
|
2016-09-28 14:07:16 +03:00
|
|
|
|
2016-09-29 16:43:29 +03:00
|
|
|
/*
|
|
|
|
* The PTRACE_SYSCALL will trap task twice -- on
|
|
|
|
* enter into and on exit from syscall. If we trace
|
|
|
|
* a single task, we may skip half of all getregs
|
|
|
|
* calls -- on exit we don't need them.
|
|
|
|
*/
|
|
|
|
enum trace_flags {
|
|
|
|
TRACE_ALL,
|
|
|
|
TRACE_ENTER,
|
|
|
|
TRACE_EXIT,
|
|
|
|
};
|
|
|
|
|
|
|
|
extern int compel_stop_on_syscall(int tasks, int sys_nr,
|
|
|
|
int sys_nr_compat, enum trace_flags trace);
|
|
|
|
|
|
|
|
extern int compel_stop_pie(pid_t pid, void *addr, enum trace_flags *tf, bool no_bp);
|
|
|
|
|
2016-09-28 14:07:16 +03:00
|
|
|
extern int compel_unmap(struct parasite_ctl *ctl, unsigned long addr);
|
2016-09-30 14:56:28 +03:00
|
|
|
|
|
|
|
extern int compel_mode_native(struct parasite_ctl *ctl);
|
|
|
|
|
2016-09-30 14:58:29 +03:00
|
|
|
extern k_rtsigset_t *compel_task_sigmask(struct parasite_ctl *ctl);
|
2016-11-14 16:05:08 +03:00
|
|
|
extern k_rtsigset_t *compel_thread_sigmask(struct parasite_thread_ctl *tctl);
|
2016-09-30 14:58:29 +03:00
|
|
|
|
2016-09-30 14:53:49 +03:00
|
|
|
struct rt_sigframe;
|
|
|
|
|
2016-10-27 18:07:10 +03:00
|
|
|
typedef int (*open_proc_fn)(int pid, int mode, const char *fmt, ...)
|
|
|
|
__attribute__ ((__format__ (__printf__, 3, 4)));
|
|
|
|
|
2016-09-30 14:53:49 +03:00
|
|
|
struct infect_ctx {
|
2016-11-18 04:23:00 +03:00
|
|
|
int sock;
|
2016-09-30 14:53:49 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Regs manipulation context.
|
|
|
|
*/
|
|
|
|
int (*save_regs)(void *, user_regs_struct_t *, user_fpregs_struct_t *);
|
|
|
|
int (*make_sigframe)(void *, struct rt_sigframe *, struct rt_sigframe *, k_rtsigset_t *);
|
|
|
|
void *regs_arg;
|
|
|
|
|
2016-10-30 22:56:39 +03:00
|
|
|
unsigned long task_size;
|
2016-09-30 14:53:49 +03:00
|
|
|
unsigned long syscall_ip; /* entry point of infection */
|
|
|
|
unsigned long flags; /* fine-tune (e.g. faults) */
|
|
|
|
|
|
|
|
void (*child_handler)(int, siginfo_t *, void *); /* hander for SIGCHLD deaths */
|
2016-11-21 21:26:17 +03:00
|
|
|
struct sigaction orig_handler;
|
2016-10-27 18:07:10 +03:00
|
|
|
|
|
|
|
open_proc_fn open_proc;
|
2016-11-03 02:08:14 +03:00
|
|
|
|
|
|
|
int log_fd; /* fd for parasite code to send messages to */
|
2016-09-30 14:53:49 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
extern struct infect_ctx *compel_infect_ctx(struct parasite_ctl *);
|
|
|
|
|
|
|
|
#define INFECT_NO_MEMFD 0x1 /* don't use memfd() */
|
|
|
|
#define INFECT_FAIL_CONNECT 0x2 /* make parasite connect() fail */
|
|
|
|
#define INFECT_NO_BREAKPOINTS 0x4 /* no breakpoints in pie tracking */
|
2016-10-30 22:54:29 +03:00
|
|
|
#define INFECT_HAS_COMPAT_SIGRETURN 0x8
|
2016-09-30 14:53:49 +03:00
|
|
|
|
2016-11-24 15:21:00 +03:00
|
|
|
/*
|
|
|
|
* There are several ways to describe a blob to compel
|
|
|
|
* library. The simplest one derived from criu is to
|
|
|
|
* provide it from .h files.
|
|
|
|
*/
|
|
|
|
#define COMPEL_BLOB_CHEADER 0x1
|
|
|
|
|
2016-11-04 00:30:00 +03:00
|
|
|
struct parasite_blob_desc {
|
2016-11-24 15:21:00 +03:00
|
|
|
unsigned parasite_type;
|
|
|
|
union {
|
|
|
|
struct {
|
|
|
|
const void *mem;
|
2016-11-25 16:21:12 +03:00
|
|
|
size_t bsize;
|
|
|
|
size_t nr_gotpcrel;
|
2016-11-24 15:21:00 +03:00
|
|
|
unsigned long parasite_ip_off;
|
|
|
|
unsigned long addr_cmd_off;
|
|
|
|
unsigned long addr_arg_off;
|
|
|
|
compel_reloc_t *relocs;
|
|
|
|
unsigned int nr_relocs;
|
|
|
|
} hdr;
|
|
|
|
};
|
2016-11-04 00:30:00 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
extern struct parasite_blob_desc *compel_parasite_blob_desc(struct parasite_ctl *);
|
|
|
|
|
2016-10-19 12:32:44 +03:00
|
|
|
typedef int (*save_regs_t)(void *, user_regs_struct_t *, user_fpregs_struct_t *);
|
2016-11-14 16:05:49 +03:00
|
|
|
extern int compel_get_thread_regs(struct parasite_thread_ctl *, save_regs_t, void *);
|
2016-10-19 12:32:44 +03:00
|
|
|
|
2016-11-07 01:20:46 +03:00
|
|
|
extern void compel_relocs_apply(void *mem, void *vbase, size_t size, compel_reloc_t *elf_relocs, size_t nr_relocs);
|
|
|
|
|
2016-11-18 19:44:52 +03:00
|
|
|
extern unsigned long compel_task_size(void);
|
|
|
|
|
2016-09-27 18:12:25 +03:00
|
|
|
#endif
|