mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-07-17 16:47:50 +00:00
zdtm: check reservation mmaps are restored correctly
mmaps done just for reserving address space something like void *addr = mmap(NULL, SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); Ensure that these do not have ac flag set in /proc/pid/smaps. Signed-off-by: Bhavik Sachdev <b.sachdev1904@gmail.com>
This commit is contained in:
parent
7daaa11aa0
commit
b0b89a94f3
4 changed files with 136 additions and 1 deletions
|
|
@ -215,6 +215,7 @@ TST_NOFILE := \
|
|||
dumpable02 \
|
||||
remap_dead_pid \
|
||||
remap_dead_pid_root \
|
||||
reservation_mmaps \
|
||||
scm00 \
|
||||
scm01 \
|
||||
scm02 \
|
||||
|
|
@ -663,6 +664,7 @@ mntns_root_bind02: CFLAGS += -DROOT_BIND02
|
|||
maps02: get_smaps_bits.o
|
||||
mlock_setuid: get_smaps_bits.o
|
||||
thp_disable: get_smaps_bits.o
|
||||
reservation_mmaps: get_smaps_bits.o
|
||||
inotify01: CFLAGS += -DINOTIFY01
|
||||
unlink_fstat01+: CFLAGS += -DUNLINK_OVER
|
||||
unlink_fstat04: CFLAGS += -DUNLINK_FSTAT04
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ static void parse_vmflags(char *buf, unsigned long *flags, unsigned long *madv)
|
|||
|
||||
#define is_hex_digit(c) (((c) >= '0' && (c) <= '9') || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F'))
|
||||
|
||||
static int is_vma_range_fmt(char *line, unsigned long *start, unsigned long *end)
|
||||
int is_vma_range_fmt(char *line, unsigned long *start, unsigned long *end)
|
||||
{
|
||||
char *p = line;
|
||||
while (*line && is_hex_digit(*line))
|
||||
|
|
|
|||
|
|
@ -2,5 +2,6 @@
|
|||
#define ZDTM_GET_SMAPS_BITS_H_
|
||||
|
||||
extern int get_smaps_bits(unsigned long where, unsigned long *flags, unsigned long *madv);
|
||||
extern int is_vma_range_fmt(char *line, unsigned long *start, unsigned long *end);
|
||||
|
||||
#endif /* ZDTM_GET_SMAPS_BITS_H_ */
|
||||
|
|
|
|||
132
test/zdtm/static/reservation_mmaps.c
Normal file
132
test/zdtm/static/reservation_mmaps.c
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
#include <sys/mman.h>
|
||||
|
||||
#include "zdtmtst.h"
|
||||
#include "get_smaps_bits.h"
|
||||
|
||||
#define SIZE (4UL * (1UL << 20)) /* 4MB */
|
||||
|
||||
const char *test_doc = "Check mmaps done for reserving virtual address space, do not have ac flag set in /proc/pid/smaps\n";
|
||||
const char *test_author = "Bhavik Sachdev <b.sachdev1904@gmail.com>";
|
||||
|
||||
static void check_ac_flag(char *buf, bool *no_ac)
|
||||
{
|
||||
char *tok;
|
||||
|
||||
if (!buf[0])
|
||||
return;
|
||||
|
||||
*no_ac = true;
|
||||
tok = strtok(buf, " \n");
|
||||
if (!tok)
|
||||
return;
|
||||
|
||||
#define _vmflag_match(_t, _s) (_t[0] == _s[0] && _t[1] == _s[1])
|
||||
|
||||
do {
|
||||
if (_vmflag_match(tok, "ac")) {
|
||||
*no_ac = false;
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Anything else is just ignored.
|
||||
*/
|
||||
} while ((tok = strtok(NULL, " \n")));
|
||||
|
||||
#undef _vmflag_match
|
||||
return;
|
||||
}
|
||||
|
||||
static int is_accountable(unsigned long where, bool *no_ac)
|
||||
{
|
||||
unsigned long start = 0, end = 0;
|
||||
FILE *smaps = NULL;
|
||||
char buf[1024];
|
||||
int found = 0;
|
||||
|
||||
if (!where)
|
||||
return 0;
|
||||
|
||||
smaps = fopen("/proc/self/smaps", "r");
|
||||
if (!smaps) {
|
||||
pr_perror("Can't open smaps");
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (fgets(buf, sizeof(buf), smaps)) {
|
||||
is_vma_range_fmt(buf, &start, &end);
|
||||
|
||||
if (!strncmp(buf, "VmFlags: ", 9) && start <= where && where < end) {
|
||||
found = 1;
|
||||
check_ac_flag(buf, no_ac);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(smaps);
|
||||
|
||||
if (!found) {
|
||||
pr_perror("VmFlags not found for %lx", where);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
uint32_t crc = ~0;
|
||||
uint8_t *data_mmap, *reservation_mmap;
|
||||
bool no_ac;
|
||||
|
||||
test_init(argc, argv);
|
||||
data_mmap = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
|
||||
if (data_mmap == MAP_FAILED) {
|
||||
pr_perror("Failed to mmap %lu Mb memory", SIZE >> 20);
|
||||
return 1;
|
||||
}
|
||||
|
||||
reservation_mmap = mmap(NULL, SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
|
||||
if (reservation_mmap == MAP_FAILED) {
|
||||
pr_perror("Failed to mmap %lu Mb memory", SIZE >> 20);
|
||||
return 1;
|
||||
}
|
||||
|
||||
datagen(data_mmap, SIZE, &crc);
|
||||
|
||||
if (mprotect(data_mmap, SIZE, PROT_NONE)) {
|
||||
pr_perror("Failed to set protections on %p", data_mmap);
|
||||
return 1;
|
||||
}
|
||||
|
||||
test_daemon();
|
||||
test_waitsig();
|
||||
|
||||
/*
|
||||
* check that a mmap whose memory protection got changed
|
||||
* to PROT_NONE still has the data stored in it.
|
||||
*/
|
||||
if (mprotect(data_mmap, SIZE, PROT_READ)) {
|
||||
pr_perror("Failed to set protections on %p", data_mmap);
|
||||
return 1;
|
||||
}
|
||||
|
||||
crc = ~0;
|
||||
if (datachk(data_mmap, SIZE, &crc)) {
|
||||
fail("Data mismatch");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* reservation_mmap should not have ac flag set in /proc/pid/smaps */
|
||||
if (is_accountable((unsigned long)reservation_mmap, &no_ac)) {
|
||||
fail("could not check for no ac flag on reservation mmap");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!no_ac) {
|
||||
fail("reservation mmap has ac flag set");
|
||||
return 1;
|
||||
}
|
||||
|
||||
pass();
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue