summaryrefslogtreecommitdiff
blob: 95bad206372e72913d80bec1345ef3f09f2ce619 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
https://bugs.gentoo.org/797358

From 21cb1dad1243f4c0a427d893babab12e48b60f0e Mon Sep 17 00:00:00 2001
From: Masatake YAMATO <yamato@redhat.com>
Date: Sun, 20 Jun 2021 21:40:55 +0900
Subject: [PATCH] Adjust alignment of buffer passed to stat()

Close #160.

The original code passes char[] buffer to stat().
This can be cause a SIGBUS.

#160 reported an actual crash on armv7a + glibc-2.33 platform.
See also https://sourceware.org/bugzilla/show_bug.cgi?id=27993.

The issue is reported by @10ne1.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
[Adrian: Backported to 4.94]
Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
--- a/misc.c
+++ b/misc.c
@@ -293,7 +293,15 @@ doinchild(fn, fp, rbuf, rbln)
 		 */
 
 		    int r_al, r_rbln;
-		    char r_arg[MAXPATHLEN+1], r_rbuf[MAXPATHLEN+1];
+		    char r_arg[MAXPATHLEN+1];
+		    union {
+			    char r_rbuf[MAXPATHLEN+1];
+			    /*
+			     * This field is only for adjusting the alignment of r_rbuf that
+			     * can be used as an argument for stat().
+			     */
+			    struct stat _;
+		    } r;
 		    int (*r_fn)();
 		/*
 		 * Close sufficient open file descriptors except Pipes[0] and
@@ -358,16 +366,16 @@ doinchild(fn, fp, rbuf, rbln)
 			||  read(Pipes[0], r_arg, r_al) != r_al
 			||  read(Pipes[0], (char *)&r_rbln, sizeof(r_rbln))
 			    != (int)sizeof(r_rbln)
-			||  r_rbln < 1 || r_rbln > (int)sizeof(r_rbuf))
+			||  r_rbln < 1 || r_rbln > (int)sizeof(r.r_rbuf))
 			    break;
-			zeromem (r_rbuf, r_rbln);
-			rv = r_fn(r_arg, r_rbuf, r_rbln);
+			zeromem (r.r_rbuf, r_rbln);
+			rv = r_fn(r_arg, r.r_rbuf, r_rbln);
 			en = errno;
 			if (write(Pipes[3], (char *)&rv, sizeof(rv))
 			    != sizeof(rv)
 			||  write(Pipes[3], (char *)&en, sizeof(en))
 			    != sizeof(en)
-			||  write(Pipes[3], r_rbuf, r_rbln) != r_rbln)
+			||  write(Pipes[3], r.r_rbuf, r_rbln) != r_rbln)
 			    break;
 		    }
 		    (void) _exit(0);
-- 
2.32.0