VirtualBox

Ticket #16693: diff_5.1.22_dlopen_fix

File diff_5.1.22_dlopen_fix, 6.9 KB (added by Frank Mehnert, 7 years ago)

Patch against 5.1.22 for resolving the symlink problems

Line 
1Index: src/VBox/HostDrivers/Support/posix/SUPR3HardenedMain-posix.cpp
2===================================================================
3--- src/VBox/HostDrivers/Support/posix/SUPR3HardenedMain-posix.cpp (revision 115126)
4+++ src/VBox/HostDrivers/Support/posix/SUPR3HardenedMain-posix.cpp (revision 115307)
5@@ -341,6 +341,7 @@
6 * Patch 64-bit hosts.
7 */
8 uint32_t cRipRelMovs = 0;
9+ uint32_t cRelCalls = 0;
10
11 /* Just use the disassembler to skip 12 bytes or more, we might need to
12 rewrite mov instructions using RIP relative addressing. */
13@@ -349,7 +350,8 @@
14 cbInstr = 1;
15 int rc = DISInstr(pbTarget + offJmpBack, DISCPUMODE_64BIT, &Dis, &cbInstr);
16 if ( RT_FAILURE(rc)
17- || (Dis.pCurInstr->fOpType & DISOPTYPE_CONTROLFLOW)
18+ || ( Dis.pCurInstr->fOpType & DISOPTYPE_CONTROLFLOW
19+ && Dis.pCurInstr->uOpcode != OP_CALL)
20 || ( Dis.ModRM.Bits.Mod == 0
21 && Dis.ModRM.Bits.Rm == 5 /* wrt RIP */
22 && Dis.pCurInstr->uOpcode != OP_MOV))
23@@ -357,15 +359,23 @@
24
25 if (Dis.ModRM.Bits.Mod == 0 && Dis.ModRM.Bits.Rm == 5 /* wrt RIP */)
26 cRipRelMovs++;
27+ if ( Dis.pCurInstr->uOpcode == OP_CALL
28+ && (Dis.pCurInstr->fOpType & DISOPTYPE_RELATIVE_CONTROLFLOW))
29+ cRelCalls++;
30
31 offJmpBack += cbInstr;
32 cbPatchMem += cbInstr;
33 }
34
35+ /*
36+ * Each relative call requires extra bytes as it is converted to a pushq imm32
37+ * + mov [RSP+4], imm32 + a jmp qword [$+8 wrt RIP] to avoid clobbering registers.
38+ */
39+ cbPatchMem += cRelCalls * RT_ALIGN_32(13 + 6 + 8, 8);
40 cbPatchMem += 14; /* jmp qword [$+8 wrt RIP] + 8 byte address to jump to. */
41 cbPatchMem = RT_ALIGN_32(cbPatchMem, 8);
42
43- /* Allocate suitable exectuable memory available. */
44+ /* Allocate suitable executable memory available. */
45 bool fConvRipRelMovs = false;
46 uint8_t *pbPatchMem = supR3HardenedMainPosixExecMemAlloc(cbPatchMem, pbTarget, cRipRelMovs > 0);
47 if (!pbPatchMem)
48@@ -396,7 +406,8 @@
49 cbInstr = 1;
50 int rc = DISInstr(pbTarget + offInsn, DISCPUMODE_64BIT, &Dis, &cbInstr);
51 if ( RT_FAILURE(rc)
52- || (Dis.pCurInstr->fOpType & DISOPTYPE_CONTROLFLOW))
53+ || ( Dis.pCurInstr->fOpType & DISOPTYPE_CONTROLFLOW
54+ && Dis.pCurInstr->uOpcode != OP_CALL))
55 return VERR_SUPLIB_UNEXPECTED_INSTRUCTION;
56
57 if ( Dis.ModRM.Bits.Mod == 0
58@@ -439,6 +450,34 @@
59 pbPatchMem += sizeof(int32_t);
60 }
61 }
62+ else if ( Dis.pCurInstr->uOpcode == OP_CALL
63+ && (Dis.pCurInstr->fOpType & DISOPTYPE_RELATIVE_CONTROLFLOW))
64+ {
65+ /* Convert to absolute jump. */
66+ uintptr_t uAddr = (uintptr_t)&pbTarget[offInsn + cbInstr] + (intptr_t)Dis.Param1.uValue;
67+
68+ /* Skip the push instructions till the return address is known. */
69+ uint8_t *pbPatchMemPush = pbPatchMem;
70+ pbPatchMem += 13;
71+
72+ *pbPatchMem++ = 0xff; /* jmp qword [$+8 wrt RIP] */
73+ *pbPatchMem++ = 0x25;
74+ *(uint32_t *)pbPatchMem = (uint32_t)(RT_ALIGN_PT(pbPatchMem + 4, 8, uint8_t *) - (pbPatchMem + 4));
75+ pbPatchMem = RT_ALIGN_PT(pbPatchMem + 4, 8, uint8_t *);
76+ *(uint64_t *)pbPatchMem = uAddr;
77+ pbPatchMem += sizeof(uint64_t);
78+
79+ /* Push the return address onto stack. Difficult on amd64 without clobbering registers... */
80+ uintptr_t uAddrReturn = (uintptr_t)pbPatchMem;
81+ *pbPatchMemPush++ = 0x68; /* push imm32 sign-extended as 64-bit*/
82+ *(uint32_t *)pbPatchMemPush = RT_LO_U32(uAddrReturn);
83+ pbPatchMemPush += sizeof(uint32_t);
84+ *pbPatchMemPush++ = 0xc7;
85+ *pbPatchMemPush++ = 0x44;
86+ *pbPatchMemPush++ = 0x24;
87+ *pbPatchMemPush++ = 0x04; /* movl [RSP+4], imm32 */
88+ *(uint32_t *)pbPatchMemPush = RT_HI_U32(uAddrReturn);
89+ }
90 else
91 {
92 memcpy(pbPatchMem, pbTarget + offInsn, cbInstr);
93Index: src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp
94===================================================================
95--- src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp (revision 115126)
96+++ src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp (revision 115307)
97@@ -86,6 +86,9 @@
98 /** The max path length acceptable for a trusted path. */
99 #define SUPR3HARDENED_MAX_PATH 260U
100
101+/** Enable to resolve symlinks using realpath() instead of cooking our own stuff. */
102+#define SUP_HARDENED_VERIFY_FOLLOW_SYMLINKS_USE_REALPATH 1
103+
104 #ifdef RT_OS_SOLARIS
105 # define dirfd(d) ((d)->d_fd)
106 #endif
107@@ -1091,7 +1094,8 @@
108 #endif
109
110
111-#if defined(RT_OS_DARWIN) || defined(RT_OS_LINUX)
112+#ifndef SUP_HARDENED_VERIFY_FOLLOW_SYMLINKS_USE_REALPATH
113+# if defined(RT_OS_DARWIN) || defined(RT_OS_LINUX)
114 /**
115 * Copies the error message to the error buffer and returns @a rc.
116 *
117@@ -1104,6 +1108,7 @@
118 {
119 return supR3HardenedSetErrorN(rc, pErrInfo, 1, pszMsg);
120 }
121+# endif
122 #endif
123
124
125@@ -1893,7 +1898,9 @@
126 /*
127 * Verify each component from the root up.
128 */
129+#ifndef SUP_HARDENED_VERIFY_FOLLOW_SYMLINKS_USE_REALPATH
130 uint32_t iLoops = 0;
131+#endif
132 SUPR3HARDENEDFSOBJSTATE FsObjState;
133 uint32_t iComponent = 0;
134 while (iComponent < Info.cComponents)
135@@ -1915,6 +1922,24 @@
136 if ( RT_SUCCESS(rc)
137 && S_ISLNK(FsObjState.Stat.st_mode))
138 {
139+#if SUP_HARDENED_VERIFY_FOLLOW_SYMLINKS_USE_REALPATH /* Another approach using realpath() and verifying the result when encountering a symlink. */
140+ char *pszFilenameResolved = realpath(pszFilename, NULL);
141+ if (pszFilenameResolved)
142+ {
143+ rc = supR3HardenedVerifyFile(pszFilenameResolved, hNativeFile, fMaybe3rdParty, pErrInfo);
144+ free(pszFilenameResolved);
145+ return rc;
146+ }
147+ else
148+ {
149+ int iErr = errno;
150+ supR3HardenedError(VERR_ACCESS_DENIED, false /*fFatal*/,
151+ "supR3HardenedVerifyFileFollowSymlinks: Failed to resolve the real path '%s': %s (%d)\n",
152+ pszFilename, strerror(iErr), iErr);
153+ return supR3HardenedSetError4(VERR_ACCESS_DENIED, pErrInfo,
154+ "realpath failed for '", pszFilename, "': ", strerror(iErr));
155+ }
156+#else
157 /* Don't loop forever. */
158 iLoops++;
159 if (iLoops < 8)
160@@ -1989,6 +2014,7 @@
161 else
162 return supR3HardenedSetError3(VERR_TOO_MANY_SYMLINKS, pErrInfo,
163 "Too many symbolic links: '", pszFilename, "'");
164+#endif
165 }
166 }
167 if (RT_FAILURE(rc))

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy