Skip to content
Snippets Groups Projects
Commit 9c8dc218 authored by Luis Gerhorst's avatar Luis Gerhorst
Browse files

task-find-magic: read stdin

parent 8cf747ec
No related branches found
No related tags found
No related merge requests found
...@@ -9,7 +9,7 @@ INCLUDES := -I$(OUTPUT) -idirafter $(abspath ../libbpf/include) ...@@ -9,7 +9,7 @@ INCLUDES := -I$(OUTPUT) -idirafter $(abspath ../libbpf/include)
CFLAGS := -g -Wall CFLAGS := -g -Wall
ARCH := $(shell uname -m | sed 's/x86_64/x86/') ARCH := $(shell uname -m | sed 's/x86_64/x86/')
APPS = minimal bootstrap uprobe task task_bulk task_mmap task_sleep task_bulk_minimal task_ag task_find task_find_magic APPS = minimal bootstrap uprobe task task_bulk task_mmap task_sleep task_bulk_minimal task_ag task_find task_filter_magic
# Get Clang's default includes on this system. We'll explicitly add these dirs # Get Clang's default includes on this system. We'll explicitly add these dirs
# to the includes list when compiling with `-target bpf` because otherwise some # to the includes list when compiling with `-target bpf` because otherwise some
......
#!/usr/bin/env bash
set -euo pipefail
path=$1
args=${@:2}
src_dir=$(dirname "$(command -v $0)")
find "${path}" | env -C "$src_dir" ./task_filter_magic ${args}
File moved
...@@ -19,11 +19,11 @@ ...@@ -19,11 +19,11 @@
#include <sys/resource.h> #include <sys/resource.h>
#include <bpf/libbpf.h> #include <bpf/libbpf.h>
#define NAME task_find_magic #define NAME task_filter_magic
#define NAME_BPF task_find_magic_bpf #define NAME_BPF task_filter_magic_bpf
#define BPF_OPEN task_find_magic_bpf__open #define BPF_OPEN task_filter_magic_bpf__open
#define BPF_LOAD task_find_magic_bpf__load #define BPF_LOAD task_filter_magic_bpf__load
#define BPF_DESTROY task_find_magic_bpf__destroy #define BPF_DESTROY task_filter_magic_bpf__destroy
/* https://stackoverflow.com/questions/5873722/c-macro-dynamic-include */ /* https://stackoverflow.com/questions/5873722/c-macro-dynamic-include */
#define __header(x) #x #define __header(x) #x
...@@ -144,18 +144,8 @@ static void plog(const unsigned int level, const char *fmt, ...) { ...@@ -144,18 +144,8 @@ static void plog(const unsigned int level, const char *fmt, ...) {
va_end(args); va_end(args);
} }
static int search_buf_user(const char *buf, size_t f_len, const char *file_full_path,
const char *literal) {
size_t literal_len = strlen(literal);
for (int i = 0; i < f_len - literal_len + 1; i++) {
if (!memcmp(buf + i, literal, literal_len))
printf("%d\n", i);
}
return EXIT_SUCCESS;
}
static int search_buf_bpf(const char *buf, size_t f_len, const char *file_full_path, static int search_buf_bpf(const char *buf, size_t f_len, const char *file_full_path,
const char *literal) { const char *magic) {
struct NAME_BPF *skel; struct NAME_BPF *skel;
int err; int err;
...@@ -191,118 +181,60 @@ destroy: ...@@ -191,118 +181,60 @@ destroy:
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
static int search_buf(const char *buf, size_t f_len, const char *file_full_path, static char *safe_fgets(char *s, int size, FILE *stream) {
const char *literal, bool variant_bpf) { char *res = fgets(s, size, stream);
if (variant_bpf) { if (res == NULL && ferror(stream)) {
return search_buf_bpf(buf, f_len, file_full_path, literal); perror("fgets");
} else { exit(EXIT_FAILURE);
return search_buf_user(buf, f_len, file_full_path, literal);
}
} }
return res;
static int search_file(const char *file_full_path, const char *literal, bool variant_bpf) {
int err = EXIT_SUCCESS;
int fd = -1;
off_t f_len = 0;
char *buf = NULL;
struct stat statbuf;
int rv = 0;
int matches_count = -1;
FILE *fp = NULL;
rv = stat(file_full_path, &statbuf);
if (rv != 0) {
log_err("Skipping %s: Error fstat()ing file.", file_full_path);
err = EXIT_FAILURE;
goto cleanup;
} }
// handling only regular files and FIFOs #define MAX_PATHLEN 512
if (!S_ISREG(statbuf.st_mode) && !S_ISFIFO(statbuf.st_mode)) {
log_err("Skipping %s: Mode %u is not a file.", file_full_path, statbuf.st_mode);
err = EXIT_FAILURE;
goto cleanup;
}
fd = open(file_full_path, O_RDONLY); static int filter_magic(size_t offset, const char *magic) {
if (fd < 0) { while (true) {
/* XXXX: strerror is not thread-safe */ char pathbuf[MAX_PATHLEN];
log_err("Skipping %s: Error opening file: %s", file_full_path, strerror(errno)); char *ptr = fgets(pathbuf, MAX_PATHLEN, stdin);
err = EXIT_FAILURE; if (ptr == NULL) {
goto cleanup; if (ferror(stdin)) {
} log_err("fgets(stdin) failed");
return EXIT_FAILURE;
// repeating stat check with file handle to prevent TOCTOU issue } else {
rv = fstat(fd, &statbuf); log_debug("EOF reached");
if (rv != 0) { return EXIT_SUCCESS;
log_err("Skipping %s: Error fstat()ing file.", file_full_path);
err = EXIT_FAILURE;
goto cleanup;
}
// handling only regular files and FIFOs
if (!S_ISREG(statbuf.st_mode) && !S_ISFIFO(statbuf.st_mode)) {
log_err("Skipping %s: Mode %u is not a file.", file_full_path, statbuf.st_mode);
err = EXIT_FAILURE;
goto cleanup;
}
if (statbuf.st_mode & S_IFIFO) {
log_debug("%s is a named pipe. stream searching", file_full_path);
err = EXIT_FAILURE;
goto cleanup;
} }
f_len = statbuf.st_size;
buf = mmap(0, f_len, PROT_READ, MAP_PRIVATE, fd, 0);
if (buf == MAP_FAILED) {
log_err("File %s failed to load: %s.", file_full_path, strerror(errno));
err = EXIT_FAILURE;
goto cleanup;
} }
#if HAVE_MADVISE
madvise(buf, f_len, MADV_SEQUENTIAL);
#elif HAVE_POSIX_FADVISE
posix_fadvise(fd, 0, f_len, POSIX_MADV_SEQUENTIAL);
#endif
search_buf(buf, f_len, file_full_path, literal, variant_bpf); pathbuf[strlen(pathbuf)] = '\0';
cleanup: log_debug("pathbuf = %s", pathbuf);
if (buf != NULL) {
if (buf != MAP_FAILED) {
munmap(buf, f_len);
}
} }
if (fd != -1) {
close(fd);
}
return err;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
bool variant_bpf = true;
bool fixed_strings = false; /* literal */
bool debug = false; bool debug = false;
char *literal; bool variant_bpf = true;
char *path; size_t offset = 0;
char *magic;
int c; int c;
opterr = 0; opterr = 0;
while ((c = getopt(argc, argv, "v:" "F" "D")) != -1) { while ((c = getopt(argc, argv, "v:" "D" "o:" "m:")) != -1) {
switch (c) { switch (c) {
case 'v': case 'v':
variant_bpf = strcmp("bpf", optarg) == 0; variant_bpf = strcmp("bpf", optarg) == 0;
break; break;
case 'F':
fixed_strings = true;
break;
case 'D': case 'D':
debug = true; debug = true;
break; break;
case 'o':
offset = atoi(optarg);
break;
case 'm':
magic = optarg;
break;
case '?': case '?':
if (optopt == 'v') { if (optopt == 'v') {
fprintf(stderr, "Option -%c requires an argument.\n", optopt); fprintf(stderr, "Option -%c requires an argument.\n", optopt);
...@@ -317,19 +249,17 @@ int main(int argc, char **argv) ...@@ -317,19 +249,17 @@ int main(int argc, char **argv)
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} }
if (optind != argc - 2 || !fixed_strings) { if (optind != argc) {
print_usage(argv); print_usage(argv);
return EXIT_FAILURE; return EXIT_FAILURE;
} else {
literal = argv[optind];
path = argv[optind+1];
} }
if (debug) { if (debug) {
set_log_level(LOG_LEVEL_DEBUG); set_log_level(LOG_LEVEL_DEBUG);
fprintf(stderr, "%s: variant_bpf=%d, fixed_strings=%d, debug=%d, literal='%s', path='%s'\n", fprintf(stderr, "%s: variant_bpf=%d, debug=%d, magic='%s', offset='%llu'\n",
argv[0], variant_bpf, fixed_strings, debug, literal, path); argv[0], variant_bpf, debug, magic, offset);
} }
return search_file(path, literal, variant_bpf);
filter_magic(offset, magic);
} }
File moved
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment