Package: mklibs
Version: 0.1.40
Tags: patch

Hello,

We encountered a bug in mklibs in our build system where there were
required symbols that weren't added. The reason the symbols weren't added
was because the library that required them was treated as a hardlink to an
object that was already in the objects dictionary.

At every "library reduction pass", stripped versions of required libraries
are created/recreated using objcopy. If a separate thread or process
creates a new file in between the deletion and recreation of a library, the
recreated library will have a different inode from the one used in the
objects dictionary and the new file would get the recreated library's old
inode. At the next pass there would be two entries of the same library on
the objects dictionary. If the new file gets deleted before a new library
is created, the new library might get the the previous library's old inode.
If this new library hasn't been added to the objects dictionary yet then it
will mistaken as a hardlink and will not be added in the next pass. As a
result, it will not be checked for undefined symbols.

Adding a check at the start of every library reduction pass to make sure
that all entries in the objects dictionary are updated. Attached is a patch
that does that.

If checking for hardlinks at the library reduction loop isn't needed, the
bug could also be fixed by simply keeping a set of the file paths of all
objects and libraries.

Regards,
Isser
From c59476ebe0982eec0a94b2d2079fcb01cb54162c Mon Sep 17 00:00:00 2001
From: Isser Kadusale <isser.kadus...@lexmark.com>
Date: Tue, 18 Oct 2016 09:29:44 +0800
Subject: [PATCH] mklibs: Prune obsolete inode to filename mappings

Libraries are recreated at every pass. While recreating a library,
the new one might get a different inode if another thread or
process creates a new file in between the library deletion and
recreation. This will result in duplicate entries in the objects
dictionary.

If the aforementioned file is deleted right before a new library
is added, that library will be mistaken as a hardlink to one
of the existing libraries since inodes can get reused. As a result,
the new library will not be added to the objects dictionary.
---
 src/mklibs | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/src/mklibs b/src/mklibs
index 437b36b..20fe5ec 100755
--- a/src/mklibs
+++ b/src/mklibs
@@ -481,6 +481,12 @@ while 1:
         print
 
     passnr = passnr + 1
+
+    # Prune obsolete inode to filename mappings
+    for inode in objects.keys():
+        if not os.access(objects[inode], os.F_OK) or os.stat(objects[inode])[ST_INO] != inode:
+            del objects[inode]
+
     # Gather all already reduced libraries and treat them as objects as well
     small_libs = []
     for lib in regexpfilter(os.listdir(dest_path), "(.*-so-stripped)$"):
-- 
1.9.3

Reply via email to