Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 7 Jun 1999 10:30:05 -0700 (PDT)
From:      Dag-Erling Smorgrav <des@flood.ping.uio.no>
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: bin/12052: sh type builtin appends first path component to absolute result
Message-ID:  <199906071730.KAA34575@freefall.freebsd.org>

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

From: Dag-Erling Smorgrav <des@flood.ping.uio.no>
To: matt@zigg.com
Cc: FreeBSD-gnats-submit@FreeBSD.ORG
Subject: Re: bin/12052: sh type builtin appends first path component to absolute result
Date: 07 Jun 1999 19:28:36 +0200

 matt@zigg.com writes:
 > >Fix:
 
 No fix yet, but an analysis: since the argument to 'type' (typecmd()
 in src/bin/sh/exec.c) is neither a builtin nor an alias, typecmd()
 calls find_command() (also in src/bin/sh/exec.c). The first thing
 find_command() does is check if the command contains a slash, in which
 case it sets the command type to CMDNORMAL and the path index to 0:
 
 	/* If name contains a slash, don't use the hash table */
 	if (strchr(name, '/') != NULL) {
 		entry->cmdtype = CMDNORMAL;
 		entry->u.index = 0;
 		return;
 	}
 
 Here's the hitch - the caller has no way of distinguishing "a normal
 command which resides in the first directory in the path" from "a
 normal command which contains slashes". It tries to construct a full
 command name by calling padvance() entry->u.index times:
 
 		case CMDNORMAL: {
 			int j = entry.u.index;
 			char *path = pathval(), *name;
 			do { 
 				name = padvance(&path, argv[i]);
 				stunalloc(name);
 				out1fmt("%s\n", name);
 			} while (--j >= 0);
 			out1fmt(" is%s %s\n",
 			    cmdp ? " a tracked alias for" : "", name);
 			break;
 		}
 
 This seems to me an extremely awkward way of concatenating two
 strings... but never mind.
 
 To summarize, there are (at least) two bugs in the way find_command()
 treats command names with slashes in them:
 
  * it sets entry->u.index to 0, thus telling the caller that the
    command is in the first directory in the path
 
  * it does not check that the command actually exists and is
    executable by the current user, which results in the following:
 
 des@des ~% sh -c 'type this/file/does/not/exist'
 this/file/does/not/exist is /usr/home/des/bin/this/file/does/not/exist
 
 It is my humble opinion that the root of this problem lies with the
 use of padvance(), which is a horrible hackery. I would modify
 padvance() to take a numeric argument indicating which path component
 to use, rather than have it modify the path pointer, and to interpret
 -1 to mean "do not prepend anything at all". I would also modify it so
 it does not use a global variable (pathopt).
 
 DES
 -- 
 Dag-Erling Smorgrav - des@flood.ping.uio.no
 


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?199906071730.KAA34575>