Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 9 Apr 1995 09:10:01 -0700
From:      pritc003@maroon.tc.umn.edu
To:        freebsd-bugs
Subject:   kern/312: link system call on msdos filesystem causes panic
Message-ID:  <199504091610.JAA25763@freefall.cdrom.com>
In-Reply-To: Your message of Sun, 9 Apr 1995 11:01:57 -0500 <199504091601.LAA00372@mpp.com>

next in thread | previous in thread | raw e-mail | index | archive | help

>Number:         312
>Category:       kern
>Synopsis:       link system call on msdos filesystem causes panic
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    freebsd-bugs (FreeBSD bugs mailing list)
>State:          open
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Apr  9 09:10:01 1995
>Originator:     Mike Pritchard
>Organization:
>Release:        FreeBSD 2.1.0-Development i386
>Environment:

>Description:

If a program does a link("file1", "file2") system call followed by an 
unlink("file1") system call on a msdos file system, the system will 
panic with the following message:

panic: msdosfs_lock: locking against myself

This is because the msdosfs link code does not vput the vnode like
it should before returning.  The link code should also return an
error to the user so that the calling program doesn't accidently 
destroy the file it was attempting to link, thinking that the
link() call actually worked.

>How-To-Repeat:

Compile and run the following program on a msdos file system:

#include <stdio.h>
#include <fcntl.h>

main()
{
	int	fd;

	if ((fd = open("testfile", O_RDWR | O_CREAT, 0666)) < 0) {
		perror("open");
		exit(1);
	}
	if (link("testfile", "newfile") < 0) {
		perror("link");
		exit(1);
	}
	if (unlink("testfile") < 0) {
		perror("unlink");
		exit(1);
	}
	close(fd);
}


>Fix:
	
The attached fix corrects the msdosfs_link() routine to correctly vput 
the vnode before returning, and return an error of EMLINK (too many 
links) to the user.  Feel free to choose another errno if you think
something else is more appropriate.  ENODEV would be my next choice.


*** msdosfs/orig2/msdosfs_vnops.c	Sun Apr  9 10:29:49 1995
--- msdosfs/msdosfs_vnops.c	Sun Apr  9 10:34:30 1995
***************
*** 907,913 ****
  		struct componentname *a_cnp;
  	} */ *ap;
  {
! 	return VOP_ABORTOP(ap->a_vp, ap->a_cnp);
  }
  
  /*
--- 907,915 ----
  		struct componentname *a_cnp;
  	} */ *ap;
  {
! 	VOP_ABORTOP(ap->a_vp, ap->a_cnp);
! 	vput(ap->a_vp);
! 	return EMLINK;
  }
  
  /*
>Audit-Trail:
>Unformatted:





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199504091610.JAA25763>