Skip to content

Commit 5f7416d

Browse files
committed
Fix /proc/<pid>/cmdline and environ
When the addresses set by PR_SET_MM_ARG_START|END and PR_SET_MM_ENV_START|END are mapped to a file (which is the case after mmaping the image into memory) the proc filesystem won't print cmdline and environ correctly.
1 parent daeef8f commit 5f7416d

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

criu/pie/restorer.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1435,6 +1435,26 @@ static ssize_t mmap_image(int fd, const struct iovec *iov, int iovcnt,
14351435
return mmaped;
14361436
}
14371437

1438+
static void anonymize_range(const char *name, unsigned long start, unsigned long end, bool executable) {
1439+
unsigned long anon;
1440+
size_t size;
1441+
size = end - start + (start & (PAGE_SIZE - 1));
1442+
size = ((size - 1) & PAGE_MASK) + PAGE_SIZE;
1443+
anon = sys_mmap(NULL, size, PROT_READ | PROT_WRITE | (executable ? PROT_EXEC : 0),
1444+
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
1445+
if (IS_ERR((void *) anon)) {
1446+
pr_err("sys_mmap(%s) failed with %d\n", name, -(int) anon);
1447+
} else {
1448+
unsigned long target, to;
1449+
target = start & PAGE_MASK;
1450+
memcpy((void *) anon, (void *) target, size);
1451+
to = sys_mremap(anon, size, size, MREMAP_MAYMOVE | MREMAP_FIXED, target);
1452+
if (to != target) {
1453+
pr_err("sys_mremap(%s) failed with %d\n", name, -(int) to);
1454+
}
1455+
}
1456+
}
1457+
14381458
/*
14391459
* The main routine to restore task via sigreturn.
14401460
* This one is very special, we never return there
@@ -1812,6 +1832,18 @@ long __export_restore_task(struct task_restore_args *args)
18121832
if (ret)
18131833
goto core_restore_end;
18141834

1835+
/*
1836+
* When args and env are mmapped from a file, /proc/<pid>/cmdline and /proc/<pid>/environ
1837+
* will be empty. Therefore we have to mmap+memcpy+mremap
1838+
*/
1839+
if (args->mmap_page_image && args->mm.mm_arg_start != args->mm.mm_arg_end) {
1840+
anonymize_range("args", args->mm.mm_arg_start, args->mm.mm_arg_end, false);
1841+
}
1842+
/* We might be anonymizing the pages twice but this is simple enough */
1843+
if (args->mmap_page_image && args->mm.mm_env_start != args->mm.mm_env_end) {
1844+
anonymize_range("env", args->mm.mm_env_start, args->mm.mm_env_end, false);
1845+
}
1846+
18151847
/* SELinux (1) process context needs to be set before creating threads. */
18161848
if (args->lsm_type == LSMTYPE__SELINUX) {
18171849
/* Only for SELinux */

include/common/arch/aarch64/asm/page.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ static inline unsigned page_shift(void)
3030
* page_size() across sources (as it may differ on aarch64).
3131
*/
3232
#define PAGE_SIZE page_size()
33-
#define PAGE_MASK (~(PAGE_SIZE - 1))
3433
#define PAGE_SHIFT page_shift()
3534

3635
#define PAGE_PFN(addr) ((addr) / PAGE_SIZE)
@@ -41,4 +40,7 @@ extern unsigned page_size(void);
4140
#define PAGE_SIZE page_size()
4241

4342
#endif /* CR_NOGLIBC */
43+
44+
#define PAGE_MASK (~(PAGE_SIZE - 1))
45+
4446
#endif /* __CR_ASM_PAGE_H__ */

0 commit comments

Comments
 (0)