From 63967abe62ecba22a792e728f1af509f3604881f Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Thu, 23 Apr 2020 17:47:05 -0500 Subject: storage/filesystem: dotgit, sanity check provided reference path On some operating systems, read() of a directory fd may actually succeed and return garbage resembling on-disk contents. As a result, dotgit may return successful from readReferenceFile() when it should in-fact not. This fixes readReferenceFile() on FreeBSD. Signed-off-by: Kyle Evans --- storage/filesystem/dotgit/dotgit.go | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'storage/filesystem/dotgit/dotgit.go') diff --git a/storage/filesystem/dotgit/dotgit.go b/storage/filesystem/dotgit/dotgit.go index 503ce18..8c3896b 100644 --- a/storage/filesystem/dotgit/dotgit.go +++ b/storage/filesystem/dotgit/dotgit.go @@ -59,6 +59,9 @@ var ( // targeting a non-existing object. This usually means the repository // is corrupt. ErrSymRefTargetNotFound = errors.New("symbolic reference target not found") + // ErrIsDir is returned when a reference file is attempting to be read, + // but the path specified is a directory. + ErrIsDir = errors.New("reference path is a directory") ) // Options holds configuration for the storage. @@ -946,6 +949,14 @@ func (d *DotGit) addRefFromHEAD(refs *[]*plumbing.Reference) error { func (d *DotGit) readReferenceFile(path, name string) (ref *plumbing.Reference, err error) { path = d.fs.Join(path, d.fs.Join(strings.Split(name, "/")...)) + st, err := d.fs.Stat(path) + if err != nil { + return nil, err + } + if st.IsDir() { + return nil, ErrIsDir + } + f, err := d.fs.Open(path) if err != nil { return nil, err -- cgit