(Fix): replaced unsafe.Pointer(&h) (Go stack pointer passed to C) with storeHandle/loadHandle helpers that keep the cgo.Handle in C-heap memory.

This commit is contained in:
2026-07-18 21:19:05 +05:30
parent 89fafb892b
commit 12dfb32f71

View File

@@ -10,12 +10,22 @@ package auth
#cgo LDFLAGS: -lpam
#include <security/pam_appl.h>
#include <stdlib.h>
#include <stdint.h>
// 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)