$NetBSD: patch-ae,v 1.7 2009/05/17 22:04:11 dholland Exp $ Fix insecure-temp-files. Replaces older nonworking patch with similar intent. XXX inadequately tested, lack of time. Upstream: sent upstream by obache@: http://sourceforge.net/tracker/?func=detail&atid=406763&aid=2537314&group_id=32880 --- src/types.c.orig 2008-07-09 15:51:26.000000000 -0400 +++ src/types.c 2009-05-17 17:55:28.000000000 -0400 @@ -28,6 +28,12 @@ #include #include +#ifdef __sun /* paths.h missing in solaris */ +#define _PATH_TMP "/tmp/" +#else +#include +#endif + #include #include "strutil.h" @@ -345,14 +351,18 @@ static FType * match_file(GList *list, D void typ_identify_end(MainInfo *min, const gchar *path) { const GList *here; - gchar buf[MAXNAMLEN + 2], *temp_name; + gchar buf[MAXNAMLEN + 2]; gint fd[2], len, status; pid_t file_pid; FType *type; + char tempnamebuf[64]; + int tempfd; if(file_list == NULL) return; - if((temp_name = tmpnam(NULL)) == NULL) + strcpy(tempnamebuf, _PATH_TMP "gentoo.XXXXXX"); + tempfd = mkstemp(tempnamebuf); + if (tempfd < 0) return; if(pipe(fd) != 0) return; @@ -360,20 +370,16 @@ void typ_identify_end(MainInfo *min, con file_pid = fork(); if(file_pid == 0) { - guint bits = 0U; - - if(close(STDIN_FILENO) == 0) - { - if(dup(fd[STDIN_FILENO]) == STDIN_FILENO) - bits |= (close(fd[STDIN_FILENO]) == 0); - } - if(close(STDOUT_FILENO) == 0) - { - if(open(temp_name, O_CREAT | O_RDWR, S_IRWXU) == STDOUT_FILENO) - bits |= (close(fd[STDOUT_FILENO]) == 0) << 1; - } - if(bits == 3U && chdir(path) == 0) - execlp("file", "file", "-f", "-", NULL); + if (dup2(fd[0], STDIN_FILENO) < 0) + _exit(EXIT_FAILURE); + if (dup2(tempfd, STDOUT_FILENO) < 0) + _exit(EXIT_FAILURE); + close(fd[0]); + close(fd[1]); + close(tempfd); + if (chdir(path) < 0) + _exit(EXIT_FAILURE); + execlp("file", "file", "-f", "-", NULL); _exit(EXIT_FAILURE); } else if(file_pid < 0) @@ -382,21 +388,21 @@ void typ_identify_end(MainInfo *min, con return; } /* We don't need the input part of the pipe, so close it. */ - close(fd[STDIN_FILENO]); + close(fd[0]); /* Now, we have file listening on pipe, so write all filenames to it. */ for(here = file_list; here != NULL; here = g_list_next(here)) { len = g_snprintf(buf, sizeof buf, "%s\n", DP_SEL_NAME(here)); - write(fd[STDOUT_FILENO], buf, len); + write(fd[1], buf, len); } - close(fd[STDOUT_FILENO]); + close(fd[1]); waitpid(file_pid, &status, 0); if(WIFEXITED(status)) { FILE *in; - if((in = fopen(temp_name, "rt")) != NULL) + if((in = fdopen(tempfd, "rt")) != NULL) { const gchar *fout; gchar line[MAXNAMLEN + 256]; @@ -412,10 +418,14 @@ void typ_identify_end(MainInfo *min, con } fclose(in); } + else + close(tempfd); } + else + close(tempfd); g_list_free(file_list); file_list = NULL; - remove(temp_name); + remove(tempnamebuf); } /* ----------------------------------------------------------------------------------------- */