Skip to content

Commit 57c644c

Browse files
Nisha Krnjudge
authored andcommitted
classes: Parse extended attributes
Although fs_hash.sh collects extended attribute data using getfattr, that data is not parsed by the add_files method in the ImageLayer class. This creates a serious bug when running Tern on a host OS with selinux enabled, even when running Tern in a container. This commit fixes this issue by adding more checks when parsing the results from the fs_hash.sh script. Since it is a lot of code, we add an internal function _parse_hash_content which takes care of creating a list of FileData objects from the hashed contents. Fixes #1100 Signed-off-by: Nisha K <[email protected]>
1 parent e74466b commit 57c644c

File tree

1 file changed

+41
-9
lines changed

1 file changed

+41
-9
lines changed

tern/classes/image_layer.py

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,45 @@ def gen_fs_hash(self):
338338
rootfs.extract_tarfile(tar_file, fs_dir)
339339
self.__fs_hash = rootfs.calc_fs_hash(fs_dir)
340340

341+
def _parse_hash_content(self, content):
342+
"""This is an internal function to parse the content of the hash
343+
and return a list of FileData objects
344+
The content consists of lines of the form:
345+
permissions|uid|gid|size|hard links| sha256sum filepath xattrs
346+
where xattrs is the list of extended attributes for the file
347+
The extended attributes start with a '# file' indicator, followed
348+
by a list of key-value pairs separated by newlines. For now, we will
349+
conserve the key-value pair list as they appear and separate
350+
each one by a comma"""
351+
file_list = []
352+
# keep track of where we are on the list of files
353+
index = 0
354+
# loop through the content
355+
while content:
356+
line = content.pop(0)
357+
if "# file" in line:
358+
# collect the extended attributes
359+
xattrlist = []
360+
xattrline = content.pop(0)
361+
while xattrline != '\n':
362+
xattrlist.append(xattrline.strip())
363+
xattrline = content.pop(0)
364+
# when we break out of the extended attributes loop
365+
# we combine the results and update the FileData object
366+
# existing in the previous index
367+
file_list[index-1].extattrs = file_list[index-1].extattrs + \
368+
" " + ','.join(xattrlist)
369+
else:
370+
# collect the regular attributes
371+
file_info = line[:-1].split(' ')
372+
file_data = FileData(os.path.basename(file_info[2]),
373+
os.path.relpath(file_info[2], '.'))
374+
file_data.set_checksum('sha256', file_info[1])
375+
file_data.set_whiteout()
376+
file_list.append(file_data)
377+
index = index + 1
378+
return file_list
379+
341380
def add_files(self):
342381
'''Get all the files present in a layer and store
343382
them as a list of FileData objects'''
@@ -346,15 +385,8 @@ def add_files(self):
346385
self.__fs_hash) + '.txt'
347386
with open(hash_file, encoding='utf-8') as f:
348387
content = f.readlines()
349-
for line in content:
350-
# lines are of the form:
351-
# permissions|uid|gid|size|hard links| sha256sum filepath
352-
file_info = line[:-1].split(' ')
353-
file_data = FileData(os.path.basename(file_info[2]),
354-
os.path.relpath(file_info[2], '.'))
355-
file_data.set_checksum('sha256', file_info[1])
356-
file_data.extattrs = file_info[0]
357-
file_data.set_whiteout()
388+
file_list = self._parse_hash_content(content)
389+
for file_data in file_list:
358390
self.add_file(file_data)
359391

360392
def get_layer_workdir(self):

0 commit comments

Comments
 (0)