Annotation of embedaddon/pimd/libite/tempfile.c, revision 1.1
1.1 ! misho 1: /* A secure tmpfile() replacement.
! 2: *
! 3: * Copyright (c) 2015 Joachim Nilsson <troglobit@gmail.com>
! 4: *
! 5: * Permission to use, copy, modify, and/or distribute this software for any
! 6: * purpose with or without fee is hereby granted, provided that the above
! 7: * copyright notice and this permission notice appear in all copies.
! 8: *
! 9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
! 10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
! 11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
! 12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
! 13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
! 14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
! 15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
! 16: */
! 17:
! 18: #include <paths.h>
! 19: #include <fcntl.h> /* O_TMPFILE requires -D_GNU_SOURCE */
! 20: #include <linux/version.h>
! 21: #include <stdlib.h> /* mkstemp() */
! 22: #include <stdio.h> /* fdopen() */
! 23: #include <sys/stat.h> /* umask() */
! 24:
! 25: #ifndef O_TMPFILE /* Too old GLIBC or kernel */
! 26: #warning O_TMPFILE missing on your system, tempfile() may not work!
! 27: #define __O_TMPFILE 020000000
! 28: #define O_TMPFILE (__O_TMPFILE | O_DIRECTORY) /* Define and let it fail at runtime */
! 29: #endif
! 30:
! 31: /**
! 32: * tempfile - A secure tmpfile() replacement
! 33: *
! 34: * This is the secure replacement for tmpfile() that does not exist in
! 35: * GLIBC. The function uses the Linux specific %O_TMPFILE and %O_EXCL
! 36: * for security. When the %FILE is fclose()'ed the file contents is
! 37: * lost. The file is hidden in the %_PATH_TMP directory on the system.
! 38: *
! 39: * This function requires Linux 3.11, or later, due to %O_TMPFILE.
! 40: *
! 41: * Returns:
! 42: * An open %FILE pointer, or %NULL on error.
! 43: */
! 44: FILE *tempfile(void)
! 45: {
! 46: #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
! 47: int fd;
! 48: mode_t oldmask;
! 49:
! 50: oldmask = umask(0077);
! 51: fd = open(_PATH_TMP, O_TMPFILE | O_RDWR | O_EXCL | O_CLOEXEC, S_IRUSR | S_IWUSR);
! 52: umask(oldmask);
! 53: if (-1 == fd)
! 54: return NULL;
! 55:
! 56: return fdopen(fd, "rw");
! 57: #else
! 58: #warning Too old kernel, reverting to wrap unsafe tmpfile() ...
! 59: return tmpfile();
! 60: #endif
! 61: }
! 62:
! 63: #ifdef UNITTEST
! 64: int main(void)
! 65: {
! 66: FILE *fp = tempfile(); system("ls -lrt "
! 67: _PATH_TMP " | tail -10"); return fclose(fp);
! 68: }
! 69: #endif
! 70:
! 71: /**
! 72: * Local Variables:
! 73: * compile-command: "make V=1 -f tempfile.mk"
! 74: * version-control: t
! 75: * indent-tabs-mode: t
! 76: * c-file-style: "linux"
! 77: * End:
! 78: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>