It appears that the driver does not retain the internal pointers, but it also seems that my current use of Cgo is pretty unobtrusive (just malloc and friends) so I'm not too concerned about ridding myself of it either.

- Matt

On 2019-05-17 11:48 a.m., Robert Engels wrote:
I only meant that if if the driver retains this pointers... In reading Ian's email, the top-level pointer will be retained and not collected, and it has references to the contained pointers.

    -----Original Message-----
    From: Robert Engels
    Sent: May 17, 2019 10:45 AM
    To: Matt Layher , golang-nuts
    Subject: Re: [go-nuts] Passing structures containing other
    pointers to ioctl: Go vs Cgo memory

    If Go ever adding a compacting collector I don't think these
    techniques would work - I would start with cgo as you will be
    protected then.

        -----Original Message-----
        From: Matt Layher
        Sent: May 17, 2019 9:44 AM
        To: golang-nuts
        Subject: Re: [go-nuts] Passing structures containing other
        pointers to ioctl: Go vs Cgo memory

        Hi Ian,

            Pointers passed to unix.Syscall or syscall.Syscall are
            always safe.
            They will be treated as live for the duration of the call
            to Syscall,
            and they will not be moved.  This is a special exception
            for functions
            written in assembly, documented at
            https://golang.org/pkg/unsafe/#Pointer
            <https://golang.org/pkg/unsafe/#Pointer>.  I don't see any
            obvious
problem with your code.

        Right. I'm passing a pointer to a structure as usual to ioctl,
        but that structure also stores the memory address of an array
        in a union (which is [n]byte in Go), and then the kernel code
        interprets both the structure's address and the union's stored
        address as pointers again. That is where my concern about the
        slice potentially being moved comes from. I'm not sure this
        would fall under the rule you mention above, because the
        memory address stored in the union just appears to be random
        bytes, unless the Go compiler is keeping track of it internally.

            Note that things would be different if you were using cgo,
            which
            follows different and more complicated rules.  But at
            least in this
example, you aren't.

        I made a patch which allocates memory using Cgo instead of Go
        to potentially alleviate my above concern:
        
https://github.com/WireGuard/wgctrl-go/pull/49/commits/05d446d3d7b2e376424e57a5167205a325d61781,
        so I am using a bit of Cgo at this point. Although I'd rather
        not if it were deemed safe to go with my original pure Go
        approach.

        Thanks for your time,
        Matt

        On Friday, May 17, 2019 at 10:32:44 AM UTC-4, Ian Lance Taylor
        wrote:

            On Thu, May 16, 2019 at 5:24 AM Matt Layher
            <mdla...@gmail.com <javascript:>> wrote:
            >
            > I'm working on a project that involves an ioctl API on
            OpenBSD. The idea is that you store a memory address in a
            union within another structure, and then invoke the ioctl.
            When it returns, both the structure itself and the memory
            pointed at by the address in the union are filled with
            data by the kernel.
            >
            > I originally wrote a pure Go version of this code that
            seems to work, but after a conversation in #darkarts on
            Gophers Slack (starting at
            https://gophers.slack.com/archives/C1C1YSQBT/p1557956939402700
            <https://gophers.slack.com/archives/C1C1YSQBT/p1557956939402700>),
            several of us were unsure if this version was actually
            safe. See the body of this function:
            >
            >
            
https://github.com/WireGuard/wgctrl-go/blob/7e04c64d5b80f1991b52c6025d6f59e6aa3a3939/internal/wgopenbsd/client_openbsd.go#L59
            
<https://github.com/WireGuard/wgctrl-go/blob/7e04c64d5b80f1991b52c6025d6f59e6aa3a3939/internal/wgopenbsd/client_openbsd.go#L59>

            >
            > The concern was as follows:
            >
            > > i think the usage of `ifgrs` is unsafe...
            > > maybe it's alright because it'll always be heap
            allocated due to the dynamic size of it, but afaict, the
            compiler could deduce that it doesn't escape and then the
            call to ioctl could move it during a stack realloc..
            >
            > After thinking it over and having a further discussion,
            I decided to try passing a pointer to memory allocated
            with C.malloc instead, and this also seems to work.
            >
            >
            
https://github.com/WireGuard/wgctrl-go/pull/49/commits/05d446d3d7b2e376424e57a5167205a325d61781
            
<https://github.com/WireGuard/wgctrl-go/pull/49/commits/05d446d3d7b2e376424e57a5167205a325d61781>

            >
            > My question is: is this necessary, and if so, have I
            implemented it correctly? I've typically just passed
            pointers to structures with no other pointers directly
            with Linux APIs; never a pointer to a structure that also
            contains other pointers to other memory. I'm a little
            shaky on Cgo since I've mostly gotten by without it during
            my time writing Go.

            Pointers passed to unix.Syscall or syscall.Syscall are
            always safe.
            They will be treated as live for the duration of the call
            to Syscall,
            and they will not be moved.  This is a special exception
            for functions
            written in assembly, documented at
            https://golang.org/pkg/unsafe/#Pointer
            <https://golang.org/pkg/unsafe/#Pointer>.  I don't see any
            obvious
            problem with your code.

            Note that things would be different if you were using cgo,
            which
            follows different and more complicated rules.  But at
            least in this
            example, you aren't.

            Ian

-- You received this message because you are subscribed to the
        Google Groups "golang-nuts" group.
        To unsubscribe from this group and stop receiving emails from
        it, send an email to golang-nuts+unsubscr...@googlegroups.com
        <mailto:golang-nuts+unsubscr...@googlegroups.com>.
        To view this discussion on the web visit
        
https://groups.google.com/d/msgid/golang-nuts/8c5a3a65-2891-4c4a-bd79-71e910571ac2%40googlegroups.com
        
<https://groups.google.com/d/msgid/golang-nuts/8c5a3a65-2891-4c4a-bd79-71e910571ac2%40googlegroups.com?utm_medium=email&utm_source=footer>.
        For more options, visit https://groups.google.com/d/optout.








--
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/d849469b-fec6-8c65-efb9-ce20e39b626b%40gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to