[PATCH] lib: zlib: Use post-increment only in inffast.c

Ley Foon Tan lftan.linux at gmail.com
Thu Oct 15 22:40:00 CEST 2020


On Fri, Jul 17, 2020 at 9:29 PM Tom Rini <trini at konsulko.com> wrote:
>
> On Wed, Jun 24, 2020 at 04:34:03PM +0800, Ley Foon Tan wrote:
>
> > From: Chin Liang See <chin.liang.see at intel.com>
> >
> > This fixes CVE-2016-9841. Changes integrated from [1], with changes
> > make for Uboot code base.
> >
> > An old inffast.c optimization turns out to not be optimal anymore
> > with modern compilers, and furthermore was not compliant with the
> > C standard, for which decrementing a pointer before its allocated
> > memory is undefined. Per the recommendation of a security audit of
> > the zlib code by Trail of Bits and TrustInSoft, in support of the
> > Mozilla Foundation, this "optimization" was removed, in order to
> > avoid the possibility of undefined behavior.
> >
> > [1]: https://github.com/madler/zlib/commit/9aaec95e82117c1cb0f9624264c3618fc380cecb
> >
> > Signed-off-by: Mark Adler <madler at alumni.caltech.edu>
> > Signed-off-by: Chin Liang See <chin.liang.see at intel.com>
> > Signed-off-by: Ley Foon Tan <ley.foon.tan at intel.com>
>
> This breaks the following tests on sandbox:
> FAILED test/py/tests/test_efi_fit.py::test_efi_fit_launch - u_boot_spawn.Timeout
> FAILED test/py/tests/test_fit.py::test_fit - OSError: [Errno 5] Input/output error
>
Hi Tom

I have tried to run the sandtest, but it failed in different test
cases. I am run this command "./test/py/test.py --bd sandbox --build".
Error log at bottom of email.

Found that https://gitlab.denx.de/u-boot/u-boot/-/blob/master/lib/zlib/zlib.h
always "#undef POSTINC", it is mean that U-boot can only support
pre-increment? I have tried changing "#undef POSTINC" to "define
POSTINC" and without this patch, the test failed at the same location.
So, the failure is not caused by this patch.
Note, this patch mainly changes to support post-increment only.

Any suggestion to fix this?

Regards
Ley Foon

-----------------
test/py/tests/test_fs/test_squashfs/test_sqfs_load.py F
                                        [  0%]
test/py/tests/test_fs/test_squashfs/test_sqfs_ls.py F

====================================================== FAILURES
======================================================
___________________________________________________ test_sqfs_load
___________________________________________________

u_boot_console = <u_boot_console_sandbox.ConsoleSandbox object at
0x7f788515dd60>

    @pytest.mark.boardspec('sandbox')
    @pytest.mark.buildconfigspec('cmd_fs_generic')
    @pytest.mark.buildconfigspec('cmd_squashfs')
    @pytest.mark.buildconfigspec('fs_squashfs')
    @pytest.mark.requiredtool('mksquashfs')
    def test_sqfs_load(u_boot_console):
        build_dir = u_boot_console.config.build_dir
        command = "sqfsload host 0 $kernel_addr_r "

        for opt in comp_opts:
            # generate and load the squashfs image
            try:
                opt.gen_image(build_dir)
            except RuntimeError:
                opt.clean_source(build_dir)
                # skip unsupported compression types
                continue

            path = os.path.join(build_dir, "sqfs-" + opt.name)
            output = u_boot_console.run_command("host bind 0 " + path)

>           output = u_boot_console.run_command(command + "xxx")

test/py/tests/test_fs/test_squashfs/test_sqfs_load.py:30:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
test/py/u_boot_console_base.py:205: in run_command
    m = self.p.expect([self.prompt_compiled] + self.bad_patterns)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <u_boot_spawn.Spawn object at 0x7f7884ba9d00>
patterns = [re.compile('^=>\\ ', re.MULTILINE), re.compile('(U-Boot
SPL \\d{4}\\.\\d{2}[^\r\n]*\\))'), re.compile('(U-Boot SPL
\\...d{2}[^\r\n]*\\))'), re.compile('Hit any key to stop autoboot: '),
re.compile("Unknown command '.*' - try 'help'"), ...]

    def expect(self, patterns):
        """Wait for the sub-process to emit specific data.

        This function waits for the process to emit one pattern from the
        supplied list of patterns, or for a timeout to occur.

        Args:
            patterns: A list of strings or regex objects that we expect to
                see in the sub-process' stdout.

        Returns:
            The index within the patterns array of the pattern the process
            emitted.

        Notable exceptions:
            Timeout, if the process did not emit any of the patterns within
            the expected time.
        """

        for pi in range(len(patterns)):
            if type(patterns[pi]) == type(''):
                patterns[pi] = re.compile(patterns[pi])

        tstart_s = time.time()
        try:
            while True:
                earliest_m = None
                earliest_pi = None
                for pi in range(len(patterns)):
                    pattern = patterns[pi]
                    m = pattern.search(self.buf)
                    if not m:
                        continue
                    if earliest_m and m.start() >= earliest_m.start():
                        continue
                    earliest_m = m
                    earliest_pi = pi
                if earliest_m:
                    pos = earliest_m.start()
                    posafter = earliest_m.end()
                    self.before = self.buf[:pos]
                    self.after = self.buf[pos:posafter]
                    self.output += self.buf[:posafter]
                    self.buf = self.buf[posafter:]
                    return earliest_pi
                tnow_s = time.time()
                if self.timeout:
                    tdelta_ms = (tnow_s - tstart_s) * 1000
                    poll_maxwait = self.timeout - tdelta_ms
                    if tdelta_ms > self.timeout:
                        raise Timeout()
                else:
                    poll_maxwait = None
                events = self.poll.poll(poll_maxwait)
                if not events:
                    raise Timeout()
>               c = os.read(self.fd, 1024).decode(errors='replace')
E               OSError: [Errno 5] Input/output error

test/py/u_boot_spawn.py:171: OSError
------------------------------------------------ Captured stdout call
------------------------------------------------
Parallel mksquashfs: Using 1 processor
Creating 4.0 filesystem on
/home/lftan/git/u-boot/build-sandbox/sqfs-gzip, block size 4096.
[===================================================================|] 4/4 100%

Exportable Squashfs 4.0 filesystem, gzip compressed, data block size 4096
    compressed data, compressed metadata, compressed fragments,
    compressed xattrs, compressed ids
    duplicates are removed
Filesystem size 6.97 Kbytes (0.01 Mbytes)
    73.37% of uncompressed filesystem size (9.50 Kbytes)
Inode table size 98 bytes (0.10 Kbytes)
    57.31% of uncompressed inode table size (171 bytes)
Directory table size 55 bytes (0.05 Kbytes)
    72.37% of uncompressed directory table size (76 bytes)
Number of duplicate files found 0
Number of inodes 5
Number of files 3
Number of fragments 1
Number of symbolic links  1
Number of device nodes 0
Number of fifo nodes 0
Number of socket nodes 0
Number of directories 1
Number of ids (unique uids + gids) 1
Number of uids 1
    lftan (1000)
Number of gids 1
    lftan (1000)
=> host bind 0 /home/lftan/git/u-boot/build-sandbox/sqfs-gzip
=> => sqfsload host 0 $kernel_addr_r xxx
Error: corrupted compressed data.
____________________________________________________ test_sqfs_ls
____________________________________________________

u_boot_console = <u_boot_console_sandbox.ConsoleSandbox object at
0x7f788515dd60>

    @pytest.mark.boardspec('sandbox')
    @pytest.mark.buildconfigspec('cmd_fs_generic')
    @pytest.mark.buildconfigspec('cmd_squashfs')
    @pytest.mark.buildconfigspec('fs_squashfs')
    @pytest.mark.requiredtool('mksquashfs')
    def test_sqfs_ls(u_boot_console):
        build_dir = u_boot_console.config.build_dir
        for opt in comp_opts:
            try:
>               opt.gen_image(build_dir)

test/py/tests/test_fs/test_squashfs/test_sqfs_ls.py:18:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <sqfs_common.Compression object at 0x7f7884c986a0>, build_dir =
'/home/lftan/git/u-boot/build-sandbox'

    def gen_image(self, build_dir):
        src = os.path.join(build_dir, "sqfs_src/")
>       os.mkdir(src)
E       FileExistsError: [Errno 17] File exists:
'/home/lftan/git/u-boot/build-sandbox/sqfs_src/'

test/py/tests/test_fs/test_squashfs/sqfs_common.py:35: FileExistsError
----------------------------------------------- Captured stdout setup
------------------------------------------------
/u-boot


U-Boot 2020.10-00718-g0f35d96bfd-dirty (Oct 16 2020 - 04:30:45 +0800)

Model: sandbox
DRAM:  128 MiB
WDT:   Started with servicing (60s timeout)
MMC:   mmc2: 2 (SD), mmc1: 1 (SD), mmc0: 0 (SD)
In:    serial
Out:   vidconsole
Err:   vidconsole
Model: sandbox
SCSI:
Net:   eth0: eth at 10002000, eth5: eth at 10003000, eth3: sbe5, eth6: eth at 10004000
Hit any key to stop autoboot:  0
=>
=============================== 2 failed, 641 passed, 88 skipped in
113.21s (0:01:53) ================================


More information about the U-Boot mailing list