From 704d91fc7c01241c6c4a8c841dc81344f81ae3bc Mon Sep 17 00:00:00 2001 From: Aleksa Sarai Date: Sat, 12 Nov 2016 01:48:17 +1100 Subject: [PATCH] keywords: safely encode symlink keywords symlink(2) is a very dumb syscall, and allows you to put any damn value you please inside a symlink. In addition, spaces are valid path characters which causes issues with keyword parsing. So use Vis() and Unvis() to safely store an encoded version of the path. This also adds a cli test for this behaviour. Signed-off-by: Aleksa Sarai --- keywords.go | 12 ++++++++++-- tar.go | 6 +++++- test/cli/0002.sh | 24 ++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 test/cli/0002.sh diff --git a/keywords.go b/keywords.go index 3faad1d..cfaadb0 100644 --- a/keywords.go +++ b/keywords.go @@ -297,7 +297,11 @@ var ( linkKeywordFunc = func(path string, info os.FileInfo, r io.Reader) (string, error) { if sys, ok := info.Sys().(*tar.Header); ok { if sys.Linkname != "" { - return fmt.Sprintf("link=%s", sys.Linkname), nil + linkname, err := Vis(sys.Linkname) + if err != nil { + return "", err + } + return fmt.Sprintf("link=%s", linkname), nil } return "", nil } @@ -307,7 +311,11 @@ var ( if err != nil { return "", err } - return fmt.Sprintf("link=%s", str), nil + linkname, err := Vis(str) + if err != nil { + return "", err + } + return fmt.Sprintf("link=%s", linkname), nil } return "", nil } diff --git a/tar.go b/tar.go index 0225b8b..8b8b034 100644 --- a/tar.go +++ b/tar.go @@ -129,7 +129,11 @@ func (ts *tarStream) readHeaders() { log.Println(err) break } - linkname := KeyVal(kv).Value() + linkname, err := Unvis(KeyVal(kv).Value()) + if err != nil { + log.Println(err) + break + } if _, ok := ts.hardlinks[linkname]; !ok { ts.hardlinks[linkname] = []string{hdr.Name} } else { diff --git a/test/cli/0002.sh b/test/cli/0002.sh new file mode 100644 index 0000000..5bf9a40 --- /dev/null +++ b/test/cli/0002.sh @@ -0,0 +1,24 @@ +#!/bin/bash +set -e + +name=$(basename $0) +root=$1 +gomtree=$(readlink -f ${root}/gomtree) +t=$(mktemp -d /tmp/go-mtree.XXXXXX) + +echo "[${name}] Running in ${t}" +# This test is for basic running check of manifest, and check against tar and file system +# + +pushd ${root} + +# Create a symlink with spaces in the entries. +mkdir ${t}/root +ln -s "this is a dummy symlink" ${t}/root/link + +# Create manifest and check it against the same symlink. +${gomtree} -K link,sha256digest -c -p ${t}/root > ${t}/root.mtree +${gomtree} -K link,sha256digest -f ${t}/root.mtree -p ${t}/root + +popd +rm -rf ${t}