+uudeview (0.5.20-3.1) unstable; urgency=high ... + * Fixed a classical tempfile symlink attack vulnerability in libuu. + Thanks to Nico Golde for the patch. (Closes: #480972) ... + -- Marco d'Itri Wed, 21 May 2008 01:34:35 +0200 Index: uudeview-0.5.20/unix/uudeview.c =================================================================== --- uudeview-0.5.20.orig/unix/uudeview.c +++ uudeview-0.5.20/unix/uudeview.c @@ -443,18 +443,46 @@ proc_stdin (void) FILE *target; size_t bytes; int res; +#define HAVE_MKSTEMP +#ifdef HAVE_MKSTEMP + int tmpfd; + const char *tmpprefix = "uuXXXXXX"; + char *tmpdir = NULL; +#endif /* HAVE_MKSTEMP */ if (stdinput) { fprintf (stderr, "proc_stdin: cannot process stdin twice\n"); return 0; } +#ifdef HAVE_MKSTEMP + if ((getuid()==geteuid()) && (getgid()==getegid())) { + tmpdir=getenv("TMPDIR"); + } + + if (!tmpdir) { + tmpdir = "/tmp"; + } + stdfile = malloc(strlen(tmpdir)+strlen(tmpprefix)+2); + + if (!stdfile) { +#else if ((stdfile = tempnam (NULL, "uu")) == NULL) { +#endif fprintf (stderr, "proc_stdin: cannot get temporary file\n"); return 0; } +#ifdef HAVE_MKSTEMP + strcpy(stdfile, tmpdir); + strcat(stdfile, "/"); + strcat(stdfile, tmpprefix); + + if ((tmpfd = mkstemp(stdfile)) == -1 || + (target = fdopen(tmpfd, "wbx")) == NULL) { +#else if ((target = fopen (stdfile, "wbx")) == NULL) { +#endif fprintf (stderr, "proc_stdin: cannot open temp file %s for writing: %s\n", stdfile, strerror (errno)); _FP_free (stdfile); Index: uudeview-0.5.20/uulib/uunconc.c =================================================================== --- uudeview-0.5.20.orig/uulib/uunconc.c +++ uudeview-0.5.20/uulib/uunconc.c @@ -1311,6 +1311,12 @@ UUDecode (uulist *data) char *mode, *ntmp; uufile *iter; size_t bytes; +#define HAVE_MKSTEMP +#ifdef HAVE_MKSTEMP + int tmpfd; + const char *tmpprefix = "uuXXXXXX"; + char *tmpdir = NULL; +#endif /* HAVE_MKSTEMP */ if (data == NULL || data->thisfile == NULL) return UURET_ILLVAL; @@ -1329,13 +1335,35 @@ UUDecode (uulist *data) else mode = "wbx"; /* otherwise in binary */ +#ifdef HAVE_MKSTEMP + if ((getuid()==geteuid()) && (getgid()==getegid())) { + tmpdir=getenv("TMPDIR"); + } + + if (!tmpdir) { + tmpdir = "/tmp"; + } + data->binfile = malloc(strlen(tmpdir)+strlen(tmpprefix)+2); + + if (!data->binfile) { +#else if ((data->binfile = tempnam (NULL, "uu")) == NULL) { +#endif /* HAVE_MKSTEMP */ UUMessage (uunconc_id, __LINE__, UUMSG_ERROR, uustring (S_NO_TEMP_NAME)); return UURET_NOMEM; } +#ifdef HAVE_MKSTEMP + strcpy(data->binfile, tmpdir); + strcat(data->binfile, "/"); + strcat(data->binfile, tmpprefix); + + if ((tmpfd = mkstemp(data->binfile)) == -1 || + (dataout = fdopen(tmpfd, mode)) == NULL) { +#else if ((dataout = fopen (data->binfile, mode)) == NULL) { +#endif /* HAVE_MKSTEMP */ /* * we couldn't create a temporary file. Usually this means that TMP * and TEMP aren't set @@ -1343,6 +1371,12 @@ UUDecode (uulist *data) UUMessage (uunconc_id, __LINE__, UUMSG_ERROR, uustring (S_WR_ERR_TARGET), data->binfile, strerror (uu_errno = errno)); +#ifdef HAVE_MKSTEMP + if (tmpfd != -1) { + unlink(data->binfile); + close(tmpfd); + } +#endif /* HAVE_MKSTEMP */ _FP_free (data->binfile); data->binfile = NULL; uu_errno = errno; @@ -1499,7 +1533,13 @@ UUDecode (uulist *data) */ if (data->uudet == BH_ENCODED && data->binfile) { +#ifdef HAVE_MKSTEMP + ntmp = malloc(strlen(tmpdir)+strlen(tmpprefix)+2); + + if (ntmp == NULL) { +#else if ((ntmp = tempnam (NULL, "uu")) == NULL) { +#endif /* HAVE_MKSTEMP */ UUMessage (uunconc_id, __LINE__, UUMSG_ERROR, uustring (S_NO_TEMP_NAME)); progress.action = 0; @@ -1513,12 +1553,27 @@ UUDecode (uulist *data) free (ntmp); return UURET_IOERR; } + +#ifdef HAVE_MKSTEMP + strcpy(ntmp, tmpdir); + strcat(ntmp, "/"); + strcat(ntmp, tmpprefix); + if ((tmpfd = mkstemp(ntmp)) == -1 || + (dataout = fdopen(tmpfd, "wb")) == NULL) { +#else if ((dataout = fopen (ntmp, "wb")) == NULL) { +#endif /* HAVE_MKSTEMP */ UUMessage (uunconc_id, __LINE__, UUMSG_ERROR, uustring (S_NOT_OPEN_TARGET), ntmp, strerror (uu_errno = errno)); progress.action = 0; fclose (datain); +#ifdef HAVE_MKSTEMP + if (tmpfd != -1) { + unlink(ntmp); + close(tmpfd); + } +#endif /* HAVE_MKSTEMP */ free (ntmp); return UURET_IOERR; }