Bug 219464 - [PATCH] linux_getrandom always returns 0
Summary: [PATCH] linux_getrandom always returns 0
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Some People
Assignee: Dmitry Chagin
URL:
Keywords: patch
Depends on:
Blocks:
 
Reported: 2017-05-22 20:21 UTC by Maciej Pasternacki
Modified: 2017-06-11 09:33 UTC (History)
2 users (show)

See Also:


Attachments
linux_getrandom.patch (740 bytes, patch)
2017-05-22 20:21 UTC, Maciej Pasternacki
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Maciej Pasternacki 2017-05-22 20:21:57 UTC
Created attachment 182818 [details]
linux_getrandom.patch

In a Linux-based jail, running Ubuntu 16.04, `lsb_release` command (which is widely used in various scripts and during Factorio startup) hangs. `top` shows it forks a `python3.5` process which uses 100% CPU. `truss` shows this process repeatedly calls `linux_getrandom(…)`, which always returns 0.

`man 2 getrandom` on Ubuntu 16.04 specifies that this syscall should return number of random bytes written (http://man7.org/linux/man-pages/man2/getrandom.2.html). A short test program shows that this it returns positive value on Linux, and returns 0 on FreeBSD despite the fact that random bytes have been written to the buffer:

> $ cat test_getrandom.c
> #define _GNU_SOURCE
> #include <unistd.h>
> #include <sys/syscall.h>
> #include <stdio.h>
> #include <linux/random.h>
> 
> int main(void) {
>         int rv;
>         int buf = 0;
>         rv = syscall(SYS_getrandom, &buf, sizeof(buf), GRND_NONBLOCK);
>         printf("getrandom(&buf, %d, 0) => %d buf=%d\n", (int)sizeof(buf), rv, buf);
>         return 0;
> }

When this program runs natively on Linux, `getrandom(2)` returns size of buffer:

> $ ./test_getrandom
> getrandom(&buf, 4, 0) => 4 buf=-707083248

On FreeBSD 12-CURRENT (possibly also on 11-STABLE, r315505 which introduces this implementation is marked for MFC after 1 month), the syscall always returns 0:

> $ ./test_getrandom
> getrandom(&buf, 4, 0) => 0 buf=-1643413282

After applying attached patch, return value reported from the test program is the same as on native Linux, and `lsb_release` no longer hangs:

> $ ./test_getrandom
> getrandom(&buf, 4, 0) => 4 buf=-943351330
> $ lsb_release -a
> No LSB modules are available.
> Distributor ID:	Ubuntu
> Description:	Ubuntu 16.04.2 LTS
> Release:	16.04
> Codename:	xenial
Comment 1 Maciej Pasternacki 2017-05-22 20:24:25 UTC
Cc: dchagin as r315505 committer
Comment 2 Dmitry Chagin freebsd_committer freebsd_triage 2017-05-23 16:25:02 UTC
take, my fault
Comment 3 commit-hook freebsd_committer freebsd_triage 2017-05-28 07:41:11 UTC
A commit references this bug:

Author: dchagin
Date: Sun May 28 07:40:10 UTC 2017
New revision: 319053
URL: https://svnweb.freebsd.org/changeset/base/319053

Log:
  On success, getrandom() Linux system call returns the number of bytes that
  were copied to the buffer supplied by the user.

  Also fix getrandom() if Linuxulator modules are built without the kernel.

  PR:		219464
  Submitted by:	Maciej Pasternacki
  Reported by:	Maciej Pasternacki
  MFC after:	1 week

Changes:
  head/sys/compat/linux/linux_misc.c
  head/sys/conf/config.mk
  head/sys/modules/linux/Makefile
  head/sys/modules/linux64/Makefile
Comment 4 commit-hook freebsd_committer freebsd_triage 2017-06-04 18:36:11 UTC
A commit references this bug:

Author: dchagin
Date: Sun Jun  4 18:35:30 UTC 2017
New revision: 319571
URL: https://svnweb.freebsd.org/changeset/base/319571

Log:
  On success, getrandom() Linux system call returns the number of bytes that
  were copied to the buffer supplied by the user.

  PR:           219464
  Submitted by: Maciej Pasternacki
  Reported by:  Maciej Pasternacki
  MFC after:    1 week

Changes:
  head/sys/compat/linux/linux_misc.c
Comment 5 commit-hook freebsd_committer freebsd_triage 2017-06-11 09:33:34 UTC
A commit references this bug:

Author: dchagin
Date: Sun Jun 11 09:33:09 UTC 2017
New revision: 319823
URL: https://svnweb.freebsd.org/changeset/base/319823

Log:
  MFC r319571:

  On success, getrandom() Linux system call returns the number of bytes that
  were copied to the buffer supplied by the user.

  PR:		219464
  Submitted by:	Maciej Pasternacki
  Reported by:	Maciej Pasternacki
  Approved by:	re (kib)

Changes:
_U  stable/11/
  stable/11/sys/compat/linux/linux_misc.c