small NFS bug

Frank van Maarseveen (fvm@tasking.nl)
Sun, 23 May 1999 19:06:38 +0200


The following program shows a small bug in various Linux
kernels (2.0.36, 2.2.6-ac3) and also on SunOS 4.x. It has to do
with setuid root programs accessing an NFS mounted
filesystem when the server maps root to user "nobody".

The access() function incorrectly thinks after a while
that the program has no access to a file inside a subdirectory.
bypass: stat() before the access().

Run this program with the setuid root bit set (but not on NFS):
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

#define D "testdir"
#define S D "/testfile"
#ifndef __GNUC__
#define __attribute__(a)
#endif

static void fatal(const char *fmt, ...) __attribute__((noreturn, format(printf, 1, 2)));

void main(int argc, char **argv)
{
int d;
uid_t uid;

uid = getuid();
if (setreuid(0,0) == -1) fatal("setreuid at line %d: %s\n", __LINE__, strerror(errno));
if (setreuid(0,uid) == -1) fatal("setreuid at line %d: %s\n", __LINE__, strerror(errno));
if (mkdir(D, 0700) == -1) fatal("mkdir: %s\n", strerror(errno));
if ((d = open(S, O_RDWR | O_CREAT, 0666)) == -1) fatal("open %s: %s\n", S, strerror(errno));
close(d);
sleep(argc == 2 ? atoi(argv[1]) : 66);
if (access(S, R_OK) == -1 && open(S, O_RDONLY, 0) != -1)
{
perror("access bug");
}
if (unlink(S) == -1) fatal("another problem: unlink: %s\n", strerror(errno));
if (rmdir(D) == -1) fatal("another problem: rmdir: %s\n", strerror(errno));
exit(0);
}

static void fatal(const char *fmt, ...)
{
va_list ap;

va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
exit(1);
}
--------

-- 
Frank

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/