Apply multiarch rules when loading plugins too.
This commit is contained in:
2
MANIFEST
2
MANIFEST
@@ -253,6 +253,7 @@ lib/util/mksiglist.c
|
||||
lib/util/mksigname.c
|
||||
lib/util/mktemp.c
|
||||
lib/util/mmap_alloc.c
|
||||
lib/util/multiarch.c
|
||||
lib/util/nanosleep.c
|
||||
lib/util/openat.c
|
||||
lib/util/parseln.c
|
||||
@@ -280,6 +281,7 @@ lib/util/regress/glob/globtest.c
|
||||
lib/util/regress/glob/globtest.in
|
||||
lib/util/regress/harness.in
|
||||
lib/util/regress/mktemp/mktemp_test.c
|
||||
lib/util/regress/multiarch/multiarch_test.c
|
||||
lib/util/regress/open_parent_dir/open_parent_dir_test.c
|
||||
lib/util/regress/parse_gids/parse_gids_test.c
|
||||
lib/util/regress/progname/progname_test.c
|
||||
|
@@ -262,6 +262,10 @@ sudo_dso_public void sudo_mmap_free_v1(void *ptr);
|
||||
sudo_dso_public int sudo_mmap_protect_v1(void *ptr);
|
||||
#define sudo_mmap_protect(_a) sudo_mmap_protect_v1(_a)
|
||||
|
||||
/* multiarch.c */
|
||||
sudo_dso_public char *sudo_stat_multiarch_v1(const char *path, struct stat *sb);
|
||||
#define sudo_stat_multiarch(_a, _b) sudo_stat_multiarch_v1((_a), (_b))
|
||||
|
||||
/* parseln.c */
|
||||
sudo_dso_public ssize_t sudo_parseln_v1(char **buf, size_t *bufsize, unsigned int *lineno, FILE *fp);
|
||||
sudo_dso_public ssize_t sudo_parseln_v2(char **buf, size_t *bufsize, unsigned int *lineno, FILE *fp, int flags);
|
||||
|
@@ -111,8 +111,8 @@ PVS_IGNORE = 'V707,V011,V002,V536'
|
||||
PVS_LOG_OPTS = -a 'GA:1,2' -e -t errorfile -d $(PVS_IGNORE)
|
||||
|
||||
# Regression tests
|
||||
TEST_PROGS = conf_test hltq_test parseln_test progname_test \
|
||||
parse_gids_test getgids getgrouplist_test open_parent_dir_test \
|
||||
TEST_PROGS = conf_test hltq_test parseln_test progname_test parse_gids_test \
|
||||
getgids getgrouplist_test multiarch_test open_parent_dir_test \
|
||||
strsplit_test strtobool_test strtoid_test strtomode_test \
|
||||
strtonum_test uuid_test @COMPAT_TEST_PROGS@
|
||||
TEST_LIBS = @LIBS@
|
||||
@@ -144,11 +144,11 @@ SHELL = @SHELL@
|
||||
|
||||
LTOBJS = basename.lo @DIGEST@ event.lo fatal.lo key_val.lo gethostname.lo \
|
||||
gettime.lo getgrouplist.lo gidlist.lo json.lo lbuf.lo locking.lo \
|
||||
logfac.lo logpri.lo mkdir_parents.lo mmap_alloc.lo parseln.lo \
|
||||
progname.lo rcstr.lo regex.lo roundup.lo secure_path.lo setgroups.lo \
|
||||
strsplit.lo strtobool.lo strtoid.lo strtomode.lo strtonum.lo \
|
||||
sudo_conf.lo sudo_debug.lo sudo_dso.lo term.lo ttyname_dev.lo \
|
||||
ttysize.lo uuid.lo @COMMON_OBJS@ @LTLIBOBJS@
|
||||
logfac.lo logpri.lo mkdir_parents.lo mmap_alloc.lo multiarch.lo \
|
||||
parseln.lo progname.lo rcstr.lo regex.lo roundup.lo secure_path.lo \
|
||||
setgroups.lo strsplit.lo strtobool.lo strtoid.lo strtomode.lo \
|
||||
strtonum.lo sudo_conf.lo sudo_debug.lo sudo_dso.lo term.lo \
|
||||
ttyname_dev.lo ttysize.lo uuid.lo @COMMON_OBJS@ @LTLIBOBJS@
|
||||
|
||||
IOBJS = $(LTOBJS:.lo=.i)
|
||||
|
||||
@@ -172,6 +172,8 @@ GLOBTEST_OBJS = globtest.lo glob.lo
|
||||
|
||||
GETDELIM_TEST_OBJS = getdelim_test.lo getdelim.lo
|
||||
|
||||
MULTIARCH_TEST_OBJS = multiarch_test.lo multiarch.lo
|
||||
|
||||
OPEN_PARENT_DIR_TEST_OBJS = open_parent_dir_test.lo mkdir_parents.lo
|
||||
|
||||
STRTOBOOL_TEST_OBJS = strtobool_test.lo strtobool.lo
|
||||
@@ -285,6 +287,9 @@ hltq_test: $(HLTQ_TEST_OBJS) libsudo_util.la
|
||||
mktemp_test: $(MKTEMP_TEST_OBJS) libsudo_util.la
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(MKTEMP_TEST_OBJS) libsudo_util.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(HARDENING_LDFLAGS) $(TEST_LDFLAGS) $(TEST_LIBS)
|
||||
|
||||
multiarch_test: $(MULTIARCH_TEST_OBJS) libsudo_util.la
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(MULTIARCH_TEST_OBJS) libsudo_util.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(HARDENING_LDFLAGS) $(TEST_LDFLAGS) $(TEST_LIBS)
|
||||
|
||||
open_parent_dir_test: $(OPEN_PARENT_DIR_TEST_OBJS) libsudo_util.la
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(OPEN_PARENT_DIR_TEST_OBJS) libsudo_util.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(HARDENING_LDFLAGS) $(TEST_LDFLAGS) $(TEST_LIBS)
|
||||
|
||||
@@ -460,6 +465,7 @@ check: $(TEST_PROGS) check-fuzzer
|
||||
./strsig_test || rval=`expr $$rval + $$?`; \
|
||||
fi; \
|
||||
./getgrouplist_test || rval=`expr $$rval + $$?`; \
|
||||
./multiarch_test || rval=`expr $$rval + $$?`; \
|
||||
./open_parent_dir_test || rval=`expr $$rval + $$?`; \
|
||||
./strtobool_test || rval=`expr $$rval + $$?`; \
|
||||
./strtoid_test || rval=`expr $$rval + $$?`; \
|
||||
@@ -1111,6 +1117,28 @@ mmap_alloc.i: $(srcdir)/mmap_alloc.c $(incdir)/compat/stdbool.h \
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
mmap_alloc.plog: mmap_alloc.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/mmap_alloc.c --i-file $< --output-file $@
|
||||
multiarch.lo: $(srcdir)/multiarch.c $(incdir)/compat/stdbool.h \
|
||||
$(incdir)/sudo_compat.h $(incdir)/sudo_util.h \
|
||||
$(top_builddir)/config.h
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(HARDENING_CFLAGS) $(srcdir)/multiarch.c
|
||||
multiarch.i: $(srcdir)/multiarch.c $(incdir)/compat/stdbool.h \
|
||||
$(incdir)/sudo_compat.h $(incdir)/sudo_util.h \
|
||||
$(top_builddir)/config.h
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
multiarch.plog: multiarch.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/multiarch.c --i-file $< --output-file $@
|
||||
multiarch_test.lo: $(srcdir)/regress/multiarch/multiarch_test.c \
|
||||
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
|
||||
$(incdir)/sudo_fatal.h $(incdir)/sudo_plugin.h \
|
||||
$(incdir)/sudo_util.h $(top_builddir)/config.h
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(HARDENING_CFLAGS) $(srcdir)/regress/multiarch/multiarch_test.c
|
||||
multiarch_test.i: $(srcdir)/regress/multiarch/multiarch_test.c \
|
||||
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
|
||||
$(incdir)/sudo_fatal.h $(incdir)/sudo_plugin.h \
|
||||
$(incdir)/sudo_util.h $(top_builddir)/config.h
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
multiarch_test.plog: multiarch_test.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/multiarch/multiarch_test.c --i-file $< --output-file $@
|
||||
nanosleep.lo: $(srcdir)/nanosleep.c $(incdir)/compat/stdbool.h \
|
||||
$(incdir)/sudo_compat.h $(incdir)/sudo_util.h \
|
||||
$(top_builddir)/config.h
|
||||
@@ -1527,11 +1555,13 @@ sudo_debug.i: $(srcdir)/sudo_debug.c $(incdir)/compat/stdbool.h \
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
sudo_debug.plog: sudo_debug.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/sudo_debug.c --i-file $< --output-file $@
|
||||
sudo_dso.lo: $(srcdir)/sudo_dso.c $(incdir)/sudo_compat.h $(incdir)/sudo_dso.h \
|
||||
$(top_builddir)/config.h
|
||||
sudo_dso.lo: $(srcdir)/sudo_dso.c $(incdir)/compat/stdbool.h \
|
||||
$(incdir)/sudo_compat.h $(incdir)/sudo_dso.h \
|
||||
$(incdir)/sudo_util.h $(top_builddir)/config.h
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(HARDENING_CFLAGS) $(srcdir)/sudo_dso.c
|
||||
sudo_dso.i: $(srcdir)/sudo_dso.c $(incdir)/sudo_compat.h $(incdir)/sudo_dso.h \
|
||||
$(top_builddir)/config.h
|
||||
sudo_dso.i: $(srcdir)/sudo_dso.c $(incdir)/compat/stdbool.h \
|
||||
$(incdir)/sudo_compat.h $(incdir)/sudo_dso.h \
|
||||
$(incdir)/sudo_util.h $(top_builddir)/config.h
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
sudo_dso.plog: sudo_dso.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/sudo_dso.c --i-file $< --output-file $@
|
||||
|
103
lib/util/multiarch.c
Normal file
103
lib/util/multiarch.c
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: ISC
|
||||
*
|
||||
* Copyright (c) 2022 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is an open source non-commercial project. Dear PVS-Studio, please check it.
|
||||
* PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ifdef __linux__
|
||||
# include <sys/utsname.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "sudo_compat.h"
|
||||
#include "sudo_util.h"
|
||||
|
||||
# if defined(__linux__)
|
||||
/*
|
||||
* On Linux systems that use muti-arch, the actual DSO may be in a
|
||||
* machine-specific subdirectory. If the specified path contains
|
||||
* /lib/ or /libexec/, insert a multi-arch directory after it.
|
||||
* If sb is non-NULL, stat(2) will be called on the new path, filling in sb.
|
||||
* Returns a dynamically allocated string on success and NULL on failure.
|
||||
*/
|
||||
char *
|
||||
sudo_stat_multiarch_v1(const char *path, struct stat *sb)
|
||||
{
|
||||
# if defined(__ILP32__)
|
||||
const char *libdirs[] = { "/libx32/", "/lib/", "/libexec/", NULL };
|
||||
# elif defined(__LP64__)
|
||||
const char *libdirs[] = { "/lib64/", "/lib/", "/libexec/", NULL };
|
||||
# else
|
||||
const char *libdirs[] = { "/lib32/", "/lib/", "/libexec/", NULL };
|
||||
# endif
|
||||
const char **lp, *lib, *slash;
|
||||
struct utsname unamebuf;
|
||||
char *newpath = NULL;
|
||||
int len;
|
||||
|
||||
if (uname(&unamebuf) == -1)
|
||||
return NULL;
|
||||
|
||||
for (lp = libdirs; *lp != NULL; lp++) {
|
||||
/* Replace lib64, lib32, libx32 with lib in new path. */
|
||||
const char *newlib = lp == libdirs ? "/lib/" : *lp;
|
||||
|
||||
/* Search for lib dir in path, find the trailing slash. */
|
||||
lib = strstr(path, *lp);
|
||||
if (lib == NULL)
|
||||
continue;
|
||||
slash = lib + strlen(*lp) - 1;
|
||||
|
||||
/* Make sure there isn't already a machine-linux-gnu dir. */
|
||||
len = strcspn(slash + 1, "/-");
|
||||
if (strncmp(slash + 1 + len, "-linux-gnu/", 11) == 0) {
|
||||
/* Multiarch already present. */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Add machine-linux-gnu dir after /lib/ or /libexec/. */
|
||||
len = asprintf(&newpath, "%.*s%s%s-linux-gnu%s",
|
||||
(int)(lib - path), path, newlib, unamebuf.machine, slash);
|
||||
if (len == -1) {
|
||||
newpath = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* If sb was set, use stat(2) to make sure newpath exists. */
|
||||
if (sb == NULL || stat(newpath, sb) == 0)
|
||||
break;
|
||||
free(newpath);
|
||||
newpath = NULL;
|
||||
}
|
||||
|
||||
return newpath;
|
||||
}
|
||||
#else
|
||||
char *
|
||||
sudo_stat_multiarch_v1(const char *path, struct stat *sb)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif /* __linux__ */
|
178
lib/util/regress/multiarch/multiarch_test.c
Normal file
178
lib/util/regress/multiarch/multiarch_test.c
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: ISC
|
||||
*
|
||||
* Copyright (c) 2022 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define SUDO_ERROR_WRAP 0
|
||||
|
||||
#include "sudo_compat.h"
|
||||
#include "sudo_fatal.h"
|
||||
#include "sudo_util.h"
|
||||
|
||||
sudo_dso_public int main(int argc, char *argv[]);
|
||||
|
||||
#ifdef __linux__
|
||||
# include <sys/utsname.h>
|
||||
|
||||
# if defined(__ILP32__)
|
||||
# define ARCH_LIB "libx32"
|
||||
# elif defined(__LP64__)
|
||||
# define ARCH_LIB "lib64"
|
||||
# else
|
||||
# define ARCH_LIB "lib32"
|
||||
# endif
|
||||
|
||||
struct multiarch_test {
|
||||
const char *inpath;
|
||||
char *outpath;
|
||||
};
|
||||
|
||||
static struct multiarch_test *
|
||||
make_test_data(void)
|
||||
{
|
||||
struct multiarch_test *test_data;
|
||||
struct utsname unamebuf;
|
||||
int i;
|
||||
|
||||
if (uname(&unamebuf) == -1)
|
||||
return NULL;
|
||||
|
||||
test_data = calloc(7, sizeof(*test_data));
|
||||
if (test_data == NULL)
|
||||
return NULL;
|
||||
|
||||
test_data[0].inpath = "/usr/" ARCH_LIB "/libfoo.so";
|
||||
i = asprintf(&test_data[0].outpath, "/usr/lib/%s-linux-gnu/libfoo.so",
|
||||
unamebuf.machine);
|
||||
if (i == -1) {
|
||||
test_data[0].outpath = NULL;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
test_data[1].inpath = "/usr/lib/something.so";
|
||||
i = asprintf(&test_data[1].outpath, "/usr/lib/%s-linux-gnu/something.so",
|
||||
unamebuf.machine);
|
||||
if (i == -1) {
|
||||
test_data[1].outpath = NULL;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
test_data[2].inpath = "/usr/libexec/libbar.so";
|
||||
i = asprintf(&test_data[2].outpath, "/usr/libexec/%s-linux-gnu/libbar.so",
|
||||
unamebuf.machine);
|
||||
if (i == -1) {
|
||||
test_data[2].outpath = NULL;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
test_data[3].inpath = "/usr/local/lib/sudo/libsudo_util.so";
|
||||
i = asprintf(&test_data[3].outpath, "/usr/local/lib/%s-linux-gnu/sudo/libsudo_util.so",
|
||||
unamebuf.machine);
|
||||
if (i == -1) {
|
||||
test_data[3].outpath = NULL;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
test_data[4].inpath = "/opt/sudo/lib/sudoers.so";
|
||||
i = asprintf(&test_data[4].outpath, "/opt/sudo/lib/%s-linux-gnu/sudoers.so",
|
||||
unamebuf.machine);
|
||||
if (i == -1) {
|
||||
test_data[4].outpath = NULL;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
i = asprintf(&test_data[5].outpath, "/usr/lib/%s-linux-gnu/something.so",
|
||||
unamebuf.machine);
|
||||
if (i == -1) {
|
||||
test_data[5].outpath = NULL;
|
||||
goto bad;
|
||||
}
|
||||
test_data[5].inpath = test_data[5].outpath;
|
||||
test_data[5].outpath = NULL;
|
||||
|
||||
return test_data;
|
||||
bad:
|
||||
for (i = 0; test_data[i].outpath != NULL; i++)
|
||||
free(test_data[i].outpath);
|
||||
free(test_data);
|
||||
return NULL;
|
||||
}
|
||||
#endif /* __linux__ */
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int ch, errors = 0;
|
||||
#ifdef __linux__
|
||||
int ntests = 0;
|
||||
struct multiarch_test *test_data;
|
||||
#endif
|
||||
|
||||
initprogname(argc > 0 ? argv[0] : "multiarch_test");
|
||||
|
||||
while ((ch = getopt(argc, argv, "v")) != -1) {
|
||||
switch (ch) {
|
||||
case 'v':
|
||||
/* ignore */
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "usage: %s [-v]\n", getprogname());
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
#ifdef __linux__
|
||||
test_data = make_test_data();
|
||||
if (test_data == NULL) {
|
||||
sudo_warnx("%s", "failed to generate test data");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
for (ch = 0; test_data[ch].inpath != NULL; ch++) {
|
||||
char *outpath = sudo_stat_multiarch(test_data[ch].inpath, NULL);
|
||||
ntests++;
|
||||
if (outpath == NULL) {
|
||||
if (test_data[ch].outpath != NULL) {
|
||||
sudo_warnx("%s: sudo_stat_multiarch failed",
|
||||
test_data[ch].inpath);
|
||||
errors++;
|
||||
}
|
||||
} else if (strcmp(outpath, test_data[ch].outpath) != 0) {
|
||||
sudo_warnx("%s: expected %s got %s", test_data[ch].inpath,
|
||||
test_data[ch].outpath, outpath);
|
||||
errors++;
|
||||
free(outpath);
|
||||
}
|
||||
}
|
||||
|
||||
if (ntests != 0) {
|
||||
printf("%s: %d tests run, %d errors, %d%% success rate\n",
|
||||
getprogname(), ntests, errors, (ntests - errors) * 100 / ntests);
|
||||
}
|
||||
#endif /* __linux__ */
|
||||
return errors;
|
||||
}
|
@@ -39,6 +39,7 @@
|
||||
|
||||
#include "sudo_compat.h"
|
||||
#include "sudo_dso.h"
|
||||
#include "sudo_util.h"
|
||||
|
||||
/*
|
||||
* Pointer for statically compiled symbols.
|
||||
@@ -183,47 +184,27 @@ sudo_dso_strerror_v1(void)
|
||||
static void *
|
||||
dlopen_multi_arch(const char *path, int flags)
|
||||
{
|
||||
# if defined(__ILP32__)
|
||||
const char *libdirs[] = { "/libx32/", "/lib/", "/libexec/", NULL };
|
||||
# elif defined(__LP64__)
|
||||
const char *libdirs[] = { "/lib64/", "/lib/", "/libexec/", NULL };
|
||||
# else
|
||||
const char *libdirs[] = { "/lib32/", "/lib/", "/libexec/", NULL };
|
||||
# endif
|
||||
const char **lp, *lib, *slash;
|
||||
struct utsname unamebuf;
|
||||
void *ret = NULL;
|
||||
struct stat sb;
|
||||
char *newpath;
|
||||
int len;
|
||||
|
||||
/* Only try multi-arch if the original path does not exist. */
|
||||
if (stat(path, &sb) == -1 && errno == ENOENT && uname(&unamebuf) == 0) {
|
||||
for (lp = libdirs; *lp != NULL; lp++) {
|
||||
/* Replace lib64, lib32, libx32 with lib in new path. */
|
||||
const char *newlib = lp == libdirs ? "/lib/" : *lp;
|
||||
|
||||
/* Search for lib dir in path, find the trailing slash. */
|
||||
lib = strstr(path, *lp);
|
||||
if (lib == NULL)
|
||||
continue;
|
||||
slash = lib + strlen(*lp) - 1;
|
||||
|
||||
/* Add machine-linux-gnu dir after /lib/ or /libexec/. */
|
||||
len = asprintf(&newpath, "%.*s%s%s-linux-gnu%s",
|
||||
(int)(lib - path), path, newlib, unamebuf.machine, slash);
|
||||
if (len == -1)
|
||||
break;
|
||||
if (stat(newpath, &sb) == 0)
|
||||
ret = dlopen(newpath, flags);
|
||||
if (stat(path, &sb) == -1 && errno == ENOENT) {
|
||||
newpath = sudo_stat_multiarch(path, &sb);
|
||||
if (newpath != NULL) {
|
||||
ret = dlopen(newpath, flags);
|
||||
free(newpath);
|
||||
if (ret != NULL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif /* __linux__ */
|
||||
# else
|
||||
static void *
|
||||
dlopen_multi_arch(const char *path, int flags)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
# endif /* __linux__ */
|
||||
|
||||
void *
|
||||
sudo_dso_load_v1(const char *path, int mode)
|
||||
@@ -231,9 +212,9 @@ sudo_dso_load_v1(const char *path, int mode)
|
||||
struct sudo_preload_table *pt;
|
||||
int flags = 0;
|
||||
void *ret;
|
||||
#ifdef RTLD_MEMBER
|
||||
# ifdef RTLD_MEMBER
|
||||
char *cp;
|
||||
#endif
|
||||
# endif
|
||||
|
||||
/* Check prelinked symbols first. */
|
||||
if (preload_table != NULL) {
|
||||
@@ -253,7 +234,7 @@ sudo_dso_load_v1(const char *path, int mode)
|
||||
if (ISSET(mode, SUDO_DSO_LOCAL))
|
||||
SET(flags, RTLD_LOCAL);
|
||||
|
||||
#ifdef RTLD_MEMBER
|
||||
# ifdef RTLD_MEMBER
|
||||
/* Check for AIX path(module) syntax and add RTLD_MEMBER for a module. */
|
||||
cp = strrchr(path, '(');
|
||||
if (cp != NULL) {
|
||||
@@ -261,9 +242,9 @@ sudo_dso_load_v1(const char *path, int mode)
|
||||
if (len > 2 && cp[len - 1] == '\0')
|
||||
SET(flags, RTLD_MEMBER);
|
||||
}
|
||||
#endif /* RTLD_MEMBER */
|
||||
# endif /* RTLD_MEMBER */
|
||||
ret = dlopen(path, flags);
|
||||
#if defined(RTLD_MEMBER)
|
||||
# if defined(RTLD_MEMBER)
|
||||
/*
|
||||
* If we try to dlopen() an AIX .a file without an explicit member
|
||||
* it will fail with ENOEXEC. Try again using the default member.
|
||||
@@ -278,11 +259,10 @@ sudo_dso_load_v1(const char *path, int mode)
|
||||
ret = dlopen(path, flags);
|
||||
}
|
||||
}
|
||||
#elif defined(__linux__)
|
||||
# endif /* RTLD_MEMBER */
|
||||
/* On failure, try again with a muti-arch path where possible. */
|
||||
if (ret == NULL)
|
||||
ret = dlopen_multi_arch(path, flags);
|
||||
#endif /* RTLD_MEMBER */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@@ -131,6 +131,7 @@ sudo_secure_file_v1
|
||||
sudo_secure_open_dir_v1
|
||||
sudo_secure_open_file_v1
|
||||
sudo_setgroups_v1
|
||||
sudo_stat_multiarch_v1
|
||||
sudo_str2logfac_v1
|
||||
sudo_str2logpri_v1
|
||||
sudo_strsplit_v1
|
||||
|
@@ -43,6 +43,7 @@ sudo_stat_plugin(struct plugin_info *info, char *fullpath,
|
||||
size_t pathsize, struct stat *sb)
|
||||
{
|
||||
int status = -1;
|
||||
size_t len;
|
||||
debug_decl(sudo_stat_plugin, SUDO_DEBUG_PLUGIN);
|
||||
|
||||
if (info->path[0] == '/') {
|
||||
@@ -52,8 +53,6 @@ sudo_stat_plugin(struct plugin_info *info, char *fullpath,
|
||||
}
|
||||
status = stat(fullpath, sb);
|
||||
} else {
|
||||
int len;
|
||||
|
||||
#ifdef STATIC_SUDOERS_PLUGIN
|
||||
/* Check static symbols. */
|
||||
if (strcmp(info->path, SUDOERS_PLUGIN) == 0) {
|
||||
@@ -77,20 +76,22 @@ sudo_stat_plugin(struct plugin_info *info, char *fullpath,
|
||||
|
||||
len = snprintf(fullpath, pathsize, "%s%s", sudo_conf_plugin_dir_path(),
|
||||
info->path);
|
||||
if (len < 0 || (size_t)len >= pathsize) {
|
||||
if (len >= pathsize) {
|
||||
errno = ENAMETOOLONG;
|
||||
goto done;
|
||||
}
|
||||
/* Try parent dir for compatibility with old plugindir default. */
|
||||
if ((status = stat(fullpath, sb)) != 0) {
|
||||
char *cp = strrchr(fullpath, '/');
|
||||
if (cp > fullpath + 4 && cp[-5] == '/' && cp[-4] == 's' &&
|
||||
cp[-3] == 'u' && cp[-2] == 'd' && cp[-1] == 'o') {
|
||||
int serrno = errno;
|
||||
strlcpy(cp - 4, info->path, pathsize - (cp - 4 - fullpath));
|
||||
if ((status = stat(fullpath, sb)) != 0)
|
||||
errno = serrno;
|
||||
status = stat(fullpath, sb);
|
||||
}
|
||||
if (status == -1) {
|
||||
char *newpath = sudo_stat_multiarch(fullpath, sb);
|
||||
if (newpath != NULL) {
|
||||
len = strlcpy(fullpath, newpath, pathsize);
|
||||
free(newpath);
|
||||
if (len >= pathsize) {
|
||||
errno = ENAMETOOLONG;
|
||||
goto done;
|
||||
}
|
||||
status = 0;
|
||||
}
|
||||
}
|
||||
done:
|
||||
|
Reference in New Issue
Block a user