1 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2 From: Ivan Trubach <mr.trubach@icloud.com>
3 Date: Sat, 27 Jul 2024 20:46:31 +0300
4 Subject: [PATCH 14/19] Fix segfault when copying xattr buffers
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
9 xar_linuxattr_read allocates an internal buffer and incrementally copies
10 the data to xar_attrcopy_to_heap’s inbuf. This change fixes the offset
11 handling by rewriting xar_linuxattr_read function from scratch (with an
12 arguably cleaner implementation).
14 xar/lib/linuxattr.c | 68 +++++++++++++++++++++++++++------------------
15 1 file changed, 41 insertions(+), 27 deletions(-)
17 diff --git a/xar/lib/linuxattr.c b/xar/lib/linuxattr.c
18 index 496dd82..30c85c2 100644
19 --- a/xar/lib/linuxattr.c
20 +++ b/xar/lib/linuxattr.c
21 @@ -97,39 +97,50 @@ struct _linuxattr_context{
23 #define LINUXATTR_CONTEXT(x) ((struct _linuxattr_context *)(x))
25 -int32_t xar_linuxattr_read(xar_t x, xar_file_t f, void * buf, size_t len, void *context) {
27 - if( !LINUXATTR_CONTEXT(context)->buf ) {
29 - LINUXATTR_CONTEXT(context)->bufsz = 1024;
30 +int32_t xar_linuxattr_read(xar_t x, xar_file_t f, void *inbuf, size_t len, void *context) {
32 + int bufsz, off, ret;
35 + buf = LINUXATTR_CONTEXT(context)->buf;
36 + bufsz = LINUXATTR_CONTEXT(context)->bufsz;
37 + off = LINUXATTR_CONTEXT(context)->off;
42 - LINUXATTR_CONTEXT(context)->buf = malloc(LINUXATTR_CONTEXT(context)->bufsz);
43 - if(!LINUXATTR_CONTEXT(context)->buf)
45 - memset(LINUXATTR_CONTEXT(context)->buf, 0, LINUXATTR_CONTEXT(context)->bufsz);
46 - r = lgetxattr(LINUXATTR_CONTEXT(context)->file, LINUXATTR_CONTEXT(context)->attrname, LINUXATTR_CONTEXT(context)->buf, LINUXATTR_CONTEXT(context)->bufsz);
49 - case ERANGE: LINUXATTR_CONTEXT(context)->bufsz *= 2; free(LINUXATTR_CONTEXT(context)->buf); goto AGAIN2;
50 - case ENOTSUP: free(LINUXATTR_CONTEXT(context)->buf); return 0;
52 + buf = malloc(bufsz);
56 + memset(buf, 0, bufsz);
57 + r = lgetxattr(LINUXATTR_CONTEXT(context)->file, LINUXATTR_CONTEXT(context)->attrname, buf, bufsz);
69 + LINUXATTR_CONTEXT(context)->buf = buf;
70 LINUXATTR_CONTEXT(context)->bufsz = r;
74 - if( (LINUXATTR_CONTEXT(context)->bufsz-LINUXATTR_CONTEXT(context)->off) <= len ) {
76 - ret = LINUXATTR_CONTEXT(context)->bufsz - LINUXATTR_CONTEXT(context)->off;
77 - memcpy(buf, ((char *)LINUXATTR_CONTEXT(context)->buf)+LINUXATTR_CONTEXT(context)->off, ret);
78 - LINUXATTR_CONTEXT(context)->off += ret;
81 - memcpy(buf, ((char *)LINUXATTR_CONTEXT(context)->buf)+LINUXATTR_CONTEXT(context)->off, len);
82 - LINUXATTR_CONTEXT(context)->buf = ((char *)LINUXATTR_CONTEXT(context)->buf) + len;
86 + memcpy(inbuf, ((char *)buf) + off, ret);
87 + LINUXATTR_CONTEXT(context)->off = bufsz;
91 + memcpy(inbuf, ((char *)buf) + off, len);
92 + LINUXATTR_CONTEXT(context)->off += len;
96 int32_t xar_linuxattr_write(xar_t x, xar_file_t f, void *buf, size_t len, void *context) {
97 @@ -185,6 +196,7 @@ TRYAGAIN:
99 for( i=buf; (i-buf) < ret; i += strlen(i)+1 ) {
105 @@ -194,11 +206,13 @@ TRYAGAIN:
106 xar_ea_pset(f, e, "fstype", fsname);
107 context.attrname = i;
109 - if (XAR(x)->attrcopy_to_heap(x, f, xar_ea_root(e), xar_linuxattr_read,&context) < 0) {
110 + rc = XAR(x)->attrcopy_to_heap(x, f, xar_ea_root(e), xar_linuxattr_read, &context);
111 + if (context.buf != NULL)
118 context.attrname = NULL;