Skip to content

Commit 4862f8a

Browse files
committed
Fix SIGSEGV when nokogiri is loaded before oci8
This bug was introduced in 2.2.13.
1 parent 7226147 commit 4862f8a

File tree

5 files changed

+310
-111
lines changed

5 files changed

+310
-111
lines changed

NEWS

+8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# @markup markdown
22

3+
2.2.14 (2024-08-XX)
4+
===================
5+
6+
Fixed issues
7+
------------
8+
9+
- Fix SIGSEGV when nokogiri is loaded before oci8 (GH-263 - Linux only)
10+
311
2.2.13 (2024-07-27)
412
===================
513

ext/oci8/oci8lib.c

+14-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#endif
1010
#if defined(HAVE_PLTHOOK) && !defined(WIN32)
1111
#include <dlfcn.h>
12+
#include <sys/mman.h>
1213
#include "plthook.h"
1314
#endif
1415

@@ -135,6 +136,8 @@ static void rebind_internal_symbols(void)
135136
void **addr;
136137
const char *prefix;
137138
size_t prefix_len;
139+
int prot;
140+
size_t page_size = sysconf(_SC_PAGESIZE);
138141

139142
#ifdef RTLD_FIRST
140143
flags |= RTLD_FIRST; /* for macOS */
@@ -161,7 +164,7 @@ static void rebind_internal_symbols(void)
161164
plthook_close(ph);
162165
return;
163166
}
164-
while (plthook_enum(ph, &pos, &name, &addr) == 0) {
167+
while (plthook_enum_with_prot(ph, &pos, &name, &addr, &prot) == 0) {
165168
void *funcaddr;
166169
if (prefix_len != 0) {
167170
if (strncmp(name, prefix, prefix_len) != 0) {
@@ -179,7 +182,17 @@ static void rebind_internal_symbols(void)
179182
* PLT entries are forcedly modified to point to itself not
180183
* to use functions in other libraries.
181184
*/
185+
#define ALIGN_ADDR(addr) ((void*)((size_t)(addr) & ~(page_size - 1)))
186+
if ((prot & PROT_WRITE) == 0) {
187+
/* when the region containing addr isn't writable, make it writable temporarily */
188+
if (mprotect(ALIGN_ADDR(addr), page_size, PROT_READ | PROT_WRITE) != 0) {
189+
continue;
190+
}
191+
}
182192
*addr = funcaddr;
193+
if ((prot & PROT_WRITE) == 0) {
194+
mprotect(ALIGN_ADDR(addr), page_size, prot);
195+
}
183196
}
184197
}
185198
plthook_close(ph);

ext/oci8/plthook.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,14 @@ int plthook_replace(plthook_t *plthook, const char *funcname, void *funcaddr, vo
5959
void plthook_close(plthook_t *plthook);
6060
const char *plthook_error(void);
6161

62+
/* enumerate entries with memory protection information (bitwise-OR of PROT_READ, PROT_WRITE and PROT_EXEC)
63+
*
64+
* source: plthook_elf.c and plthook_osx.c
65+
*/
66+
int plthook_enum_with_prot(plthook_t *plthook, unsigned int *pos, const char **name_out, void ***addr_out, int *prot);
67+
6268
#ifdef __cplusplus
63-
}; /* extern "C" */
69+
} /* extern "C" */
6470
#endif
6571

6672
#endif

0 commit comments

Comments
 (0)