The branch main has been updated by dchagin:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=18d1c86788f66f42c4e096142f4f8d168f68732c

commit 18d1c86788f66f42c4e096142f4f8d168f68732c
Author:     Dmitry Chagin <dcha...@freebsd.org>
AuthorDate: 2023-09-05 08:51:46 +0000
Commit:     Dmitry Chagin <dcha...@freebsd.org>
CommitDate: 2023-09-05 08:51:46 +0000

    linux(4): Fix listxattr for the case when the size is 0
    
    If size is specified as zero, these calls return the current size
    of the list of extended attribute names (and leave list unchanged).
    
    Tested by:              zirias
    MFC after:              1 week
---
 sys/compat/linux/linux_xattr.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/sys/compat/linux/linux_xattr.c b/sys/compat/linux/linux_xattr.c
index 74b47f1cbaec..71d7ae58439e 100644
--- a/sys/compat/linux/linux_xattr.c
+++ b/sys/compat/linux/linux_xattr.c
@@ -173,24 +173,28 @@ listxattr(struct thread *td, struct listxattr_args *args)
                while (rs > 0) {
                        keylen = (unsigned char)key[0];
                        pairlen = prefixlen + 1 + keylen + 1;
-                       if (cnt + pairlen > LINUX_XATTR_LIST_MAX) {
+                       cnt += pairlen;
+                       if (cnt > LINUX_XATTR_LIST_MAX) {
                                error = E2BIG;
                                break;
                        }
-                       if ((args->list != NULL && cnt > args->size) ||
+                       /*
+                        * If size is specified as zero, return the current size
+                        * of the list of extended attribute names.
+                        */
+                       if ((args->size > 0 && cnt > args->size) ||
                            pairlen >= sizeof(attrname)) {
                                error = ERANGE;
                                break;
                        }
                        ++key;
-                       if (args->list != NULL) {
+                       if (args->list != NULL && args->size > 0) {
                                sprintf(attrname, "%s.%.*s", prefix, keylen, 
key);
                                error = copyout(attrname, args->list, pairlen);
                                if (error != 0)
                                        break;
                                args->list += pairlen;
                        }
-                       cnt += pairlen;
                        key += keylen;
                        rs -= (keylen + 1);
                }

Reply via email to