/
use_ashmem.patch
84 lines (80 loc) · 2.03 KB
/
use_ashmem.patch
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
--- ./Xext/shm_old.c 2023-02-07 03:16:51.000000000 +0200
+++ ./Xext/shm.c 2023-02-21 10:35:54.199460924 +0200
@@ -60,6 +60,7 @@
#include <sys/mman.h>
#include "protocol-versions.h"
#include "busfault.h"
+#include <linux/ioctl.h>
/* Needed for Solaris cross-zone shared memory extension */
#ifdef HAVE_SHMCTL64
@@ -1142,6 +1143,20 @@
FreeResource (shmdesc->resource, RT_NONE);
}
+static int
+shm_tmpfile_size(int fd)
+{
+ char path[PATH_MAX] = {0};
+ char realpath[256] = {0};
+ sprintf(path, "/proc/self/fd/%d", fd);
+
+ int size;
+ if (readlink(path, realpath, sizeof(realpath)) != -1 && !strcmp("/dev/ashmem", realpath))
+ return ioctl(fd, /* ASHMEM_GET_SIZE */ _IO(0x77, 4), NULL);
+ else
+ return 0;
+}
+
static int
ProcShmAttachFd(ClientPtr client)
{
@@ -1161,7 +1176,7 @@
if (fd < 0)
return BadMatch;
- if (fstat(fd, &statb) < 0 || statb.st_size == 0) {
+ if (fstat(fd, &statb) < 0 || (statb.st_size == 0 && (statb.st_size = shm_tmpfile_size(fd)) == 0)) {
close(fd);
return BadMatch;
}
@@ -1257,6 +1272,28 @@
return -1;
}
+static inline int
+shm_tmpfile_sized(size_t size)
+{
+ int fd, ret;
+ long flags;
+ fd = open("/dev/ashmem", O_RDWR | O_CLOEXEC);
+ if (fd < 0)
+ return fd;
+ ret = ioctl(fd, /* ASHMEM_SET_SIZE */ _IOW(0x77, 3, size_t), size);
+ if (ret < 0)
+ goto err;
+ flags = fcntl(fd, F_GETFD);
+ if (flags == -1)
+ goto err;
+ if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
+ goto err;
+ return fd;
+ err:
+ close(fd);
+ return ret;
+}
+
static int
ProcShmCreateSegment(ClientPtr client)
{
@@ -1276,13 +1313,9 @@
client->errorValue = stuff->readOnly;
return BadValue;
}
- fd = shm_tmpfile();
+ fd = shm_tmpfile_sized(stuff->size);
if (fd < 0)
return BadAlloc;
- if (ftruncate(fd, stuff->size) < 0) {
- close(fd);
- return BadAlloc;
- }
shmdesc = malloc(sizeof(ShmDescRec));
if (!shmdesc) {
close(fd);