Google Nest Hello round 2 of N

Denver Gingerich compliance at sfconservancy.org
Sat Feb 3 05:12:05 UTC 2024


This is the report we sent to Google on 2020-08-17:



Here are the results of the CCS check I did on the source candidate published on Google's site as of 2020-08-13 for the Nest Hello "smart doorbell", firmware version 4030024 (the second candidate).


Source candidate (12 repositories total):
master branch last commit a1ec0d62a2ce3f00ebb8ee126da25b2353fc75ac bandwidth
master branch last commit 5299cfdcf5c8c5802160cbd0f1b6cc077bf89885 bluez
master branch last commit e2acce03319f6213de4558a2562d7bb078379b9f busybox
master branch last commit b9b4323db5049a7c0e4df517a7999ee60c37f355 connman-nest
master branch last commit d190fa6c256a4afa4cae62524321356e64208cc1 e2fsprogs
master branch last commit 4170fa5dec7f8bebcf7189a00cdea0cc22ea1fb1 glib
master branch last commit de2d60839d0713009754b4b7f38699cdab3b6871 i2ctools
master branch last commit 17a230cb3ac927d05a7979a75a68ade18affa994 libatomic_ops
master branch last commit 2a7ccb451f606a9d46457b8c6a3fe0d9da5c1194 libgcrypt
master branch last commit 187c068a88a73655f37431b8c0e96eede1195edd libiconv
master branch last commit 88783dd411e691fbf66594cb7832185bb08e3d3e linux-3.10
master branch last commit 3b0d95fcd373a28acb1d97379f23ad4af4776402 mxml


The above were downloaded from Google's Nest source release page at https://nest-open-source.googlesource.com/nest-hello/ . Note that this is different from the page we used last time - https://nest.com/legal/compliance/ - and this is still the page linked to from https://nest.com/downloads/legal/open_source_compliance_en.pdf . If https://nest.com/legal/compliance/ is no longer the correct place to receive Nest source code, Google should update its documentation to point to the correct location.

No firmware image was provided; we ask Google to provide a firmware image, or at least copies of the GPLv2'd binaries that appear in that firmware, to us in order to confirm compliance, as our other option is to painstakingly and at great expense extract the firmware from the Hello device itself, which will likely simply delay and complicate this compliance matter.

The only way to confirm compliance is to compare binary output, per GPLv2 section 3, which states:

"You may copy and distribute the Program ... in object code or executable form ... provided that you ... Accompany it with the complete corresponding machine-readable source code" (or an offer for this)

So the source code must "correspond" to the "object code or executable form". Since we have not been provided with the "object code or executable form" in a format we can use for comparison purposes, we are unable to confirm that the source code is "corresponding" to the "object code or executable form".

[...]


= Check summary of sources provided =

We were not able to find any README file to describe how to build all the packages at once. Furthermore, the individual packages did not contain adequate README or similar files for compiling corresponding source either. So we were unable to build object code that corresponded to Google's binaries (see below for how we determined the object code did not correspond, the linux-3.10 section in particular).

The main issue preventing us from building corresponding object code was that Google did not provide any information on which compiler to use. Since it is rare for a device like Nest Hello to self-host, we chose to use our desktop (running Debian 9 on x86_64 hardware) to build the source candidate that Google provided. Because the candidate did not specify any compiler, we used the default compiler, which creates x86_64 binaries, clearly not corresponding to the Nest Hello object code (per below). If there is a way for us to compile the Nest Hello object code on the Nest Hello itself, please do tell us how to do this so we can use its default compiler. Otherwise, we must receive details on which exact custom compiler must be used. It is sufficient for compilation compliance purposes to give detailed specifications for the cross-compiler, such as configuration options used to build upstream GCC for the purpose.

Since we were not able to find any README or similar at the top level of the repositories we were pointed at, we tried to build each repository individually, using its README or INSTALL file to guide our compilation steps, especially looking for any custom compiler we might be able to use (but were unsuccessful in finding).



= Specific repository issues =



== linux-3.10 ==

We did not find any instructions (i.e. "scripts used to control compilation", which can be (and often are), BTW, provided as step-by-step English instructions instead of machine scripts) indicating how we might build this repository. While there is a conventional way to build Linux, this requires a configuration file first. So we first tried to find a configuration file to use, as no instructions or other indication of which hardware or configuration would be appropriate for the Nest Hello were provided.

We eventually found some configuration files in linux-3.10/arch/arm/configs that we determined were not distributed with upstream Linux, suggesting we should use those configuration files. We still however need you confirm if these are the right configuration files or not (more detail below), as it is unclear whether we need to use precisely one of them (and, if so, which one) or if each corresponds to a different version of the Nest Hello, or if there is some other significance to each different configuration file.


=== On why ARM was assumed ===

Note that we did not find any non-upstream configuration files outside of linux-3.10/arch/arm, which was the primary property of Google's source candidate that indicated to us we should be building the code for ARM instead of for some other architecture. We had to use this assumption for the rest of the build steps, since there was no other indication of which architecture to use.


=== Compilation issues ===

After we determined that we should use the configuration files in linux-3.10/arch/arm/configs we tried to figure out which of these non-upstream configuration files to use. There were several to choose from:

ambarella_a5s_defconfig
ambarella_a7l_defconfig
ambarella_a8_ramfs_ca9_a_defconfig
ambarella_a8_ramfs_ca9_b_defconfig
ambarella_s2_arm11_defconfig
ambarella_s2_cortex_defconfig
ambarella_s2e_defconfig
ambarella_s2l_defconfig
ambarella_s3_defconfig

>From these we tried to find the configuration file that was likely to exercise the most kernel features (since that was most likely to result in a kernel that could work on (or at least downgrade to) the Nest Hello, given the very little information we have about the hardware it uses). We settled on ambarella_s2e_defconfig since it was SMP and used the most features of the other SMP config files.

After deciding on this configuration file, we tried building with it, using these commands:

$ make ARCH=arm ambarella_s2e_defconfig
$ make ARCH=arm

However, this resulted in the following errors:

gcc: error: unrecognized argument in option ‘-mabi=aapcs-linux’
gcc: note: valid arguments to ‘-mabi=’ are: ms sysv
gcc: error: unrecognized command line option ‘-mlittle-endian’
gcc: error: unrecognized command line option ‘-mno-thumb-interwork’; did you mean ‘-fno-sched-interblock’?

So we researched this and, as expected, determined that we needed to use some sort of ARM (cross-)compiler to do the actual build, instead of the default compiler we had on our system. As described above, Google must indicate which such compiler needs to be used.

In order to try and expedite the resolution of these compilation problems, we attempted to use an arbitrary ARM cross-compiler we happened to have available to use. We used the following to invoke it:

$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-

However, this too resulted in compilation errors, but much later in the build process:

drivers/built-in.o: In function `arizona_dev_exit':
:(.text+0x562fc): undefined reference to `mfd_remove_devices'
drivers/built-in.o: In function `arizona_dev_init':
:(.text+0x56614): undefined reference to `mfd_add_devices'
:(.text+0x567bc): undefined reference to `mfd_remove_devices'
drivers/built-in.o: In function `arizona_map_irq':
:(.text+0x56fec): undefined reference to `regmap_irq_get_virq'
:(.text+0x5700c): undefined reference to `regmap_irq_get_virq'
drivers/built-in.o: In function `arizona_irq_exit':
:(.text+0x570e0): undefined reference to `regmap_del_irq_chip'
:(.text+0x570f4): undefined reference to `regmap_del_irq_chip'
Makefile:785: recipe for target 'vmlinux' failed
make: *** [vmlinux] Error 1

We eventually were able to fix all these errors by editing different Makefiles to add the required CONFIG_* lines. As an example, we found this at the top of linux-3.10/drivers/mfd/Makefile:

CONFIG_MFD_ARIZONA=y
CONFIG_MFD_ARIZONA_SPI=m
CONFIG_MFD_LARGO=y

We then added the following to it to fix the mfd_* related errors above:

CONFIG_MFD_CORE=y

The fact that the CONFIG_* lists were incomplete is a compliance problem, as users must not be required to guess which lines to add to receive a complete build of Linux. Please ensure that either a corrected *_defconfig file is used/specified in your next candidate, or ensure the Makefiles in your next candidate already have all of the appropriate CONFIG_* lists updated so the kernel will compile without requiring any fixes from the user.

Once we made these changes, we were eventually able to get a kernel compiled. However, due to the above issues we ran into, we strongly suspect this Linux does not correspond to the one on the Nest device so the source for Linux is incomplete. We must receive proper instructions ("scripts") for how to build the kernel for the Nest Hello, including exactly which (cross-)compiler to use, if applicable, and how to invoke it.



== bandwidth ==

Since we did not find any instructions in README.txt for building, we just ran "make". This gave us:

$ make

To compile for x86 Linux: make bandwidth32
To compile for x86_64 Linux: make bandwidth64
To compile for x86 Linux with pthread: make bandwidth32-thread
To compile for x86_64 Linux with pthread: make bandwidth64-thread


Note of these seemed entirely appropriate, since we know (per above) that Nest Hello uses ARM, but we tried this anyway:

$ make bandwidth64

After installing some dependencies given the errors we got (i.e. missing "nasm" - Google should be explicit in which dependencies we need in its instructions file) we were able to build it. However, the resulting binary did not correspond to the object code on the Nest Hello because it was for the wrong architecture:

$ file bandwidth64
bandwidth64: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=bfff5e11b446733dc2d66534c6703bf4cc5b5716, not stripped



== bluez ==

Since no "configure" file was available (despite being directed to use this in the README), we ran this instead (note that the user cannot be expected to figure this out - you must provide this information explicitly so those unfamiliar with this type of build system can still build the package):

$ ./bootstrap-configure
$ make

After installing some dependencies (again, Google must be explicit about which ones we need so we don't have to guess), the package did compile, but we found it again did not correspond to the object code on the Nest Hello because it was for the wrong architecture:

$ file android/bluetoothd
android/bluetoothd: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=a4e4327f83b2199bea703bde21566a3f0ff2b3f2, not stripped

$ file src/bluetoothd
src/bluetoothd: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=31e0cf9a33f90338b37a583a3d4a4648137732c0, not stripped



== busybox ==

Since no instructions were provided as to which configuration we should use and no .config file was included (which is rare - please include one if you used one), from the INSTALL file we chose this method:

$ make defconfig
$ make

However, again we had the same problem with binaries that did not correspond, since they were not ARM:

$ file busybox busybox_unstripped
busybox: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=5bc99fbebea53d1165a882b2b1b429d5ece6fb5d, stripped
busybox_unstripped: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=5bc99fbebea53d1165a882b2b1b429d5ece6fb5d, not stripped



== connman-nest ==

Since we only found generic build instructions in INSTALL, we ran them:

$ ./configure
$ make

However, again we had the same problem with binaries that did not correspond, since they were not ARM:

$ file src/connmand
src/connmand: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=5906e51de6bc1af66abc54660f96065cee1c4ce2, not stripped



== e2fsprogs ==

Since we only found generic build instructions in INSTALL, we ran them:

$ ./configure
$ make

However, again we had the same problem with binaries that did not correspond, since they were not ARM:

$ file ./misc/dumpe2fs ./misc/e2image ./resize/resize2fs ./misc/tune2fs ./misc/mke2fs ./debugfs/debugfs ./e2fsck/e2fsck
./misc/dumpe2fs: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=cf53c4013d3b8840c6f1c54005285e518d52c7ed, not stripped
./misc/e2image: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=fea016ab35e2c27f738c39b27a1ad9853741c663, not stripped
./resize/resize2fs: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=75fee4f1848eb20220c2bde89d9c4491cff9db5b, not stripped
./misc/tune2fs: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=bc53108de49bb7f38c1cf2a9f3d6ac938d322713, not stripped
./misc/mke2fs: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=e77fb851c9df65fe22b53be2c784c24ad6ef9064, not stripped
./debugfs/debugfs: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=51fdce8cf596334ff34cc70a69612c5e44da51ea, not stripped
./e2fsck/e2fsck: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=72d7ada0e1387ab95e73fbfb4439d959433424ff, not stripped



== glib ==

We found generic build instructions in INSTALL, which we ran:

$ ./configure
$ make

However, again we had the same problem with binaries that did not correspond, since they were not ARM:

$ file ./gobject/.libs/libgobject-2.0.so.0.4904.0 ./glib/.libs/libglib-2.0.so.0.4904.0 ./gio/.libs/libgio-2.0.so.0.4904.0
./gobject/.libs/libgobject-2.0.so.0.4904.0: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=b1200d0d5b26e8ccad79317a1562f0bbbadaefb1, not stripped
./glib/.libs/libglib-2.0.so.0.4904.0: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=8b4d5d0c09f42f8498b5858da953fefbf070c4ab, not stripped
./gio/.libs/libgio-2.0.so.0.4904.0: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=775d354143effa9f962cd2b61b7811e42951a154, not stripped



== i2ctools ==

Per the README we ran:

$ make

However, again we had the same problem with binaries that did not correspond, since they were not ARM:

$ file ./tools/i2cdetect ./tools/i2cdump ./tools/i2cget ./tools/i2cset
./tools/i2cdetect: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=dde058c438a86877e1afacfa8d647f961530b963, not stripped
./tools/i2cdump: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=d956df4dcb304f025dfc9fdc0798e58f6b99d095, not stripped
./tools/i2cget: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=2440918aaa0fc74eb9768e43ed8c29d3218af326, not stripped
./tools/i2cset: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=2cc42ef821126186ecbd139c9180da4043c4b4fb, not stripped



== libatomic_ops ==

Since we only found generic build instructions in INSTALL, we ran them:

$ ./configure
$ make

However, again we had the same problem with binaries that did not correspond, since they were not ARM:

$ file ./src/atomic_ops_stack.o ./src/atomic_ops_malloc.o ./src/atomic_ops.o
./src/atomic_ops_stack.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
./src/atomic_ops_malloc.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
./src/atomic_ops.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped



== libgcrypt ==

Since we only found generic build instructions in INSTALL, we ran them:

$ ./configure

We noticed in particular that the compilation was likely to fail to produce corresponding files because of these lines in the ./configure output:

Libgcrypt v1.6.1 has been configured as follows:

Platform: GNU/Linux (x86_64-unknown-linux-gnu)
Hardware detection module: hwf-x86
Enabled cipher algorithms: arcfour blowfish cast5 des aes twofish
serpent rfc2268 seed camellia idea salsa20
gost28147
Enabled digest algorithms: crc gostr3411-94 md4 md5 rmd160 sha1
sha256 sha512 tiger whirlpool stribog

Enabled kdf algorithms: s2k pkdf2 scrypt
Enabled pubkey algorithms: dsa elgamal rsa ecc
Random number generator: default
Using linux capabilities: no
Try using Padlock crypto: yes
Try using AES-NI crypto: yes
Try using Intel PCLMUL: yes
Try using DRNG (RDRAND): yes
Try using Intel AVX: yes
Try using Intel AVX2: yes
Try using ARM NEON: n/a

The lack of support for ARM (including "ARM NEON: n/a") suggested we'd have problems. We continued anyway:

$ make

However, again we had the same problem with binaries that did not correspond, since they were not ARM:

$ file ./cipher/.libs/ecc.o ./cipher/.libs/primegen.o ./cipher/.libs/rsa.o ./cipher/.libs/camellia.o ./src/.libs/libgcrypt_la-visibility.o ./src/.libs/libgcrypt_la-sexp.o ./cipher/.libs/serpent.o ./src/.libs/libgcrypt.so.20.0.1
./cipher/.libs/ecc.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
./cipher/.libs/primegen.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
./cipher/.libs/rsa.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
./cipher/.libs/camellia.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
./src/.libs/libgcrypt_la-visibility.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
./src/.libs/libgcrypt_la-sexp.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
./cipher/.libs/serpent.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
./src/.libs/libgcrypt.so.20.0.1: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=e5f82fc882253b1573eb540177d93ba1f8a638b9, not stripped



== libiconv ==

We found generic build instructions in INSTALL.generic, which we ran:

$ ./configure
$ make

However, again we had the same problem with binaries that did not correspond, since they were not ARM:

$ file ./preload/.libs/libiconv.so.0.0.0 ./preload/preloadable_libiconv.so ./lib/.libs/libiconv.so.2.5.1 ./lib/.libs/iconv.o
./preload/.libs/libiconv.so.0.0.0: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=b64eb720ad9a44cb17d7b92aaa6382c5364668de, not stripped
./preload/preloadable_libiconv.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=b64eb720ad9a44cb17d7b92aaa6382c5364668de, not stripped
./lib/.libs/libiconv.so.2.5.1: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=4d1052b83daf7b8a9b64278e0093f2e8f0e4457b, not stripped
./lib/.libs/iconv.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped



== mxml ==

We found generic build instructions in README, which we ran:

$ ./configure
$ make

However, again we had the same problem with binaries that did not correspond, since they were not ARM:

$ file ./mxml-file.o ./libmxml.so.1.5 ./mxmldoc ./mxmldoc-static ./mxmldoc.o
./mxml-file.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
./libmxml.so.1.5: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=6956a84d76f4b66cd6ce0f0c494b8cac294f23c1, not stripped
./mxmldoc: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=925985f00f8931975d89586cb2528ab2cb0db08f, not stripped
./mxmldoc-static: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=aa71ef3e404203c965272809abf06db67aa2104e, not stripped
./mxmldoc.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped

To view this candidate and download the source candidate and firmware image, visit:
https://sfconservancy.org/usethesource/candidate/google-nest-hello-round-2-of-n/

--
Denver Gingerich
(Via https://sfconservancy.org/usethesource/)


More information about the ccs-review mailing list