From c0d727dfed74f197b5e477887bb671a130477dc7 Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Sat, 16 Nov 2024 20:56:59 +0100 Subject: [PATCH] fs: correctly handle O_NOFOLLOW for xattr / generic attribute retrieval --- internal/fs/ea_windows_test.go | 4 ++-- internal/fs/meta_windows.go | 4 ++-- internal/fs/meta_xattr.go | 14 ++++++++++++-- internal/fs/node_xattr.go | 13 +++++++++++++ 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/internal/fs/ea_windows_test.go b/internal/fs/ea_windows_test.go index a1f940b49..b5f7d109f 100644 --- a/internal/fs/ea_windows_test.go +++ b/internal/fs/ea_windows_test.go @@ -262,7 +262,7 @@ func TestPathSupportsExtendedAttributes(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - handle, err := openMetadataHandle(tc.path, false) + handle, err := openMetadataHandle(tc.path, 0) rtest.OK(t, err) supported, err := handleSupportsExtendedAttributes(windows.Handle(handle.Fd())) if err != nil { @@ -276,7 +276,7 @@ func TestPathSupportsExtendedAttributes(t *testing.T) { // Test with an invalid path - handle, err := openMetadataHandle("Z:\\NonExistentPath-UAS664da5s4dyu56das45f5as", false) + handle, err := openMetadataHandle("Z:\\NonExistentPath-UAS664da5s4dyu56das45f5as", 0) rtest.OK(t, err) _, err = handleSupportsExtendedAttributes(windows.Handle(handle.Fd())) if err == nil { diff --git a/internal/fs/meta_windows.go b/internal/fs/meta_windows.go index d6edeb939..62d859439 100644 --- a/internal/fs/meta_windows.go +++ b/internal/fs/meta_windows.go @@ -11,7 +11,7 @@ import ( ) func (p *pathMetadataHandle) Xattr(_ bool) ([]restic.ExtendedAttribute, error) { - f, err := openMetadataHandle(p.name, false) + f, err := openMetadataHandle(p.name, p.flag) if err != nil { return nil, err } @@ -54,7 +54,7 @@ func xattrFromHandle(path string, handle windows.Handle) ([]restic.ExtendedAttri } func (p *pathMetadataHandle) SecurityDescriptor() (buf *[]byte, err error) { - f, err := openMetadataHandle(p.name, 0) + f, err := openMetadataHandle(p.name, p.flag) if err != nil { return nil, err } diff --git a/internal/fs/meta_xattr.go b/internal/fs/meta_xattr.go index 224154cb1..9e762bd3d 100644 --- a/internal/fs/meta_xattr.go +++ b/internal/fs/meta_xattr.go @@ -15,8 +15,18 @@ func (p *pathMetadataHandle) Xattr(ignoreListError bool) ([]restic.ExtendedAttri path := p.Name() return xattrFromPath( path, - func() ([]string, error) { return listxattr(path) }, - func(attr string) ([]byte, error) { return getxattr(path, attr) }, + func() ([]string, error) { + if (p.flag & O_NOFOLLOW) != 0 { + return llistxattr(path) + } + return listxattr(path) + }, + func(attr string) ([]byte, error) { + if (p.flag & O_NOFOLLOW) != 0 { + return lgetxattr(path, attr) + } + return getxattr(path, attr) + }, ignoreListError, ) } diff --git a/internal/fs/node_xattr.go b/internal/fs/node_xattr.go index 988c37845..7becbd10b 100644 --- a/internal/fs/node_xattr.go +++ b/internal/fs/node_xattr.go @@ -51,6 +51,12 @@ func fgetxattr(f *os.File, name string) (b []byte, err error) { // getxattr retrieves extended attribute data associated with path. func getxattr(path string, name string) (b []byte, err error) { + b, err = xattr.Get(path, name) + return b, handleXattrErr(err) +} + +// lgetxattr retrieves extended attribute data associated with path. +func lgetxattr(path string, name string) (b []byte, err error) { b, err = xattr.LGet(path, name) return b, handleXattrErr(err) } @@ -70,6 +76,13 @@ func flistxattr(f *os.File) (l []string, err error) { // listxattr retrieves a list of names of extended attributes associated with the // given path in the file system. func listxattr(path string) ([]string, error) { + l, err := xattr.List(path) + return l, handleXattrErr(err) +} + +// llistxattr retrieves a list of names of extended attributes associated with the +// given path in the file system. +func llistxattr(path string) ([]string, error) { l, err := xattr.LList(path) return l, handleXattrErr(err) }