summaryrefslogtreecommitdiffstats
path: root/libexec
diff options
context:
space:
mode:
authormdodd <mdodd@FreeBSD.org>2004-05-24 01:24:13 +0000
committermdodd <mdodd@FreeBSD.org>2004-05-24 01:24:13 +0000
commitc29bed19c8b31736bce40910d1ef1e2e85f6f07a (patch)
tree18dae3c6c57f45d1bee336c75c04f08312498ba5 /libexec
parentc06663e28d152236fb3e27ce54f4e8a540acd85d (diff)
downloadFreeBSD-src-c29bed19c8b31736bce40910d1ef1e2e85f6f07a.zip
FreeBSD-src-c29bed19c8b31736bce40910d1ef1e2e85f6f07a.tar.gz
Support basename and path based constrained matches.
eg: [foo] ... matches any executable 'foo' [/usr/bin/foo/] ... matches any executable under the directory /usr/bin/foo/ Exact matches continue to function as before. PR: bin/66769 Submitted-by: Dan Nelson
Diffstat (limited to 'libexec')
-rw-r--r--libexec/rtld-elf/libmap.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/libexec/rtld-elf/libmap.c b/libexec/rtld-elf/libmap.c
index e710fd5..4705bc6 100644
--- a/libexec/rtld-elf/libmap.c
+++ b/libexec/rtld-elf/libmap.c
@@ -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 char *f)
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;
+}
OpenPOWER on IntegriCloud