Skip to content

Commit

Permalink
os: handle the sticky bit separately for *BSD and Solaris
Browse files Browse the repository at this point in the history
open(2) and mkdir(2) won't set the sticky bit on *BSD and Solaris.
This behavior is mentioned on sticky(8).
see also: moby/moby#6587

Fixes golang#8383.

Change-Id: Ic4733700f9926b9fc2b6fd1f998acec34e518764
Reviewed-on: https://go-review.googlesource.com/1673
Reviewed-by: Ian Lance Taylor <iant@golang.org>
  • Loading branch information
kzys authored and ianlancetaylor committed Dec 17, 2014
1 parent 60ea2c5 commit 6262902
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/os/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,12 @@ func (f *File) WriteString(s string) (ret int, err error) {
// If there is an error, it will be of type *PathError.
func Mkdir(name string, perm FileMode) error {
e := syscall.Mkdir(name, syscallMode(perm))

// mkdir(2) itself won't handle the sticky bit on *BSD and Solaris
if !supportsCreateWithStickyBit && e == nil && perm&ModeSticky != 0 {
e = Chmod(name, perm)
}

if e != nil {
return &PathError{"mkdir", name, e}
}
Expand Down
12 changes: 12 additions & 0 deletions src/os/file_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,23 @@ const DevNull = "/dev/null"
// methods on the returned File can be used for I/O.
// If there is an error, it will be of type *PathError.
func OpenFile(name string, flag int, perm FileMode) (file *File, err error) {
chmod := false
if !supportsCreateWithStickyBit && flag&O_CREATE != 0 && perm&ModeSticky != 0 {
if _, err := Stat(name); IsNotExist(err) {
chmod = true
}
}

r, e := syscall.Open(name, flag|syscall.O_CLOEXEC, syscallMode(perm))
if e != nil {
return nil, &PathError{"open", name, e}
}

// open(2) itself won't handle the sticky bit on *BSD and Solaris
if chmod && e == nil {
e = Chmod(name, perm)
}

// There's a race here with fork/exec, which we are
// content to live with. See ../syscall/exec_unix.go.
if !supportsCloseOnExec {
Expand Down
11 changes: 11 additions & 0 deletions src/os/sticky_bsd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build darwin dragonfly freebsd netbsd openbsd solaris

package os

// According to sticky(8), neither open(2) nor mkdir(2) will create
// a file with the sticky bit set.
const supportsCreateWithStickyBit = false
14 changes: 14 additions & 0 deletions src/os/sticky_notbsd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build !darwin
// +build !dragonfly
// +build !freebsd
// +build !netbsd
// +build !openbsd
// +build !solaris

package os

const supportsCreateWithStickyBit = true

0 comments on commit 6262902

Please sign in to comment.