Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FAT32: path traversal fails if the first directory is equal to the FAT volume label #269

Closed
nkraetzschmar opened this issue Dec 2, 2024 · 0 comments · Fixed by #270
Closed

Comments

@nkraetzschmar
Copy link
Contributor

nkraetzschmar commented Dec 2, 2024

If the first component of a file path is equal to the FAT32 volume label then the function readDirWithMkdir incorrectly matches the volume label entry to the file name being searched for1.

A very common scenario where this error can occur is trying to access files in the /EFI directory on an ESP partition with volume label EFI.

Steps to reproduce:

  • build two FAT32 images (using mtools), one with LABEL=TEST, one with LABEL=EFI, both containing an /EFI directory:
#!/usr/bin/env bash

set -e

for i in TEST EFI; do
	truncate -s 256M disk_$i
	mformat -i disk_$i -F -v $i ::
	mmd -i disk_$i ::/EFI
	mdir -i disk_$i -/ ::
done
  • try to read the /EFI directory on each using the following
package main

import (
	"fmt"
	"os"

	"github.com/diskfs/go-diskfs/filesystem/fat32"
)

func main() {
	paths := []string{"disk_TEST", "disk_EFI"}

	for _, path := range paths {
		file, err := os.Open(path)
		if err != nil {
			panic(err)
		}
		defer file.Close()

		fs, err := fat32.Read(file, 256*1024*1024, 0, 512)
		if err != nil {
			panic(err)
		}

		dir, err := fs.ReadDir("/EFI")
		if err != nil {
			panic(err)
		}

		fmt.Printf("%#v\n", dir)
	}
}

This results in the following output:

[]fs.FileInfo{fat32.FileInfo{modTime:time.Time{wall:0x0, ext:63868765252, loc:(*time.Location)(nil)}, mode:0x0, name:"", shortName:".", size:0, isDir:true}, fat32.FileInfo{modTime:time.Time{wall:0x0, ext:63868765252, loc:(*time.Location)(nil)}, mode:0x0, name:"", shortName:"..", size:0, isDir:true}}
panic: error reading directory /EFI: cannot create directory at /EFI since it is a file

The expected behaviour would obviously be, that this works for both disk images, regardless of the volume label.

Footnotes

  1. https://github.com/diskfs/go-diskfs/blob/15ebb7b3fb4e7106cfad897d1939ccce8f51743a/filesystem/fat32/fat32.go#L997

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant