Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Merge pull request #922 from vstakhov/shlibabi
Vsevolod Stakhov committed 11 years ago
commit 88de6564e1738c0c020360ecd8491742e388cdf2
parent b5789f6
2 files changed +90 -2
modified libpkg/pkg_elf.c
@@ -45,7 +45,6 @@
#include <assert.h>
#include <ctype.h>
#include <dlfcn.h>
-
#include <err.h>
#include <fcntl.h>
#include <gelf.h>
#include <libgen.h>
@@ -75,6 +74,9 @@

#define roundup2(x, y)	(((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */

+
static const char * elf_corres_to_string(const struct _elf_corres* m, int e);
+
static int elf_string_to_corres(const struct _elf_corres* m, const char *s);
+

static int
filter_system_shlibs(const char *name, char *path, size_t pathlen)
{
@@ -127,13 +129,79 @@ add_shlibs_to_pkg(__unused void *actdata, struct pkg *pkg, const char *fpath,
		}

		pkg_get(pkg, PKG_NAME, &pkgname, PKG_VERSION, &pkgversion);
-
		warnx("(%s-%s) %s - shared library %s not found",
+
		pkg_emit_notice("(%s-%s) %s - shared library %s not found",
		      pkgname, pkgversion, fpath, name);

		return (EPKG_FATAL);
	}
}

+
static bool
+
shlib_valid_abi(GElf_Ehdr *hdr, const char *abi)
+
{
+
	int semicolon;
+
	const char *p, *t;
+
	char arch[64], wordsize[64];
+
	int narch, wclass;
+

+
	/*
+
	 * ABI string is in format:
+
	 * <osname>:<osversion>:<arch>:<wordsize>[.other]
+
	 * We need here arch and wordsize only
+
	 */
+
	arch[0] = '\0';
+
	wordsize[0] = '\0';
+
	p = abi;
+
	for(semicolon = 0; semicolon < 3 && p != NULL; semicolon ++, p ++) {
+
		p = strchr(p, ':');
+
		if (p != NULL) {
+
			switch(semicolon) {
+
			case 1:
+
				/* We have arch here */
+
				t = strchr(p + 1, ':');
+
				/* Abi line is likely invalid */
+
				if (t == NULL)
+
					return (true);
+
				strlcpy(arch, p + 1, MIN((long)sizeof(arch), t - p));
+
				break;
+
			case 2:
+
				t = strchr(p + 1, ':');
+
				if (t == NULL)
+
					strlcpy(wordsize, p + 1, sizeof(wordsize));
+
				else
+
					strlcpy(wordsize, p + 1, MIN((long)sizeof(wordsize), t - p));
+
				break;
+
			}
+
		}
+
	}
+
	/* Invalid ABI line */
+
	if (arch[0] == '\0' || wordsize[0] == '\0')
+
		return (true);
+

+
	narch = elf_string_to_corres(mach_corres, arch);
+
	if (narch == -1)
+
		return (true);
+

+
	wclass = elf_string_to_corres(wordsize_corres, wordsize);
+
	if (wclass == -1)
+
		return (true);
+

+

+
	if ((int)hdr->e_machine != narch) {
+
		pkg_debug(1, "not valid abi for shlib: %s",
+
			elf_corres_to_string(mach_corres, (int)hdr->e_machine));
+
		return (false);
+
	}
+
	if ((int)hdr->e_ident[EI_CLASS] != wclass) {
+
		pkg_debug(1, "not valid elf class for shlib: %s",
+
					elf_corres_to_string(wordsize_corres,
+
						(int)hdr->e_ident[EI_CLASS]));
+
		return (false);
+
	}
+

+
	return (true);
+
}
+

static int
analyse_elf(struct pkg *pkg, const char *fpath,
	int (action)(void *, struct pkg *, const char *, const char *, bool),
@@ -154,12 +222,14 @@ analyse_elf(struct pkg *pkg, const char *fpath,
	size_t sh_link = 0;
	size_t dynidx;
	const char *osname;
+
	const char *myarch;
	const char *shlib;

	bool developer = false;
	bool is_shlib = false;

	developer = pkg_object_bool(pkg_config_get("DEVELOPER_MODE"));
+
	myarch = pkg_object_string(pkg_config_get("ABI"));

	int fd;

@@ -235,6 +305,11 @@ analyse_elf(struct pkg *pkg, const char *fpath,
		goto cleanup; /* not a dynamically linked elf: no results */
	}

+
	if (!shlib_valid_abi(&elfhdr, myarch)) {
+
		ret = EPKG_END;
+
		goto cleanup; /* Invalid ABI */
+
	}
+

	if (note != NULL) {
		if ((data = elf_getdata(note, NULL)) == NULL) {
			ret = EPKG_END; /* Some error occurred, ignore this file */
@@ -462,6 +537,18 @@ elf_corres_to_string(const struct _elf_corres* m, int e)
	return ("unknown");
}

+
static int
+
elf_string_to_corres(const struct _elf_corres* m, const char *s)
+
{
+
	int i = 0;
+

+
	for (i = 0; m[i].string != NULL; i++)
+
		if (strcmp(m[i].string, s) == 0)
+
			return (m[i].elf_nb);
+

+
	return (-1);
+
}
+

static const char *
aeabi_parse_arm_attributes(void *data, size_t length)
{
modified libpkg/pkg_manifest.c
@@ -759,6 +759,7 @@ pkg_parse_manifest_fileat(int dfd, struct pkg *pkg, const char *file,

	p = ucl_parser_new(0);
	if (!ucl_parser_add_string(p, data, sz)) {
+
		pkg_emit_error("manifest parsing error: %s", ucl_parser_get_error(p));
		ucl_parser_free(p);
		return (EPKG_FATAL);
	}