void check_ftruncate_fail(const char *filename, const int lineno, int fd, off_t length) { if (ftruncate(fd, length) >= 0) { tst_res_(filename, lineno, TFAIL, "ftruncate(%d, %ld) succeeded unexpectedly", fd, length); return; } tst_res_(filename, lineno, TPASS | TERRNO, "ftruncate(%d, %ld) failed as expected", fd, length); }
void check_mfd_non_growable_by_write(const char *filename, const int lineno, int fd) { char buf[MFD_DEF_SIZE * 8]; if (pwrite(fd, buf, sizeof(buf), 0) == sizeof(buf)) { tst_res_(filename, lineno, TFAIL, "pwrite(%d, %s, %zu, %d) didn't fail as expected", fd, buf, sizeof(buf), 0); return; } tst_res_(filename, lineno, TPASS, "pwrite(%d, %s, %zu, %d) succeeded", fd, buf, sizeof(buf), 0); }
void check_mmap_fail(const char *file, const int lineno, void *addr, size_t length, int prot, int flags, int fd, off_t offset) { if (mmap(addr, length, prot, flags, fd, offset) != MAP_FAILED) { safe_munmap(file, lineno, NULL, addr, length); tst_res_(file, lineno, TFAIL, "mmap(%p, %zu, %i, %i, %i, %li) succeeded unexpectedly", addr, length, prot, flags, fd, (long)offset); return; } tst_res_(file, lineno, TPASS | TERRNO, "mmap(%p, %zu, %i, %i, %i, %li) failed as expected", addr, length, prot, flags, fd, (long)offset); }
void check_ftruncate(const char *filename, const int lineno, int fd, off_t length) { safe_ftruncate(filename, lineno, fd, length); tst_res_(filename, lineno, TPASS, "ftruncate(%d, %ld) succeeded", fd, length); }
void check_mfd_growable_by_write(const char *filename, const int lineno, int fd) { char buf[MFD_DEF_SIZE * 8]; if (pwrite(fd, buf, sizeof(buf), 0) != sizeof(buf)) { tst_res_(filename, lineno, TFAIL | TERRNO, "pwrite(%d, %s, %zu, %d) failed", fd, buf, sizeof(buf), 0); return; } tst_res_(filename, lineno, TPASS, "pwrite(%d, %s, %zu, %d) succeeded", fd, buf, sizeof(buf), 0); check_mfd_size(filename, lineno, fd, MFD_DEF_SIZE * 8); }
void check_mfd_fail_open(const char *filename, const int lineno, int fd, int flags, mode_t mode) { char buf[512]; sprintf(buf, "/proc/self/fd/%d", fd); fd = open(buf, flags, mode); if (fd > 0) { safe_close(filename, lineno, NULL, fd); tst_res_(filename, lineno, TFAIL, "open(%s, %d, %d) succeeded unexpectedly", buf, flags, mode); } else { tst_res_(filename, lineno, TPASS | TERRNO, "open(%s, %d, %d) failed as expected", buf, flags, mode); } }
int check_fallocate_fail(const char *filename, const int lineno, int fd, int mode, off_t offset, off_t len) { int r; r = fallocate(fd, mode, offset, len); if (r >= 0) { tst_res_(filename, lineno, TFAIL, "fallocate(%d, %d, %ld, %ld) succeeded unexpectedly", fd, mode, offset, len); return r; } tst_res_(filename, lineno, TPASS | TERRNO, "fallocate(%d, %d, %ld, %ld) failed as expected", fd, mode, offset, len); return r; }
void check_mprotect(const char *file, const int lineno, void *addr, size_t length, int prot) { if (mprotect(addr, length, prot) < 0) { tst_brk_(file, lineno, TFAIL | TERRNO, "mprotect(%p, %zu, %d) failed", addr, length, prot); } tst_res_(file, lineno, TPASS, "mprotect(%p, %zu, %d) succeeded", addr, length, prot); }
void tst_resm_(const char *file, const int lineno, int ttype, const char *arg_fmt, ...) { char tmesg[USERMESG]; EXPAND_VAR_ARGS(tmesg, arg_fmt, USERMESG); if (tst_test) tst_res_(file, lineno, ttype, "%s", tmesg); else tst_res__(file, lineno, ttype, "%s", tmesg); }
void check_mfd_fail_add_seals(const char *filename, const int lineno, int fd, int seals) { if (fcntl(fd, F_ADD_SEALS, seals) >= 0) { tst_brk_(filename, lineno, TFAIL, "fcntl(%d, F_ADD_SEALS) succeeded unexpectedly", fd); } tst_res_(filename, lineno, TPASS | TERRNO, "fcntl(%d, F_ADD_SEALS, %d) failed as expected", (fd), (seals)); }
void check_mfd_has_seals(const char *file, const int lineno, int fd, int seals) { int ret = SAFE_FCNTL((fd), F_GET_SEALS); if (ret != seals) { tst_brk_(file, lineno, TFAIL, "fd %d doesn't have expected seals (%d expected %d)", fd, ret, seals); } tst_res_(file, lineno, TPASS, "fd %d has expected seals (%d)", fd, seals); }
void *check_mmap(const char *file, const int lineno, void *addr, size_t length, int prot, int flags, int fd, off_t offset) { void *p; p = safe_mmap(file, lineno, addr, length, prot, flags, fd, offset); tst_res_(file, lineno, TPASS, "mmap(%p, %zu, %i, %i, %i, %li) succeeded", addr, length, prot, flags, fd, (long)offset); return p; }
void check_mfd_size(const char *filename, const int lineno, int fd, size_t size) { struct stat st; safe_fstat(filename, lineno, fd, &st); if (st.st_size != (long)size) { tst_brk_(filename, lineno, TFAIL, "fstat(%d, &st): unexpected file size", fd); } tst_res_(filename, lineno, TPASS, "fstat(%d, &st): file size is correct", fd); }
int check_mfd_open(const char *filename, const int lineno, int fd, int flags, mode_t mode) { int r; char buf[512]; sprintf(buf, "/proc/self/fd/%d", fd); r = safe_open(filename, lineno, NULL, buf, flags, mode); tst_res_(filename, lineno, TPASS, "open(%s, %d, %d) succeeded", buf, flags, mode); return r; }
void check_mfd_fail_new(const char *filename, const int lineno, const char *name, int flags) { int fd; fd = sys_memfd_create(name, flags); if (fd >= 0) { safe_close(filename, lineno, NULL, fd); tst_brk_(filename, lineno, TFAIL, "memfd_create(%s, %d) succeeded unexpectedly", name, flags); } tst_res_(filename, lineno, TPASS | TERRNO, "memfd_create(%s, %d) failed as expected", name, flags); }
struct group *safe_getgrnam_fallback(const char *file, const int lineno, const char *name, const char *fallback) { struct group *rval; errno = 0; rval = getgrnam(name); if (rval == NULL) { tst_res_(file, lineno, TINFO, "getgrnam(%s) failed - try fallback %s", name, fallback); rval = safe_getgrnam(file, lineno, fallback); } return rval; }
int check_mfd_new(const char *filename, const int lineno, const char *name, loff_t sz, int flags) { int fd; fd = sys_memfd_create(name, flags); if (fd < 0) { tst_brk_(filename, lineno, TBROK | TERRNO, "memfd_create(%s, %d) failed", name, flags); } tst_res_(filename, lineno, TPASS, "memfd_create(%s, %d) succeeded", name, flags); check_ftruncate(filename, lineno, fd, sz); return fd; }
int check_fallocate(const char *filename, const int lineno, int fd, int mode, off_t offset, off_t len) { int r; r = fallocate(fd, mode, offset, len); if (r < 0) { tst_brk_(filename, lineno, TFAIL | TERRNO, "fallocate(%d, %d, %ld, %ld) failed", fd, mode, offset, len); } tst_res_(filename, lineno, TPASS, "fallocate(%d, %d, %ld, %ld) succeeded", fd, mode, offset, len); return r; }
void check_mfd_non_writeable(const char *filename, const int lineno, int fd) { void *p; /* verify write() fails */ TEST(write(fd, "data", 4)); if (TEST_RETURN < 0) { if (TEST_ERRNO != EPERM) { tst_brk_(filename, lineno, TFAIL | TTERRNO, "write() didn't fail as expected"); } } else { tst_brk_(filename, lineno, TFAIL, "write() succeeded unexpectedly"); } tst_res_(filename, lineno, TPASS | TTERRNO, "write failed as expected"); /* verify PROT_READ | PROT_WRITE is not allowed */ check_mmap_fail(filename, lineno, NULL, MFD_DEF_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); /* verify PROT_WRITE is not allowed */ check_mmap_fail(filename, lineno, NULL, MFD_DEF_SIZE, PROT_WRITE, MAP_SHARED, fd, 0); /* Verify PROT_READ with MAP_SHARED with a following mprotect is not * allowed. Note that for r/w the kernel already prevents the mmap. */ p = mmap(NULL, MFD_DEF_SIZE, PROT_READ, MAP_SHARED, fd, 0); if (p != MAP_FAILED) { if (mprotect(p, MFD_DEF_SIZE, PROT_READ | PROT_WRITE) >= 0) { tst_brk_(filename, lineno, TFAIL | TERRNO, "mmap()+mprotect() succeeded unexpectedly"); } } /* verify PUNCH_HOLE fails */ check_fallocate_fail(filename, lineno, fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, 0, MFD_DEF_SIZE); }
void check_mfd_readable(const char *filename, const int lineno, int fd) { char buf[16]; void *p; safe_read(filename, lineno, NULL, 1, fd, buf, sizeof(buf)); tst_res_(filename, lineno, TPASS, "read(%d, %s, %zu) succeeded", fd, buf, sizeof(buf)); /* verify PROT_READ *is* allowed */ p = check_mmap(filename, lineno, NULL, MFD_DEF_SIZE, PROT_READ, MAP_PRIVATE, fd, 0); check_munmap(filename, lineno, p, MFD_DEF_SIZE); /* verify MAP_PRIVATE is *always* allowed (even writable) */ p = check_mmap(filename, lineno, NULL, MFD_DEF_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); check_munmap(filename, lineno, p, MFD_DEF_SIZE); }
void check_mfd_writeable(const char *filename, const int lineno, int fd) { void *p; /* verify write() succeeds */ safe_write(filename, lineno, NULL, 1, fd, "\0\0\0\0", 4); tst_res_(filename, lineno, TPASS, "write(%d, %s, %d) succeeded", fd, "\\0\\0\\0\\0", 4); /* verify PROT_READ | PROT_WRITE is allowed */ p = check_mmap(filename, lineno, NULL, MFD_DEF_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); *(char *)p = 0; check_munmap(filename, lineno, p, MFD_DEF_SIZE); /* verify PROT_WRITE is allowed */ p = check_mmap(filename, lineno, NULL, MFD_DEF_SIZE, PROT_WRITE, MAP_SHARED, fd, 0); *(char *)p = 0; check_munmap(filename, lineno, p, MFD_DEF_SIZE); /* verify PROT_READ with MAP_SHARED is allowed and a following * mprotect(PROT_WRITE) allows writing */ p = check_mmap(filename, lineno, NULL, MFD_DEF_SIZE, PROT_READ, MAP_SHARED, fd, 0); check_mprotect(filename, lineno, p, MFD_DEF_SIZE, PROT_READ | PROT_WRITE); *(char *)p = 0; check_munmap(filename, lineno, p, MFD_DEF_SIZE); /* verify PUNCH_HOLE works */ check_fallocate(filename, lineno, fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, 0, MFD_DEF_SIZE); }
static void print_result(const char *file, const int lineno, int ttype, const char *fmt, va_list va) { char buf[1024]; char *str = buf; int ret, size = sizeof(buf), ssize; const char *str_errno = NULL; const char *res; switch (TTYPE_RESULT(ttype)) { case TPASS: res = "PASS"; break; case TFAIL: res = "FAIL"; break; case TBROK: res = "BROK"; break; case TCONF: res = "CONF"; break; case TWARN: res = "WARN"; break; case TINFO: res = "INFO"; break; default: tst_brk(TBROK, "Invalid ttype value %i", ttype); abort(); } if (ttype & TERRNO) str_errno = tst_strerrno(errno); if (ttype & TTERRNO) str_errno = tst_strerrno(TEST_ERRNO); ret = snprintf(str, size, "%s:%i: ", file, lineno); str += ret; size -= ret; if (tst_color_enabled(STDERR_FILENO)) ret = snprintf(str, size, "%s%s: %s", tst_ttype2color(ttype), res, ANSI_COLOR_RESET); else ret = snprintf(str, size, "%s: ", res); str += ret; size -= ret; ssize = size - 2; ret = vsnprintf(str, size, fmt, va); str += MIN(ret, ssize); size -= MIN(ret, ssize); if (ret >= ssize) { tst_res_(file, lineno, TWARN, "Next message is too long and truncated:"); } else if (str_errno) { ssize = size - 2; ret = snprintf(str, size, ": %s", str_errno); str += MIN(ret, ssize); size -= MIN(ret, ssize); if (ret >= ssize) tst_res_(file, lineno, TWARN, "Next message is too long and truncated:"); } snprintf(str, size, "\n"); fputs(buf, stderr); }
void check_munmap(const char *file, const int lineno, void *p, size_t length) { safe_munmap(file, lineno, NULL, p, length); tst_res_(file, lineno, TPASS, "munmap(%p, %zu) succeeded", p, length); }