diff options
| -rw-r--r-- | meta/classes/insane.bbclass | 111 |
1 files changed, 109 insertions, 2 deletions
diff --git a/meta/classes/insane.bbclass b/meta/classes/insane.bbclass index 5726e69e71..b8d45073ef 100644 --- a/meta/classes/insane.bbclass +++ b/meta/classes/insane.bbclass | |||
| @@ -11,6 +11,10 @@ | |||
| 11 | # -Check if packages contains .debug directories or .so files | 11 | # -Check if packages contains .debug directories or .so files |
| 12 | # where they should be in -dev or -dbg | 12 | # where they should be in -dev or -dbg |
| 13 | # -Check if config.log contains traces to broken autoconf tests | 13 | # -Check if config.log contains traces to broken autoconf tests |
| 14 | # -Ensure that binaries in base_[bindir|sbindir|libdir] do not link | ||
| 15 | # into exec_prefix | ||
| 16 | # -Check that scripts in base_[bindir|sbindir|libdir] do not reference | ||
| 17 | # files under exec_prefix | ||
| 14 | 18 | ||
| 15 | 19 | ||
| 16 | # | 20 | # |
| @@ -19,9 +23,14 @@ | |||
| 19 | # The package.bbclass can help us here. | 23 | # The package.bbclass can help us here. |
| 20 | # | 24 | # |
| 21 | inherit package | 25 | inherit package |
| 22 | PACKAGE_DEPENDS += "pax-utils-native desktop-file-utils-native" | 26 | PACKAGE_DEPENDS += "pax-utils-native desktop-file-utils-native ${QADEPENDS}" |
| 23 | PACKAGEFUNCS += " do_package_qa " | 27 | PACKAGEFUNCS += " do_package_qa " |
| 24 | 28 | ||
| 29 | # unsafe-references-in-binaries requires prelink-rtld from | ||
| 30 | # prelink-native, but we don't want this DEPENDS for -native builds | ||
| 31 | QADEPENDS = "prelink-native" | ||
| 32 | QADEPENDS_virtclass-native = "" | ||
| 33 | QADEPENDS_virtclass-nativesdk = "" | ||
| 25 | 34 | ||
| 26 | # | 35 | # |
| 27 | # dictionary for elf headers | 36 | # dictionary for elf headers |
| @@ -100,7 +109,7 @@ def package_qa_get_machine_dict(): | |||
| 100 | 109 | ||
| 101 | 110 | ||
| 102 | # Currently not being used by default "desktop" | 111 | # Currently not being used by default "desktop" |
| 103 | WARN_QA ?= "ldflags useless-rpaths rpaths" | 112 | WARN_QA ?= "ldflags useless-rpaths rpaths unsafe-references-in-binaries unsafe-references-in-scripts" |
| 104 | ERROR_QA ?= "dev-so debug-deps dev-deps debug-files arch la2 pkgconfig la perms" | 113 | ERROR_QA ?= "dev-so debug-deps dev-deps debug-files arch la2 pkgconfig la perms" |
| 105 | 114 | ||
| 106 | def package_qa_clean_path(path,d): | 115 | def package_qa_clean_path(path,d): |
| @@ -201,6 +210,104 @@ def package_qa_check_perm(path,name,d, elf, messages): | |||
| 201 | """ | 210 | """ |
| 202 | return | 211 | return |
| 203 | 212 | ||
| 213 | QAPATHTEST[unsafe-references-in-binaries] = "package_qa_check_unsafe_references_in_binaries" | ||
| 214 | def package_qa_check_unsafe_references_in_binaries(path, name, d, elf, messages): | ||
| 215 | """ | ||
| 216 | Ensure binaries in base_[bindir|sbindir|libdir] do not link to files under exec_prefix | ||
| 217 | """ | ||
| 218 | if unsafe_references_skippable(path, name, d): | ||
| 219 | return | ||
| 220 | |||
| 221 | if elf: | ||
| 222 | import subprocess as sub | ||
| 223 | pn = d.getVar('PN', True) | ||
| 224 | |||
| 225 | exec_prefix = d.getVar('exec_prefix', True) | ||
| 226 | sysroot_path = d.getVar('STAGING_DIR_TARGET', True) | ||
| 227 | sysroot_path_usr = sysroot_path + exec_prefix | ||
| 228 | |||
| 229 | try: | ||
| 230 | ldd_output = sub.check_output(["prelink-rtld", "--root", sysroot_path, path]) | ||
| 231 | except sub.CalledProcessError as e: | ||
| 232 | if e.returncode != 127: | ||
| 233 | error_msg = pn + ": prelink-rtld aborted when processing %s" % path | ||
| 234 | package_qa_handle_error("unsafe-references-in-binaries", error_msg, d) | ||
| 235 | return False | ||
| 236 | else: | ||
| 237 | # Sometimes this is done deliberately (e.g, e2fsprogs), so only warn | ||
| 238 | bb.warn("%s has missing library dependencies" % path) | ||
| 239 | return | ||
| 240 | if sysroot_path_usr in ldd_output: | ||
| 241 | error_msg = pn + ": %s links to something under exec_prefix" % path | ||
| 242 | package_qa_handle_error("unsafe-references-in-binaries", error_msg, d) | ||
| 243 | error_msg = "ldd reports: %s" % ldd_output | ||
| 244 | package_qa_handle_error("unsafe-references-in-binaries", error_msg, d) | ||
| 245 | return False | ||
| 246 | |||
| 247 | QAPATHTEST[unsafe-references-in-scripts] = "package_qa_check_unsafe_references_in_scripts" | ||
| 248 | def package_qa_check_unsafe_references_in_scripts(path, name, d, elf, messages): | ||
| 249 | """ | ||
| 250 | Warn if scripts in base_[bindir|sbindir|libdir] reference files under exec_prefix | ||
| 251 | """ | ||
| 252 | if unsafe_references_skippable(path, name, d): | ||
| 253 | return | ||
| 254 | |||
| 255 | if not elf: | ||
| 256 | import stat | ||
| 257 | pn = d.getVar('PN', True) | ||
| 258 | |||
| 259 | # Ensure we're checking an executable script | ||
| 260 | statinfo = os.stat(path) | ||
| 261 | if bool(statinfo.st_mode & stat.S_IXUSR): | ||
| 262 | # grep shell scripts for possible references to /exec_prefix/ | ||
| 263 | exec_prefix = d.getVar('exec_prefix', True) | ||
| 264 | statement = "grep -e '%s/' %s > /dev/null" % (exec_prefix, path) | ||
| 265 | if os.system(statement) == 0: | ||
| 266 | error_msg = pn + ": Found a reference to %s/ in %s" % (exec_prefix, path) | ||
| 267 | package_qa_handle_error("unsafe-references-in-scripts", error_msg, d) | ||
| 268 | error_msg = "Shell scripts in base_bindir and base_sbindir should not reference anything in exec_prefix" | ||
| 269 | package_qa_handle_error("unsafe-references-in-scripts", error_msg, d) | ||
| 270 | |||
| 271 | def unsafe_references_skippable(path, name, d): | ||
| 272 | if bb.data.inherits_class('native', d) or bb.data.inherits_class('nativesdk', d): | ||
| 273 | return True | ||
| 274 | |||
| 275 | if "-dbg" in name or "-dev" in name: | ||
| 276 | return True | ||
| 277 | |||
| 278 | # Other package names to skip: | ||
| 279 | if name.startswith("kernel-module-"): | ||
| 280 | return True | ||
| 281 | |||
| 282 | # Skip symlinks | ||
| 283 | if os.path.islink(path): | ||
| 284 | return True | ||
| 285 | |||
| 286 | # Skip unusual rootfs layouts which make these tests irrelevant | ||
| 287 | exec_prefix = d.getVar('exec_prefix', True) | ||
| 288 | if exec_prefix == "": | ||
| 289 | return True | ||
| 290 | |||
| 291 | pkgdest = d.getVar('PKGDEST', True) | ||
| 292 | pkgdest = pkgdest + "/" + name | ||
| 293 | pkgdest = os.path.abspath(pkgdest) | ||
| 294 | base_bindir = pkgdest + d.getVar('base_bindir', True) | ||
| 295 | base_sbindir = pkgdest + d.getVar('base_sbindir', True) | ||
| 296 | base_libdir = pkgdest + d.getVar('base_libdir', True) | ||
| 297 | bindir = pkgdest + d.getVar('bindir', True) | ||
| 298 | sbindir = pkgdest + d.getVar('sbindir', True) | ||
| 299 | libdir = pkgdest + d.getVar('libdir', True) | ||
| 300 | |||
| 301 | if base_bindir == bindir and base_sbindir == sbindir and base_libdir == libdir: | ||
| 302 | return True | ||
| 303 | |||
| 304 | # Skip files not in base_[bindir|sbindir|libdir] | ||
| 305 | path = os.path.abspath(path) | ||
| 306 | if not (base_bindir in path or base_sbindir in path or base_libdir in path): | ||
| 307 | return True | ||
| 308 | |||
| 309 | return False | ||
| 310 | |||
| 204 | QAPATHTEST[arch] = "package_qa_check_arch" | 311 | QAPATHTEST[arch] = "package_qa_check_arch" |
| 205 | def package_qa_check_arch(path,name,d, elf, messages): | 312 | def package_qa_check_arch(path,name,d, elf, messages): |
| 206 | """ | 313 | """ |
