diff --git a/src/cli/fapolicyd-cli.c b/src/cli/fapolicyd-cli.c index fc32104a..009034db 100644 --- a/src/cli/fapolicyd-cli.c +++ b/src/cli/fapolicyd-cli.c @@ -603,10 +603,14 @@ static int check_watch_fs(void) return 1; } + fd_fgets_context_t *fd_fgets_context = fd_fgets_init(); + if (!fd_fgets_context) + return 1; + // Build the list of mount point types list_init(&mnt); do { - if (fd_fgets(buf, sizeof(buf), fd)) { + if (fd_fgets(fd_fgets_context, buf, sizeof(buf), fd)) { sscanf(buf, "%1024s %4096s %31s %127s %d %d\n", device,point, type, mntops, &fs_req, &fs_passno); // Some file systems are not watchable @@ -614,9 +618,11 @@ static int check_watch_fs(void) continue; list_append(&mnt, strdup(type), strdup("0")); } - } while (!fd_fgets_eof()); + } while (!fd_fgets_eof(fd_fgets_context)); + fd_fgets_destroy(fd_fgets_context); close(fd); + // Now search the list we just built for (list_item_t *lptr = mnt.first; lptr; lptr = lptr->next) { // See if the file system is watched @@ -806,13 +812,18 @@ static int check_path(void) static int do_status_report(void) { const char *reason = "no pid file"; + + fd_fgets_context_t *fd_fgets_context = fd_fgets_init(); + if (!fd_fgets_context) + return 1; + // open pid file int pidfd = open(pidfile, O_RDONLY); if (pidfd >= 0) { char pid_buf[16]; // read contents - if (fd_fgets(pid_buf, sizeof(pid_buf), pidfd)) { + if (fd_fgets(fd_fgets_context, pid_buf, sizeof(pid_buf), pidfd)) { int rpt_fd; unsigned int pid, tries = 0; char exe_buf[64]; @@ -862,11 +873,12 @@ static int do_status_report(void) goto err_out; } } + fd_fgets_rewind(fd_fgets_context); do { char buf[80]; - if (fd_fgets(buf, sizeof(buf), rpt_fd)) + if (fd_fgets(fd_fgets_context, buf, sizeof(buf), rpt_fd)) write(1, buf, strlen(buf)); - } while (!fd_fgets_eof()); + } while (!fd_fgets_eof(fd_fgets_context)); close(rpt_fd); } else reason = "can't read pid file"; @@ -874,10 +886,11 @@ static int do_status_report(void) return 0; } err_out: - if (pidfd >= 0) - close(pidfd); - printf("Can't find fapolicyd: %s\n", reason); - return 1; + fd_fgets_destroy(fd_fgets_context); + if (pidfd >= 0) + close(pidfd); + printf("Can't find fapolicyd: %s\n", reason); + return 1; } int main(int argc, char * const argv[]) diff --git a/src/daemon/fapolicyd.c b/src/daemon/fapolicyd.c index dc3db63d..b9d89040 100644 --- a/src/daemon/fapolicyd.c +++ b/src/daemon/fapolicyd.c @@ -369,10 +369,13 @@ static void handle_mounts(int fd) // Rewind the descriptor lseek(fd, 0, SEEK_SET); - fd_fgets_rewind(); + fd_fgets_context_t * fd_fgets_context = fd_fgets_init(); + if (!fd_fgets_context) + return; + mlist_mark_all_deleted(m); do { - int rc = fd_fgets(buf, sizeof(buf), fd); + int rc = fd_fgets(fd_fgets_context, buf, sizeof(buf), fd); // Get a line if (rc > 0) { // Parse it @@ -391,8 +394,9 @@ static void handle_mounts(int fd) } } else if (rc < 0) // Some kind of error - stop break; - } while (!fd_fgets_eof()); + } while (!fd_fgets_eof(fd_fgets_context)); + fd_fgets_destroy(fd_fgets_context); // update marks fanotify_update(m); } @@ -421,11 +425,15 @@ void do_stat_report(FILE *f, int shutdown) int already_running(void) { + fd_fgets_context_t * fd_fgets_context = fd_fgets_init(); + if (!fd_fgets_context) + return 1; + int pidfd = open(pidfile, O_RDONLY); if (pidfd >= 0) { char pid_buf[16]; - if (fd_fgets(pid_buf, sizeof(pid_buf), pidfd)) { + if (fd_fgets(fd_fgets_context, pid_buf, sizeof(pid_buf), pidfd)) { int pid; char exe_buf[80], my_path[80]; @@ -457,6 +465,7 @@ int already_running(void) if (pid != getpid()) goto err_out; good: + fd_fgets_destroy(fd_fgets_context); close(pidfd); unlink(pidfile); return 0; @@ -464,9 +473,13 @@ int already_running(void) msg(LOG_ERR, "fapolicyd pid file found but unreadable"); err_out: // At this point, we have a pid file, let's just assume it's alive // because if 2 are running, it deadlocks the machine + + fd_fgets_destroy(fd_fgets_context); close(pidfd); return 1; } + + fd_fgets_destroy(fd_fgets_context); return 0; // pid file doesn't exist, we're good to go } diff --git a/src/library/database.c b/src/library/database.c index 1ccbce47..44dd0b2b 100644 --- a/src/library/database.c +++ b/src/library/database.c @@ -1315,9 +1315,10 @@ static void *update_thread_main(void *arg) } else { if (ffd[0].revents & POLLIN) { + fd_fgets_context_t * fd_fgets_context = fd_fgets_init(); do { - fd_fgets_rewind(); - int res = fd_fgets(buff, sizeof(buff), ffd[0].fd); + fd_fgets_rewind(fd_fgets_context); + int res = fd_fgets(fd_fgets_context, buff, sizeof(buff), ffd[0].fd); // nothing to read if (res == -1) @@ -1390,7 +1391,8 @@ static void *update_thread_main(void *arg) } } - } while(!fd_fgets_eof()); + } while(!fd_fgets_eof(fd_fgets_context)); + fd_fgets_destroy(fd_fgets_context); } } } diff --git a/src/library/fd-fgets.c b/src/library/fd-fgets.c index ff9f1d82..7b2cfe25 100644 --- a/src/library/fd-fgets.c +++ b/src/library/fd-fgets.c @@ -23,27 +23,41 @@ #include "config.h" #include #include +#include #include #include #include "fd-fgets.h" -#define BUF_SIZE 8192 -static char buffer[2*BUF_SIZE+1] = { 0 }; -static char *current = buffer; -static const char *eptr = buffer+(2*BUF_SIZE); -static int eof = 0; -int fd_fgets_eof(void) +fd_fgets_context_t * fd_fgets_init(void) { - return eof; + fd_fgets_context_t *ctx = malloc(sizeof(fd_fgets_context_t)); + if (!ctx) + return NULL; + + memset(ctx->buffer, 0, sizeof(ctx->buffer)); + ctx->current = ctx->buffer; + ctx->eptr = ctx->buffer+(2*FD_FGETS_BUF_SIZE); + ctx->eof = 0; + return ctx; +} + +void fd_fgets_destroy(fd_fgets_context_t *ctx) +{ + free(ctx); +} + +int fd_fgets_eof(fd_fgets_context_t *ctx) +{ + return ctx->eof; } -void fd_fgets_rewind(void) +void fd_fgets_rewind(fd_fgets_context_t *ctx) { - eof = 0; + ctx->eof = 0; } -int fd_fgets(char *buf, size_t blen, int fd) +int fd_fgets(fd_fgets_context_t *ctx, char *buf, size_t blen, int fd) { int complete = 0; size_t line_len = 0; @@ -51,45 +65,45 @@ int fd_fgets(char *buf, size_t blen, int fd) assert(blen != 0); /* See if we have more in the buffer first */ - if (current != buffer) { - line_end = strchr(buffer, '\n'); - if (line_end == NULL && (size_t)(current - buffer) >= blen-1) - line_end = current-1; //enough to fill blen,point to end + if (ctx->current != ctx->buffer) { + line_end = strchr(ctx->buffer, '\n'); + if (line_end == NULL && (size_t)(ctx->current - ctx->buffer) >= blen-1) + line_end = ctx->current-1; //enough to fill blen,point to end } /* Otherwise get some new bytes */ - if (line_end == NULL && current != eptr && !eof) { + if (line_end == NULL && ctx->current != ctx->eptr && !ctx->eof) { ssize_t len; /* Use current since we may be adding more */ do { - len = read(fd, current, eptr - current); + len = read(fd, ctx->current, ctx->eptr - ctx->current); } while (len < 0 && errno == EINTR); if (len < 0) return -1; if (len == 0) - eof = 1; + ctx->eof = 1; else - current[len] = 0; - current += len; + ctx->current[len] = 0; + ctx->current += len; /* Start from beginning to see if we have one */ - line_end = strchr(buffer, '\n'); + line_end = strchr(ctx->buffer, '\n'); } /* See what we have */ if (line_end) { /* Include the last character (usually newline) */ - line_len = (line_end+1) - buffer; + line_len = (line_end+1) - ctx->buffer; /* Make sure we are within the right size */ if (line_len > blen-1) line_len = blen-1; complete = 1; - } else if (current == eptr) { + } else if (ctx->current == ctx->eptr) { /* We are full but no newline */ line_len = blen-1; complete = 1; - } else if (current >= buffer+blen-1) { + } else if (ctx->current >= ctx->buffer+blen-1) { /* Not completely full, no newline, but enough to fill buf */ line_len = blen-1; complete = 1; @@ -98,18 +112,18 @@ int fd_fgets(char *buf, size_t blen, int fd) size_t remainder_len; /* Move to external buf and terminate it */ - memcpy(buf, buffer, line_len); + memcpy(buf, ctx->buffer, line_len); buf[line_len] = 0; - remainder_len = current - (buffer + line_len); + remainder_len = ctx->current - (ctx->buffer + line_len); if (remainder_len > 0) { /* We have a few leftover bytes to move */ - memmove(buffer, buffer+line_len, remainder_len); - current = buffer+remainder_len; + memmove(ctx->buffer, ctx->buffer+line_len, remainder_len); + ctx->current = ctx->buffer+remainder_len; } else { /* Got the whole thing, just reset */ - current = buffer; + ctx->current = ctx->buffer; } - *current = 0; + *(ctx->current) = 0; } return complete; } diff --git a/src/library/fd-fgets.h b/src/library/fd-fgets.h index a79e4f44..22cd243e 100644 --- a/src/library/fd-fgets.h +++ b/src/library/fd-fgets.h @@ -24,15 +24,31 @@ #define FD_FGETS_HEADER #include +#include "gcc-attributes.h" #ifndef __attr_access # define __attr_access(x) #endif -int fd_fgets_eof(void); -void fd_fgets_rewind(void); -int fd_fgets(char *buf, size_t blen, int fd) - __attr_access ((__write_only__, 1, 2)); +#ifndef FD_FGETS_BUF_SIZE +# define FD_FGETS_BUF_SIZE 8192 +#endif + +typedef struct fd_fgets_context { + char buffer[2*FD_FGETS_BUF_SIZE+1]; + char *current; + char *eptr; + int eof; +} fd_fgets_context_t; + +void fd_fgets_destroy(fd_fgets_context_t *ctx); +fd_fgets_context_t * fd_fgets_init(void) __attribute_malloc__ + __attr_dealloc (fd_fgets_destroy, 1); + +int fd_fgets_eof(fd_fgets_context_t *ctx); +void fd_fgets_rewind(fd_fgets_context_t *ctx); +int fd_fgets(fd_fgets_context_t *ctx, char *buf, size_t blen, int fd) + __attr_access ((__write_only__, 2, 3)); #endif