diff --git a/Makefile b/Makefile index 7e2b32e..0afa2f4 100644 --- a/Makefile +++ b/Makefile @@ -38,6 +38,7 @@ STRIPINST := $(INSTALL) -s --strip-program=$(CROSS)strip -m 0755 CFLAGS += -fPIC CFLAGS += -Os +CPPFLAGS += -D_GNU_SOURCE CPPFLAGS += -W -Wall -Werror ARFLAGS = crus MAKEFLAGS = --no-print-directory --silent @@ -45,7 +46,7 @@ MAKEFLAGS = --no-print-directory --silent DISTFILES = README LICENSE HEADERS = lite.h OBJS := chomp.o copyfile.o dir.o fexist.o fisdir.o fmode.o rsync.o -OBJS += strlcpy.o strlcat.o strtonum.o +OBJS += strlcpy.o strlcat.o strtonum.o tempfile.o DEPS := $(OBJS:.o=.d) JUNK = *~ *.bak *.map .*.d *.d DEADJOE semantic.cache *.gdb *.elf core core.* diff --git a/lite.h b/lite.h index 88d2cdf..ff71a68 100644 --- a/lite.h +++ b/lite.h @@ -39,6 +39,7 @@ int fexist (char *file); int fisdir (char *file); mode_t fmode (char *file); +FILE *tempfile (void); ssize_t copyfile (char *src, char *dst, int len, int sym); int movefile (char *src, char *dst); int copy_filep (FILE *src, FILE *dst); diff --git a/tempfile.c b/tempfile.c new file mode 100644 index 0000000..c331893 --- /dev/null +++ b/tempfile.c @@ -0,0 +1,64 @@ +/* A secure tmpfile() replacement. + * + * Copyright (c) 2015 Joachim Nilsson + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include /* O_TMPFILE requires -D_GNU_SOURCE */ +#include /* mkstemp() */ +#include /* fdopen() */ +#include /* umask() */ + +/** + * tempfile - A secure tmpfile() replacement + * + * This is the secure replacement for tmpfile() that does not exist in + * GLIBC. The function uses the Linux specific %O_TMPFILE and %O_EXCL + * for security. When the %FILE is fclose()'ed the file contents is + * lost. The file is hidden in the %_PATH_TMP directory on the system. + * + * Returns: + * An open %FILE pointer, or %NULL on error. + */ +FILE *tempfile(void) +{ + int fd; + mode_t oldmask; + + oldmask = umask(0077); + fd = open(_PATH_TMP, O_TMPFILE | O_RDWR | O_EXCL | O_CLOEXEC, S_IRUSR | S_IWUSR); + umask(oldmask); + if (-1 == fd) + return NULL; + + return fdopen(fd, "rw"); +} + +#ifdef UNITTEST +int main(void) +{ + FILE *fp = tempfile(); system("ls -lrt " + _PATH_TMP " | tail -10"); return fclose(fp); +} +#endif + +/** + * Local Variables: + * compile-command: "gcc -D_GNU_SOURCE -DUNITTEST -o tempy tempfile.c && ./tempy" + * version-control: t + * indent-tabs-mode: t + * c-file-style: "linux" + * End: + */