From 669056f93dfde92cfcf5cc656df51d0c8d62903d Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Wed, 26 Feb 2020 06:44:25 -0800 Subject: [PATCH] pkg/system.getxattr: handle changed size case lgetxattr(2) man page says: > If size is specified as zero, these calls return the current size of > the named extended attribute (and leave value unchanged). This can be > used to determine the size of the buffer that should be supplied in a > subsequent call. (But, bear in mind that there is a possibility that > the attribute value may change between the two calls, so that it is > still necessary to check the return status from the second call.) The current code does not handle the case when the size changes between the two calls, and the new size is larger. Fix the above problem, and slightly simplify the code. Signed-off-by: Kir Kolyshkin --- pkg/system/xattrs_linux.go | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/pkg/system/xattrs_linux.go b/pkg/system/xattrs_linux.go index d4f1a57fb0..95b609fe7a 100644 --- a/pkg/system/xattrs_linux.go +++ b/pkg/system/xattrs_linux.go @@ -10,24 +10,23 @@ func Lgetxattr(path string, attr string) ([]byte, error) { dest := make([]byte, 128) sz, errno := unix.Lgetxattr(path, attr, dest) - switch { - case errno == unix.ENODATA: - return nil, nil - case errno == unix.ERANGE: - // 128 byte array might just not be good enough. A dummy buffer is used - // to get the real size of the xattrs on disk + for errno == unix.ERANGE { + // Buffer too small, use zero-sized buffer to get the actual size sz, errno = unix.Lgetxattr(path, attr, []byte{}) if errno != nil { return nil, errno } dest = make([]byte, sz) sz, errno = unix.Lgetxattr(path, attr, dest) - if errno != nil { - return nil, errno - } + } + + switch { + case errno == unix.ENODATA: + return nil, nil case errno != nil: return nil, errno } + return dest[:sz], nil }