(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:
@@ -10,12 +10,22 @@ package auth
|
|||||||
#cgo LDFLAGS: -lpam
|
#cgo LDFLAGS: -lpam
|
||||||
#include <security/pam_appl.h>
|
#include <security/pam_appl.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
// Match the //export-generated signature.
|
// Match the //export-generated signature.
|
||||||
extern int latchd_pam_conv(int, struct pam_message **,
|
extern int latchd_pam_conv(int, struct pam_message **,
|
||||||
struct pam_response **, void *);
|
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) {
|
static struct pam_conv makePAMConv(void *data) {
|
||||||
struct pam_conv c;
|
struct pam_conv c;
|
||||||
c.conv = (int (*)(int, const struct pam_message **,
|
c.conv = (int (*)(int, const struct pam_message **,
|
||||||
@@ -61,7 +71,7 @@ type Credentials struct {
|
|||||||
|
|
||||||
//export latchd_pam_conv
|
//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 {
|
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)
|
pw := h.Value().(string)
|
||||||
|
|
||||||
r := (*C.struct_pam_response)(C.calloc(C.ulong(numMsg), C.sizeof_struct_pam_response))
|
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)
|
h := cgo.NewHandle(pass)
|
||||||
defer h.Delete()
|
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
|
var pamh *C.pam_handle_t
|
||||||
ret := C.pam_start(cSvc, cUser, &conv, &pamh)
|
ret := C.pam_start(cSvc, cUser, &conv, &pamh)
|
||||||
|
|||||||
Reference in New Issue
Block a user