Skip to content

Commit

Permalink
fix: avoid WRITE+EXEC for CPUID check (#15912)
Browse files Browse the repository at this point in the history
  • Loading branch information
orlp committed Apr 26, 2024
1 parent 9b0503a commit 99e3399
Showing 1 changed file with 13 additions and 1 deletion.
14 changes: 13 additions & 1 deletion py-polars/polars/_cpu_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from __future__ import annotations

import ctypes
import ctypes.util
import os
from ctypes import CFUNCTYPE, POINTER, c_long, c_size_t, c_uint32, c_ulong, c_void_p
from typing import ClassVar
Expand Down Expand Up @@ -159,15 +160,26 @@ def __init__(self) -> None:
else:
import mmap # Only import if necessary.

# On some platforms PROT_WRITE + PROT_EXEC is forbidden, so we first
# only write and then mprotect into PROT_EXEC.
libc = ctypes.CDLL(ctypes.util.find_library("c"), use_errno=True)
mprotect = libc.mprotect
mprotect.argtypes = (ctypes.c_void_p, ctypes.c_size_t, ctypes.c_int)
mprotect.restype = ctypes.c_int

self.mmap = mmap.mmap(
-1,
size,
mmap.MAP_PRIVATE | mmap.MAP_ANONYMOUS,
mmap.PROT_READ | mmap.PROT_WRITE | mmap.PROT_EXEC,
mmap.PROT_READ | mmap.PROT_WRITE,
)
self.addr = ctypes.addressof(ctypes.c_void_p.from_buffer(self.mmap))
self.mmap.write(code)

if mprotect(self.addr, size, mmap.PROT_READ | mmap.PROT_EXEC) != 0:
msg = "could not execute mprotect for CPUID check"
raise RuntimeError(msg)

func_type = CFUNCTYPE(None, POINTER(CPUID_struct), c_uint32, c_uint32)
self.func_ptr = func_type(self.addr)

Expand Down

0 comments on commit 99e3399

Please sign in to comment.