mirror of
https://git.yoctoproject.org/poky
synced 2026-06-04 14:09:47 +00:00
insane.bbclass: add QA tests for unsafe references to exec_prefix
Files under exec_prefix (commonly /usr) may not be available during system recovery. exec_prefix may also be kept on a separate partition that is mounted late in the boot process. This QA test throws an warning if a binary in base_[bindir|sbindir|libdir] is dynamically linked to a file under exec_prefix. The intention is to turn this into an error in the near future. It also checks executable non-binaries (e.g, shell scripts) in the above base directories with a simple grep test to look for references to exec_prefix. This test only produces a warning, since false positives are likely. This fixes [YOCTO #1008] (From OE-Core rev: 3e9c368a8045044736fc7e348404060498c7491b) Signed-off-by: Scott Garman <scott.a.garman@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
committed by
Richard Purdie
parent
d34292c0c2
commit
29feb44e05
+109
-2
@@ -11,6 +11,10 @@
|
|||||||
# -Check if packages contains .debug directories or .so files
|
# -Check if packages contains .debug directories or .so files
|
||||||
# where they should be in -dev or -dbg
|
# where they should be in -dev or -dbg
|
||||||
# -Check if config.log contains traces to broken autoconf tests
|
# -Check if config.log contains traces to broken autoconf tests
|
||||||
|
# -Ensure that binaries in base_[bindir|sbindir|libdir] do not link
|
||||||
|
# into exec_prefix
|
||||||
|
# -Check that scripts in base_[bindir|sbindir|libdir] do not reference
|
||||||
|
# files under exec_prefix
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -19,9 +23,14 @@
|
|||||||
# The package.bbclass can help us here.
|
# The package.bbclass can help us here.
|
||||||
#
|
#
|
||||||
inherit package
|
inherit package
|
||||||
PACKAGE_DEPENDS += "pax-utils-native desktop-file-utils-native"
|
PACKAGE_DEPENDS += "pax-utils-native desktop-file-utils-native ${QADEPENDS}"
|
||||||
PACKAGEFUNCS += " do_package_qa "
|
PACKAGEFUNCS += " do_package_qa "
|
||||||
|
|
||||||
|
# unsafe-references-in-binaries requires prelink-rtld from
|
||||||
|
# prelink-native, but we don't want this DEPENDS for -native builds
|
||||||
|
QADEPENDS = "prelink-native"
|
||||||
|
QADEPENDS_virtclass-native = ""
|
||||||
|
QADEPENDS_virtclass-nativesdk = ""
|
||||||
|
|
||||||
#
|
#
|
||||||
# dictionary for elf headers
|
# dictionary for elf headers
|
||||||
@@ -100,7 +109,7 @@ def package_qa_get_machine_dict():
|
|||||||
|
|
||||||
|
|
||||||
# Currently not being used by default "desktop"
|
# Currently not being used by default "desktop"
|
||||||
WARN_QA ?= "ldflags useless-rpaths rpaths"
|
WARN_QA ?= "ldflags useless-rpaths rpaths unsafe-references-in-binaries unsafe-references-in-scripts"
|
||||||
ERROR_QA ?= "dev-so debug-deps dev-deps debug-files arch la2 pkgconfig la perms"
|
ERROR_QA ?= "dev-so debug-deps dev-deps debug-files arch la2 pkgconfig la perms"
|
||||||
|
|
||||||
def package_qa_clean_path(path,d):
|
def package_qa_clean_path(path,d):
|
||||||
@@ -201,6 +210,104 @@ def package_qa_check_perm(path,name,d, elf, messages):
|
|||||||
"""
|
"""
|
||||||
return
|
return
|
||||||
|
|
||||||
|
QAPATHTEST[unsafe-references-in-binaries] = "package_qa_check_unsafe_references_in_binaries"
|
||||||
|
def package_qa_check_unsafe_references_in_binaries(path, name, d, elf, messages):
|
||||||
|
"""
|
||||||
|
Ensure binaries in base_[bindir|sbindir|libdir] do not link to files under exec_prefix
|
||||||
|
"""
|
||||||
|
if unsafe_references_skippable(path, name, d):
|
||||||
|
return
|
||||||
|
|
||||||
|
if elf:
|
||||||
|
import subprocess as sub
|
||||||
|
pn = d.getVar('PN', True)
|
||||||
|
|
||||||
|
exec_prefix = d.getVar('exec_prefix', True)
|
||||||
|
sysroot_path = d.getVar('STAGING_DIR_TARGET', True)
|
||||||
|
sysroot_path_usr = sysroot_path + exec_prefix
|
||||||
|
|
||||||
|
try:
|
||||||
|
ldd_output = sub.check_output(["prelink-rtld", "--root", sysroot_path, path])
|
||||||
|
except sub.CalledProcessError as e:
|
||||||
|
if e.returncode != 127:
|
||||||
|
error_msg = pn + ": prelink-rtld aborted when processing %s" % path
|
||||||
|
package_qa_handle_error("unsafe-references-in-binaries", error_msg, d)
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
# Sometimes this is done deliberately (e.g, e2fsprogs), so only warn
|
||||||
|
bb.warn("%s has missing library dependencies" % path)
|
||||||
|
return
|
||||||
|
if sysroot_path_usr in ldd_output:
|
||||||
|
error_msg = pn + ": %s links to something under exec_prefix" % path
|
||||||
|
package_qa_handle_error("unsafe-references-in-binaries", error_msg, d)
|
||||||
|
error_msg = "ldd reports: %s" % ldd_output
|
||||||
|
package_qa_handle_error("unsafe-references-in-binaries", error_msg, d)
|
||||||
|
return False
|
||||||
|
|
||||||
|
QAPATHTEST[unsafe-references-in-scripts] = "package_qa_check_unsafe_references_in_scripts"
|
||||||
|
def package_qa_check_unsafe_references_in_scripts(path, name, d, elf, messages):
|
||||||
|
"""
|
||||||
|
Warn if scripts in base_[bindir|sbindir|libdir] reference files under exec_prefix
|
||||||
|
"""
|
||||||
|
if unsafe_references_skippable(path, name, d):
|
||||||
|
return
|
||||||
|
|
||||||
|
if not elf:
|
||||||
|
import stat
|
||||||
|
pn = d.getVar('PN', True)
|
||||||
|
|
||||||
|
# Ensure we're checking an executable script
|
||||||
|
statinfo = os.stat(path)
|
||||||
|
if bool(statinfo.st_mode & stat.S_IXUSR):
|
||||||
|
# grep shell scripts for possible references to /exec_prefix/
|
||||||
|
exec_prefix = d.getVar('exec_prefix', True)
|
||||||
|
statement = "grep -e '%s/' %s > /dev/null" % (exec_prefix, path)
|
||||||
|
if os.system(statement) == 0:
|
||||||
|
error_msg = pn + ": Found a reference to %s/ in %s" % (exec_prefix, path)
|
||||||
|
package_qa_handle_error("unsafe-references-in-scripts", error_msg, d)
|
||||||
|
error_msg = "Shell scripts in base_bindir and base_sbindir should not reference anything in exec_prefix"
|
||||||
|
package_qa_handle_error("unsafe-references-in-scripts", error_msg, d)
|
||||||
|
|
||||||
|
def unsafe_references_skippable(path, name, d):
|
||||||
|
if bb.data.inherits_class('native', d) or bb.data.inherits_class('nativesdk', d):
|
||||||
|
return True
|
||||||
|
|
||||||
|
if "-dbg" in name or "-dev" in name:
|
||||||
|
return True
|
||||||
|
|
||||||
|
# Other package names to skip:
|
||||||
|
if name.startswith("kernel-module-"):
|
||||||
|
return True
|
||||||
|
|
||||||
|
# Skip symlinks
|
||||||
|
if os.path.islink(path):
|
||||||
|
return True
|
||||||
|
|
||||||
|
# Skip unusual rootfs layouts which make these tests irrelevant
|
||||||
|
exec_prefix = d.getVar('exec_prefix', True)
|
||||||
|
if exec_prefix == "":
|
||||||
|
return True
|
||||||
|
|
||||||
|
pkgdest = d.getVar('PKGDEST', True)
|
||||||
|
pkgdest = pkgdest + "/" + name
|
||||||
|
pkgdest = os.path.abspath(pkgdest)
|
||||||
|
base_bindir = pkgdest + d.getVar('base_bindir', True)
|
||||||
|
base_sbindir = pkgdest + d.getVar('base_sbindir', True)
|
||||||
|
base_libdir = pkgdest + d.getVar('base_libdir', True)
|
||||||
|
bindir = pkgdest + d.getVar('bindir', True)
|
||||||
|
sbindir = pkgdest + d.getVar('sbindir', True)
|
||||||
|
libdir = pkgdest + d.getVar('libdir', True)
|
||||||
|
|
||||||
|
if base_bindir == bindir and base_sbindir == sbindir and base_libdir == libdir:
|
||||||
|
return True
|
||||||
|
|
||||||
|
# Skip files not in base_[bindir|sbindir|libdir]
|
||||||
|
path = os.path.abspath(path)
|
||||||
|
if not (base_bindir in path or base_sbindir in path or base_libdir in path):
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
QAPATHTEST[arch] = "package_qa_check_arch"
|
QAPATHTEST[arch] = "package_qa_check_arch"
|
||||||
def package_qa_check_arch(path,name,d, elf, messages):
|
def package_qa_check_arch(path,name,d, elf, messages):
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in New Issue
Block a user