Skip to content

Commit

Permalink
unix: add namespaced versions of Listxattr/Flistxattr/Llistxattr on *BSD
Browse files Browse the repository at this point in the history
Current extended attributes API mixes together attributes from different
namespaces without a way to separate them. Add versions of *listxattr
functions that return attributes only from the specified namespace.

For golang/go#54357

Change-Id: I605d677dd2f2a17541bc02f3146a7509c69269c9
Reviewed-on: https://go-review.googlesource.com/c/sys/+/430215
Reviewed-by: Yuval Pavel Zholkover <paulzhol@gmail.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Run-TryBot: Dmitri Goutnik <dgoutnik@gmail.com>
Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Jenny Rakoczy <jenny@golang.org>
Reviewed-by: Jenny Rakoczy <jenny@golang.org>
  • Loading branch information
dmgk authored and gopherbot committed Sep 13, 2022
1 parent 76c7481 commit 63ea559
Showing 1 changed file with 65 additions and 30 deletions.
95 changes: 65 additions & 30 deletions unix/xattr_bsd.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,13 +160,12 @@ func Lremovexattr(link string, attr string) (err error) {
}

func Listxattr(file string, dest []byte) (sz int, err error) {
d := initxattrdest(dest, 0)
destsiz := len(dest)

// FreeBSD won't allow you to list xattrs from multiple namespaces
s := 0
s, pos := 0, 0
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
stmp, e := ExtattrListFile(file, nsid, uintptr(d), destsiz)
stmp, e := ListxattrNS(file, nsid, dest[pos:])

/* Errors accessing system attrs are ignored so that
* we can implement the Linux-like behavior of omitting errors that
Expand All @@ -175,66 +174,102 @@ func Listxattr(file string, dest []byte) (sz int, err error) {
* Linux will still error if we ask for user attributes on a file that
* we don't have read permissions on, so don't ignore those errors
*/
if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
continue
} else if e != nil {
if e != nil {
if e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
continue
}
return s, e
}

s += stmp
destsiz -= s
if destsiz < 0 {
destsiz = 0
pos = s
if pos > destsiz {
pos = destsiz
}
d = initxattrdest(dest, s)
}

return s, nil
}

func Flistxattr(fd int, dest []byte) (sz int, err error) {
func ListxattrNS(file string, nsid int, dest []byte) (sz int, err error) {
d := initxattrdest(dest, 0)
destsiz := len(dest)

s := 0
s, e := ExtattrListFile(file, nsid, uintptr(d), destsiz)
if e != nil {
return 0, err
}

return s, nil
}

func Flistxattr(fd int, dest []byte) (sz int, err error) {
destsiz := len(dest)

s, pos := 0, 0
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
stmp, e := ExtattrListFd(fd, nsid, uintptr(d), destsiz)
if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
continue
} else if e != nil {
stmp, e := FlistxattrNS(fd, nsid, dest[pos:])

if e != nil {
if e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
continue
}
return s, e
}

s += stmp
destsiz -= s
if destsiz < 0 {
destsiz = 0
pos = s
if pos > destsiz {
pos = destsiz
}
d = initxattrdest(dest, s)
}

return s, nil
}

func Llistxattr(link string, dest []byte) (sz int, err error) {
func FlistxattrNS(fd int, nsid int, dest []byte) (sz int, err error) {
d := initxattrdest(dest, 0)
destsiz := len(dest)

s := 0
s, e := ExtattrListFd(fd, nsid, uintptr(d), destsiz)
if e != nil {
return 0, err
}

return s, nil
}

func Llistxattr(link string, dest []byte) (sz int, err error) {
destsiz := len(dest)

s, pos := 0, 0
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
stmp, e := ExtattrListLink(link, nsid, uintptr(d), destsiz)
if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
continue
} else if e != nil {
stmp, e := LlistxattrNS(link, nsid, dest[pos:])

if e != nil {
if e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
continue
}
return s, e
}

s += stmp
destsiz -= s
if destsiz < 0 {
destsiz = 0
pos = s
if pos > destsiz {
pos = destsiz
}
d = initxattrdest(dest, s)
}

return s, nil
}

func LlistxattrNS(link string, nsid int, dest []byte) (sz int, err error) {
d := initxattrdest(dest, 0)
destsiz := len(dest)

s, e := ExtattrListLink(link, nsid, uintptr(d), destsiz)
if e != nil {
return 0, err
}

return s, nil
Expand Down

0 comments on commit 63ea559

Please sign in to comment.