65 lines
1.8 KiB
Go
65 lines
1.8 KiB
Go
package extract
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"syscall"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// hyperguild#153 item 3: ingest checked a path, then extract.Text reopened it
|
|
// by name, so a file swapped for a symlink in between was followed out of
|
|
// raw/. TextIn reads through an os.Root, which refuses to leave the root.
|
|
func TestTextInReadsInsideTheRootAndRefusesEscapes(t *testing.T) {
|
|
root := t.TempDir()
|
|
require.NoError(t, os.WriteFile(filepath.Join(root, "ok.md"), []byte("inside"), 0o644))
|
|
outside := filepath.Join(t.TempDir(), "secret.md")
|
|
require.NoError(t, os.WriteFile(outside, []byte("SENTINEL-153-TEXTIN"), 0o644))
|
|
require.NoError(t, os.Symlink(outside, filepath.Join(root, "leak.md")))
|
|
|
|
r, err := os.OpenRoot(root)
|
|
require.NoError(t, err)
|
|
defer func() { _ = r.Close() }()
|
|
|
|
got, err := TextIn(r, "ok.md")
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "inside", got)
|
|
|
|
got, err = TextIn(r, "leak.md")
|
|
assert.Error(t, err)
|
|
assert.NotContains(t, got, "SENTINEL-153-TEXTIN")
|
|
|
|
_, err = TextIn(r, "../"+filepath.Base(outside))
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
// PR #156 review: a regular file swapped for a FIFO between Lstat and Open
|
|
// blocked open(2) forever. OpenRegular opens non-blocking and checks the type
|
|
// on the opened handle, so a FIFO is refused promptly instead of hanging.
|
|
func TestOpenRegularRefusesAFIFOWithoutBlocking(t *testing.T) {
|
|
dir := t.TempDir()
|
|
require.NoError(t, syscall.Mkfifo(filepath.Join(dir, "pipe.md"), 0o644))
|
|
r, err := os.OpenRoot(dir)
|
|
require.NoError(t, err)
|
|
defer func() { _ = r.Close() }()
|
|
|
|
done := make(chan error, 1)
|
|
go func() {
|
|
f, _, err := OpenRegular(r, "pipe.md")
|
|
if f != nil {
|
|
_ = f.Close()
|
|
}
|
|
done <- err
|
|
}()
|
|
select {
|
|
case err := <-done:
|
|
assert.Error(t, err)
|
|
case <-time.After(2 * time.Second):
|
|
t.Fatal("OpenRegular blocked on a FIFO")
|
|
}
|
|
}
|