Subject: lib/3194: implementation of mktemp() is broken
To: None <gnats-bugs@gnats.netbsd.org>
From: Matthias Scheler <tron@lyssa.owl.de>
List: netbsd-bugs
Date: 02/06/1997 03:23:47
>Number:         3194
>Category:       lib
>Synopsis:       implementation of mktemp() is broken
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    lib-bug-people (Library Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Feb  5 18:35:01 1997
>Last-Modified:
>Originator:     Matthias Scheler
>Organization:
Matthias Scheler				http://home.pages.de/~tron/
>Release:        970124
>Environment:
System: NetBSD lyssa 1.2B NetBSD 1.2B (LYSSA) #3: Sun Jan 26 02:48:28 MET 1997 tron@lyssa:/usr/src/sys/arch/i386/compile/LYSSA i386


>Description:
Today I tried to install "ELM 2.4 PL25 PGP7". It worked fine except for
the decoding of PGP encrypted message. I started debugging and found out
that "pgp" gets called like this:

pgp -t +batchmode +verbose=0 +force -o /tmp/pgp.a08428 /tmp/pgp.a08428 /tmp/pgp.a08428

So "pgp" overwrites its own input file while decoding the message. I
started to search for the reason and found out that it calls tempnam()
three times in a row and gets the same filename all three times.

>How-To-Repeat:
Compile this program and run it:

#include <stdio.h>

int main(void)

{
 int Index;

 for (Index=0; Index<3; Index++) (void)puts(tempnam("tmp","pgp."));

 return 0;
}

NetBSD:
tron@lyssa:~>bug
/tmp/pgp.014416
/tmp/pgp.014416
/tmp/pgp.014416

Linux:
tron@pri:~>bug
/tmp/pgp.16399aaa
/tmp/pgp.16399baa
/tmp/pgp.16399caa

Solaris:
tron@taifun:~>bug
/var/tmp/pgp.AAAa006KA
/var/tmp/pgp.BAAa006KA
/var/tmp/pgp.CAAa006KA

>Fix:
It's not perfect but better than nothing.

*** src/lib/libc/stdio/mktemp.c.orig	Sat Oct 14 01:51:56 1995
--- src/lib/libc/stdio/mktemp.c	Thu Feb  6 03:18:16 1997
*************** _gettemp(path, doopen)
*** 74,83 ****
--- 74,86 ----
  	extern int errno;
  	register char *start, *trv;
  	struct stat sbuf;
+ 	static u_int count = 0;
  	u_int pid;
  
  	pid = getpid();
  	for (trv = path; *trv; ++trv);		/* extra X's get set to 0's */
+ 	if (trv[-1] == 'X') *--trv = (count % 10) + '0';
+ 	count++;
  	while (*--trv == 'X') {
  		*trv = (pid % 10) + '0';
  		pid /= 10;

>Audit-Trail:
>Unformatted: