New issue
Advanced search Search tips

Issue 742260 link

Starred by 1 user

Issue metadata

Status: Fixed
Owner:
Closed: Jul 2017
Components:
EstimatedDays: ----
NextAction: ----
OS: Linux
Pri: 2
Type: Bug



Sign in to add a comment

SYS_getrandom detection in boringssl/crypto/rand/urandom.c doesn't work well with glibc

Reported by r...@endlessm.com, Jul 13 2017

Issue description

UserAgent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0

Steps to reproduce the problem:
1. Attempt to build Chromium 59 on a Linux platform using glibc where <asm/unistd.h> does not define __NR_getrandom.

What is the expected behavior?
It compiles.

What went wrong?
[4787/27905] arm-linux-gnueabihf-gcc -MMD -MF obj/third_party/boringssl/boringssl/urandom.o.d -DV8_DEPRECATION_WARNINGS -DUSE_UDEV -DUSE_AURA=1 -DUSE_PANGO=1 -DUSE_CAIRO=1 -DUSE_GLIB=1 -DUSE_NSS_CERTS=1 -DUSE_X11=1 -DNO_TCMALLOC -DDISABLE_NACL -DFULL_SAFE_BROWSING -DSAFE_BROWSING_CSD -DSAFE_BROWSING_DB_LOCAL -DCHROMIUM_BUILD -DENABLE_MEDIA_ROUTER=1 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -DCOMPONENT_BUILD -DNDEBUG -DNVALGRIND -DDYNAMIC_ANNOTATIONS_ENABLED=0 -DBORINGSSL_IMPLEMENTATION -DBORINGSSL_NO_STATIC_INITIALIZER -DOPENSSL_SMALL -D_XOPEN_SOURCE=700 -DBORINGSSL_SHARED_LIBRARY -I../.. -Igen -I../../third_party/boringssl/src/include -fno-strict-aliasing --param=ssp-buffer-size=4 -fstack-protector -Wno-builtin-macro-redefined -D__DATE__= -D__TIME__= -D__TIMESTAMP__= -funwind-tables -fPIC -pipe -march=armv7-a -mfloat-abi=hard -mtune=generic-armv7-a -pthread -mfpu=neon -mthumb -O2 -fno-ident -fdata-sections -ffunction-sections -fomit-frame-pointer -g1 -fvisibility=hidden -Wno-psabi -Wno-unused-local-typedefs -Wno-maybe-uninitialized -Wno-missing-field-initializers -Wno-unused-parameter -std=c99 -fno-delete-null-pointer-checks -c ../../third_party/boringssl/src/crypto/rand/urandom.c -o obj/third_party/boringssl/boringssl/urandom.o
FAILED: obj/third_party/boringssl/boringssl/urandom.o 
arm-linux-gnueabihf-gcc -MMD -MF obj/third_party/boringssl/boringssl/urandom.o.d -DV8_DEPRECATION_WARNINGS -DUSE_UDEV -DUSE_AURA=1 -DUSE_PANGO=1 -DUSE_CAIRO=1 -DUSE_GLIB=1 -DUSE_NSS_CERTS=1 -DUSE_X11=1 -DNO_TCMALLOC -DDISABLE_NACL -DFULL_SAFE_BROWSING -DSAFE_BROWSING_CSD -DSAFE_BROWSING_DB_LOCAL -DCHROMIUM_BUILD -DENABLE_MEDIA_ROUTER=1 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -DCOMPONENT_BUILD -DNDEBUG -DNVALGRIND -DDYNAMIC_ANNOTATIONS_ENABLED=0 -DBORINGSSL_IMPLEMENTATION -DBORINGSSL_NO_STATIC_INITIALIZER -DOPENSSL_SMALL -D_XOPEN_SOURCE=700 -DBORINGSSL_SHARED_LIBRARY -I../.. -Igen -I../../third_party/boringssl/src/include -fno-strict-aliasing --param=ssp-buffer-size=4 -fstack-protector -Wno-builtin-macro-redefined -D__DATE__= -D__TIME__= -D__TIMESTAMP__= -funwind-tables -fPIC -pipe -march=armv7-a -mfloat-abi=hard -mtune=generic-armv7-a -pthread -mfpu=neon -mthumb -O2 -fno-ident -fdata-sections -ffunction-sections -fomit-frame-pointer -g1 -fvisibility=hidden -Wno-psabi -Wno-unused-local-typedefs -Wno-maybe-uninitialized -Wno-missing-field-initializers -Wno-unused-parameter -std=c99 -fno-delete-null-pointer-checks -c ../../third_party/boringssl/src/crypto/rand/urandom.c -o obj/third_party/boringssl/boringssl/urandom.o
../../third_party/boringssl/src/crypto/rand/urandom.c:62:2: error: #error "system call number for getrandom is not the expected value"
 #error "system call number for getrandom is not the expected value"
  ^
In file included from /usr/include/arm-linux-gnueabihf/sys/syscall.h:31:0,
                 from ../../third_party/boringssl/src/crypto/rand/urandom.c:32:
../../third_party/boringssl/src/crypto/rand/urandom.c: In function 'init_once':
../../third_party/boringssl/src/crypto/rand/urandom.c:128:15: error: '__NR_getrandom' undeclared (first use in this function)
       syscall(SYS_getrandom, &dummy, sizeof(dummy), GRND_NONBLOCK);
               ^
../../third_party/boringssl/src/crypto/rand/urandom.c:128:15: note: each undeclared identifier is reported only once for each function it appears in
../../third_party/boringssl/src/crypto/rand/urandom.c: In function 'fill_with_entropy':
../../third_party/boringssl/src/crypto/rand/urandom.c:258:21: error: '__NR_getrandom' undeclared (first use in this function)
         r = syscall(SYS_getrandom, out, len, 0 /* no flags */);
                     ^
ninja: build stopped: subcommand failed.

The reason is that glibc <sys/syscall.h> has an entry like `#define SYS_getrandom __NR_getrandom` and otherwise relies on the kernel's definitions of these __NR_foo values coming from asm/unistd.h. If this kernel asm/unistd.h is old, it will not define __NR_getrandom, so SYS_getrandom ends up defined, but not actually declared/usable. The check in urandom.c is whether, on Linux, SYS_getrandom is defined - which it is - so it enters the path of comparing SYS_getrandom with EXPECTED_SYS_getrandom and fails with #error.

It looks to me that in the case of Linux and glibc, this macro trickery of having a fallback value for SYS_getrandom will not do it's intended job if glibc's syscall.h is newer than the kernel's unistd.h. I fixed it in our build (at least until we get new kernel headers!) by adding a simple check:
#if !defined(__NR_getrandom)
#undef SYS_getrandom
#endif

That's definitely not the "right" fix, but to me all of this macro checking seems kind of weird and may just be a legacy from a time when the syscall was newly-added / not stably numbered. Given that the syscall is runtime-detected anyway, and the current macro checks means it won't use the syscall unless an EXPECTED_SYS_getrandom is already included in the file for the architecture... you already have all of the syscall numbers anyway, and cross-checking with the C library introduces scope for spurious errors. You could just do something like this:

#ifdef EXPECTED_SYS_getrandom
#undef SYS_getrandom
#define SYS_getrandom EXPECTED_SYS_getrandom
#endif

#ifdef SYS_getrandom
#define USE_SYS_getrandom
#endif

Then it will use your hardcoded numbers on "known" architectures, or the C library provided number otherwise, and not #error unnecessarily.

Other parts of Chromium use things like sandbox/linux/system_headers/arm_linux_syscalls.h to just ensure that the syscall numbers are always defined, and hence break the dependency on asm/unistd.h being complete. Also a solid option - cut out the need to maintain a syscall ABI table inside your library and you can just delete all of that macro stuff.

Did this work before? No 

Chrome version:   Channel: n/a
OS Version: 
Flash Version:
 
Components: Internals>Network>SSL
Labels: TE-NeedsTriageHelp
Owner: davidben@chromium.org
Status: Started (was: Unconfirmed)
Does this patch resolve things for you?
https://boringssl-review.googlesource.com/c/17864/
Labels: Needs-Feedback

Comment 4 by r...@endlessm.com, Jul 14 2017

Thanks David for your prompt response! That very much looks like it will address the issue. I'll queue it up on our build service and should be able to get back to you next week.

Comment 5 by r...@endlessm.com, Jul 18 2017

Yep, that worked on our build - thanks very much!
Project Member

Comment 6 by bugdroid1@chromium.org, Jul 18 2017

The following revision refers to this bug:
  https://boringssl.googlesource.com/boringssl/+/7d536388724a7df6eab1c9c510ffdfd0eb1a69e8

commit 7d536388724a7df6eab1c9c510ffdfd0eb1a69e8
Author: David Benjamin <davidben@google.com>
Date: Tue Jul 18 16:28:41 2017

Use __NR_getrandom rather than SYS_getrandom.

The former is defined by the kernel and is a straightforward number. The
latter is defined by glibc as:

  #define SYS_getrandom __NR_getrandom

which does not work when kernel headers are older than glibc headers.
Instead, use the kernel values.

Bug:  chromium:742260 
Change-Id: Id162f125db660643269e0b1329633437048575c4
Reviewed-on: https://boringssl-review.googlesource.com/17864
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>

[modify] https://crrev.com/7d536388724a7df6eab1c9c510ffdfd0eb1a69e8/crypto/fipsmodule/rand/urandom.c

Labels: M-61
Status: Fixed (was: Started)
We'll roll the change into Chromium sometime later this week, but marking the bug as fixed since all the work is done. It should show up in Chrome 61.

Sign in to add a comment