Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 24 Jun 2002 23:00:06 -0700 (PDT)
From:      Paul Herman <pherman@frenchfries.net>
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: bin/38676 change request for pw command
Message-ID:  <200206250600.g5P606q08404@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR bin/38676; it has been noted by GNATS.

From: Paul Herman <pherman@frenchfries.net>
To: FreeBSD-gnats-submit@FreeBSD.ORG
Cc: Takumi ISHII <takishii@xephion.ne.jp>,
	"Geoffrey C. Speicher" <geoff@sea-incorporated.com>,
	"Matthew D. Fuller" <fullermd@over-yonder.net>
Subject: Re: bin/38676 change request for pw command
Date: Mon, 24 Jun 2002 22:52:50 -0700 (PDT)

 Here is an better version of the patch in bin/23501.  In addition
 to the advisory lock, link counts are checked to avoid any
 unlink/rename issues.  This has been tested by myself and seems to
 also fix the problem.
 
 The topic of HOW to best fix this bug has recently been hashed out
 a bit on -hackers and -stable.  Matthew Fuller proposed an
 alternate fix by using a giant lock in /var/run/, so the jury is
 still out on the best way to solve the problem.
 
 I'll let Matthew speak for himself, but I feel that the either the
 patch in bin/23501 or the following improved patch is the best way
 to solve the problem.  Opinions in the audit-trail are surely to
 follow.  :-)
 
 -Paul.
 
 Index: edgroup.c
 ===================================================================
 RCS file: /u02/ncvs/src/usr.sbin/pw/edgroup.c,v
 retrieving revision 1.8
 diff -u -r1.8 edgroup.c
 --- edgroup.c	28 Aug 1999 01:19:16 -0000	1.8
 +++ edgroup.c	25 Jun 2002 05:27:49 -0000
 @@ -68,7 +68,26 @@
  	strcpy(grouptmp, groupfile);
  	strcat(grouptmp, ".new");
 
 -	if ((infd = open(groupfile, O_RDWR | O_CREAT, 0644)) != -1) {
 +	/*
 +	 * Open and lock the original group file.  We check the link count
 +	 * in order to avoid any link/unlink/remove race.
 +	 */
 +	for (;;) {
 +		struct stat st;
 +
 +		infd = open(groupfile, O_RDWR | O_CREAT | O_EXLOCK, 0644);
 +		if (infd == -1)
 +			break;
 +		if (fstat(infd, &st) < 0) {
 +			close(infd);
 +			return -1;
 +		}
 +		if (st.st_nlink == 1)
 +			break;
 +		close(infd);
 +	}
 +
 +	if (infd != -1) {
  		FILE           *infp;
 
  		if ((infp = fdopen(infd, "r+")) == NULL)
 Index: fileupd.c
 ===================================================================
 RCS file: /u02/ncvs/src/usr.sbin/pw/fileupd.c,v
 retrieving revision 1.9
 diff -u -r1.9 fileupd.c
 --- fileupd.c	26 Oct 1999 04:27:13 -0000	1.9
 +++ fileupd.c	25 Jun 2002 04:15:08 -0000
 @@ -76,8 +76,25 @@
  	if (pfxlen <= 1)
  		rc = EINVAL;
  	else {
 -		int    infd = open(filename, O_RDWR | O_CREAT, fmode);
 -
 +		/*
 +		 * Open and lock the original file.  We check the link count
 +		 * in order to avoid any link/unlink/rename race.
 +		 */
 +		int infd;
 +		for (;;) {
 +			struct stat st;
 +			infd = open(filename, O_RDWR | O_CREAT | O_EXLOCK, fmode);
 +			if (infd == -1)
 +				break;
 +			if (fstat(infd, &st) < 0) {
 +				rc = errno;
 +				close(infd);
 +				return rc;
 +			}
 +			if (st.st_nlink == 1)
 +				break;
 +			close(infd);
 +		}
  		if (infd == -1)
  			rc = errno;
  		else {
 

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




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