Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 3 additions & 24 deletions rust/plex-pg-core/src/pms_process_compat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ use crate::db_interpose_common;
use crate::db_interpose_common::stderr_ptr;
use crate::env_utils;

// Do not interpose vfork. Until the child execs, it shares the parent's stack;
// returning through a Rust wrapper can corrupt the suspended caller's frame.

type CloneStartFn = unsafe extern "C" fn(*mut libc::c_void) -> c_int;
type CloneFn = unsafe extern "C" fn(
Option<CloneStartFn>,
Expand Down Expand Up @@ -39,7 +42,6 @@ type SyscallFn = unsafe extern "C" fn(
libc::c_long,
libc::c_long,
) -> libc::c_long;
type VForkFn = unsafe extern "C" fn() -> libc::pid_t;

static mut ORIG_DAEMON: Option<DaemonFn> = None;
static mut ORIG_FORK: Option<ForkFn> = None;
Expand All @@ -48,7 +50,6 @@ static mut ORIG_PRCTL: Option<PrctlFn> = None;
static mut ORIG_PTHREAD_SETNAME_NP: Option<PthreadSetnameNpFn> = None;
static mut ORIG_SETSID: Option<SetsidFn> = None;
static mut ORIG_SYSCALL: Option<SyscallFn> = None;
static mut ORIG_VFORK: Option<VForkFn> = None;

static PROCESS_COMPAT_LOG_BUDGET: AtomicI32 = AtomicI32::new(0);
static SUPPRESS_DAEMON: AtomicI32 = AtomicI32::new(0);
Expand Down Expand Up @@ -117,10 +118,6 @@ unsafe fn resolve_syscall() -> Option<SyscallFn> {
resolve_symbol(&mut ORIG_SYSCALL, b"syscall\0")
}

unsafe fn resolve_vfork() -> Option<VForkFn> {
resolve_symbol(&mut ORIG_VFORK, b"vfork\0")
}

unsafe fn set_errno(err: c_int) {
*libc::__errno_location() = err;
}
Expand Down Expand Up @@ -370,24 +367,6 @@ pub unsafe extern "C" fn clone(
rc
}

#[no_mangle]
/// # Safety
/// ABI interposition wrapper for `vfork`. Callers must obey libc preconditions.
pub unsafe extern "C" fn vfork() -> libc::pid_t {
let Some(orig) = resolve_vfork() else {
set_errno(libc::ENOSYS);
return -1;
};

let rc = orig();
if rc > 0 {
maybe_log_event(b"vfork\0", i64::from(rc), 0);
} else if rc < 0 {
maybe_log_event(b"vfork\0", -1, *libc::__errno_location());
}
rc
}

#[no_mangle]
/// # Safety
/// ABI interposition wrapper for `prctl`. Callers must obey libc preconditions.
Expand Down
37 changes: 37 additions & 0 deletions rust/plex-pg-core/src/runtime_linux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,43 @@ static INIT: extern "C" fn() = shim_init_wrapper;
#[cfg_attr(target_os = "linux", link_section = ".fini_array")]
static FINI: extern "C" fn() = shim_cleanup_wrapper;

// ────────────────────────────────────────────────────────────────────────────
// The bundled x86-64 Boost codecvt also rejects the "ASCII" name. Preserve
// the C++ hidden return pointer in rdi and tail-call the UTF-8 variant with
// its two explicit arguments (locale in rsi, facet moved from ecx to edx).
#[cfg(all(feature = "interpose", target_arch = "x86_64"))]
std::arch::global_asm!(
".global _ZN5boost6locale4util21create_simple_codecvtERKNSt3__26localeERKNS2_12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_12char_facet_tE",
".type _ZN5boost6locale4util21create_simple_codecvtERKNSt3__26localeERKNS2_12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_12char_facet_tE, @function",
"_ZN5boost6locale4util21create_simple_codecvtERKNSt3__26localeERKNS2_12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_12char_facet_tE:",
"cmp byte ptr [rdx], 65",
"jne .Lshim_x86_csc_orig",
"cmp byte ptr [rdx + 1], 83",
"jne .Lshim_x86_csc_orig",
"cmp byte ptr [rdx + 2], 67",
"jne .Lshim_x86_csc_orig",
"cmp byte ptr [rdx + 3], 73",
"jne .Lshim_x86_csc_orig",
"cmp byte ptr [rdx + 4], 73",
"jne .Lshim_x86_csc_orig",
"cmp byte ptr [rdx + 5], 0",
"jne .Lshim_x86_csc_orig",
"mov r11, qword ptr [rip + SHIM_CREATE_UTF8_CODECVT_PTR@GOTPCREL]",
"mov r11, qword ptr [r11]",
"test r11, r11",
"je .Lshim_x86_csc_orig",
"mov edx, ecx",
"jmp r11",
".Lshim_x86_csc_orig:",
"mov r11, qword ptr [rip + SHIM_CREATE_SIMPLE_CODECVT_PTR@GOTPCREL]",
"mov r11, qword ptr [r11]",
"test r11, r11",
"je .Lshim_x86_csc_abort",
"jmp r11",
".Lshim_x86_csc_abort:",
"jmp abort@PLT",
);

// ────────────────────────────────────────────────────────────────────────────
// ────────────────────────────────────────────────────────────────────────────
// AArch64 assembly hook for boost::locale::util::create_simple_codecvt.
Expand Down
7 changes: 4 additions & 3 deletions scripts/migrate_lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,8 @@ migrate_sqlite_to_pg() {

if [[ -z "$pg_cols" ]]; then
echo -e "${YELLOW}SKIP (no PG table)${NC}"
((skipped++))
# Prefix increment succeeds when this script runs under set -e.
((++skipped))
continue
fi

Expand Down Expand Up @@ -276,10 +277,10 @@ migrate_sqlite_to_pg() {
if python3 "$migrate_py" \
"$SQLITE_DB" "$table" "$sqlite_select" "$pg_cols_list" "$schema" 2>>"$log_dir/migration_errors.log"; then
echo -e "${GREEN}OK${NC}"
((migrated++))
((++migrated))
else
echo -e "${RED}FAIL${NC}"
((failed++))
((++failed))
fi

# Restore check constraints and triggers
Expand Down