Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/image/tiff: excessive memory consumption #11389

Closed
dvyukov opened this issue Jun 24, 2015 · 6 comments
Closed

x/image/tiff: excessive memory consumption #11389

dvyukov opened this issue Jun 24, 2015 · 6 comments
Milestone

Comments

@dvyukov
Copy link
Member

dvyukov commented Jun 24, 2015

The following program:

package main

import (
    "bytes"
    "fmt"
    "golang.org/x/image/tiff"
)

func main() {
    cfg, err := tiff.DecodeConfig(bytes.NewReader(data))
    if err != nil {
        panic(err)
    }
    fmt.Printf("%+v\n", cfg)
    tiff.Decode(bytes.NewReader(data))
}

var data = []byte(
    "II*\x00\xc8\x03\x00\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00" +
        "\xff\xff\xff\x00\x88\x88\x88\x00\x00\x00\x00dRH=\xd2eca\xf0" +
        "SSR\xe91*#\xe27/&\xe6<<<$\xff\xff\xff\x00" +
        "\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00" +
        "\xff\xff\xff\x00\xa2\xa2\xa3\x03/.-\x9c\x99\x87r\xff\xbd\xab\x95\xff" +
        "\xff\xff\xff\xff\x84\x86\x88\xff\x80q_\xffp`O\xffbbc<" +
        "\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00" +
        "eee\x00Z[\\\x00\x1e\x1a\x16\xab\xb9\xb8\xb8\xff\x95\x94\x92\xff" +
        "}m\\\xff\xbd\xbb\xb9\xff\xc4\xc0\xbc\xff\xc1\xaa\x8f\xffū\x8e\xff" +
        "@=;x``a\x00\\\\\\\x00\xff\xff\xff\x00\xff\xff\xff\x00" +
        "\xff\xff\xff\x00\x02\x02\x01A\x1a\x16\x11\xa8~o]\xff\xf1\xf0\xef\xff" +
        "\xc9\xcb\xcd\xff;72\xffD9,\xff\xa9\x93z\xff\u05fb\x9c\xff" +
        "\xde¢\xff`TF\xda\x12\x13\x15\x02@@@\x00\xff\xff\xff\x00" +
        "\xff\xff\xff\x00\xff\xff\xff\x00\x0e\f\nz?7.穓{\xff" +
        "\xbb\xa8\x93\xff\xbb\xab\x99\xff\x86ua\xfftpl\xff\xb5\xa0\x87\xff" +
        \x9a\xffӹ\x9b\xff\xb7\x9f\x84\xff:98mYZZ\x00" +
        "\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\x00\x00\x00\x05\x00\x00\x002" +
        "i\\M\xeb\xdfá\xffҷ\x97\xffӹ\x9a\xff\xb6\xa2\x8b\xff" +
        \x95\xffӹ\x9a\xffԹ\x9a\xffۿ\x9f\xfftj^\xff" +
        "\r\x0f\x10\x87\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\x00\x00\x00\x00" +
        "\x00\x00\x00\x00\x15\x12\x0f\x93ʹ\x96\xffҸ\x9a\xffж\x98\xff" +
        \x9a\xffӸ\x9a\xff\xc0\xa9\x8f\xff\xb7\xa2\x8b\xffۿ\x9f\xff" +
        "\x87vd\xff\x00\x00\x00<\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00" +
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10cVH\xdfۿ\xa0\xff" +
        \x98\xffж\x98\xffպ\x9b\xff\x9c\x8bw\xff\x91\x87{\xff" +
        \x9b\xff\x9d\x8as\xff\x00\x00\x00)\xff\xff\xff\x00\xff\xff\xff\x00" +
        "\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x03\x03W" +
        "\xb9\xa2\x88\xffӹ\x9a\xffж\x98\xffж\x98\xffϴ\x96\xff" +
        \x96\xffֻ\x9d\xff\xa6\x91y\xff\x00\x00\x004\xff\xff\xff\x00" +
        "\xff\xff\xff\x00\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
        "\x00\x00\x00\x12|m[\xf5ڿ\x9f\xffж\x98\xffж\x98\xff" +
        \x98\xffж\x98\xffֻ\x9d\xff\xa1\x8dv\xff\x00\x00\x000" +
        "\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
        "\x00\x00\x00\x00\x00\x00\x00\x03dXI\xe8\xdc\xc1\xa1\xffж\x98\xff" +
        \x98\xffж\x98\xffж\x98\xffڿ\xa0\xff\x88vc\xfc" +
        "\x00\x00\x00\x19\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00###\x00" +
        "###\x00%%%\x00\x02\x03\x05\x03gZK\xe8\xdd\xc1\xa1\xff" +
        \x98\xffж\x98\xffж\x98\xffӸ\x9a\xffܿ\x9f\xff" +
        "vmb\xff\v\f\x0ee\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00" +
        "\xec\xec\xec\x00\xec\xec\xec\x00\xf9\xf9\xf9\x00qrs\x0e:1'\xf1" +
        "\xe1Ť\xffպ\x9b\xffؽ\x9e\xff\xdd¢\xffж\x98\xff" +
        "qcT\xeb-..\x8bAABK\xff\xff\xff\x00\xff\xff\xff\x00" +
        "\xff\xff\xff\x00&&&\x00&&&\x00(((\x00\x10\x10\x10\f" +
        "\x00\x00\x00cxk]\U000378cd\xff\x9d\x88p\xffpbR\xec" +
        " \x1c\x16\xa0\x1f\x1f\x1f ~~~\x00\xd9\xd9\xd9\x00\xff\xff\xff\x00" +
        "\xff\xff\xff\x00\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
        "\x00\x00\x00\x00\x00\x00\x00\x00344\xbeFFF\xb5OOOA" +
        "\x00\x00\x00\x11\x00\x00\x00\x00!!!\x00\u007f\u007f\u007f\x00\xd9\xd9\xd9\x00" +
        "\xff\xff\xff\x00\xff\xff\xff\x00\f\x00\x00\x01\x03\x00\x01\x00\x00\x00\x10\x00" +
        "\x00\x00\x01\x01\x03\x00\x01\x00\x00\x00\x0f\x00\x00\x00\x02\x01\x03\x00\x04\x00" +
        "\x00\x00^\x04\x00\x00\x06\x01\x03\x00\x01\x00\x00\x00\x02\x00\x00\x00\x11\x01" +
        "\x04\x00\x01\x00\x00\x00\b\x00\x00\x00\x15\x01\x03\x00\x01\x00\x00\x00\x04\x00" +
        "\x00\x00\x16\x01\x03\x00\x01\x00\x00\x00\x0f\x00\x00\x00\x17\x01\x04\x00\x01\x00" +
        "\x00\x00\xfa\x00\x00\xfa\x1a\x01\x05\x00\x01\x00\x00\x00f\x04\x00\x00\x1b\x01" +
        "\x05\x00\x01\x00\x00\x00n\x04\x00\x00(\x01\x03\x00\x01\x00\x00\x00\x02\x00" +
        "\x00\x00R\x01\x03\x00\x01\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\b\x00" +
        "\b\x00\b\x00\b\x00")

when run with ulimit -v 1000000 crashes as:

{ColorModel:0xc820032030 Width:16 Height:15}
fatal error: runtime: out of memory
runtime.mallocgc(0xfa0000fa, 0x4fd060, 0x1, 0xc820034c00)
    src/runtime/malloc.go:632 +0x972 fp=0xc820045590 sp=0xc8200454c0
runtime.newarray(0x4fd060, 0xfa0000fa, 0x7fdc0fc12498)
    src/runtime/malloc.go:756 +0xc9 fp=0xc8200455d0 sp=0xc820045590
runtime.makeslice(0x4f5b60, 0xfa0000fa, 0xfa0000fa, 0x0, 0x0, 0x0)
    src/runtime/slice.go:32 +0x165 fp=0xc820045620 sp=0xc8200455d0
golang.org/x/image/tiff.Decode(0x7fdc0fc12260, 0xc820014420, 0x7fdc0fc12498, 0xc820010440, 0x0, 0x0)
    src/golang.org/x/image/tiff/reader.go:641 +0xc23 fp=0xc820045e10 sp=0xc820045620
main.main()
    tiff.go:15 +0x31c fp=0xc820045f50 sp=0xc820045e10

That is, tiff tries to allocate 0xfa0000fa (4194304250) bytes to decode 15x16 image. That is too much.

on commit eb11b45157c1b71f30b3cec66306f1cd779a689e
go version devel +3cab476 Sun Jun 21 03:11:01 2015 +0000 linux/amd64

@ianlancetaylor ianlancetaylor added this to the Unreleased milestone Jul 11, 2015
@sha-256
Copy link

sha-256 commented Nov 6, 2018

Another similar case is when IFD offset is large, so tiff/buffer fills the buf till the offset, which can consumer a lot of memory if tiff-file is big.

Commit: 63626fb251ce5d89650d28bc5d6ccd7d63a70fef
go version go1.11.1 linux/amd64

@dvyukov
Copy link
Member Author

dvyukov commented Aug 16, 2023

@dvyukov dvyukov closed this as completed Aug 16, 2023
@dvyukov
Copy link
Member Author

dvyukov commented Aug 16, 2023

This effectively CVE-2022-41727 ignored for 8 years... the magic of CVEs...

@catenacyber
Copy link
Contributor

@dvyukov this CVE was in tiff.DecodeConfig not Decode as in your stack trace...

(Decode can allocate arbitrary amounts of memory, especially png which use u32 for dimensions.)

@dvyukov
Copy link
Member Author

dvyukov commented Aug 16, 2023

Humm... this reproducer is also fixed by the commit.

"This makes DecodeConfig safe to use to determine if the image is of a reasonable size to call Decode on"
Image in this issue is 15x16, so it looks safe to call Decode on, right? So this issue is the same vector, in the same code, fixed by the same commit at least :)

@catenacyber
Copy link
Contributor

Indeed.

I guess the last replacement of ReadAt fixes your case and the first one fixed my case

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants