Subject: kern/35675: magiclinks implementation broken
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: None <juan@xtrarom.org>
List: netbsd-bugs
Date: 02/17/2007 18:30:01
>Number:         35675
>Category:       kern
>Synopsis:       magiclinks implementation broken
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Feb 17 18:30:00 +0000 2007
>Originator:     Juan RP
>Release:        NetBSD 4.99.10
>Organization:
The NetBSD Project
>Environment:
System: NetBSD nocturno 4.99.10 NetBSD 4.99.10 (Nocturno) #37: Sat Feb 17 18:54:02 CET 2007 juan@nocturno:/home/juan/build/obj/sys/arch/i386/compile/Nocturno i386
Architecture: i386
Machine: i386
>Description:

	I was wondering why the man(1) command didn't work while
	using the cleartmp rc.d script, so I did start a crusade
	finding what's wrong.

	I made a simple test code to show that mkstemp(3) doesn't
	work with magiclinks:

#include <sys/param.h>
#include <sys/stat.h>

#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define TMPL	"test.XXXXXX"

int main(int argc, char **argv)
{
	struct stat st;
	char buf[MAXPATHLEN - 1];

	setprogname(argv[0]);

	if (argc != 2) {
		(void)printf("usage: %s directory\n", getprogname());
		return 1;
	}

	stat(argv[1], &st);
	(void)snprintf(buf, sizeof(buf), "%s/%s", argv[1], TMPL);

	switch (st.st_mode & S_IFMT) {
	case S_IFDIR:
	case S_IFLNK:
		if (mkstemp(buf) == -1)
			errx(errno, "mkstemp %s", strerror(errno));

		(void)printf("%s created\n", buf);
		break;
	default:
		errx(1, "not a directory or symlink to directory");
	}

	return 0;
}


	Now let's try to show how I found that magiclinks is broken:

[juan@nocturno][~/mkstemp]> mkdir blah
[juan@nocturno][~/mkstemp]> ./test blah
blah/test.01190a created
[juan@nocturno][~/mkstemp]> ln -s blah/@uid foo
[juan@nocturno][~/mkstemp]> file foo
foo: broken symbolic link to `blah/@uid'
[juan@nocturno][~/mkstemp]> ./test foo/
test: not a directory or symlink to directory
[juan@nocturno][~/mkstemp]> echo lalala > foo
[juan@nocturno][~/mkstemp]> cat foo
lalala
[juan@nocturno][~/mkstemp]> ls -l
total 48
-rw-r--r--  1 juan  wheel    48 Feb 14 21:49 Makefile
drwxr-xr-x  2 juan  wheel   512 Feb 17 19:23 blah
lrwxr-xr-x  1 juan  wheel     9 Feb 17 19:23 foo -> blah/@uid
-rwxr-xr-x  1 juan  wheel  6424 Feb 17 19:22 test
-rw-r--r--  1 juan  wheel   707 Feb 14 21:23 test.c
-rw-r--r--  1 juan  wheel  1520 Feb 17 19:22 test.o
[juan@nocturno][~/mkstemp]> file foo
foo: broken symbolic link to `blah/@uid'
[juan@nocturno][~/mkstemp]> ls -l blah
total 8
-rw-r--r--  1 juan  wheel  7 Feb 17 19:23 1000
-rw-------  1 juan  wheel  0 Feb 17 19:23 test.01190a
[juan@nocturno][~/mkstemp]> cat blah/1000
lalala
[juan@nocturno][~/mkstemp]>

	See how a file called 1000 was created in the blah
	directory... hmmm.

>How-To-Repeat:
>Fix:
	Yes, please.