You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
x/sys: invalid use of unsafe.Pointer in ioctl arg parameters #44834
(4) Conversion of a Pointer to a uintptr when calling syscall.Syscall.
The Syscall functions in package syscall pass their uintptr arguments
directly to the operating system, which then may, depending on the details
of the call, reinterpret some of them as pointers.
That is, the system call implementation is implicitly converting certain
arguments back from uintptr to pointer.
If a pointer argument must be converted to uintptr for use as an argument,
that conversion must appear in the call expression itself
Now, as far as I can tell this forces packages to adhere to exactly that.
The code in x/sys clearly violates that rule.
in unix/ioctl.go there's
// IoctlSetPointerInt performs an ioctl operation which sets an
// integer value on fd, using the specified request number. The ioctl
// argument is called with a pointer to the integer value, rather than
// passing the integer value directly.
func IoctlSetPointerInt(fd int, req uint, value int) error {
v := int32(value)
return ioctl(fd, req, uintptr(unsafe.Pointer(&v)))
}
and the declaration of ioctl in zsyskall_linux.go:
The ioctl function does not have any pragmas to mark it as a syscall function, so the compiler won't know to do anything special for it. So the call to ioctl could potentially grow the stack, and then the arg pointer would be stale pointing to old memory.
Reacted by Cuong Manh Le, Tom Thorogood, Dominik Honnef and Bryan C. Mills
The ioctl function does not have any pragmas to mark it as a syscall function, so the compiler won't know to do anything special for it. So the call to ioctl could potentially grow the stack, and then the arg pointer would be stale pointing to old memory.
Hmm, so, whether it violates unsafe pointer rule?
Maybe the right fix is passing in an unsafe.Pointer instead of an uintptr 🤔
Maybe the right fix is passing in an unsafe.Pointer instead of an uintptr
I think so. The Linux ioctl man page at least says that the third argument is always a pointer. (If there are any ioctls that do actually pass a scalar value directly instead of a pointer, they'll need a separate utility wrapper.)
@mdlayher added IoctlSetInt for Linux in https://golang.org/cl/44009 for #20474. That suggests that Linux has some ioctls that don't take a pointer value for the third argument, although off hand I do not know what they are.
@mdlayher added IoctlSetInt for Linux in https://golang.org/cl/44009 for #20474. That suggests that Linux has some ioctls that don't take a pointer value for the third argument, although off hand I do not know what they are.
The arg argument represents a third argument that has additional information that is needed by this specific device to perform the requested function. The data type of arg depends upon the particular control request, but it is either an int or a pointer to a device-specific data structure.
It thus seems like IoctlSetInt was made for solaris consistent with the description in #20474. It should never be used for linux.
@mdlayher added IoctlSetInt for Linux in https://golang.org/cl/44009 for #20474. That suggests that Linux has some ioctls that don't take a pointer value for the third argument, although off hand I do not know what they are.
Activity
cuonglm commentedon Apr 30, 2021
This is safe.
vwill be kept alive throughioctlcall.ioctldoesuintptr(arg)whereargis anuintptr, not a pointer.cuonglm commentedon May 3, 2021
cc @mdempsky
mdempsky commentedon May 3, 2021
I don't think that code is safe.
The
ioctlfunction does not have any pragmas to mark it as a syscall function, so the compiler won't know to do anything special for it. So the call toioctlcould potentially grow the stack, and then theargpointer would be stale pointing to old memory.cuonglm commentedon May 3, 2021
Hmm, so, whether it violates unsafe pointer rule?
Maybe the right fix is passing in an unsafe.Pointer instead of an uintptr 🤔
cuonglm commentedon May 3, 2021
or using
go:nosplitmdempsky commentedon May 3, 2021
I think so. The Linux
ioctlman page at least says that the third argument is always a pointer. (If there are anyioctls that do actually pass a scalar value directly instead of a pointer, they'll need a separate utility wrapper.)ianlancetaylor commentedon May 3, 2021
@mdlayher added
IoctlSetIntfor Linux in https://golang.org/cl/44009 for #20474. That suggests that Linux has some ioctls that don't take a pointer value for the third argument, although off hand I do not know what they are.lhl2617 commentedon May 9, 2021
From https://man7.org/linux/man-pages/man2/ioctl.2.html:
From https://docs.oracle.com/cd/E23824_01/html/821-1463/ioctl-2.html
It thus seems like
IoctlSetIntwas made forsolarisconsistent with the description in #20474. It should never be used forlinux.lhl2617 commentedon May 9, 2021
Relevant issue: #34684
gopherbot commentedon Aug 9, 2021
Change https://golang.org/cl/340915 mentions this issue:
unix: generate ioctlNew on Linux with unsafe.Pointer argunix: generate ioctlPtr on Linux with unsafe.Pointer arg
[-]x/sys: potential invalid use of unsafe[/-][+]x/sys: invalid use of unsafe.Pointer in ioctl arg parameters[/+]bcmills commentedon Feb 7, 2023
@mdempsky, @ianlancetaylor, @mdlayher: was this fixed by CL 340915, or is there more to do here?
2 remaining items
thediveo commentedon Feb 7, 2023
Here we are,
FICLONEhttps://man7.org/linux/man-pages/man2/ioctl_ficlonerange.2.html ... which I didn't knew existed a few moments ago 😁gopherbot commentedon Feb 17, 2023
Change https://go.dev/cl/469315 mentions this issue:
unix: add ioctlPtr with unsafe.Pointer arg on other unicesgopherbot commentedon Feb 20, 2023
Change https://go.dev/cl/469675 mentions this issue:
syscall: avoid passing Go pointers as uintptr in exec testsunix: add ioctlPtr with unsafe.Pointer arg on other unices
gopherbot commentedon Feb 21, 2023
Change https://go.dev/cl/469835 mentions this issue:
unix: add ptracePtr that accepts pointer arg as unsafe.Pointersyscall: introduce IoctlPtr for exec_unix tests
syscall: introduce IoctlPtr for exec_unix tests
gopherbot commentedon Feb 24, 2023
Change https://go.dev/cl/471119 mentions this issue:
unix: add ioctlPtr with unsafe.Pointer arg on other unices (cont)unix: add ioctlPtr with unsafe.Pointer arg on other unices (cont)
bcmills commentedon May 3, 2023
@dmgk, can this issue be closed now, or is there more work remaining for it?
dmgk commentedon May 3, 2023
I believe this is done, closing.
brunnre8 commentedon May 4, 2023
Thanks a lot to everyone involved