diff --git a/cr-dump.c b/cr-dump.c index 86351e5c4..7a876f24a 100644 --- a/cr-dump.c +++ b/cr-dump.c @@ -471,6 +471,9 @@ static int dump_task_mm(pid_t pid, const struct proc_pid_stat *stat, mme.mm_brk = misc->brk; + mme.dumpable = misc->dumpable; + mme.has_dumpable = true; + mme.n_mm_saved_auxv = AT_VECTOR_SIZE; mme.mm_saved_auxv = xmalloc(pb_repeated_size(&mme, mm_saved_auxv)); if (!mme.mm_saved_auxv) diff --git a/include/parasite.h b/include/parasite.h index 502d57504..544a5a8ed 100644 --- a/include/parasite.h +++ b/include/parasite.h @@ -156,6 +156,8 @@ struct parasite_dump_misc { u32 umask; struct parasite_dump_thread ti; + + int dumpable; }; #define PARASITE_MAX_GROUPS (PAGE_SIZE / sizeof(unsigned int) - 2 * sizeof(unsigned)) diff --git a/include/prctl.h b/include/prctl.h index 2bf1a13c0..b815b96bb 100644 --- a/include/prctl.h +++ b/include/prctl.h @@ -16,6 +16,12 @@ #ifndef PR_SET_SECUREBITS # define PR_SET_SECUREBITS 28 #endif +#ifndef PR_GET_DUMPABLE +# define PR_GET_DUMPABLE 3 +#endif +#ifndef PR_SET_DUMPABLE +# define PR_SET_DUMPABLE 4 +#endif #ifndef PR_SET_MM #define PR_SET_MM 35 diff --git a/pie/parasite.c b/pie/parasite.c index 152186271..1a6f9838b 100644 --- a/pie/parasite.c +++ b/pie/parasite.c @@ -159,6 +159,7 @@ static int dump_misc(struct parasite_dump_misc *args) args->pgid = sys_getpgid(0); args->umask = sys_umask(0); sys_umask(args->umask); /* never fails */ + args->dumpable = sys_prctl(PR_GET_DUMPABLE, 0, 0, 0, 0); return dump_thread_common(&args->ti); } diff --git a/pie/restorer.c b/pie/restorer.c index f0a2d3e55..2cbc2fa9c 100644 --- a/pie/restorer.c +++ b/pie/restorer.c @@ -30,6 +30,7 @@ #include "restorer.h" #include "protobuf/creds.pb-c.h" +#include "protobuf/mm.pb-c.h" #include "asm/restorer.h" @@ -187,6 +188,21 @@ static int restore_creds(CredsEntry *ce) return 0; } +static int restore_dumpable_flag(MmEntry *mme) +{ + int ret; + + if (mme->has_dumpable) { + ret = sys_prctl(PR_SET_DUMPABLE, mme->dumpable, 0, 0, 0); + if (ret) { + pr_err("Unable to set PR_SET_DUMPABLE: %d\n", ret); + return -1; + } + } + + return 0; +} + static void restore_sched_info(struct rst_sched_param *p) { struct sched_param parm; @@ -295,6 +311,10 @@ long __export_restore_thread(struct thread_restore_args *args) if (ret) goto core_restore_end; + ret = restore_dumpable_flag(&args->ta->mm); + if (ret) + goto core_restore_end; + pr_info("%ld: Restored\n", sys_gettid()); restore_finish_stage(CR_STATE_RESTORE); @@ -918,6 +938,7 @@ long __export_restore_task(struct task_restore_args *args) */ ret = restore_creds(&args->creds); + ret = ret || restore_dumpable_flag(&args->mm); futex_set_and_wake(&thread_inprogress, args->nr_threads); diff --git a/protobuf/mm.proto b/protobuf/mm.proto index b809061af..1556b602d 100644 --- a/protobuf/mm.proto +++ b/protobuf/mm.proto @@ -17,4 +17,6 @@ message mm_entry { repeated uint64 mm_saved_auxv = 13; repeated vma_entry vmas = 14; + + optional int32 dumpable = 15; }