bin/153261: sed: fix for a race condition (from illumos)

Pedro Giffuni giffunip at tutopia.com
Sat Dec 18 01:20:07 UTC 2010


>Number:         153261
>Category:       bin
>Synopsis:       sed: fix for a race condition (from illumos)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Sat Dec 18 01:20:06 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator:     Pedro Giffuni
>Release:        8.1-RELEASE
>Organization:
>Environment:
FreeBSD mogwai.giffuni.net 8.1-RELEASE FreeBSD 8.1-RELEASE #0: Tue Nov  9 10:31:43 UTC 2010     pedro at mogwai.giffuni.net:/usr/src/sys/i386/compile/GENERIC  i386

>Description:
Garrett D'Amore's blog:

http://blogs.nexenta.org/

"I just integrated a new sed(1) port for illumos. This is derived from FreeBSD, but it includes a fix for a race condition, and support for translated messages. (FreeBSD friends, please feel free to include these changes back — I’ve not changed the original BSD license.)"

The complete sources are available here:
http://mexico.purplecow.org/gdamore/webrev/sed/

I only looked where link was replaced by rename and was careful to apply this patch here:
http://www.illumos.org/issues/524

It should also be noted that they made a small change to libc/regex (PR bin/153257) to obtain a Solaris compatible behavior.

>How-To-Repeat:

>Fix:


Patch attached with submission follows:

diff -ru sed.orig/main.c sed/main.c
--- sed.orig/main.c	2010-12-17 17:42:46.000000000 +0000
+++ sed/main.c	2010-12-17 19:58:41.000000000 +0000
@@ -338,8 +338,10 @@
 		if (infile != NULL) {
 			fclose(infile);
 			if (*oldfname != '\0') {
-				if (rename(fname, oldfname) != 0) {
-					warn("rename()");
+				/* if there was a backup file, remove it */
+				unlink(oldfname);
+				if (link(fname, oldfname) != 0) {
+					warn("link()");
 					unlink(tmpfname);
 					exit(1);
 				}
@@ -347,9 +349,18 @@
 			}
 			if (*tmpfname != '\0') {
 				if (outfile != NULL && outfile != stdout)
-					fclose(outfile);
+					if (fclose(outfile) != 0) {
+						warn("fclose()");
+						unlink(tmpfname);
+						exit(1);
+					}
 				outfile = NULL;
-				rename(tmpfname, fname);
+				if (rename(tmpfname, fname) != 0) {
+					/* this should not happen really! */
+					warn("rename()");
+					unlink(tmpfname);
+					exit(1);
+				}
 				*tmpfname = '\0';
 			}
 			outfname = NULL;


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list