Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix migration of fds to ELF files #2283

Merged
merged 3 commits into from
Oct 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 15 additions & 18 deletions criu/files-reg.c
Original file line number Diff line number Diff line change
Expand Up @@ -1650,39 +1650,36 @@ static int get_build_id_64(Elf64_Ehdr *file_header, unsigned char **build_id, co
*/
static int get_build_id(const int fd, const struct stat *fd_status, unsigned char **build_id)
{
char buf[SELFMAG + 1];
void *start_addr;
char *start_addr;
size_t mapped_size;
int ret = -1;

if (read(fd, buf, SELFMAG + 1) != SELFMAG + 1)
return -1;

/*
* The first 4 bytes contain a magic number identifying the file as an
* ELF file. They should contain the characters ‘\x7f’, ‘E’, ‘L’, and
* ‘F’, respectively. These characters are together defined as ELFMAG.
*/
if (strncmp(buf, ELFMAG, SELFMAG))
return -1;

/*
* If the build-id exists, then it will most likely be present in the
* beginning of the file. Therefore at most only the first 1 MB of the
* file is mapped.
*/
mapped_size = min_t(size_t, fd_status->st_size, BUILD_ID_MAP_SIZE);
start_addr = mmap(0, mapped_size, PROT_READ, MAP_PRIVATE | MAP_FILE, fd, 0);
if (start_addr == MAP_FAILED) {
if ((void*)start_addr == MAP_FAILED) {
pr_warn("Couldn't mmap file with fd %d\n", fd);
return -1;
}

if (buf[EI_CLASS] == ELFCLASS32)
ret = get_build_id_32(start_addr, build_id, fd, mapped_size);
if (buf[EI_CLASS] == ELFCLASS64)
ret = get_build_id_64(start_addr, build_id, fd, mapped_size);
/*
* The first 4 bytes contain a magic number identifying the file as an
* ELF file. They should contain the characters ‘\x7f’, ‘E’, ‘L’, and
* ‘F’, respectively. These characters are together defined as ELFMAG.
*/
if (memcmp(start_addr, ELFMAG, SELFMAG))
goto out;

if (start_addr[EI_CLASS] == ELFCLASS32)
ret = get_build_id_32((Elf32_Ehdr *)start_addr, build_id, fd, mapped_size);
if (start_addr[EI_CLASS] == ELFCLASS64)
ret = get_build_id_64((Elf64_Ehdr *)start_addr, build_id, fd, mapped_size);

out:
munmap(start_addr, mapped_size);
return ret;
}
Expand Down
1 change: 1 addition & 0 deletions test/zdtm/lib/lock.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <sys/time.h>
#include <limits.h>
#include <errno.h>
#include <signal.h>
#include "asm/atomic.h"

#define BUG_ON(condition) \
Expand Down
1 change: 1 addition & 0 deletions test/zdtm/static/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ TST_NOFILE := \
sigtrap \
sigtrap01 \
change_mnt_context \
fd_offset \
# jobctl00 \

PKG_CONFIG ?= pkg-config
Expand Down
42 changes: 42 additions & 0 deletions test/zdtm/static/fd_offset.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#include <fcntl.h>

#include "zdtmtst.h"
#include "lock.h"

const char *test_doc = "Check that criu properly restores offsets on ELF files";
const char *test_author = "Michal Clapinski <[email protected]>";

void check_offset(int fd)
{
int offset = lseek(fd, 0, SEEK_CUR);
if (offset < 0) {
fail("lseek");
exit(1);
}
if (offset != 0) {
fail("wrong offset; expected: 0, got: %d", offset);
exit(1);
}
}

int main(int argc, char **argv)
{
int fd;

test_init(argc, argv);

fd = open("/proc/self/exe", O_RDONLY);
if (fd < 0) {
fail("open");
exit(1);
}
check_offset(fd);

test_daemon();
test_waitsig();

check_offset(fd);

pass();
return 0;
}