From: Tobias Klauser Date: Wed, 10 Mar 2021 09:06:11 +0000 (+0100) Subject: internal/syscall/unix: unify GetRandom implementation X-Git-Tag: go1.17beta1~1186 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=79e3ee52f48411eb7c4edfe3daa55e2ecf7a6c61;p=gostls13.git internal/syscall/unix: unify GetRandom implementation The implementation of GetRandom for Linux, FreeBSD and DragonflyBSD can be shared. Also remove GRND_INSECURE on DragonflyBSD as pointed out by Ian in the review of CL 269999. Change-Id: I5bf4c1bd51ddb2ad600652a57e0bc1bafa1cf40d Reviewed-on: https://go-review.googlesource.com/c/go/+/299133 Trust: Tobias Klauser Run-TryBot: Tobias Klauser TryBot-Result: Go Bot Reviewed-by: Ian Lance Taylor --- diff --git a/src/internal/syscall/unix/getrandom.go b/src/internal/syscall/unix/getrandom.go new file mode 100644 index 0000000000..d2c58c0f6f --- /dev/null +++ b/src/internal/syscall/unix/getrandom.go @@ -0,0 +1,40 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build dragonfly || freebsd || linux +// +build dragonfly freebsd linux + +package unix + +import ( + "sync/atomic" + "syscall" + "unsafe" +) + +var getrandomUnsupported int32 // atomic + +// GetRandomFlag is a flag supported by the getrandom system call. +type GetRandomFlag uintptr + +// GetRandom calls the getrandom system call. +func GetRandom(p []byte, flags GetRandomFlag) (n int, err error) { + if len(p) == 0 { + return 0, nil + } + if atomic.LoadInt32(&getrandomUnsupported) != 0 { + return 0, syscall.ENOSYS + } + r1, _, errno := syscall.Syscall(getrandomTrap, + uintptr(unsafe.Pointer(&p[0])), + uintptr(len(p)), + uintptr(flags)) + if errno != 0 { + if errno == syscall.ENOSYS { + atomic.StoreInt32(&getrandomUnsupported, 1) + } + return 0, errno + } + return int(r1), nil +} diff --git a/src/internal/syscall/unix/getrandom_dragonfly.go b/src/internal/syscall/unix/getrandom_dragonfly.go index b345b4c00c..fbf78f9de8 100644 --- a/src/internal/syscall/unix/getrandom_dragonfly.go +++ b/src/internal/syscall/unix/getrandom_dragonfly.go @@ -4,19 +4,8 @@ package unix -import ( - "sync/atomic" - "syscall" - "unsafe" -) - -var randomUnsupported int32 // atomic - // DragonFlyBSD getrandom system call number. -const randomTrap uintptr = 550 - -// GetRandomFlag is a flag supported by the getrandom system call. -type GetRandomFlag uintptr +const getrandomTrap uintptr = 550 const ( // GRND_RANDOM is only set for portability purpose, no-op on DragonFlyBSD. @@ -24,28 +13,4 @@ const ( // GRND_NONBLOCK means return EAGAIN rather than blocking. GRND_NONBLOCK GetRandomFlag = 0x0002 - - // GRND_INSECURE is an GRND_NONBLOCK alias - GRND_INSECURE GetRandomFlag = 0x0004 ) - -// GetRandom calls the DragonFlyBSD getrandom system call. -func GetRandom(p []byte, flags GetRandomFlag) (n int, err error) { - if len(p) == 0 { - return 0, nil - } - if atomic.LoadInt32(&randomUnsupported) != 0 { - return 0, syscall.ENOSYS - } - r1, _, errno := syscall.Syscall(randomTrap, - uintptr(unsafe.Pointer(&p[0])), - uintptr(len(p)), - uintptr(flags)) - if errno != 0 { - if errno == syscall.ENOSYS { - atomic.StoreInt32(&randomUnsupported, 1) - } - return 0, errno - } - return int(r1), nil -} diff --git a/src/internal/syscall/unix/getrandom_freebsd.go b/src/internal/syscall/unix/getrandom_freebsd.go index f1ba5730c9..8c4f3dff82 100644 --- a/src/internal/syscall/unix/getrandom_freebsd.go +++ b/src/internal/syscall/unix/getrandom_freebsd.go @@ -4,19 +4,8 @@ package unix -import ( - "sync/atomic" - "syscall" - "unsafe" -) - -var randomUnsupported int32 // atomic - // FreeBSD getrandom system call number. -const randomTrap uintptr = 563 - -// GetRandomFlag is a flag supported by the getrandom system call. -type GetRandomFlag uintptr +const getrandomTrap uintptr = 563 const ( // GRND_NONBLOCK means return EAGAIN rather than blocking. @@ -25,24 +14,3 @@ const ( // GRND_RANDOM is only set for portability purpose, no-op on FreeBSD. GRND_RANDOM GetRandomFlag = 0x0002 ) - -// GetRandom calls the FreeBSD getrandom system call. -func GetRandom(p []byte, flags GetRandomFlag) (n int, err error) { - if len(p) == 0 { - return 0, nil - } - if atomic.LoadInt32(&randomUnsupported) != 0 { - return 0, syscall.ENOSYS - } - r1, _, errno := syscall.Syscall(randomTrap, - uintptr(unsafe.Pointer(&p[0])), - uintptr(len(p)), - uintptr(flags)) - if errno != 0 { - if errno == syscall.ENOSYS { - atomic.StoreInt32(&randomUnsupported, 1) - } - return 0, errno - } - return int(r1), nil -} diff --git a/src/internal/syscall/unix/getrandom_linux.go b/src/internal/syscall/unix/getrandom_linux.go index 490d516978..8ccd8d328a 100644 --- a/src/internal/syscall/unix/getrandom_linux.go +++ b/src/internal/syscall/unix/getrandom_linux.go @@ -4,17 +4,6 @@ package unix -import ( - "sync/atomic" - "syscall" - "unsafe" -) - -var randomUnsupported int32 // atomic - -// GetRandomFlag is a flag supported by the getrandom system call. -type GetRandomFlag uintptr - const ( // GRND_NONBLOCK means return EAGAIN rather than blocking. GRND_NONBLOCK GetRandomFlag = 0x0001 @@ -22,25 +11,3 @@ const ( // GRND_RANDOM means use the /dev/random pool instead of /dev/urandom. GRND_RANDOM GetRandomFlag = 0x0002 ) - -// GetRandom calls the Linux getrandom system call. -// See https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=c6e9d6f38894798696f23c8084ca7edbf16ee895 -func GetRandom(p []byte, flags GetRandomFlag) (n int, err error) { - if len(p) == 0 { - return 0, nil - } - if atomic.LoadInt32(&randomUnsupported) != 0 { - return 0, syscall.ENOSYS - } - r1, _, errno := syscall.Syscall(getrandomTrap, - uintptr(unsafe.Pointer(&p[0])), - uintptr(len(p)), - uintptr(flags)) - if errno != 0 { - if errno == syscall.ENOSYS { - atomic.StoreInt32(&randomUnsupported, 1) - } - return 0, errno - } - return int(r1), nil -}