Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 17 May 2004 12:43:50 -0500 (CDT)
From:      Dan Nelson <dnelson@allantgroup.com>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   bin/66769: [PATCH] more flexible libmap matching rules
Message-ID:  <200405171743.i4HHho3S043920@dan.emsphone.com>
Resent-Message-ID: <200405171750.i4HHoAW4095836@freefall.freebsd.org>

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

>Number:         66769
>Category:       bin
>Synopsis:       [PATCH] more flexible libmap matching rules
>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:   Mon May 17 10:50:10 PDT 2004
>Closed-Date:
>Last-Modified:
>Originator:     Dan Nelson
>Release:        FreeBSD 5.2-CURRENT i386
>Organization:
>Environment:
System: FreeBSD dan.emsphone.com 5.2-CURRENT FreeBSD 5.2-CURRENT #329: Wed May 12 01:05:37 CDT 2004 dan@dan.emsphone.com:/usr/src/sys/i386/compile/DANSMP i386


	
>Description:

Allows three matching styles for libmap.conf:

[progname]          matches all executables whose basename is 'progname'
[/usr/local/bin/]   matches all executables under /usr/local/bin/
[/usr/bin/ls]       matches only this executable (note ./ls and
                    /usr/bin/./ls will not match)

The current libmap code only supports the third style, which is also
the least useful .

	
>How-To-Repeat:
	
>Fix:

Index: /usr/src/share/man/man5/libmap.conf.5
===================================================================
RCS file: /home/ncvs/src/share/man/man5/libmap.conf.5,v
retrieving revision 1.5
diff -u -p -r1.5 libmap.conf.5
--- /usr/src/share/man/man5/libmap.conf.5	31 Jan 2004 22:02:03 -0000	1.5
+++ /usr/src/share/man/man5/libmap.conf.5	17 May 2004 17:38:20 -0000
@@ -46,14 +46,44 @@ Dependencies are matched against candida
 Constrained mappings may be specified by enclosing the name of the
 executable or library in brackets.
 All mappings following a constraint will only be evaluated for that constraint.
-Currently, constraints
-are matched literally so that an executable with a fully qualified pathname
-will only match the same constraint.
-This means that
+Constraints can be one of three types:
+.Bl -tag -width indent
+.It Exact 
+The constraint is matched literally so that only an executable with an
+identical fully qualified pathname will match the constraint.
+This means that the executable
 .Pa /usr/bin/foo
 will not match a constraint for
-.Pa foo
+.Pa /usr/bin/./foo
 and vise-versa.
+This is the default constraint type.
+.It Basename
+A constraint with no path is matched against the basename of the
+executable.
+.Pa foo
+will match 
+.Pa /bin/foo ,
+.Pa /usr/local/sbin/foo ,
+or any other executable named 
+.Pa foo ,
+no matter what its path is.
+.It Directory
+A constraint with a trailing slash is prefix-matched against the full
+pathname of the executable.
+.Pa /usr/bin/
+will match any executable with a path starting with /usr/bin.
+.El
+.Pp
+Note that the executable path matched against is the 
+.Pa path
+parameter in an 
+.Fn exec*
+function call. 
+The Directory or Exact constraints can only match when the executable
+is called with a full pathname.
+Most programs executed from a shell are run without a full path, via
+.Fn exec*p ,
+so the Basename constraint type is the most useful.  
 .Pp
 WARNING!
 Constrained mappings must never appear first in the configuration file.
@@ -77,19 +107,17 @@ libpthread.so		libpthread.so
 libc_r.so.5		libpthread.so.1	# Everything that uses 'libc_r'
 libc_r.so		libpthread.so	# now uses 'libpthread'
 
-[/usr/local/bin/mplayer]		# 'mplayer' uses libc_r.
-libpthread.so.1		libc_r.so.5
-libpthread.so		libc_r.so
-
-[mplayer]
+[/tmp/mplayer]		# Test version of mplayer uses libc_r
 libpthread.so.1		libc_r.so.5
 libpthread.so		libc_r.so
 
-[/usr/local/sbin/httpd]			# Apache uses libthr
-libpthread.so.1		libthr.so.1
-libpthread.so		libthr.so
+[mplayer]		# All other mplayers use libpthread
+libpthread.so.1		libpthread.so.1
+libpthread.so		libpthread.so
 
-[httpd]
+[/usr/local/jdk1.4.1/]	# All Java 1.4.1 programs use libthr
+			# This works because "javavms" executes
+			# programs with the full pathname
 libpthread.so.1		libthr.so.1
 libpthread.so		libthr.so
 .Ed
Index: /usr/src/libexec/rtld-elf/libmap.c
===================================================================
RCS file: /home/ncvs/src/libexec/rtld-elf/libmap.c,v
retrieving revision 1.11
diff -u -p -r1.11 libmap.c
--- /usr/src/libexec/rtld-elf/libmap.c	21 Mar 2004 01:21:26 -0000	1.11
+++ /usr/src/libexec/rtld-elf/libmap.c	14 Apr 2004 21:35:19 -0000
@@ -33,6 +33,7 @@ struct lm {
 TAILQ_HEAD(lmp_list, lmp) lmp_head = TAILQ_HEAD_INITIALIZER(lmp_head);
 struct lmp {
 	char *p;
+	enum { T_EXACT=0, T_BASENAME, T_DIRECTORY } type;
 	struct lm_list lml;
 	TAILQ_ENTRY(lmp) lmp_link;
 };
@@ -42,6 +43,7 @@ static void		lm_free		(struct lm_list *)
 static char *		lml_find	(struct lm_list *, const char *);
 static struct lm_list *	lmp_find	(const char *);
 static struct lm_list *	lmp_init	(char *);
+static const char * quickbasename	(const char *);
 
 #define	iseol(c)	(((c) == '#') || ((c) == '\0') || \
 			 ((c) == '\n') || ((c) == '\r'))
@@ -216,6 +218,8 @@ lm_find (const char *p, const char *f)
 		return (NULL);
 }
 
+/* Given a libmap translation list and a library name, return the
+   replacement library, or NULL */
 #ifdef COMPAT_32BIT
 char *
 lm_findn (const char *p, const char *f, const int n)
@@ -250,6 +254,8 @@ lml_find (struct lm_list *lmh, const cha
 	return NULL;
 }
 
+/* Given an executable name, return a pointer to the translation list or
+   NULL if no matches */
 static struct lm_list *
 lmp_find (const char *n)
 {
@@ -258,7 +264,9 @@ lmp_find (const char *n)
 	dbg("%s(\"%s\")", __func__, n);
 
 	TAILQ_FOREACH(lmp, &lmp_head, lmp_link)
-		if (strcmp(n, lmp->p) == 0)
+		if ((lmp->type == T_EXACT && strcmp(n, lmp->p) == 0) ||
+		    (lmp->type == T_DIRECTORY && strncmp(n, lmp->p, strlen(lmp->p)) == 0) ||
+		    (lmp->type == T_BASENAME && strcmp(quickbasename(n), lmp->p) == 0))
 			return (&lmp->lml);
 	return (NULL);
 }
@@ -272,8 +280,28 @@ lmp_init (char *n)
 
 	lmp = xmalloc(sizeof(struct lmp));
 	lmp->p = n;
+	if (n[strlen(n)-1] == '/')
+		lmp->type = T_DIRECTORY;
+	else if (strchr(n,'/') == NULL)
+		lmp->type = T_BASENAME;
+	else
+		lmp->type = T_EXACT;
 	TAILQ_INIT(&lmp->lml);
 	TAILQ_INSERT_HEAD(&lmp_head, lmp, lmp_link);
 
 	return (&lmp->lml);
 }
+
+/* libc basename is overkill.  Return a pointer to the character after the
+   last /, or the original string if there are no slashes. */
+static const char *
+quickbasename (const char *path)
+{
+	const char *p = path;
+	for (; *path; path++)
+	{
+		if (*path == '/')
+			p = path+1;
+	}
+	return p;
+}

	


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



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