azureblob: fix crash when listing outside a SAS URL's root - fixes #4851

Before this change if you attempted to list a remote set up with a SAS
URL outside its container then it would crash the Azure SDK.

A check is done to make sure the root is inside the container when
starting the backend which is usually enough, but when two SAS URL
based remotes are mounted in a union, the union backend attempts to
read paths outside the named container. This was causing a mysterious
crash in the Azure SDK.

This fixes the problem by checking to see if the container in the
listing is the one in the SAS URL before listing the directory and
returning directory not found if it isn't.
This commit is contained in:
Nick Craig-Wood 2020-12-10 21:08:58 +00:00
parent 74a321e156
commit f7404f52e7
1 changed files with 21 additions and 0 deletions

View File

@ -776,8 +776,26 @@ func (f *Fs) itemToDirEntry(remote string, object *azblob.BlobItemInternal, isDi
return o, nil
}
// Check to see if this is a limited container and the container is not found
func (f *Fs) containerOK(container string) bool {
if !f.isLimited {
return true
}
f.cntURLcacheMu.Lock()
defer f.cntURLcacheMu.Unlock()
for limitedContainer := range f.cntURLcache {
if container == limitedContainer {
return true
}
}
return false
}
// listDir lists a single directory
func (f *Fs) listDir(ctx context.Context, container, directory, prefix string, addContainer bool) (entries fs.DirEntries, err error) {
if !f.containerOK(container) {
return nil, fs.ErrorDirNotFound
}
err = f.list(ctx, container, directory, prefix, addContainer, false, f.opt.ListChunkSize, func(remote string, object *azblob.BlobItemInternal, isDirectory bool) error {
entry, err := f.itemToDirEntry(remote, object, isDirectory)
if err != nil {
@ -886,6 +904,9 @@ func (f *Fs) ListR(ctx context.Context, dir string, callback fs.ListRCallback) (
f.cache.MarkOK(container)
}
} else {
if !f.containerOK(container) {
return fs.ErrorDirNotFound
}
err = listR(container, directory, f.rootDirectory, f.rootContainer == "")
if err != nil {
return err