Skip site navigation (1)Skip section navigation (2)
Date:      Wed,  4 Sep 2002 19:21:32 +0200 (CEST)
From:      Thomas Quinot <thomas@FreeBSD.org>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   bin/42418: [patch] perl wrapper loops on itself
Message-ID:  <20020904172132.077722C3D1@melusine.cuivre.fr.eu.org>

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

>Number:         42418
>Category:       bin
>Synopsis:       [patch] perl wrapper loops on itself
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Sep 04 10:30:02 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     Thomas Quinot
>Release:        FreeBSD 5.0-CURRENT i386
>Organization:
>Environment:
System: FreeBSD shalmaneser.enst.fr 5.0-CURRENT FreeBSD 5.0-CURRENT #1: Tue Sep  3 14:05:44 CEST 2002     root@shalmaneser.enst.fr:/usr/obj/usr/src/sys/SHALMANESER  i386


	
>Description:
	When PATH contains a symbolic link to /usr/bin/perl (typically,
	a /usr/local/bin/perl link that used to point the the base
	system perl), the wrapper loops on itself.

>How-To-Repeat:
	mkdir /tmp/foo
	PATH=/tmp/foo:$PATH
	ln -s /usr/bin/perl /tmp/foo
	/usr/bin/perl
	# will loop forever
>Fix:
	The proposed solution is to make the wrapper stat the files
	it is considering as candidate real interpreter, and skip
	itself. Patch included.

Index: perl.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/perl/perl.c,v
retrieving revision 1.4
diff -u -r1.4 perl.c
--- perl.c	21 Aug 2002 20:54:45 -0000	1.4
+++ perl.c	4 Sep 2002 17:21:11 -0000
@@ -30,6 +30,7 @@
 __FBSDID("$FreeBSD: src/usr.bin/perl/perl.c,v 1.4 2002/08/21 20:54:45 joerg Exp $");
 
 #include <sys/param.h>
+#include <sys/stat.h>
 #include <sys/sysctl.h>
 
 #include <err.h>
@@ -49,8 +50,13 @@
 	char path[PATH_MAX], *cp;
 	const char *cmd, *p, *q, *self;
 	size_t len;
+	struct stat self_stat, perl_stat;
 
 	self = argv[0];
+	if (stat (self, &self_stat) != 0) {
+		self_stat.st_dev = makedev (0, 0);
+		self_stat.st_ino = 0;
+	}
 	if ((cmd = strrchr(self, '/')) == NULL)
 		cmd = self;
 	else
@@ -78,6 +84,10 @@
 			/* nothing */ ;
 		len = snprintf(path, sizeof path, "%.*s/%s", (int)(q - p), p, cmd);
 		if (len >= PATH_MAX || strcmp(path, self) == 0)
+			continue;
+		if (stat (path, &perl_stat) == 0
+		    && self_stat.st_dev == perl_stat.st_dev
+		    && self_stat.st_ino == perl_stat.st_ino)
 			continue;
 		execve(path, argv, environ);
 		if (errno != ENOENT)
>Release-Note:
>Audit-Trail:
>Unformatted:

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?20020904172132.077722C3D1>