From 2ebf95a81ea99005912a82ec64381d51e84e4034 Mon Sep 17 00:00:00 2001 From: Alexandr Morozov Date: Wed, 26 Nov 2014 23:00:13 -0800 Subject: [PATCH] Change path breakout detection logic in archive package Fixes #9375 Signed-off-by: Alexandr Morozov --- archive/archive.go | 9 ++++++--- archive/diff.go | 12 +++++++----- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/archive/archive.go b/archive/archive.go index aaeed31..3783e72 100644 --- a/archive/archive.go +++ b/archive/archive.go @@ -530,10 +530,13 @@ loop: } } - // Prevent symlink breakout path := filepath.Join(dest, hdr.Name) - if !strings.HasPrefix(path, dest) { - return breakoutError(fmt.Errorf("%q is outside of %q", path, dest)) + rel, err := filepath.Rel(dest, path) + if err != nil { + return err + } + if strings.HasPrefix(rel, "..") { + return breakoutError(fmt.Errorf("%q is outside of %q", hdr.Name, dest)) } // If path exits we almost always just want to remove and replace it diff --git a/archive/diff.go b/archive/diff.go index 856cedc..c6118c5 100644 --- a/archive/diff.go +++ b/archive/diff.go @@ -92,12 +92,14 @@ func ApplyLayer(dest string, layer ArchiveReader) error { } path := filepath.Join(dest, hdr.Name) - base := filepath.Base(path) - - // Prevent symlink breakout - if !strings.HasPrefix(path, dest) { - return breakoutError(fmt.Errorf("%q is outside of %q", path, dest)) + rel, err := filepath.Rel(dest, path) + if err != nil { + return err } + if strings.HasPrefix(rel, "..") { + return breakoutError(fmt.Errorf("%q is outside of %q", hdr.Name, dest)) + } + base := filepath.Base(path) if strings.HasPrefix(base, ".wh.") { originalBase := base[len(".wh."):]