Linux libc's mktemp() Vulnerability

BID:79

Info

Linux libc's mktemp() Vulnerability

Bugtraq ID: 79
Class: Unknown
CVE:
Remote: No
Local: Unknown
Published: Apr 11 1998 12:00AM
Updated: Apr 11 1998 12:00AM
Credit: The vulnerability was published as "Linux libc5.4.33 dumbness w/ mk[s]temp()" by Greg Alexander <[email protected]> to the BugTraq mailing list on April 11, 1998.
Vulnerable: Linux libc 5.4.33
GNU glibc 2.0
Not Vulnerable: GNU glibc 2.1
BSDI BSD/OS 4.0

Discussion

Linux libc's mktemp() Vulnerability

Linux libc5.4.33's mktemp() function can generate only 62 unique temporary file names per process. It requires that six X's be used in the template but only one of them is really used. The rest are the process id.

This can use used as a denial of service by creating all possible temporary files a process could use before it gets to open them and possibly in symbolic link attacks by having prior knowledge of the files the process will attempt to open.

Exploit / POC

Linux libc's mktemp() Vulnerability

Currently the SecurityFocus staff are not aware of any exploits for this issue. If you feel we are in error or are aware of more recent information, please mail us at: [email protected].

Solution / Fix

Linux libc's mktemp() Vulnerability

Solution:
This were the changes made between glibc 2.0 and 2.1. It can probably be
applied to glibc 2.0 will mimnimal effort and with some work to libc 5.

Index: sysdeps/posix/mkstemp.c
===================================================================
RCS file: /egcs/carton/cvsfiles/libc/sysdeps/posix/mkstemp.c,v
retrieving revision 1.5
retrieving revision 1.7
diff -u -r1.5 -r1.7
--- sysdeps/posix/mkstemp.c 1998/03/10 10:44:45 1.5
+++ sysdeps/posix/mkstemp.c 1998/04/07 12:52:50 1.7
@@ -19,9 +19,11 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
+#include <stdint.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
+#include <sys/time.h>

/* Generate a unique temporary file name from TEMPLATE.
The last six characters of TEMPLATE must be "XXXXXX";
@@ -33,8 +35,11 @@
{
static const char letters[]
= "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+ static uint32_t value;
+ struct timeval tv;
+ char *XXXXXX;
size_t len;
- size_t i;
+ int count;

len = strlen (template);
if (len < 6 || strcmp (&template[len - 6], "XXXXXX"))
@@ -43,20 +48,40 @@
return -1;
}

- if (sprintf (&template[len - 5], "%.5u",
- (unsigned int) getpid () % 100000) != 5)
- /* Inconceivable lossage. */
- return -1;
+ /* This is where the Xs start. */
+ XXXXXX = &template[len - 6];

- for (i = 0; i < sizeof (letters); ++i)
+ /* Get some more or less random data. */
+ __gettimeofday (&tv, NULL);
+ value += tv.tv_usec | getpid ();
+
+ for (count = 0; count < TMP_MAX; ++count)
{
+ uint32_t v = value;
int fd;

- template[len - 6] = letters[i];
+ /* Fill in the random bits. */
+ XXXXXX[0] = letters[v % 62];
+ v /= 62;
+ XXXXXX[1] = letters[v % 62];
+ v /= 62;
+ XXXXXX[2] = letters[v % 62];
+ v /= 62;
+ XXXXXX[3] = letters[v % 62];
+ v /= 62;
+ XXXXXX[4] = letters[v % 62];
+ v /= 62;
+ XXXXXX[5] = letters[v % 62];

fd = open (template, O_RDWR|O_CREAT|O_EXCL, 0600);
if (fd >= 0)
+ /* The file does not exist. */
return fd;
+
+ /* This is a random value. It is only necessary that the next
+ TMP_MAX values generated by adding 7777 to VALUE are different
+ with (module 2^32). */
+ value += 7777;
}

/* We return the null string if we can't find a unique file name. */
Index: sysdeps/posix/mktemp.c
===================================================================
RCS file: /egcs/carton/cvsfiles/libc/sysdeps/posix/mktemp.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- sysdeps/posix/mktemp.c 1996/11/06 04:24:39 1.8
+++ sysdeps/posix/mktemp.c 1998/04/07 09:08:11 1.9
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992, 1993, 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1992, 1993, 1996, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.

The GNU C Library is free software; you can redistribute it and/or
@@ -16,13 +16,15 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */

+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <errno.h>
#include <unistd.h>
-#include <stdio.h>
-#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>

/* Generate a unique temporary file name from TEMPLATE.
The last six characters of TEMPLATE must be "XXXXXX";
@@ -33,8 +35,11 @@
{
static const char letters[]
= "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+ static uint32_t value;
+ struct timeval tv;
+ char *XXXXXX;
size_t len;
- size_t i;
+ int count;

len = strlen (template);
if (len < 6 || strcmp (&template[len - 6], "XXXXXX"))
@@ -43,20 +48,39 @@
return NULL;
}

- if (sprintf (&template[len - 5], "%.5u",
- (unsigned int) getpid () % 100000) != 5)
- /* Inconceivable lossage. */
- return NULL;
+ /* This is where the Xs start. */
+ XXXXXX = &template[len - 6];


- for (i = 0; i < sizeof (letters); ++i)
+ /* Get some more or less random data. */
+ __gettimeofday (&tv, NULL);
+ value += tv.tv_usec | getpid ();
+
+ for (count = 0; count < TMP_MAX; ++count)
{
struct stat ignored;
+ uint32_t v = value;

- template[len - 6] = letters[i];
+ /* Fill in the random bits. */
+ XXXXXX[0] = letters[v % 62];
+ v /= 62;
+ XXXXXX[1] = letters[v % 62];
+ v /= 62;
+ XXXXXX[2] = letters[v % 62];
+ v /= 62;
+ XXXXXX[3] = letters[v % 62];
+ v /= 62;
+ XXXXXX[4] = letters[v % 62];
+ v /= 62;
+ XXXXXX[5] = letters[v % 62];

if (stat (template, &ignored) < 0 && errno == ENOENT)
/* The file does not exist. So return this name. */
return template;
+
+ /* This is a random value. It is only necessary that the next
+ TMP_MAX values generated by adding 7777 to VALUE are different
+ with (module 2^32). */
+ value += 7777;
}

/* We return the null string if we can't find a unique file name. */

References

Linux libc's mktemp() Vulnerability

References:

© CVE.report 2026

Use of this information constitutes acceptance for use in an AS IS condition. There are NO warranties, implied or otherwise, with regard to this information or its use. Any use of this information is at the user's risk. It is the responsibility of user to evaluate the accuracy, completeness or usefulness of any information, opinion, advice or other content. EACH USER WILL BE SOLELY RESPONSIBLE FOR ANY consequences of his or her direct or indirect use of this web site. ALL WARRANTIES OF ANY KIND ARE EXPRESSLY DISCLAIMED. This site will NOT BE LIABLE FOR ANY DIRECT, INDIRECT or any other kind of loss.

CVE, CWE, and OVAL are registred trademarks of The MITRE Corporation and the authoritative source of CVE content is MITRE's CVE web site. This site includes MITRE data granted under the following license.

Free CVE JSON API cve.report/api

CVE.report and Source URL Uptime Status status.cve.report