btrbk: add mainProgram (#356350)
[NixPkgs.git] / pkgs / by-name / xa / xar / patches / 0014-Fix-segfault-when-copying-xattr-buffers.patch
blob6a9f3998e512f54df104bee599fa92eda715d7ee
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
5 MIME-Version: 1.0
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).
13 ---
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 ) {
28 - int r;
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) {
31 + void *buf;
32 + int bufsz, off, ret;
33 + int r;
35 + buf = LINUXATTR_CONTEXT(context)->buf;
36 + bufsz = LINUXATTR_CONTEXT(context)->bufsz;
37 + off = LINUXATTR_CONTEXT(context)->off;
39 + if (buf == NULL) {
40 + bufsz = 1024;
41 AGAIN2:
42 - LINUXATTR_CONTEXT(context)->buf = malloc(LINUXATTR_CONTEXT(context)->bufsz);
43 - if(!LINUXATTR_CONTEXT(context)->buf)
44 - goto AGAIN2;
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);
47 - if( r < 0 ) {
48 - switch(errno) {
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;
51 - default: break;
52 + buf = malloc(bufsz);
53 + if (!buf) {
54 + return -1;
55 + }
56 + memset(buf, 0, bufsz);
57 + r = lgetxattr(LINUXATTR_CONTEXT(context)->file, LINUXATTR_CONTEXT(context)->attrname, buf, bufsz);
58 + if (r < 0) {
59 + free(buf);
60 + switch (errno) {
61 + case ERANGE:
62 + bufsz *= 2;
63 + goto AGAIN2;
64 + case ENOTSUP:
65 + return 0;
67 return -1;
69 + LINUXATTR_CONTEXT(context)->buf = buf;
70 LINUXATTR_CONTEXT(context)->bufsz = r;
71 + bufsz = r;
74 - if( (LINUXATTR_CONTEXT(context)->bufsz-LINUXATTR_CONTEXT(context)->off) <= len ) {
75 - int32_t ret;
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;
79 - return(ret);
80 - } else {
81 - memcpy(buf, ((char *)LINUXATTR_CONTEXT(context)->buf)+LINUXATTR_CONTEXT(context)->off, len);
82 - LINUXATTR_CONTEXT(context)->buf = ((char *)LINUXATTR_CONTEXT(context)->buf) + len;
83 - return len;
84 + ret = bufsz - off;
85 + if (ret <= len) {
86 + memcpy(inbuf, ((char *)buf) + off, ret);
87 + LINUXATTR_CONTEXT(context)->off = bufsz;
88 + return ret;
91 + memcpy(inbuf, ((char *)buf) + off, len);
92 + LINUXATTR_CONTEXT(context)->off += len;
93 + return 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 ) {
100 xar_ea_t e;
101 + int rc;
103 context.bufsz = 0;
104 context.off = 0;
105 @@ -194,11 +206,13 @@ TRYAGAIN:
106 xar_ea_pset(f, e, "fstype", fsname);
107 context.attrname = i;
108 context.ea = e;
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)
112 + free(context.buf);
113 + if (rc < 0) {
114 retval = -1;
115 goto BAIL;
117 - free(context.buf);
118 context.attrname = NULL;
122 2.44.1