Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package ubi_reader for openSUSE:Factory checked in at 2022-12-06 15:44:53 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ubi_reader (Old) and /work/SRC/openSUSE:Factory/.ubi_reader.new.1835 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ubi_reader" Tue Dec 6 15:44:53 2022 rev:6 rq:1040669 version:0.8.5 Changes: -------- --- /work/SRC/openSUSE:Factory/ubi_reader/ubi_reader.changes 2022-04-30 00:46:43.295012993 +0200 +++ /work/SRC/openSUSE:Factory/.ubi_reader.new.1835/ubi_reader.changes 2022-12-06 15:44:53.437359617 +0100 @@ -1,0 +2,9 @@ +Tue Dec 6 13:26:24 UTC 2022 - Dirk Müller <[email protected]> + +- update to 0.8.5: + * fix path traversal vulnerability + * Ignore block align, let fail if data actually is missing + * fix old block crc check + * python 3.x related cleanups + +------------------------------------------------------------------- Old: ---- ubi_reader-0.8.0.tar.gz New: ---- ubi_reader-0.8.5.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ubi_reader.spec ++++++ --- /var/tmp/diff_new_pack.J07D4T/_old 2022-12-06 15:44:53.881362115 +0100 +++ /var/tmp/diff_new_pack.J07D4T/_new 2022-12-06 15:44:53.893362182 +0100 @@ -18,7 +18,7 @@ Name: ubi_reader -Version: 0.8.0 +Version: 0.8.5 Release: 0 Summary: Extract files from UBI and UBIFS images License: LGPL-3.0-or-later ++++++ ubi_reader-0.8.0.tar.gz -> ubi_reader-0.8.5.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ubi_reader-0.8.0-master/README.md new/ubi_reader-0.8.5-master/README.md --- old/ubi_reader-0.8.0-master/README.md 2022-04-28 20:51:58.000000000 +0200 +++ new/ubi_reader-0.8.5-master/README.md 2022-12-04 05:25:59.000000000 +0100 @@ -24,7 +24,7 @@ ## Dependencies: -Python 2.7 or 3. +Python 2.7 or 3 with the following packages: $ sudo apt-get install liblzo2-dev $ sudo pip install python-lzo diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ubi_reader-0.8.0-master/setup.py new/ubi_reader-0.8.5-master/setup.py --- old/ubi_reader-0.8.0-master/setup.py 2022-04-28 20:51:58.000000000 +0200 +++ new/ubi_reader-0.8.5-master/setup.py 2022-12-04 05:25:59.000000000 +0100 @@ -2,7 +2,7 @@ from setuptools import setup, find_packages -version = '0.8.0' +version = '0.8.5' setup( name='ubi_reader', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ubi_reader-0.8.0-master/ubireader/settings.py new/ubi_reader-0.8.5-master/ubireader/settings.py --- old/ubi_reader-0.8.0-master/ubireader/settings.py 2022-04-28 20:51:58.000000000 +0200 +++ new/ubi_reader-0.8.5-master/ubireader/settings.py 2022-12-04 05:25:59.000000000 +0100 @@ -17,8 +17,6 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. ############################################################# -import os - output_dir = 'ubifs-root' error_action = True # if 'exit' on any error exit program. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ubi_reader-0.8.0-master/ubireader/ubi/__init__.py new/ubi_reader-0.8.5-master/ubireader/ubi/__init__.py --- old/ubi_reader-0.8.0-master/ubireader/ubi/__init__.py 2022-04-28 20:51:58.000000000 +0200 +++ new/ubi_reader-0.8.5-master/ubireader/ubi/__init__.py 2022-12-04 05:25:59.000000000 +0100 @@ -17,13 +17,11 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. ############################################################# - -from ubireader.debug import error, log +from ubireader.debug import error from ubireader.ubi.block import sort, extract_blocks -from ubireader.ubi.defines import UBI_EC_HDR_MAGIC, FILE_CHUNK_SZ from ubireader.ubi import display from ubireader.ubi.image import description as image -from ubireader.ubi.block import layout +from ubireader.ubi.block import layout, rm_old_blocks class ubi_base(object): """UBI Base object @@ -149,17 +147,19 @@ layout_list, data_list, int_vol_list, unknown_list = sort.by_type(self.blocks) - if len(layout_list) < 2: - error(self, 'Fatal', 'Less than 2 layout blocks found.') - - self._layout_blocks_list = layout.get_newest(self.blocks, layout_list) + self._layout_blocks_list = layout_list self._data_blocks_list = data_list self._int_vol_blocks_list = int_vol_list self._unknown_blocks_list = unknown_list + + newest_layout_list = rm_old_blocks(self.blocks, self.layout_blocks_list) + + if len(newest_layout_list) < 2: + error(self, 'Fatal', 'Less than 2 layout blocks found.') - layout_pairs = layout.group_pairs(self.blocks, self.layout_blocks_list) + layout_pairs = layout.group_pairs(self.blocks, newest_layout_list) - layout_infos = layout.associate_blocks(self.blocks, layout_pairs, self.first_peb_num) + layout_infos = layout.associate_blocks(self.blocks, layout_pairs) self._images = [] for i in range(0, len(layout_infos)): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ubi_reader-0.8.0-master/ubireader/ubi/block/__init__.py new/ubi_reader-0.8.5-master/ubireader/ubi/block/__init__.py --- old/ubi_reader-0.8.0-master/ubireader/ubi/block/__init__.py 2022-04-28 20:51:58.000000000 +0200 +++ new/ubi_reader-0.8.5-master/ubireader/ubi/block/__init__.py 2022-12-04 05:25:59.000000000 +0100 @@ -17,11 +17,11 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. ############################################################# -import re +from zlib import crc32 from ubireader import settings from ubireader.debug import error, log, verbose_display, verbose_log from ubireader.ubi import display -from ubireader.ubi.defines import UBI_EC_HDR_SZ, UBI_VID_HDR_SZ, UBI_INTERNAL_VOL_START, UBI_EC_HDR_MAGIC +from ubireader.ubi.defines import UBI_EC_HDR_SZ, UBI_VID_HDR_SZ, UBI_INTERNAL_VOL_START, UBI_EC_HDR_MAGIC, UBI_CRC32_INIT from ubireader.ubi.headers import ec_hdr, vid_hdr, vtbl_recs @@ -44,6 +44,7 @@ Int:leb_num -- Logical Erase Block number. Int:file_offset -- Address location in file of this block. Int:size -- Size of total block data or PEB size. + Int:data_crc -- crc32 of block data. Will print out all information when invoked as a string. """ @@ -120,20 +121,14 @@ # range instead of xrange, as xrange breaks > 4GB end_offset. for i in range(ubi.file.start_offset, ubi.file.end_offset, ubi.file.block_size): - try: - buf = ubi.file.read(ubi.file.block_size) - except Exception as e: - if settings.warn_only_block_read_errors: - error(extract_blocks, 'Error', 'PEB: %s: %s' % (ubi.first_peb_num + peb_count, str(e))) - continue - else: - error(extract_blocks, 'Fatal', 'PEB: %s: %s' % (ubi.first_peb_num + peb_count, str(e))) + buf = ubi.file.read(ubi.file.block_size) if buf.startswith(UBI_EC_HDR_MAGIC): blk = description(buf) blk.file_offset = i blk.peb_num = ubi.first_peb_num + peb_count blk.size = ubi.file.block_size + blk.data_crc = (~crc32(buf[blk.ec_hdr.data_offset:blk.ec_hdr.data_offset+blk.vid_hdr.data_size]) & UBI_CRC32_INIT) blocks[blk.peb_num] = blk peb_count += 1 log(extract_blocks, blk) @@ -156,7 +151,87 @@ else: cur_offset += ubi.file.block_size - ubi.first_peb_num = cur_offset/ubi.file.block_size + ubi.first_peb_num = cur_offset//ubi.file.block_size ubi.file.start_offset = cur_offset return blocks + + +def rm_old_blocks(blocks, block_list): + del_blocks = [] + + for i in block_list: + if i in del_blocks: + continue + + if blocks[i].is_valid is not True: + del_blocks.append(i) + continue + + for k in block_list: + if i == k: + continue + + if k in del_blocks: + continue + + if blocks[k].is_valid is not True: + del_blocks.append(k) + continue + + if blocks[i].leb_num != blocks[k].leb_num: + continue + + if blocks[i].ec_hdr.image_seq != blocks[k].ec_hdr.image_seq: + continue + + second_newer = blocks[k].vid_hdr.sqnum > blocks[i].vid_hdr.sqnum + del_block = None + use_block = None + + if second_newer: + if blocks[k].vid_hdr.copy_flag == 0: + del_block = i + use_block = k + + else: + if blocks[i].vid_hdr.copy_flag == 0: + del_block = k + use_block = i + + if del_block is not None: + del_blocks.append(del_block) + log(rm_old_blocks, 'Old block removed (copy_flag): PEB %s, LEB %s, Using PEB%s' % (blocks[del_block].peb_num, blocks[del_block].leb_num, use_block)) + break + + if second_newer: + if blocks[k].data_crc != blocks[k].vid_hdr.data_crc: + del_block = k + use_block = i + else: + del_block = i + use_block = k + else: + if blocks[i].data_crc != blocks[i].vid_hdr.data_crc: + del_block = i + use_block = k + else: + del_block = k + use_block = i + + if del_block is not None: + del_blocks.append(del_block) + log(rm_old_blocks, 'Old block removed (data_crc): PEB %s, LEB %s, vid_hdr.data_crc %s / %s, Using PEB %s' % (blocks[del_block].peb_num, + blocks[del_block].leb_num, + blocks[del_block].vid_hdr.data_crc, + blocks[del_block].data_crc, + use_block)) + + else: + use_block = min(k, i) + del_blocks.append(use_block) + error('Warn', rm_old_blocks, 'Multiple PEB [%s] for LEB %s: Using first.' % (', '.join(i, k), blocks[i].leb_num, use_block)) + + break + + return [j for j in block_list if j not in del_blocks] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ubi_reader-0.8.0-master/ubireader/ubi/block/layout.py new/ubi_reader-0.8.5-master/ubireader/ubi/block/layout.py --- old/ubi_reader-0.8.0-master/ubireader/ubi/block/layout.py 2022-04-28 20:51:58.000000000 +0200 +++ new/ubi_reader-0.8.5-master/ubireader/ubi/block/layout.py 2022-12-04 05:25:59.000000000 +0100 @@ -17,36 +17,9 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. ############################################################# -from ubireader.debug import error, log +from ubireader.debug import log from ubireader.ubi.block import sort -def get_newest(blocks, layout_blocks): - """Filter out old layout blocks from list - - Arguments: - List:blocks -- List of block objects - List:layout_blocks -- List of layout block indexes - - Returns: - List -- Newest layout blocks in list - """ - layout_temp = list(layout_blocks) - - for i in range(0, len(layout_temp)): - for k in range(0, len(layout_blocks)): - if blocks[layout_temp[i]].ec_hdr.image_seq != blocks[layout_blocks[k]].ec_hdr.image_seq: - continue - - if blocks[layout_temp[i]].leb_num != blocks[layout_blocks[k]].leb_num: - continue - - if blocks[layout_temp[i]].vid_hdr.sqnum > blocks[layout_blocks[k]].vid_hdr.sqnum: - del layout_blocks[k] - break - - return layout_blocks - - def group_pairs(blocks, layout_blocks_list): """Sort a list of layout blocks into pairs @@ -71,21 +44,21 @@ return list(image_dict.values()) -def associate_blocks(blocks, layout_pairs, start_peb_num): +def associate_blocks(blocks, layout_pairs): """Group block indexes with appropriate layout pairs Arguments: List:blocks -- List of block objects List:layout_pairs -- List of grouped layout blocks - Int:start_peb_num -- Number of the PEB to start from. Returns: List -- Layout block pairs grouped with associated block ranges. """ + seq_blocks = [] for layout_pair in layout_pairs: seq_blocks = sort.by_image_seq(blocks, blocks[layout_pair[0]].ec_hdr.image_seq) - + seq_blocks = [b for b in seq_blocks if b not in layout_pair] layout_pair.append(seq_blocks) return layout_pairs diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ubi_reader-0.8.0-master/ubireader/ubi/block/sort.py new/ubi_reader-0.8.5-master/ubireader/ubi/block/sort.py --- old/ubi_reader-0.8.0-master/ubireader/ubi/block/sort.py 2022-04-28 20:51:58.000000000 +0200 +++ new/ubi_reader-0.8.5-master/ubireader/ubi/block/sort.py 2022-12-04 05:25:59.000000000 +0100 @@ -16,6 +16,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. ############################################################# + from ubireader import settings def by_image_seq(blocks, image_seq): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ubi_reader-0.8.0-master/ubireader/ubi/headers.py new/ubi_reader-0.8.5-master/ubireader/ubi/headers.py --- old/ubi_reader-0.8.0-master/ubireader/ubi/headers.py 2022-04-28 20:51:58.000000000 +0200 +++ new/ubi_reader-0.8.5-master/ubireader/ubi/headers.py 2022-12-04 05:25:59.000000000 +0100 @@ -41,7 +41,7 @@ yield key, getattr(self, key) def _check_errors(self, buf_crc): - crc_chk = (~crc32(buf_crc) & 0xFFFFFFFF) + crc_chk = (~crc32(buf_crc) & UBI_CRC32_INIT) if self.hdr_crc != crc_chk: log(vid_hdr, 'CRC Failed: expected 0x%x got 0x%x' % (crc_chk, self.hdr_crc)) self.errors.append('crc') @@ -65,7 +65,7 @@ return 'VID Header' def _check_errors(self, buf_crc): - crc_chk = (~crc32(buf_crc) & 0xFFFFFFFF) + crc_chk = (~crc32(buf_crc) & UBI_CRC32_INIT) if self.hdr_crc != crc_chk: log(vid_hdr, 'CRC Failed: expected 0x%x got 0x%x' % (crc_chk, self.hdr_crc)) self.errors.append('crc') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ubi_reader-0.8.0-master/ubireader/ubi/image.py new/ubi_reader-0.8.5-master/ubireader/ubi/image.py --- old/ubi_reader-0.8.0-master/ubireader/ubi/image.py 2022-04-28 20:51:58.000000000 +0200 +++ new/ubi_reader-0.8.5-master/ubireader/ubi/image.py 2022-12-04 05:25:59.000000000 +0100 @@ -38,7 +38,7 @@ def get_blocks(self, blocks): - return get_blocks_in_list(blocks, self._block_list) #range(self._start_peb, self._end_peb+1)) + return get_blocks_in_list(blocks, self._block_list) def _get_peb_range(self): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ubi_reader-0.8.0-master/ubireader/ubi/volume.py new/ubi_reader-0.8.5-master/ubireader/ubi/volume.py --- old/ubi_reader-0.8.0-master/ubireader/ubi/volume.py 2022-04-28 20:51:58.000000000 +0200 +++ new/ubi_reader-0.8.5-master/ubireader/ubi/volume.py 2022-12-04 05:25:59.000000000 +0100 @@ -19,7 +19,7 @@ from ubireader.debug import log from ubireader.ubi import display -from ubireader.ubi.block import sort, get_blocks_in_list +from ubireader.ubi.block import sort, get_blocks_in_list, rm_old_blocks class description(object): """UBI Volume object @@ -110,11 +110,12 @@ volumes = {} vol_blocks_lists = sort.by_vol_id(blocks, layout_info[2]) - for vol_rec in blocks[layout_info[0]].vtbl_recs: vol_name = vol_rec.name.strip(b'\x00').decode('utf-8') if vol_rec.rec_index not in vol_blocks_lists: vol_blocks_lists[vol_rec.rec_index] = [] + + vol_blocks_lists[vol_rec.rec_index] = rm_old_blocks(blocks, vol_blocks_lists[vol_rec.rec_index]) volumes[vol_name] = description(vol_rec.rec_index, vol_rec, vol_blocks_lists[vol_rec.rec_index]) return volumes diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ubi_reader-0.8.0-master/ubireader/ubi_io.py new/ubi_reader-0.8.5-master/ubireader/ubi_io.py --- old/ubi_reader-0.8.0-master/ubireader/ubi_io.py 2022-04-28 20:51:58.000000000 +0200 +++ new/ubi_reader-0.8.5-master/ubireader/ubi_io.py 2022-12-04 05:25:59.000000000 +0100 @@ -17,7 +17,6 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. ############################################################# -from ubireader import settings from ubireader.debug import error, log, verbose_log from ubireader.ubi.block import sort @@ -67,14 +66,10 @@ log(self, 'Start Offset: %s' % (self._start_offset)) if end_offset: - tail = file_size - end_offset self._end_offset = end_offset else: - tail = (file_size - start_offset) % block_size - self._end_offset = file_size - tail + self._end_offset = file_size log(self, 'End Offset: %s' % (self._end_offset)) - if tail > 0: - log(self, 'File Tail Size: %s' % (tail)) self._block_size = block_size log(self, 'Block Size: %s' % block_size) @@ -87,10 +82,7 @@ remainder = (self._end_offset - start_offset) % block_size if remainder != 0: - if settings.warn_only_block_read_errors: - error(self, 'Error', 'File read is not block aligned.') - else: - error(self, 'Fatal', 'File read is not block aligned.') + error(self, 'Warning', 'end_offset - start_offset length is not block aligned, could mean missing data.') self._fhandle.seek(self._start_offset) self._last_read_addr = self._fhandle.tell() @@ -119,10 +111,6 @@ def read(self, size): - if self.end_offset < self.tell() + size: - error(self.read, 'Error', 'Block ends at %s which is greater than file size %s' % (self.tell() + size, self.end_offset)) - raise Exception('Bad Read Offset Request') - self._last_read_addr = self.tell() verbose_log(self, 'read loc: %s, size: %s' % (self._last_read_addr, size)) return self._fhandle.read(size) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ubi_reader-0.8.0-master/ubireader/ubifs/__init__.py new/ubi_reader-0.8.5-master/ubireader/ubifs/__init__.py --- old/ubi_reader-0.8.0-master/ubireader/ubifs/__init__.py 2022-04-28 20:51:58.000000000 +0200 +++ new/ubi_reader-0.8.5-master/ubireader/ubifs/__init__.py 2022-12-04 05:25:59.000000000 +0100 @@ -16,8 +16,6 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. ############################################################# -import re -import struct from ubireader.debug import error, log, verbose_display from ubireader.ubifs.defines import * diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ubi_reader-0.8.0-master/ubireader/ubifs/display.py new/ubi_reader-0.8.5-master/ubireader/ubifs/display.py --- old/ubi_reader-0.8.0-master/ubireader/ubifs/display.py 2022-04-28 20:51:58.000000000 +0200 +++ new/ubi_reader-0.8.5-master/ubireader/ubifs/display.py 2022-12-04 05:25:59.000000000 +0100 @@ -16,6 +16,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. ############################################################# + from ubireader.ubifs.defines import PRINT_UBIFS_FLGS, PRINT_UBIFS_MST def ubifs(ubifs, tab=''): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ubi_reader-0.8.0-master/ubireader/ubifs/list.py new/ubi_reader-0.8.5-master/ubireader/ubifs/list.py --- old/ubi_reader-0.8.0-master/ubireader/ubifs/list.py 2022-04-28 20:51:58.000000000 +0200 +++ new/ubi_reader-0.8.5-master/ubireader/ubifs/list.py 2022-12-04 05:25:59.000000000 +0100 @@ -18,10 +18,7 @@ ############################################################# import os -import struct - import time -from ubireader import settings from ubireader.ubifs.defines import * from ubireader.ubifs import walk from ubireader.ubifs.misc import decompress @@ -55,7 +52,7 @@ print_dent(ubifs, inodes, dent, longts=False) if len(bad_blocks): - error(list_files, 'Warning', 'Data may be missing or corrupted, bad blocks, LEB [%s]' % ','.join(map(str, bad_blocks))) + error(list_files, 'Warn', 'Data may be missing or corrupted, bad blocks, LEB [%s]' % ','.join(map(str, bad_blocks))) except Exception as e: error(list_files, 'Error', '%s' % e) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ubi_reader-0.8.0-master/ubireader/ubifs/misc.py new/ubi_reader-0.8.5-master/ubireader/ubifs/misc.py --- old/ubi_reader-0.8.0-master/ubireader/ubifs/misc.py 2022-04-28 20:51:58.000000000 +0200 +++ new/ubi_reader-0.8.5-master/ubireader/ubifs/misc.py 2022-12-04 05:25:59.000000000 +0100 @@ -16,6 +16,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. ############################################################# + import lzo import struct import zlib diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ubi_reader-0.8.0-master/ubireader/ubifs/output.py new/ubi_reader-0.8.5-master/ubireader/ubifs/output.py --- old/ubi_reader-0.8.0-master/ubireader/ubifs/output.py 2022-04-28 20:51:58.000000000 +0200 +++ new/ubi_reader-0.8.5-master/ubireader/ubifs/output.py 2022-12-04 05:25:59.000000000 +0100 @@ -26,6 +26,11 @@ from ubireader.ubifs.misc import decompress from ubireader.debug import error, log, verbose_log +def is_safe_path(basedir, path): + basedir = os.path.realpath(basedir) + path = os.path.realpath(os.path.join(basedir, path)) + return True if path.startswith(basedir) else False + def extract_files(ubifs, out_path, perms=False): """Extract UBIFS contents to_path/ @@ -47,7 +52,7 @@ extract_dents(ubifs, inodes, dent, out_path, perms) if len(bad_blocks): - error(extract_files, 'Warning', 'Data may be missing or corrupted, bad blocks, LEB [%s]' % ','.join(map(str, bad_blocks))) + error(extract_files, 'Warn', 'Data may be missing or corrupted, bad blocks, LEB [%s]' % ','.join(map(str, bad_blocks))) except Exception as e: error(extract_files, 'Error', '%s' % e) @@ -59,8 +64,12 @@ return inode = inodes[dent_node.inum] - dent_path = os.path.join(path, dent_node.name) - + + if not is_safe_path(path, dent_node.name): + error(extract_dents, 'Warn', 'Path traversal attempt: %s, discarding.' % (dent_node.name)) + return + dent_path = os.path.realpath(os.path.join(path, dent_node.name)) + if dent_node.type == UBIFS_ITYPE_DIR: try: if not os.path.exists(dent_path): @@ -188,7 +197,7 @@ verbose_log(_process_reg_file, 'ino num: %s, compression: %s, path: %s' % (inode['ino'].key['ino_num'], compr_type, path)) except Exception as e: - error(_process_reg_file, 'Warn', 'inode num:%s :%s' % (inode['ino'].key['ino_num'], e)) + error(_process_reg_file, 'Warn', 'inode num:%s path:%s :%s' % (inode['ino'].key['ino_num'], path, e)) # Pad end of file with \x00 if needed. if inode['ino'].size > len(buf): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ubi_reader-0.8.0-master/ubireader/ubifs/walk.py new/ubi_reader-0.8.5-master/ubireader/ubifs/walk.py --- old/ubi_reader-0.8.0-master/ubireader/ubifs/walk.py 2022-04-28 20:51:58.000000000 +0200 +++ new/ubi_reader-0.8.5-master/ubireader/ubifs/walk.py 2022-12-04 05:25:59.000000000 +0100 @@ -37,26 +37,35 @@ 'data' -- List of data nodes if present. 'dent' -- List of directory entry nodes if present. """ - try: - if len(bad_blocks): - if lnum in bad_blocks: - return - - ubifs.file.seek((ubifs.leb_size * lnum) + offset) - buf = ubifs.file.read(UBIFS_COMMON_HDR_SZ) - chdr = nodes.common_hdr(buf) - log(index , '%s file addr: %s' % (chdr, ubifs.file.last_read_addr())) - verbose_display(chdr) - node_buf = ubifs.file.read(chdr.len - UBIFS_COMMON_HDR_SZ) - file_offset = ubifs.file.last_read_addr() - - except Exception as e: - if str(e) == 'Bad Read Offset Request' and settings.warn_only_block_read_errors: - bad_blocks.append(lnum) + if len(bad_blocks): + if lnum in bad_blocks: + return + + ubifs.file.seek((ubifs.leb_size * lnum) + offset) + buf = ubifs.file.read(UBIFS_COMMON_HDR_SZ) + + if len(buf) < UBIFS_COMMON_HDR_SZ: + if settings.warn_only_block_read_errors: + error(index, 'Error', 'LEB: %s, Common Hdr Size smaller than expected.' % (lnum)) + return + + else: + error(index, 'Fatal', 'LEB: %s, Common Hdr Size smaller than expected.' % (lnum)) + + chdr = nodes.common_hdr(buf) + log(index , '%s file addr: %s' % (chdr, ubifs.file.last_read_addr())) + verbose_display(chdr) + read_size = chdr.len - UBIFS_COMMON_HDR_SZ + node_buf = ubifs.file.read(read_size) + file_offset = ubifs.file.last_read_addr() + + if len(node_buf) < read_size: + if settings.warn_only_block_read_errors: + error(index, 'Error', 'LEB: %s at %s, Node size smaller than expected.' % (lnum, file_offset)) return else: - error(index, 'Fatal', 'LEB: %s, UBIFS offset: %s, error: %s' % (lnum, ((ubifs.leb_size * lnum) + offset), e)) + error(index, 'Fatal', 'LEB: %s at %s, Node size smaller than expected.' % (lnum, file_offset)) if chdr.node_type == UBIFS_IDX_NODE: try: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ubi_reader-0.8.0-master/ubireader/utils.py new/ubi_reader-0.8.5-master/ubireader/utils.py --- old/ubi_reader-0.8.0-master/ubireader/utils.py 2022-04-28 20:51:58.000000000 +0200 +++ new/ubi_reader-0.8.5-master/ubireader/utils.py 2022-12-04 05:25:59.000000000 +0100 @@ -60,7 +60,6 @@ f.close() - def guess_filetype(path, start_offset=0): log(guess_filetype, 'Looking for file type at %s' % start_offset) @@ -82,7 +81,6 @@ return ftype - def guess_leb_size(path): """Get LEB size from superblock @@ -127,7 +125,6 @@ return block_size - def guess_peb_size(path): """Determine the most likely block size @@ -163,24 +160,24 @@ file_offset += FILE_CHUNK_SZ f.close() - occurances = {} + occurrences = {} for i in range(0, len(offsets)): try: diff = offsets[i] - offsets[i-1] except: diff = offsets[i] - if diff not in occurances: - occurances[diff] = 0 + if diff not in occurrences: + occurrences[diff] = 0 - occurances[diff] += 1 + occurrences[diff] += 1 most_frequent = 0 block_size = None - for offset in occurances: - if occurances[offset] > most_frequent: - most_frequent = occurances[offset] + for offset in occurrences: + if occurrences[offset] > most_frequent: + most_frequent = occurrences[offset] block_size = offset - return block_size + return block_size \ No newline at end of file
