NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

bin/41837: tempnap(3) doesn't return at least {TMP_MAX} unique file paths



>Number:         41837
>Category:       bin
>Synopsis:       tempnap(3) doesn't return at least {TMP_MAX} unique file paths
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Aug 07 08:05:00 +0000 2009
>Originator:     Stathis Kamperis
>Release:        NetBSD 5.0_STABLE
>Organization:
Aristotle University of Thessaloniki
>Environment:
NetBSD voyager 5.0_STABLE NetBSD 5.0_STABLE (MYGENERIC) #9: Wed Aug  5 00:38:20 
EEST 2009  root@voyager:/usr/obj/sys/arch/i386/compile/MYGENERIC i386

>Description:
First of all, I know that tempnam(3) is of little use nowadays.
Second, the bug I'm going to describe is even rarer to cause any problems.
Thirt, Issue 7 says that tempnam() might be removed in future versions of the 
standard.
That's why I flagged the PR as non-critical/low.

Anyway.

tempnam(3) doesn't return {TMP_MAX} unique file paths during the lifetime
of a process. Instead it starts repeating itself with a period of = 676
= 26*26. This is because it appends 'aa' to a constant string (that is 
different from process to process, but stays constant during the lifecycle of a 
single process) to 'zz'.

As I comment in the code of the test case, it isn't very clear whether
tempnam(3) should always guarantee {TMP_MAX} file paths.

To quote Issue 7:
Some implementations of tempnam() may use tmpnam() internally. On such 
implementations, if called more than {TMP_MAX} times in a single process, the 
behavior is implementation-defined.

So, if tempnam(3) uses tmpnamp() internally, then it will at least
return {TMP_MAX} unique strings. But what about in the case that it
doesn't use tmpnam() ? 

Given that tmpfile() and tmpnam() share this {TMP_MAX} limit and tempnam() 
adheres to it in the case where it makes use of tmpnam(),
it is reasonable to deduce that it should honour the limit even in
the case it isn't implemented on top of tmpnam().

Just for the record, Linux, OpenBSD and Solaris 10 get it right.

>How-To-Repeat:

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>     /* strcmp() */

int main(void)
{
        /*
         * If TMP_MAX is defined, use that unless it exceeds 2000.
         * We do this because the implementation may support some
         * astronomically large value and blow up the memory limits.
         * E.g., in DragonFly it equals 308915776. But, even if
         * TMP_MAX isn't that large, it still needs to be kept low,
         * because later on when we check if the generated strings are
         * unique, we use a nested loop which is of O(n^2) complexity.
         * And we want the test to complete in reasonable amount of time.
         */
#ifdef TMP_MAX
        size_t N = TMP_MAX > 2000 ? 2000 : TMP_MAX;
#else
        size_t N = 25;          /* Lowest possible value for TMP_MAX. */
#endif
        char **files;
        size_t i, j;

        /*
         * Allocate memory for file paths.
         * We could use a variable-sized array, but let's stick for now
         * 
>Fix:



Home | Main Index | Thread Index | Old Index