Annotation of embedaddon/pimd/libite/tempfile.c, revision 1.1.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>