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 | """ |