mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-22 09:58:09 +00:00
arm64: C/R PAC keys
PAC stands for Pointer Authentication Code. Each process has 5 PAC keys and a mask of enabled keys. All this properties have to be C/R-ed. As they are per-process protperties, we can save/restore them just for one thread. Signed-off-by: Andrei Vagin <avagin@google.com>
This commit is contained in:
parent
8d5cef546a
commit
1cf8040173
@ -81,7 +81,7 @@ int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs, user_fpregs_struct
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = save(arg, regs, fpsimd);
|
ret = save(pid, arg, regs, fpsimd);
|
||||||
err:
|
err:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,7 @@ int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs, user_fpregs_struct
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = save(arg, regs, vfp);
|
ret = save(pid, arg, regs, vfp);
|
||||||
err:
|
err:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -91,7 +91,7 @@ int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs, user_fpregs_struct
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = save(arg, regs, fpregs);
|
ret = save(pid, arg, regs, fpregs);
|
||||||
err:
|
err:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -149,7 +149,7 @@ int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs, user_fpregs_struct
|
|||||||
regs->regs[0] = 0;
|
regs->regs[0] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = save(arg, regs, xs);
|
ret = save(pid, arg, regs, xs);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,7 +400,7 @@ int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs, user_fpregs_struct
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
return save(arg, regs, fpregs);
|
return save(pid, arg, regs, fpregs);
|
||||||
}
|
}
|
||||||
|
|
||||||
int compel_set_task_ext_regs(pid_t pid, user_fpregs_struct_t *ext_regs)
|
int compel_set_task_ext_regs(pid_t pid, user_fpregs_struct_t *ext_regs)
|
||||||
|
@ -92,7 +92,7 @@ int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs, user_fpregs_struct
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = save(arg, regs, fpsimd);
|
ret = save(pid, arg, regs, fpsimd);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,7 +348,7 @@ int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs, user_fpregs_struct
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Call save_task_regs() */
|
/* Call save_task_regs() */
|
||||||
return save(arg, regs, fpregs);
|
return save(pid, arg, regs, fpregs);
|
||||||
}
|
}
|
||||||
|
|
||||||
int compel_set_task_ext_regs(pid_t pid, user_fpregs_struct_t *ext_regs)
|
int compel_set_task_ext_regs(pid_t pid, user_fpregs_struct_t *ext_regs)
|
||||||
|
@ -453,7 +453,7 @@ int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs, user_fpregs_struct
|
|||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
ret = save(arg, regs, xs);
|
ret = save(pid, arg, regs, xs);
|
||||||
err:
|
err:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ extern k_rtsigset_t *compel_thread_sigmask(struct parasite_thread_ctl *tctl);
|
|||||||
struct rt_sigframe;
|
struct rt_sigframe;
|
||||||
|
|
||||||
typedef int (*open_proc_fn)(int pid, int mode, const char *fmt, ...) __attribute__((__format__(__printf__, 3, 4)));
|
typedef int (*open_proc_fn)(int pid, int mode, const char *fmt, ...) __attribute__((__format__(__printf__, 3, 4)));
|
||||||
typedef int (*save_regs_t)(void *, user_regs_struct_t *, user_fpregs_struct_t *);
|
typedef int (*save_regs_t)(pid_t pid, void *, user_regs_struct_t *, user_fpregs_struct_t *);
|
||||||
typedef int (*make_sigframe_t)(void *, struct rt_sigframe *, struct rt_sigframe *, k_rtsigset_t *);
|
typedef int (*make_sigframe_t)(void *, struct rt_sigframe *, struct rt_sigframe *, k_rtsigset_t *);
|
||||||
|
|
||||||
struct infect_ctx {
|
struct infect_ctx {
|
||||||
|
@ -1300,7 +1300,7 @@ struct plain_regs_struct {
|
|||||||
user_fpregs_struct_t fpregs;
|
user_fpregs_struct_t fpregs;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int save_regs_plain(void *to, user_regs_struct_t *r, user_fpregs_struct_t *f)
|
static int save_regs_plain(pid_t pid, void *to, user_regs_struct_t *r, user_fpregs_struct_t *f)
|
||||||
{
|
{
|
||||||
struct plain_regs_struct *prs = to;
|
struct plain_regs_struct *prs = to;
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <linux/auxvec.h>
|
||||||
|
|
||||||
#include <linux/elf.h>
|
#include <linux/elf.h>
|
||||||
|
|
||||||
@ -20,10 +21,86 @@
|
|||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "restorer.h"
|
#include "restorer.h"
|
||||||
#include "compel/infect.h"
|
#include "compel/infect.h"
|
||||||
|
#include "pstree.h"
|
||||||
|
|
||||||
|
extern unsigned long getauxval(unsigned long type);
|
||||||
|
|
||||||
#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)
|
static int save_pac_keys(int pid, CoreEntry *core)
|
||||||
|
{
|
||||||
|
struct user_pac_address_keys paca;
|
||||||
|
struct user_pac_generic_keys pacg;
|
||||||
|
PacKeys *pac_entry;
|
||||||
|
long pac_enabled_key;
|
||||||
|
struct iovec iov;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
unsigned long hwcaps = getauxval(AT_HWCAP);
|
||||||
|
|
||||||
|
pac_entry = xmalloc(sizeof(PacKeys));
|
||||||
|
if (!pac_entry)
|
||||||
|
return -1;
|
||||||
|
core->ti_aarch64->pac_keys = pac_entry;
|
||||||
|
pac_keys__init(pac_entry);
|
||||||
|
|
||||||
|
if (hwcaps & HWCAP_PACA) {
|
||||||
|
PacAddressKeys *pac_address_keys;
|
||||||
|
|
||||||
|
pr_debug("%d: Dumping address authentication keys\n", pid);
|
||||||
|
iov.iov_base = &paca;
|
||||||
|
iov.iov_len = sizeof(paca);
|
||||||
|
if ((ret = ptrace(PTRACE_GETREGSET, pid, NT_ARM_PACA_KEYS, &iov))) {
|
||||||
|
pr_perror("Failed to get address authentication key for %d", pid);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
pac_address_keys = xmalloc(sizeof(PacAddressKeys));
|
||||||
|
if (!pac_address_keys)
|
||||||
|
return -1;
|
||||||
|
pac_address_keys__init(pac_address_keys);
|
||||||
|
pac_entry->pac_address_keys = pac_address_keys;
|
||||||
|
pac_address_keys->apiakey_lo = paca.apiakey;
|
||||||
|
pac_address_keys->apiakey_hi = paca.apiakey >> 64;
|
||||||
|
pac_address_keys->apibkey_lo = paca.apibkey;
|
||||||
|
pac_address_keys->apibkey_hi = paca.apibkey >> 64;
|
||||||
|
pac_address_keys->apdakey_lo = paca.apdakey;
|
||||||
|
pac_address_keys->apdakey_hi = paca.apdakey >> 64;
|
||||||
|
pac_address_keys->apdbkey_lo = paca.apdbkey;
|
||||||
|
pac_address_keys->apdbkey_hi = paca.apdbkey >> 64;
|
||||||
|
|
||||||
|
iov.iov_base = &pac_enabled_key;
|
||||||
|
iov.iov_len = sizeof(pac_enabled_key);
|
||||||
|
ret = ptrace(PTRACE_GETREGSET, pid, NT_ARM_PAC_ENABLED_KEYS, &iov);
|
||||||
|
if (ret) {
|
||||||
|
pr_perror("Failed to get authentication key mask for %d", pid);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pac_address_keys->pac_enabled_key = pac_enabled_key;
|
||||||
|
|
||||||
|
}
|
||||||
|
if (hwcaps & HWCAP_PACG) {
|
||||||
|
PacGenericKeys *pac_generic_keys;
|
||||||
|
|
||||||
|
pr_debug("%d: Dumping generic authentication keys\n", pid);
|
||||||
|
iov.iov_base = &pacg;
|
||||||
|
iov.iov_len = sizeof(pacg);
|
||||||
|
if ((ret = ptrace(PTRACE_GETREGSET, pid, NT_ARM_PACG_KEYS, &iov))) {
|
||||||
|
pr_perror("Failed to get a generic authantication key for %d", pid);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
pac_generic_keys = xmalloc(sizeof(PacGenericKeys));
|
||||||
|
if (!pac_generic_keys)
|
||||||
|
return -1;
|
||||||
|
pac_generic_keys__init(pac_generic_keys);
|
||||||
|
pac_entry->pac_generic_keys = pac_generic_keys;
|
||||||
|
pac_generic_keys->apgakey_lo = pacg.apgakey;
|
||||||
|
pac_generic_keys->apgakey_hi = pacg.apgakey >> 64;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int save_task_regs(pid_t pid, void *x, user_regs_struct_t *regs, user_fpregs_struct_t *fpsimd)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
CoreEntry *core = x;
|
CoreEntry *core = x;
|
||||||
@ -43,6 +120,8 @@ int save_task_regs(void *x, user_regs_struct_t *regs, user_fpregs_struct_t *fpsi
|
|||||||
assign_reg(core->ti_aarch64->fpsimd, fpsimd, fpsr);
|
assign_reg(core->ti_aarch64->fpsimd, fpsimd, fpsr);
|
||||||
assign_reg(core->ti_aarch64->fpsimd, fpsimd, fpcr);
|
assign_reg(core->ti_aarch64->fpsimd, fpsimd, fpcr);
|
||||||
|
|
||||||
|
if (save_pac_keys(pid, core))
|
||||||
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,6 +171,12 @@ void arch_free_thread_info(CoreEntry *core)
|
|||||||
xfree(CORE_THREAD_ARCH_INFO(core)->fpsimd->vregs);
|
xfree(CORE_THREAD_ARCH_INFO(core)->fpsimd->vregs);
|
||||||
xfree(CORE_THREAD_ARCH_INFO(core)->fpsimd);
|
xfree(CORE_THREAD_ARCH_INFO(core)->fpsimd);
|
||||||
}
|
}
|
||||||
|
if (CORE_THREAD_ARCH_INFO(core)->pac_keys) {
|
||||||
|
PacKeys *pac_entry = CORE_THREAD_ARCH_INFO(core)->pac_keys;
|
||||||
|
xfree(pac_entry->pac_address_keys);
|
||||||
|
xfree(pac_entry->pac_generic_keys);
|
||||||
|
xfree(pac_entry);
|
||||||
|
}
|
||||||
xfree(CORE_THREAD_ARCH_INFO(core)->gpregs->regs);
|
xfree(CORE_THREAD_ARCH_INFO(core)->gpregs->regs);
|
||||||
xfree(CORE_THREAD_ARCH_INFO(core)->gpregs);
|
xfree(CORE_THREAD_ARCH_INFO(core)->gpregs);
|
||||||
xfree(CORE_THREAD_ARCH_INFO(core));
|
xfree(CORE_THREAD_ARCH_INFO(core));
|
||||||
@ -135,3 +220,83 @@ int restore_gpregs(struct rt_sigframe *f, UserRegsEntry *r)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int arch_ptrace_restore(int pid, struct pstree_item *item)
|
||||||
|
{
|
||||||
|
unsigned long hwcaps = getauxval(AT_HWCAP);
|
||||||
|
struct user_pac_address_keys upaca;
|
||||||
|
struct user_pac_generic_keys upacg;
|
||||||
|
PacAddressKeys *paca;
|
||||||
|
PacGenericKeys *pacg;
|
||||||
|
long pac_enabled_keys;
|
||||||
|
struct iovec iov;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
|
||||||
|
pr_debug("%d: Restoring PAC keys\n", pid);
|
||||||
|
|
||||||
|
paca = &rsti(item)->arch_info.pac_address_keys;
|
||||||
|
pacg = &rsti(item)->arch_info.pac_generic_keys;
|
||||||
|
if (rsti(item)->arch_info.has_paca) {
|
||||||
|
if (!(hwcaps & HWCAP_PACA)) {
|
||||||
|
pr_err("PACG support is required from the source system.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
pac_enabled_keys = rsti(item)->arch_info.pac_address_keys.pac_enabled_key;
|
||||||
|
|
||||||
|
upaca.apiakey = paca->apiakey_lo + ((__uint128_t)paca->apiakey_hi << 64);
|
||||||
|
upaca.apibkey = paca->apibkey_lo + ((__uint128_t)paca->apibkey_hi << 64);
|
||||||
|
upaca.apdakey = paca->apdakey_lo + ((__uint128_t)paca->apdakey_hi << 64);
|
||||||
|
upaca.apdbkey = paca->apdbkey_lo + ((__uint128_t)paca->apdbkey_hi << 64);
|
||||||
|
|
||||||
|
iov.iov_base = &upaca;
|
||||||
|
iov.iov_len = sizeof(upaca);
|
||||||
|
|
||||||
|
if ((ret = ptrace(PTRACE_SETREGSET, pid, NT_ARM_PACA_KEYS, &iov))) {
|
||||||
|
pr_perror("Failed to set address authentication keys for %d", pid);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
iov.iov_base = &pac_enabled_keys;
|
||||||
|
iov.iov_len = sizeof(pac_enabled_keys);
|
||||||
|
if ((ret = ptrace(PTRACE_SETREGSET, pid, NT_ARM_PAC_ENABLED_KEYS, &iov))) {
|
||||||
|
pr_perror("Failed to set enabled key mask for %d", pid);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rsti(item)->arch_info.has_pacg) {
|
||||||
|
if (!(hwcaps & HWCAP_PACG)) {
|
||||||
|
pr_err("PACG support is required from the source system.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
upacg.apgakey = pacg->apgakey_lo + ((__uint128_t)pacg->apgakey_hi << 64);
|
||||||
|
iov.iov_base = &upacg;
|
||||||
|
iov.iov_len = sizeof(upacg);
|
||||||
|
if ((ret = ptrace(PTRACE_SETREGSET, pid, NT_ARM_PACG_KEYS, &iov))) {
|
||||||
|
pr_perror("Failed to set the generic authentication key for %d", pid);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void arch_rsti_init(struct pstree_item *p)
|
||||||
|
{
|
||||||
|
PacKeys *pac_keys = p->core[0]->ti_aarch64->pac_keys;
|
||||||
|
|
||||||
|
rsti(p)->arch_info.has_paca = false;
|
||||||
|
rsti(p)->arch_info.has_pacg = false;
|
||||||
|
|
||||||
|
if (!pac_keys)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (pac_keys->pac_address_keys) {
|
||||||
|
rsti(p)->arch_info.has_paca = true;
|
||||||
|
rsti(p)->arch_info.pac_address_keys = *pac_keys->pac_address_keys;
|
||||||
|
}
|
||||||
|
if (pac_keys->pac_generic_keys) {
|
||||||
|
rsti(p)->arch_info.has_pacg = true;
|
||||||
|
rsti(p)->arch_info.pac_generic_keys = *pac_keys->pac_generic_keys;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef __CR_ASM_DUMP_H__
|
#ifndef __CR_ASM_DUMP_H__
|
||||||
#define __CR_ASM_DUMP_H__
|
#define __CR_ASM_DUMP_H__
|
||||||
|
|
||||||
extern int save_task_regs(void *, user_regs_struct_t *, user_fpregs_struct_t *);
|
extern int save_task_regs(pid_t pid, void *, user_regs_struct_t *, user_fpregs_struct_t *);
|
||||||
extern int arch_alloc_thread_info(CoreEntry *core);
|
extern int arch_alloc_thread_info(CoreEntry *core);
|
||||||
extern void arch_free_thread_info(CoreEntry *core);
|
extern void arch_free_thread_info(CoreEntry *core);
|
||||||
|
|
||||||
|
@ -26,4 +26,14 @@ static inline void core_get_tls(CoreEntry *pcore, tls_t *ptls)
|
|||||||
|
|
||||||
int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core);
|
int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core);
|
||||||
|
|
||||||
|
#define ARCH_RST_INFO y
|
||||||
|
struct rst_arch_info {
|
||||||
|
bool has_paca, has_pacg;
|
||||||
|
PacAddressKeys pac_address_keys;
|
||||||
|
PacGenericKeys pac_generic_keys;
|
||||||
|
};
|
||||||
|
|
||||||
|
int arch_ptrace_restore(int pid, struct pstree_item *item);
|
||||||
|
void arch_rsti_init(struct pstree_item *current);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#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)
|
int save_task_regs(pid_t pid, void *x, user_regs_struct_t *regs, user_fpregs_struct_t *fpregs)
|
||||||
{
|
{
|
||||||
CoreEntry *core = x;
|
CoreEntry *core = x;
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef __CR_ASM_DUMP_H__
|
#ifndef __CR_ASM_DUMP_H__
|
||||||
#define __CR_ASM_DUMP_H__
|
#define __CR_ASM_DUMP_H__
|
||||||
|
|
||||||
extern int save_task_regs(void *, user_regs_struct_t *, user_fpregs_struct_t *);
|
extern int save_task_regs(pid_t pid, void *, user_regs_struct_t *, user_fpregs_struct_t *);
|
||||||
extern int arch_alloc_thread_info(CoreEntry *core);
|
extern int arch_alloc_thread_info(CoreEntry *core);
|
||||||
extern void arch_free_thread_info(CoreEntry *core);
|
extern void arch_free_thread_info(CoreEntry *core);
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#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 *fpregs)
|
int save_task_regs(pid_t pid, void *x, user_regs_struct_t *regs, user_fpregs_struct_t *fpregs)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
CoreEntry *core = x;
|
CoreEntry *core = x;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef __CR_ASM_DUMP_H__
|
#ifndef __CR_ASM_DUMP_H__
|
||||||
#define __CR_ASM_DUMP_H__
|
#define __CR_ASM_DUMP_H__
|
||||||
|
|
||||||
extern int save_task_regs(void *, user_regs_struct_t *, user_fpregs_struct_t *);
|
extern int save_task_regs(pid_t pid, void *, user_regs_struct_t *, user_fpregs_struct_t *);
|
||||||
extern int arch_alloc_thread_info(CoreEntry *core);
|
extern int arch_alloc_thread_info(CoreEntry *core);
|
||||||
extern void arch_free_thread_info(CoreEntry *core);
|
extern void arch_free_thread_info(CoreEntry *core);
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
#include "images/core.pb-c.h"
|
#include "images/core.pb-c.h"
|
||||||
#include "images/creds.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)
|
int save_task_regs(pid_t pid, void *x, user_regs_struct_t *regs, user_fpregs_struct_t *fpregs)
|
||||||
{
|
{
|
||||||
CoreEntry *core = x;
|
CoreEntry *core = x;
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef __CR_ASM_DUMP_H__
|
#ifndef __CR_ASM_DUMP_H__
|
||||||
#define __CR_ASM_DUMP_H__
|
#define __CR_ASM_DUMP_H__
|
||||||
|
|
||||||
extern int save_task_regs(void *, user_regs_struct_t *, user_fpregs_struct_t *);
|
extern int save_task_regs(pid_t pid, void *, user_regs_struct_t *, user_fpregs_struct_t *);
|
||||||
extern int arch_alloc_thread_info(CoreEntry *core);
|
extern int arch_alloc_thread_info(CoreEntry *core);
|
||||||
extern void arch_free_thread_info(CoreEntry *core);
|
extern void arch_free_thread_info(CoreEntry *core);
|
||||||
extern int get_task_futex_robust_list_compat(pid_t pid, ThreadCoreEntry *info);
|
extern int get_task_futex_robust_list_compat(pid_t pid, ThreadCoreEntry *info);
|
||||||
|
@ -404,7 +404,7 @@ static int __copy_task_regs(user_regs_struct_t *regs, user_fpregs_struct_t *fpre
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int save_task_regs(void *arg, user_regs_struct_t *u, user_fpregs_struct_t *f)
|
int save_task_regs(pid_t pid, void *arg, user_regs_struct_t *u, user_fpregs_struct_t *f)
|
||||||
{
|
{
|
||||||
return __copy_task_regs(u, f, (CoreEntry *)arg);
|
return __copy_task_regs(u, f, (CoreEntry *)arg);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef __CR_ASM_DUMP_H__
|
#ifndef __CR_ASM_DUMP_H__
|
||||||
#define __CR_ASM_DUMP_H__
|
#define __CR_ASM_DUMP_H__
|
||||||
|
|
||||||
extern int save_task_regs(void *, user_regs_struct_t *, user_fpregs_struct_t *);
|
extern int save_task_regs(pid_t pid, void *, user_regs_struct_t *, user_fpregs_struct_t *);
|
||||||
extern int arch_alloc_thread_info(CoreEntry *core);
|
extern int arch_alloc_thread_info(CoreEntry *core);
|
||||||
extern void arch_free_thread_info(CoreEntry *core);
|
extern void arch_free_thread_info(CoreEntry *core);
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
#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)
|
int save_task_regs(pid_t pid, void *x, user_regs_struct_t *regs, user_fpregs_struct_t *fpsimd)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
CoreEntry *core = x;
|
CoreEntry *core = x;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef __CR_ASM_DUMP_H__
|
#ifndef __CR_ASM_DUMP_H__
|
||||||
#define __CR_ASM_DUMP_H__
|
#define __CR_ASM_DUMP_H__
|
||||||
|
|
||||||
extern int save_task_regs(void *, user_regs_struct_t *, user_fpregs_struct_t *);
|
extern int save_task_regs(pid_t pid, void *, user_regs_struct_t *, user_fpregs_struct_t *);
|
||||||
extern int arch_alloc_thread_info(CoreEntry *core);
|
extern int arch_alloc_thread_info(CoreEntry *core);
|
||||||
extern void arch_free_thread_info(CoreEntry *core);
|
extern void arch_free_thread_info(CoreEntry *core);
|
||||||
|
|
||||||
|
@ -282,7 +282,7 @@ static void free_ri_cb(UserS390RiEntry *ri_cb)
|
|||||||
/*
|
/*
|
||||||
* Copy internal structures into Google Protocol Buffers
|
* Copy internal structures into Google Protocol Buffers
|
||||||
*/
|
*/
|
||||||
int save_task_regs(void *arg, user_regs_struct_t *u, user_fpregs_struct_t *f)
|
int save_task_regs(pid_t pid, void *arg, user_regs_struct_t *u, user_fpregs_struct_t *f)
|
||||||
{
|
{
|
||||||
UserS390VxrsHighEntry *vxrs_high = NULL;
|
UserS390VxrsHighEntry *vxrs_high = NULL;
|
||||||
UserS390VxrsLowEntry *vxrs_low = NULL;
|
UserS390VxrsLowEntry *vxrs_low = NULL;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef __CR_ASM_DUMP_H__
|
#ifndef __CR_ASM_DUMP_H__
|
||||||
#define __CR_ASM_DUMP_H__
|
#define __CR_ASM_DUMP_H__
|
||||||
|
|
||||||
int save_task_regs(void *arg, user_regs_struct_t *u, user_fpregs_struct_t *f);
|
int save_task_regs(pid_t pid, void *arg, user_regs_struct_t *u, user_fpregs_struct_t *f);
|
||||||
int arch_alloc_thread_info(CoreEntry *core);
|
int arch_alloc_thread_info(CoreEntry *core);
|
||||||
void arch_free_thread_info(CoreEntry *core);
|
void arch_free_thread_info(CoreEntry *core);
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
#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)
|
int save_task_regs(pid_t pid, void *x, user_regs_struct_t *regs, user_fpregs_struct_t *fpregs)
|
||||||
{
|
{
|
||||||
CoreEntry *core = x;
|
CoreEntry *core = x;
|
||||||
UserX86RegsEntry *gpregs = core->thread_info->gpregs;
|
UserX86RegsEntry *gpregs = core->thread_info->gpregs;
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
static inline void *alloc_compat_syscall_stack(void)
|
static inline void *alloc_compat_syscall_stack(void)
|
||||||
{
|
{
|
||||||
void *mem = (void *)sys_mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_32BIT | MAP_ANONYMOUS | MAP_PRIVATE,
|
void *mem = (void *)sys_mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_32BIT | MAP_ANONYMOUS | MAP_PRIVATE,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef __CR_ASM_DUMP_H__
|
#ifndef __CR_ASM_DUMP_H__
|
||||||
#define __CR_ASM_DUMP_H__
|
#define __CR_ASM_DUMP_H__
|
||||||
|
|
||||||
extern int save_task_regs(void *, user_regs_struct_t *, user_fpregs_struct_t *);
|
extern int save_task_regs(pid_t pid, void *, user_regs_struct_t *, user_fpregs_struct_t *);
|
||||||
extern int arch_alloc_thread_info(CoreEntry *core);
|
extern int arch_alloc_thread_info(CoreEntry *core);
|
||||||
extern void arch_free_thread_info(CoreEntry *core);
|
extern void arch_free_thread_info(CoreEntry *core);
|
||||||
extern int get_task_futex_robust_list_compat(pid_t pid, ThreadCoreEntry *info);
|
extern int get_task_futex_robust_list_compat(pid_t pid, ThreadCoreEntry *info);
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
#include <sys/prctl.h>
|
#include <sys/prctl.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
|
#include <linux/elf.h>
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include <compel/ptrace.h>
|
#include <compel/ptrace.h>
|
||||||
@ -1707,6 +1708,9 @@ static int restore_task_with_children(void *_arg)
|
|||||||
arg);
|
arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int __attribute((weak)) arch_ptrace_restore(int pid, struct pstree_item *item);
|
||||||
|
int arch_ptrace_restore(int pid, struct pstree_item *item) { return 0; }
|
||||||
|
|
||||||
static int attach_to_tasks(bool root_seized)
|
static int attach_to_tasks(bool root_seized)
|
||||||
{
|
{
|
||||||
struct pstree_item *item;
|
struct pstree_item *item;
|
||||||
@ -1747,6 +1751,8 @@ static int attach_to_tasks(bool root_seized)
|
|||||||
pr_perror("Unable to set PTRACE_O_TRACESYSGOOD for %d", pid);
|
pr_perror("Unable to set PTRACE_O_TRACESYSGOOD for %d", pid);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (arch_ptrace_restore(pid, item))
|
||||||
|
return -1;
|
||||||
/*
|
/*
|
||||||
* Suspend seccomp if necessary. We need to do this because
|
* Suspend seccomp if necessary. We need to do this because
|
||||||
* although seccomp is restored at the very end of the
|
* although seccomp is restored at the very end of the
|
||||||
@ -3104,6 +3110,9 @@ static void *restorer_munmap_addr(CoreEntry *core, void *restorer_blob)
|
|||||||
return restorer_sym(restorer_blob, arch_export_unmap);
|
return restorer_sym(restorer_blob, arch_export_unmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void arch_rsti_init(struct pstree_item *p) __attribute__((weak));
|
||||||
|
void arch_rsti_init(struct pstree_item *p) {}
|
||||||
|
|
||||||
static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, unsigned long alen, CoreEntry *core)
|
static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, unsigned long alen, CoreEntry *core)
|
||||||
{
|
{
|
||||||
void *mem = MAP_FAILED;
|
void *mem = MAP_FAILED;
|
||||||
@ -3323,6 +3332,7 @@ static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, uns
|
|||||||
*/
|
*/
|
||||||
creds_pos_next = creds_pos;
|
creds_pos_next = creds_pos;
|
||||||
siginfo_n = task_args->siginfo_n;
|
siginfo_n = task_args->siginfo_n;
|
||||||
|
arch_rsti_init(current);
|
||||||
for (i = 0; i < current->nr_threads; i++) {
|
for (i = 0; i < current->nr_threads; i++) {
|
||||||
CoreEntry *tcore;
|
CoreEntry *tcore;
|
||||||
struct rt_sigframe *sigframe;
|
struct rt_sigframe *sigframe;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef __CR_RST_INFO_H__
|
#ifndef __CR_RST_INFO_H__
|
||||||
#define __CR_RST_INFO_H__
|
#define __CR_RST_INFO_H__
|
||||||
|
|
||||||
|
#include "asm/restore.h"
|
||||||
#include "common/lock.h"
|
#include "common/lock.h"
|
||||||
#include "common/list.h"
|
#include "common/list.h"
|
||||||
#include "vma.h"
|
#include "vma.h"
|
||||||
@ -33,6 +34,11 @@ struct rst_rseq {
|
|||||||
uint64_t rseq_cs_pointer;
|
uint64_t rseq_cs_pointer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef ARCH_RST_INFO
|
||||||
|
struct rst_arch_info {
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
struct rst_info {
|
struct rst_info {
|
||||||
struct list_head fds;
|
struct list_head fds;
|
||||||
|
|
||||||
@ -80,6 +86,8 @@ struct rst_info {
|
|||||||
futex_t shstk_unlock;
|
futex_t shstk_unlock;
|
||||||
|
|
||||||
void *breakpoint;
|
void *breakpoint;
|
||||||
|
|
||||||
|
struct rst_arch_info arch_info;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct task_entries *task_entries;
|
extern struct task_entries *task_entries;
|
||||||
|
@ -17,9 +17,32 @@ message user_aarch64_fpsimd_context_entry {
|
|||||||
required uint32 fpcr = 3;
|
required uint32 fpcr = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message pac_address_keys {
|
||||||
|
required uint64 apiakey_lo = 1;
|
||||||
|
required uint64 apiakey_hi = 2;
|
||||||
|
required uint64 apibkey_lo = 3;
|
||||||
|
required uint64 apibkey_hi = 4;
|
||||||
|
required uint64 apdakey_lo = 5;
|
||||||
|
required uint64 apdakey_hi = 6;
|
||||||
|
required uint64 apdbkey_lo = 7;
|
||||||
|
required uint64 apdbkey_hi = 8;
|
||||||
|
required uint64 pac_enabled_key = 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
message pac_generic_keys {
|
||||||
|
required uint64 apgakey_lo = 1;
|
||||||
|
required uint64 apgakey_hi = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message pac_keys {
|
||||||
|
optional pac_address_keys pac_address_keys = 6;
|
||||||
|
optional pac_generic_keys pac_generic_keys = 7;
|
||||||
|
}
|
||||||
|
|
||||||
message thread_info_aarch64 {
|
message thread_info_aarch64 {
|
||||||
required uint64 clear_tid_addr = 1[(criu).hex = true];
|
required uint64 clear_tid_addr = 1[(criu).hex = true];
|
||||||
required uint64 tls = 2;
|
required uint64 tls = 2;
|
||||||
required user_aarch64_regs_entry gpregs = 3[(criu).hex = true];
|
required user_aarch64_regs_entry gpregs = 3[(criu).hex = true];
|
||||||
required user_aarch64_fpsimd_context_entry fpsimd = 4;
|
required user_aarch64_fpsimd_context_entry fpsimd = 4;
|
||||||
|
optional pac_keys pac_keys = 5;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user