diff options
author | Jakob Unterwurzacher | 2018-09-22 19:41:58 +0200 |
---|---|---|
committer | Jakob Unterwurzacher | 2018-09-23 12:17:26 +0200 |
commit | 05c8d4a1c459dc4c73918af898119b1e17b1c0ce (patch) | |
tree | 2c1d6b7d71041f2df09e804579e610f04e7c9b82 /tests/symlink_race | |
parent | 2d01d5f2d4bb1fc9c7a7bb9165edcef42d4f89c6 (diff) |
tests: add symlink_race tool
Help uncover symlink races.
Diffstat (limited to 'tests/symlink_race')
-rw-r--r-- | tests/symlink_race/.gitignore | 3 | ||||
-rw-r--r-- | tests/symlink_race/main.go | 91 |
2 files changed, 94 insertions, 0 deletions
diff --git a/tests/symlink_race/.gitignore b/tests/symlink_race/.gitignore new file mode 100644 index 0000000..45df5f8 --- /dev/null +++ b/tests/symlink_race/.gitignore @@ -0,0 +1,3 @@ +symlink_race.test_file.tmp +symlink_race.test_file +symlink_race diff --git a/tests/symlink_race/main.go b/tests/symlink_race/main.go new file mode 100644 index 0000000..6fb794f --- /dev/null +++ b/tests/symlink_race/main.go @@ -0,0 +1,91 @@ +package main + +import ( + "fmt" + "os" + "syscall" + "time" +) + +const ( + testFile = "symlink_race.test_file" + testFileTmp = testFile + ".tmp" +) + +func renameLoop() { + // May be left behind from an earlier run + syscall.Unlink(testFileTmp) + + var err error + var fd *os.File + for { + err = syscall.Symlink("/root/chmod_me", testFileTmp) + if err != nil { + fmt.Printf("Symlink() failed: %v\n", err) + continue + } + err = syscall.Rename(testFileTmp, testFile) + if err != nil { + fmt.Printf("Rename() 1 failed: %v\n", err) + continue + } + fd, err = os.Create(testFileTmp) + if err != nil { + fmt.Printf("Create() failed: %v\n", err) + continue + } + fd.Close() + err = syscall.Rename(testFileTmp, testFile) + if err != nil { + fmt.Printf("Rename() 2 failed: %v\n", err) + continue + } + fmt.Printf(".") + } +} + +func chmodLoop() { + var err error + for { + err = syscall.Chmod(testFile, 0777) + if err != nil { + fmt.Printf("Chmod() failed: %v\n", err) + } else { + fmt.Printf("Chmod() ok\n") + } + time.Sleep(100 * time.Microsecond) + } +} + +func openLoop() { + var err error + var f *os.File + buf := make([]byte, 100) + owned := []byte("owned") + var n int + for { + f, err = os.OpenFile(testFile, os.O_RDWR, 0777) + if err != nil { + fmt.Printf("Open() failed: %v\n", err) + continue + } + _, err = f.Write(owned) + if err != nil { + fmt.Printf("Write() failed: %v\n", err) + } + n, err = f.Read(buf) + if err != nil { + fmt.Printf("Read() failed: %v\n", err) + continue + } + if n > 0 { + fmt.Printf("Content: %q\n", string(buf[:n])) + os.Exit(1) + } + } +} + +func main() { + go openLoop() + renameLoop() +} |