Skip to content

Commit

Permalink
interp: determine access to a directory via unix.Access
Browse files Browse the repository at this point in the history
Rip out the body of interp.hasPermissionToDir and replace it with just a
call to unix.Access(path, unix.X_OK).

Update the function signature of hasPermissionToDir in os_notunix.go,
too.

Fixes #1033.
  • Loading branch information
theclapp authored Sep 30, 2023
1 parent 6fe8d00 commit 08cb48c
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 44 deletions.
2 changes: 1 addition & 1 deletion interp/builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -963,7 +963,7 @@ func (r *Runner) changeDir(ctx context.Context, path string) int {
if err != nil || !info.IsDir() {
return 1
}
if !hasPermissionToDir(info) {
if !hasPermissionToDir(path) {
return 1
}
r.Dir = path
Expand Down
3 changes: 1 addition & 2 deletions interp/os_notunix.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@ package interp

import (
"fmt"
"os"
)

func mkfifo(path string, mode uint32) error {
return fmt.Errorf("unsupported")
}

// hasPermissionToDir is a no-op on Windows.
func hasPermissionToDir(info os.FileInfo) bool {
func hasPermissionToDir(string) bool {
return true
}
45 changes: 4 additions & 41 deletions interp/os_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,52 +6,15 @@
package interp

import (
"os"
"os/user"
"strconv"
"syscall"

"golang.org/x/sys/unix"
)

func mkfifo(path string, mode uint32) error {
return unix.Mkfifo(path, mode)
}

// hasPermissionToDir returns if the OS current user has execute permission
// to the given directory
func hasPermissionToDir(info os.FileInfo) bool {
user, err := user.Current()
if err != nil {
return false // unknown user; assume no permissions
}
uid, err := strconv.Atoi(user.Uid)
if err != nil {
return false // on POSIX systems, Uid should always be a decimal number
}
if uid == 0 {
return true // super-user
}

st, _ := info.Sys().(*syscall.Stat_t)
if st == nil {
panic("unexpected info.Sys type")
}
perm := info.Mode().Perm()
// user (u)
if perm&0o100 != 0 && st.Uid == uint32(uid) {
return true
}

gid, _ := strconv.Atoi(user.Gid)
// other users in group (g)
if perm&0o010 != 0 && st.Uid != uint32(uid) && st.Gid == uint32(gid) {
return true
}
// remaining users (o)
if perm&0o001 != 0 && st.Uid != uint32(uid) && st.Gid != uint32(gid) {
return true
}

return false
// hasPermissionToDir returns true if the OS current user has execute
// permission to the given directory
func hasPermissionToDir(path string) bool {
return unix.Access(path, unix.X_OK) == nil
}

0 comments on commit 08cb48c

Please sign in to comment.