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 | |
| parent | 2d01d5f2d4bb1fc9c7a7bb9165edcef42d4f89c6 (diff) | |
tests: add symlink_race tool
Help uncover symlink races.
| -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() +} | 
