]> Cypherpunks repositories - gostls13.git/commitdiff
syscall: fix NaCl Link syscall error handling
authorTim Wright <tenortim@gmail.com>
Sun, 5 Nov 2017 02:35:23 +0000 (19:35 -0700)
committerBrad Fitzpatrick <bradfitz@golang.org>
Mon, 6 Nov 2017 16:36:34 +0000 (16:36 +0000)
The existing NaCl filesystem Link system call erroneously allowed
a caller to call Link on an existing target which violates the POSIX
standard and effectively corrupted the internal filesystem
representation.

Fixes #22383

Change-Id: I77b16c37af9bf00a1799fa84277f066180edac47
Reviewed-on: https://go-review.googlesource.com/76110
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/os/os_test.go
src/syscall/fs_nacl.go

index 7ac2431df932c7ae7673c3f0c17e464eb04dce31..eb8a7d1b926a24c1be63c65c9c08b3755f807d9f 100644 (file)
@@ -721,6 +721,27 @@ func TestHardLink(t *testing.T) {
        if !SameFile(tostat, fromstat) {
                t.Errorf("link %q, %q did not create hard link", to, from)
        }
+       // We should not be able to perform the same Link() a second time
+       err = Link(to, from)
+       switch err := err.(type) {
+       case *LinkError:
+               if err.Op != "link" {
+                       t.Errorf("Link(%q, %q) err.Op = %q; want %q", to, from, err.Op, "link")
+               }
+               if err.Old != to {
+                       t.Errorf("Link(%q, %q) err.Old = %q; want %q", to, from, err.Old, to)
+               }
+               if err.New != from {
+                       t.Errorf("Link(%q, %q) err.New = %q; want %q", to, from, err.New, from)
+               }
+               if !IsExist(err.Err) {
+                       t.Errorf("Link(%q, %q) err.Err = %q; want %q", to, from, err.Err, "file exists error")
+               }
+       case nil:
+               t.Errorf("link %q, %q: expected error, got nil", from, to)
+       default:
+               t.Errorf("link %q, %q: expected %T, got %T %v", from, to, new(LinkError), err, err)
+       }
 }
 
 // chtmpdir changes the working directory to a new temporary directory and
index cbd9539c92cab3eb047c1f43638a3e161b2c207f..8fee4daee92ac530cf5a5f35c19ac1b73a9aa2c2 100644 (file)
@@ -636,6 +636,10 @@ func Link(path, link string) error {
        if ip.Mode&S_IFMT == S_IFDIR {
                return EPERM
        }
+       _, _, err = fs.dirlookup(dp, elem)
+       if err == nil {
+               return EEXIST
+       }
        fs.dirlink(dp, elem, ip)
        return nil
 }