*BSD News Article 10257


Return to BSD News archive

Received: by minnie.vk1xwt.ampr.org with NNTP
	id AA7585 ; Mon, 25 Jan 93 12:18:23 EST
Newsgroups: comp.unix.bsd
Path: sserve!manuel.anu.edu.au!munnari.oz.au!metro!ipso!runxtsa!bde
From: bde@runx.oz.au (Bruce Evans)
Subject: [386BSD] Bug + fix: NAME_MAX off by 1
Message-ID: <1993Jan22.182148.5188@runx.oz.au>
Organization: RUNX Un*x Timeshare.  Sydney, Australia.
Date: Fri, 22 Jan 93 18:21:48 GMT
Lines: 77

File names of length NAME_MAX do not work in 386BSD-0.1.  Names of length
NAME_MAX - 1 are OK.  Reducing NAME_MAX by 1 to 254 would not help - it
would invalidate the documentation and reduce the actual maximum by 1.

This program demonstrates the bug:

---
NAME_MAX-test.c
---
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int errors;

void test(size_t component_length, int expect_error);

int main(void)
{
    test(NAME_MAX, 1);
    test(NAME_MAX + 1, 0);
    exit(errors ? 1 : 0);
}

void test(size_t component_length, int expect_error)
{
    int fd;
    char *name;

    name = malloc(5 + component_length);
    if (name == NULL)
    {
	perror("malloc");
	abort();
    }
    sprintf(name, "/tmp/%0*d", (int) component_length, 0);
    fd = creat(name, 0666);
    if (fd >= 0) {
	(void) unlink(name);
	fprintf(stderr, "%s: length %d didn't cause an error\n",
		expect_error ? "  OK" : "oops", (int) component_length);
	if (expect_error)
	    ++errors;
    }
    else {
	fprintf(stderr, "%s: length %d caused error `%s'\n",
		!expect_error ? "  OK" : "oops", (int) component_length,
		strerror(errno));
	if (!expect_error)
	    ++errors;
    }
}
---

This might be a fix:

*** vfs_lookup.c~	Wed Dec 25 09:24:09 1991
--- vfs_lookup.c	Tue Jan 19 21:25:50 1993
***************
*** 275,279 ****
  		ndp->ni_hash += (unsigned char)*cp;
  	ndp->ni_namelen = cp - ndp->ni_ptr;
! 	if (ndp->ni_namelen >= NAME_MAX) {
  		error = ENAMETOOLONG;
  		goto bad;
--- 275,279 ----
  		ndp->ni_hash += (unsigned char)*cp;
  	ndp->ni_namelen = cp - ndp->ni_ptr;
! 	if (ndp->ni_namelen > NAME_MAX) {
  		error = ENAMETOOLONG;
  		goto bad;
-- 
Bruce Evans  (bde@runx.oz.au)