update
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define B23_BLOCK_SIZE 4096
|
||||
|
||||
static int
|
||||
parse_u64(const char *text, uint64_t *value)
|
||||
{
|
||||
char *end;
|
||||
uintmax_t parsed;
|
||||
|
||||
errno = 0;
|
||||
parsed = strtoumax(text, &end, 10);
|
||||
if (errno != 0 || end == text || *end != '\0' || parsed > INT64_MAX)
|
||||
return (-1);
|
||||
*value = (uint64_t)parsed;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
check_payload(const unsigned char *data)
|
||||
{
|
||||
size_t index;
|
||||
|
||||
for (index = 0; index < B23_BLOCK_SIZE; index++) {
|
||||
if (data[index] != (unsigned char)((index * 37 + 11) & 0xff))
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
check_pass(int argc, char **argv)
|
||||
{
|
||||
unsigned char data[B23_BLOCK_SIZE];
|
||||
struct stat status;
|
||||
uint64_t expected_size, offset;
|
||||
ssize_t count;
|
||||
int descriptor, index;
|
||||
|
||||
if (argc < 5 || parse_u64(argv[3], &expected_size) != 0)
|
||||
return (2);
|
||||
if (stat(argv[2], &status) != 0) {
|
||||
perror("stat positive explicit target");
|
||||
return (1);
|
||||
}
|
||||
if ((uint64_t)status.st_size != expected_size) {
|
||||
fprintf(stderr, "size mismatch: got=%jd expected=%" PRIu64 "\n",
|
||||
(intmax_t)status.st_size, expected_size);
|
||||
return (1);
|
||||
}
|
||||
descriptor = open(argv[2], O_RDONLY);
|
||||
if (descriptor < 0) {
|
||||
perror("open positive explicit target");
|
||||
return (1);
|
||||
}
|
||||
for (index = 4; index < argc; index++) {
|
||||
if (parse_u64(argv[index], &offset) != 0 ||
|
||||
offset > expected_size || B23_BLOCK_SIZE > expected_size - offset) {
|
||||
fprintf(stderr, "invalid probe offset: %s\n", argv[index]);
|
||||
close(descriptor);
|
||||
return (2);
|
||||
}
|
||||
count = pread(descriptor, data, sizeof(data), (off_t)offset);
|
||||
if (count != (ssize_t)sizeof(data) || check_payload(data) != 0) {
|
||||
fprintf(stderr, "mapped payload mismatch at offset=%" PRIu64
|
||||
" count=%zd errno=%d\n", offset, count, errno);
|
||||
close(descriptor);
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
if (close(descriptor) != 0) {
|
||||
perror("close positive explicit target");
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
check_errno(int argc, char **argv)
|
||||
{
|
||||
struct stat status;
|
||||
uint64_t expected;
|
||||
|
||||
if (argc != 4 || parse_u64(argv[3], &expected) != 0 || expected > INT_MAX)
|
||||
return (2);
|
||||
errno = 0;
|
||||
if (stat(argv[2], &status) == 0) {
|
||||
fprintf(stderr, "corrupt explicit target unexpectedly published\n");
|
||||
return (1);
|
||||
}
|
||||
if (errno != (int)expected) {
|
||||
fprintf(stderr, "errno mismatch: got=%d expected=%" PRIu64 "\n",
|
||||
errno, expected);
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
if (argc >= 2 && strcmp(argv[1], "pass") == 0)
|
||||
return (check_pass(argc, argv));
|
||||
if (argc >= 2 && strcmp(argv[1], "errno") == 0)
|
||||
return (check_errno(argc, argv));
|
||||
fprintf(stderr, "usage: %s pass PATH SIZE OFFSET... | errno PATH ERRNO\n",
|
||||
argv[0]);
|
||||
return (2);
|
||||
}
|
||||
Reference in New Issue
Block a user