[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#842020: Missing symbols due to a library being mistaken as hardlink to a different library



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.kadusale@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 to: