table of contents
getrandom(2) | System Calls Manual | getrandom(2) |
ИМЯ¶
getrandom - возвращает серию произвольных байт
LIBRARY¶
Standard C library (libc, -lc)
СИНТАКСИС¶
#include <sys/random.h>
ssize_t getrandom(void buf[.buflen], size_t buflen, unsigned int flags);
ОПИСАНИЕ¶
Системный вызов getrandom() заполняет буфер, указанный в buf, произвольными байтами в количестве до buflen. Эти байты можно использовать как начальные значения в генераторах произвольных чисел пространства пользователя или с целями шифрования.
По умолчанию, getrandom() забирает энтропию из источника urandom (т. е., того же источника что и устройство /dev/urandom). Это поведение можно изменить через параметр flags.
Если источник urandom инициализирован, то из него можно прочитать не более 256 байт, но всегда возвращается столько байт, сколько запрошено и это не будет прерываться сигналами. Для буферов большего размера это не гарантируется. Например, если вызов прерывается обработчиком сигнала, то он может вернуть частично заполненный буфер или завершиться с ошибкой EINTR.
Если источник urandom ещё не инициализирован, то вызов getrandom() блокируется, если в flags не указано значение GRND_NONBLOCK.
Аргумент flags является битовой маской, которая может содержать ноль или более следующих флагов:
- GRND_RANDOM
- Если этот бит установлен, то произвольные байты берутся из источника random (т. е., того же источника что и устройство /dev/urandom), а не из источника urandom. Ограничение источника random следует из энтропии, которую можно получить из окружающего шума. Если количество доступных байт в random меньше запрашиваемых в buflen, то вызов завершается сразу после выдачи всех доступных произвольных байт. Если произвольных байт нет, то поведение зависит от наличия флага GRND_NONBLOCK в параметре flags.
- GRND_NONBLOCK
- По умолчанию, при чтении из источника random вызов getrandom() блокируется, если произвольные байты недоступны, и а при чтении из источника urandom блокируется, если ещё не инициализирован пул энтропии. Если указан флаг GRND_NONBLOCK, то в этих случаях getrandom() не блокируется, а сразу возвращает -1 и присваивает errno значение EAGAIN.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ¶
При успешном выполнении getrandom() возвращает количество скопированных в буфер buf байт. Это значение может быть меньше, чем количество запрашиваемых в buflen байт, если в flags был указан GRND_RANDOM и нет достаточного количества энтропии в источнике random, или если системный вызов был прерван сигналом.
В случае ошибки возвращается -1, а errno устанавливается в значение ошибки.
ОШИБКИ¶
- EAGAIN
- Запрошенное количество энтропии недоступно, и getrandom() заблокировался бы, если бы отсутствовал флаг GRND_NONBLOCK.
- EFAULT
- Адрес, указанный в buf, лежит вне доступного адресного пространства.
- EINTR
- Вызов был прерван обработчиком сигнала; смотрите описание о прерывании вызовов read(2) при работе с «медленными» устройствами и при отсутствии флага SA_RESTART в справочной странице signal(7).
- EINVAL
- В flags указан неверный флаг.
- ENOSYS
- Обёрточная функция в glibc для getrandom() определила, что используемое ядро не поддерживает данный системный вызов.
СТАНДАРТЫ¶
Linux.
ИСТОРИЯ¶
Linux 3.17, glibc 2.25.
ПРИМЕЧАНИЯ¶
Обзор и сравнение возможных интерфейсов, через которые можно получать случайные данные, смотрите в random(7).
В отличие от /dev/random и /dev/urandom, в вызове getrandom() не используются пути или файловые дескрипторы. Таким образом, getrandom() полезен в случаях, когда chroot(2) делает пути /dev невидимыми и приложение (например, служба во время загрузки) закрывает файловый дескриптор одного из этих файлов, которые были открыты библиотекой.
Возвращается максимальное количество байтов¶
На момент Linux 3.19 существуют следующие ограничения:
- •
- When reading from the urandom source, a maximum of 32Mi-1 bytes is returned by a single call to getrandom() on systems where int has a size of 32 bits.
- •
- При чтении из источника random возвращается максимум 512 байт.
Прерывание обработчиком сигнала¶
При чтении из источника urandom (GRND_RANDOM не указан), getrandom() блокируется до тех пор, пока не специализируется пул энтропии (если не указан флаг GRND_NONBLOCK). Если запрос требует большого количества байт (больше 256), getrandom() будет заблокирован до тех пор, пока байты не будут сгенерированы и переданы из памяти ядра в buf. При чтении из random (указан GRND_RANDOM), getrandom() будет заблокирован до тех пор, пока какое-то количество произвольных байт не станет доступно (если не указан флаг GRND_NONBLOCK).
Поведение при прерывании обработчиком сигнала вызова getrandom(), заблокированного чтением источника urandom, зависит от состояния инициализации буфера энтропии и от запрашиваемого объёма buflen. Если энтропия ещё не инициализирована, то вызов завершается ошибкой EINTR. Если пул энтропии инициализирован и запрашиваемый объём большой (buflen > 256), то вызов или завершится успешно, вернув частично заполненный буфер, или завершится с ошибкой EINTR. Если пул энтропии инициализирован и запрашиваемый объём мал (buflen <= 256), то getrandom() завершится без ошибки EINTR. Вместо этого, он вернёт все запрашиваемый байты.
При чтении из источника random блокирующие запросы на любой объём могут быть прерваны обработчиком сигналом (вызов завершается с ошибкой EINTR).
Использование getrandom() для чтения маленьких буферов (<= 256 байт) из источника urandom — предпочтительный способ использования.
Специальный режим для маленького объёма buflen был разработан для совместимости с системным вызовом getentropy(3) из OpenBSD, который теперь поддерживается glibc.
Пользователь getrandom() всегда должен проверять возвращаемое значение, чтобы определить что возникла ошибка или возвращено меньшее количество запрошенных байт. В случае когда флаг GRND_RANDOM не указан и значение buflen меньше или равно 256, возврат меньшего количества байт чем запрошено никогда не происходит, но осторожный программист всегда проверяет значение!
ОШИБКИ¶
В Linux 3.19 существуют следующие дефекты:
- •
- В зависимости от загруженности ЦП, getrandom() не реагирует на прерывания, пока не прочитает все запрашиваемые байты.
СМОТРИТЕ ТАКЖЕ¶
ПЕРЕВОД¶
Русский перевод этой страницы руководства разработал Azamat Hackimov <azamat.hackimov@gmail.com>, Dmitry Bolkhovskikh <d20052005@yandex.ru>, Vladislav <ivladislavefimov@gmail.com>, Yuri Kozlov <yuray@komyakino.ru> и Иван Павлов <pavia00@gmail.com>
Этот перевод является свободной программной документацией; он распространяется на условиях общедоступной лицензии GNU (GNU General Public License - GPL, https://www.gnu.org/licenses/gpl-3.0.html версии 3 или более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ.
Если вы обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите об этом разработчику по его адресу электронной почты или по адресу списка рассылки русских переводчиков.
2 мая 2024 г. | Linux man-pages (unreleased) |