From 12dfb32f71c4025e9890554da5720d462c62ae88 Mon Sep 17 00:00:00 2001 From: Zane Walker Date: Sat, 18 Jul 2026 21:19:05 +0530 Subject: [PATCH] (Fix): replaced `unsafe.Pointer(&h)` (Go stack pointer passed to C) with `storeHandle`/`loadHandle` helpers that keep the `cgo.Handle` in C-heap memory. --- src/auth/pam.go | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/auth/pam.go b/src/auth/pam.go index 649ce16..55a8625 100644 --- a/src/auth/pam.go +++ b/src/auth/pam.go @@ -10,12 +10,22 @@ package auth #cgo LDFLAGS: -lpam #include #include +#include // Match the //export-generated signature. extern int latchd_pam_conv(int, struct pam_message **, struct pam_response **, void *); -// Helper to create the conv struct with the proper cast. +// Store a uintptr_t handle in C heap so the Go GC never sees a Go pointer. +static void *storeHandle(uintptr_t h) { + uintptr_t *p = malloc(sizeof(uintptr_t)); + if (p) *p = h; + return p; +} +static uintptr_t loadHandle(void *p) { + return *(uintptr_t *)p; +} + static struct pam_conv makePAMConv(void *data) { struct pam_conv c; c.conv = (int (*)(int, const struct pam_message **, @@ -61,7 +71,7 @@ type Credentials struct { //export latchd_pam_conv func latchd_pam_conv(numMsg C.int, msg **C.struct_pam_message, resp **C.struct_pam_response, data unsafe.Pointer) C.int { - h := *(*cgo.Handle)(data) + h := cgo.Handle(C.loadHandle(data)) pw := h.Value().(string) r := (*C.struct_pam_response)(C.calloc(C.ulong(numMsg), C.sizeof_struct_pam_response)) @@ -93,7 +103,10 @@ func Validate(user, pass, service string) (*Credentials, error) { h := cgo.NewHandle(pass) defer h.Delete() - conv := C.makePAMConv(unsafe.Pointer(&h)) + cData := C.storeHandle(C.uintptr_t(h)) + defer C.free(cData) + + conv := C.makePAMConv(cData) var pamh *C.pam_handle_t ret := C.pam_start(cSvc, cUser, &conv, &pamh)