Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
elf: really analyse the content of an .a
Baptiste Daroussin committed 1 month ago
commit 637c144c25fc68418fb1dc03c6c4852ab9d96a0c
parent ccbaad9
2 files changed +75 -3
modified libpkg/pkg_elf.c
@@ -101,6 +101,29 @@ analyse_elf(struct pkg *pkg, const char *fpath, char **provided,
		goto cleanup;
	}

+
	if (elf_kind(e) == ELF_K_AR) {
+
		/*
+
		 * ar archive: check if it contains ELF objects.
+
		 * WASM .a archives contain non-ELF objects and
+
		 * should not be flagged as architecture-specific.
+
		 */
+
		if (ctx.developer_mode) {
+
			Elf_Cmd cmd = ELF_C_READ;
+
			Elf *member;
+
			while ((member = elf_begin(fd, cmd, e)) != NULL) {
+
				if (elf_kind(member) == ELF_K_ELF) {
+
					pkg->flags |= PKG_CONTAINS_STATIC_LIBS;
+
					elf_end(member);
+
					break;
+
				}
+
				cmd = elf_next(member);
+
				elf_end(member);
+
			}
+
		}
+
		ret = EPKG_END;
+
		goto cleanup;
+
	}
+

	if (elf_kind(e) != ELF_K_ELF) {
		/* Not an elf file: no results */
		ret = EPKG_END;
@@ -272,9 +295,6 @@ analyse_fpath(struct pkg *pkg, const char *fpath)
	if (dot == NULL)	/* No extension */
		return (EPKG_OK);

-
	if (dot[1] == 'a' && dot[2] == '\0')
-
		pkg->flags |= PKG_CONTAINS_STATIC_LIBS;
-

	if ((dot[1] == 'l' && dot[2] == 'a' && dot[3] == '\0'))
		pkg->flags |= PKG_CONTAINS_LA;

modified tests/lib/pkg_elf.c
@@ -95,9 +95,61 @@ ATF_TC_BODY(analyse_elf, tc)
	pkg_free(p);
}

+
ATF_TC_WITHOUT_HEAD(static_lib_non_elf);
+

+
ATF_TC_BODY(static_lib_non_elf, tc)
+
{
+
	struct pkg *p = NULL;
+
	char *provided = NULL;
+
	enum pkg_shlib_flags provided_flags = PKG_SHLIB_FLAGS_NONE;
+

+
	ctx.abi.os = PKG_OS_FREEBSD;
+
	ctx.abi.arch = PKG_ARCH_AMD64;
+
	ctx.developer_mode = true;
+

+
	/* Create a non-ELF .a archive (e.g. WASM static library) */
+
	FILE *fp = fopen("dummy.txt", "w");
+
	ATF_REQUIRE(fp != NULL);
+
	fprintf(fp, "not an ELF object\n");
+
	fclose(fp);
+
	ATF_REQUIRE_EQ(0, system("ar rcs libwasm.a dummy.txt"));
+

+
	/* Create an ELF .a archive (native static library) */
+
	fp = fopen("empty.c", "w");
+
	ATF_REQUIRE(fp != NULL);
+
	fprintf(fp, "int placeholder;\n");
+
	fclose(fp);
+
	ATF_REQUIRE_EQ(0, system("cc -c -o empty.o empty.c"));
+
	ATF_REQUIRE_EQ(0, system("ar rcs libnative.a empty.o"));
+

+
	/* Non-ELF .a should NOT set PKG_CONTAINS_STATIC_LIBS */
+
	ATF_REQUIRE_EQ(EPKG_OK, pkg_new(&p, PKG_INSTALLED));
+
	p->flags &= ~PKG_CONTAINS_STATIC_LIBS;
+
	ATF_REQUIRE_EQ(pkg_analyse_elf(true, p, "libwasm.a",
+
	    &provided, &provided_flags), EPKG_END);
+
	ATF_CHECK_EQ_MSG(0, p->flags & PKG_CONTAINS_STATIC_LIBS,
+
	    "non-ELF .a should not set PKG_CONTAINS_STATIC_LIBS");
+
	pkg_free(p);
+
	free(provided);
+

+
	/* ELF .a should set PKG_CONTAINS_STATIC_LIBS */
+
	provided = NULL;
+
	provided_flags = PKG_SHLIB_FLAGS_NONE;
+
	ATF_REQUIRE_EQ(EPKG_OK, pkg_new(&p, PKG_INSTALLED));
+
	p->flags &= ~PKG_CONTAINS_STATIC_LIBS;
+
	ATF_REQUIRE_EQ(pkg_analyse_elf(true, p, "libnative.a",
+
	    &provided, &provided_flags), EPKG_END);
+
	ATF_CHECK_EQ_MSG(PKG_CONTAINS_STATIC_LIBS,
+
	    p->flags & PKG_CONTAINS_STATIC_LIBS,
+
	    "ELF .a should set PKG_CONTAINS_STATIC_LIBS");
+
	pkg_free(p);
+
	free(provided);
+
}
+

ATF_TP_ADD_TCS(tp)
{
	ATF_TP_ADD_TC(tp, analyse_elf);
+
	ATF_TP_ADD_TC(tp, static_lib_non_elf);

	return (atf_no_error());
}