Update to the latest version of tar-split, which includes a change to
fix a memory exhaustion issue where a malformed image could cause the
Docker daemon to crash.
* tar: asm: store padding in chunks to avoid memory exhaustion
Fixes: CVE-2017-14992
Signed-off-by: Aleksa Sarai <asarai@suse.de>
| ... | ... |
@@ -55,7 +55,7 @@ github.com/miekg/dns 75e6e86cc601825c5dbcd4e0c209eab180997cd7 |
| 55 | 55 |
|
| 56 | 56 |
# get graph and distribution packages |
| 57 | 57 |
github.com/docker/distribution edc3ab29cdff8694dd6feb85cfeb4b5f1b38ed9c |
| 58 |
-github.com/vbatts/tar-split v0.10.1 |
|
| 58 |
+github.com/vbatts/tar-split v0.10.2 |
|
| 59 | 59 |
github.com/opencontainers/go-digest a6d0ee40d4207ea02364bd3b9e8e77b9159ba1eb |
| 60 | 60 |
|
| 61 | 61 |
# get go-zfs packages |
| ... | ... |
@@ -1,6 +1,7 @@ |
| 1 | 1 |
# tar-split |
| 2 | 2 |
|
| 3 | 3 |
[](https://travis-ci.org/vbatts/tar-split) |
| 4 |
+[](https://goreportcard.com/report/github.com/vbatts/tar-split) |
|
| 4 | 5 |
|
| 5 | 6 |
Pristinely disassembling a tar archive, and stashing needed raw bytes and offsets to reassemble a validating original archive. |
| 6 | 7 |
|
| ... | ... |
@@ -50,7 +51,7 @@ For example stored sparse files that have "holes" in them, will be read as a |
| 50 | 50 |
contiguous file, though the archive contents may be recorded in sparse format. |
| 51 | 51 |
Therefore when adding the file payload to a reassembled tar, to achieve |
| 52 | 52 |
identical output, the file payload would need be precisely re-sparsified. This |
| 53 |
-is not something I seek to fix imediately, but would rather have an alert that |
|
| 53 |
+is not something I seek to fix immediately, but would rather have an alert that |
|
| 54 | 54 |
precise reassembly is not possible. |
| 55 | 55 |
(see more http://www.gnu.org/software/tar/manual/html_node/Sparse-Formats.html) |
| 56 | 56 |
|
| ... | ... |
@@ -2,7 +2,6 @@ package asm |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"io" |
| 5 |
- "io/ioutil" |
|
| 6 | 5 |
|
| 7 | 6 |
"github.com/vbatts/tar-split/archive/tar" |
| 8 | 7 |
"github.com/vbatts/tar-split/tar/storage" |
| ... | ... |
@@ -119,20 +118,34 @@ func NewInputTarStream(r io.Reader, p storage.Packer, fp storage.FilePutter) (io |
| 119 | 119 |
} |
| 120 | 120 |
} |
| 121 | 121 |
|
| 122 |
- // it is allowable, and not uncommon that there is further padding on the |
|
| 123 |
- // end of an archive, apart from the expected 1024 null bytes. |
|
| 124 |
- remainder, err := ioutil.ReadAll(outputRdr) |
|
| 125 |
- if err != nil && err != io.EOF {
|
|
| 126 |
- pW.CloseWithError(err) |
|
| 127 |
- return |
|
| 128 |
- } |
|
| 129 |
- _, err = p.AddEntry(storage.Entry{
|
|
| 130 |
- Type: storage.SegmentType, |
|
| 131 |
- Payload: remainder, |
|
| 132 |
- }) |
|
| 133 |
- if err != nil {
|
|
| 134 |
- pW.CloseWithError(err) |
|
| 135 |
- return |
|
| 122 |
+ // It is allowable, and not uncommon that there is further padding on |
|
| 123 |
+ // the end of an archive, apart from the expected 1024 null bytes. We |
|
| 124 |
+ // do this in chunks rather than in one go to avoid cases where a |
|
| 125 |
+ // maliciously crafted tar file tries to trick us into reading many GBs |
|
| 126 |
+ // into memory. |
|
| 127 |
+ const paddingChunkSize = 1024 * 1024 |
|
| 128 |
+ var paddingChunk [paddingChunkSize]byte |
|
| 129 |
+ for {
|
|
| 130 |
+ var isEOF bool |
|
| 131 |
+ n, err := outputRdr.Read(paddingChunk[:]) |
|
| 132 |
+ if err != nil {
|
|
| 133 |
+ if err != io.EOF {
|
|
| 134 |
+ pW.CloseWithError(err) |
|
| 135 |
+ return |
|
| 136 |
+ } |
|
| 137 |
+ isEOF = true |
|
| 138 |
+ } |
|
| 139 |
+ _, err = p.AddEntry(storage.Entry{
|
|
| 140 |
+ Type: storage.SegmentType, |
|
| 141 |
+ Payload: paddingChunk[:n], |
|
| 142 |
+ }) |
|
| 143 |
+ if err != nil {
|
|
| 144 |
+ pW.CloseWithError(err) |
|
| 145 |
+ return |
|
| 146 |
+ } |
|
| 147 |
+ if isEOF {
|
|
| 148 |
+ break |
|
| 149 |
+ } |
|
| 136 | 150 |
} |
| 137 | 151 |
pW.Close() |
| 138 | 152 |
}() |