Issues building openssl for Android - android

I am following the link here to build Android libraries for openssl:
http://wiki.openssl.org/index.php/Android
Here are my settings in Setenv-Android.sh:
_ANDROID_EABI="arm-linux-androideabi-4.6"
_ANDROID_ARCH=arch-arm
_ANDROID_API="android-16"
The next step is to run the following command:
$ . ./Setenv-Andrhoid.sh
Here is the error I am getting:
Error: FIPS_SIG does not specify incore module. Please edit this script.
There is no mention of how to configure FIPS_SIG in the wiki. Looks like the script is looking for a file or directory called "incore." I searched through my $ANDROID_NDK_ROOT. However, i don't have any "incore" file.
The next command I need to run is the following:
$ ./config shared -no-ssl2 -no-ssl3 -no-comp -no-hw -no-engine \
--openssldir=/usr/local/ssl/$ANDROID_API
Here, is openssldir pointing to absolute /usr/... directory? I am hoping the eventual header and lib files end up in $ANDROID_NDK_ROOT/platform/android-16/arch-arm directory.

Here is the error I am getting:
Error: FIPS_SIG does not specify incore module. Please edit this script.
Oh, you're right. That has been fixed on the wiki.
I thought there was a comment in the script about "it safe to ignore if...", but it appears there is no comment about it either. Sigh....
The same script is used to build both FIPS Capable and non-FIPS version of the OpenSSL library. Its safe to ignore the FIPS_SIG error if you are not building the FIPS Capable library.
Since your are using OpenSSL and Android, it is safe to ignore. If you were following FIPS Library and Android, then it could not be ignored.
Looks like the script is looking for a file or directory called "incore."
For completeness, incore is a script that embeds the HMAC's fingerprint into the program or shared object. The FIPS Object Module will use the embedded HMAC to integrity test itself at startup. Its pretty useless in practice since the key is well known ;)
incore is distributed with openssl-fips-2.0.7.tar.gz and friends. Once you put incore somewhere (the directory tree or, for example, /usr/local/ssl/android-18/bin), you set FIPS_SIG to the filename.
$ ./config shared -no-ssl2 -no-ssl3 -no-comp -no-hw -no-engine
--openssldir=/usr/local/ssl/$ANDROID_API
Here, is openssldir pointing to absolute /usr/... directory? I am hoping the eventual header and lib files end up in $ANDROID_NDK_ROOT/platform/android-16/arch-arm directory.
--openssldir is the install directory. You should set it to $ANDROID_NDK_ROOT/platform/android-16/arch-arm if that's where you want the library installed.
A little more info: by default, OpenSSL will install itself at /usr/local/ssl. When I build iOS, is use --openssldir=/usr/local/ssl/ios. When I build Android, --openssldir=/usr/local/ssl/android-18 (or android-14, etc).
For example, here's what mine looks like on a Mac Book:
$ ls /usr/local/ssl/
android-14 darwin macosx-x64
android-18 ios macosx-x86

Related

How to compile a simple OpenCL program in Android?

I've spent many hours today trying to accomplish this seemingly very simple task so my frustration may seem strange to you.
I want to "run"/execute a program that contains OpenCL functions on my Samsung Galaxy S7 (Exynos SoC). Support for OpenCL shouldn't be an issue because:
1) It's a well supported flagship phone from a well-known manufacturer
2) libOpenCL.so is present in /system/vendor/lib/libOpenCL.so
3) OpenCL-Z reports a valid platform and device (GPU only for some reason)
Things that I tried:
Rooted the phone.
Installed cppdroid.
Tried to compile a simple program that contains references to standard OpenCL functions like clGetPlatformIDs().
Header files should be included somewhere, but I could not for the life of me find where to put them (using the same path where cppdroid stores standard header files did not work), so I manually included the headers in the .c file itself, making it barely editable on the phone itself.
My understanding is that I should link the library (libOpenCL.so) to the output of gcc during the linking phase. There seems to be an option to do that in cppdroid, under "Settings" "Project settings" "Link options" so I add:
-L/system/vendor/lib/libOpenCL.so
to that field. However compilation still fails and I'm getting "undefined references to clGetPlatformIDs()" as if I hadn't included the library at all.
After searching online for a solution, a possible remedy (see below) proved useless:
-Wl,--whole-archive -L/system/vendor/lib/libOpenCL.so
I thought I'd get gcc on its own since this is the compiler used by cppdroid and try to compile that way. Found out that it's supposed to be deprecated, and replaced by "clang". But cppdroid does include gcc, so I navigated to the folder containing the executable (I believe it's an executable, there seem to be no extensions here, and I'm a Windows person) which appears to be:
/data/data/name.antonsmirnov.android.cppdroid/sdk/gcc#4.8#2/bin
and tried to "execute" gcc-4.8 (which appears to be the executable compiler) from termux (a terminal emulator for Android). Much to my surprise I got the error message:
sush: gcc-4.8: not found
Even though ls -1 lists the file normally!
I tried various other stuff that did not work, but here's my question:
How do I go about compiling a simple OpenCL program that I've written in C, so as to execute it on my Android mobile device?
Why do I get the
sush: gcc-4.8: not found
error message?
My understanding is that I should link the library (libOpenCL.so) to the output of gcc during the linking phase. There seems to be an option to do that in cppdroid, under "Settings" "Project settings" "Link options" so I add:
-L/system/vendor/lib/libOpenCL.so
to that field. However compilation still fails and I'm getting "undefined references to clGetPlatformIDs()" as if I hadn't included the library at all.
You need to add -lOpenCL and -L/system/vendor/lib to the linker flags. The second option may not be required, as this directory should be in a default search path already.
First -L provides a search directory for libraries to link, you should be using -L/system/vendor/lib you can use -l to link to a library in your case -lOpenCL without the lib prefix.
I got it working on my Samsung S9+ Exynos phone. Here is what I did to use OpenCL in the Termux app:
apt update
apt upgrade
apt autoremove
apt install vim openssh clang git
vim ~/.bashrc
# press the i key, then paste the line below, then save and exit with :wq
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/system/vendor/lib64:/system/vendor/lib64/egl
# restart Termux
exit
And finally, to compile a C++ OpenCL program with headers as described here:
cd Test/src
g++ *.cpp -o Test.exe -std=c++11 -pthread -w -I./OpenCL/include -L/system/vendor/lib64 -lOpenCL
./Test.exe
To install clinfo do the following:
apt install cmake make
cd ~
mkdir opencl
cd ~/opencl
git clone https://github.com/KhronosGroup/OpenCL-Headers
cd ~/opencl/OpenCL-Headers
cmake -S . -B build -DCMAKE_INSTALL_PREFIX=$PREFIX
cmake --build build --target install
cd ~/opencl
git clone https://github.com/Oblomov/clinfo
cd ~/opencl/clinfo
make OS=Android
./clinfo

Compiling GRPC's CSharp extensions with NDK for Android

I am attempting to use GRPC with Unity. I'm stuck compiling a libgrpc_csharp_ext.so file which will successfully work with the arm-v7a Android archetecture. I expected the following command to work from the GRPC repository root:
arm-linux-androideabi-gcc -I. -I./include -fPIC -o libgrpc_csharp_ext.o -c src/csharp/ext/grpc_csharp_ext.c
arm-linux-androideabi-gcc -I. -I./include -shared libgrpc_csharp_ext.o -o libgrpc_csharp_ext.so
I cobbled this together from this question. It compiles successfully and Unity recognizes the file when placed in /Plugins/Android as a arvm7 library:
but when GRPC attempts to DllImport("grpc_csharp_ext") on an actual Android device, I get an error:
Unable to load library
'/data/app/PACKAGE/lib/arm/libgrpc_csharp_ext.so',
native render plugin support disabled: java.lang.UnsatisfiedLinkError:
dlopen failed: cannot locate symbol "grpc_slice_from_copied_buffer"
referenced by
"/data/app/PACKAGE/lib/arm/libgrpc_csharp_ext.so"...
Followed by:
Unable to find grpc_csharp_ext
I know this is possible because this open-source project has successfully cross-compiled the necessary files. When I download the .so file from their project and drop it into mine it successfully loads, except it was compiled with a very old version of GRPC and I therefore do not wish to use it. Furthermore, I've already successfully created an .a file for iOS which works well with a similar strategy. When I check my file with file libgrpc_csharp_ext.so I see that it is ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /system/bin/linker, with debug_info, not stripped. This matches the type of the file obtained from the open-source repository.
It seems like the appropriate symbols are not included in the resulting .so, based upon the error message above and also that the .so is ~36kb, but the "correct" .so from the open-source project is >5mb. I guess I'm compiling a dynamic library that doesn't include all the necessary symbols, but I'm not enough of a compiler guru to find the correct options.
Thanks to the help of the GRPC team, I have a working solution; see my comment in the issue here: https://github.com/grpc/grpc/issues/14402#issuecomment-369942250
I'm working with them to hopefully get this integrated into master. In the mean time, I will try to keep this blog post up to date with the instructions for each platform (not just Android): http://examinedself.com/cross-compile-grpc-unity/

How to determine which dependency causes Google Play OpenSSL warning?

I'm currently working on a big legacy project and trying to fix the OpenSSL vulnerability issue as explained at How to address OpenSSL vulnerabilities in your apps.
The problem is, there are lot of dependencies, some are open source (I updated all that didn't break the compatibility) added as Gradle import, some are custom/closed source provided by partners and contractors of the company I work for and attached to the project as JARs.
Is there any way to pinpoint specific library that has this vulnerability? I used the bash script provided at Google Play and OpenSSL warning message and it points to one native dependency (actually the .so file). Is there any option to pinpoint actual dependency from there?
Is there any option to pinpoint actual dependency from there?
Yes, but you need to know the offending OpenSSL version and you need grep. Windows find won't do.
First, take note of the offending OpenSSL version. For sake of argument, say its due to OpenSSL 1.0.1h.
Next, gather a list of your dependencies and their top level folders. For sake of argument, say its $HOME/Desktop/aosp-app, $HOME/sdk-a, /usr/local/sdk-b and /opt/local/sdk-c.
Finally, for the top level directories:
grep -R '1.0.1h' "$HOME/Desktop/aosp-app"
grep -R '1.0.1h' "$HOME/sdk-a"
grep -R '1.0.1h' /usr/local/sdk-b
grep -R '1.0.1h' /opt/local/sdk-c
You don't need grep -iR, which is a case insensitive (-i) recursive (-R) search. You also don't need grep -IR, which is a recursive (-R) search that skips binary files (-I).
All of this works because OpenSSL library embeds its version in the data section as a string. Eventually, you will hit on the culprit, which is probably an SDK that comes pre-built as a shared object but includes OpenSSL as a static library. One SDK seems to be identified frequently, and it uses cURL which is built against a static OpenSSL library.
If you have JAR files and suspect them, then you can perform the following as a quick test:
find <dir> -name '*.jar' -exec grep -R '1.0.1h' {} \;
The command will look in the directory <dir> and its subdirectories. It will search for files with the *.jar extension. When it finds one, it will run grep on it looking for the string. find will do it for every *.jar it finds.

Checking for missing shared libraries (.so) from another shared library

I have a whole bunch of around 500 libraries each of them depending on one another(shared libraries)
The problem is one/few of them are failing to load due to a missing dependency library and I have no logs about which is failing due to what missing library. Due to the large number I cannot analyze it on y own with a hex editor. This scenario is from an android phone. So if I keep all of the .so libraries at one place, is there any way to write a script which analyzes each library for its dependencies and checks its existence in the given directory?
What approach should be followed to do this as AFAIK is possible to list shared libraries only of a dynamic executable using ldd.
I'm not entirely sure if I understood you correctly, but I hope my answer helps you anyway.
Normally any dynamic linked binary can be examined with "ldd". It basically shows you all libraries the dynamic linker had to load to in order to resolve all external symbols. This works on libraries, as well as on executables. If you use ldd's "-r" flag, ldd will try to resolve all external symbols, and it will report missing ones.
You can then easily feed the output of "ldd -r" to "grep" and check for missing symbols.
The bash script could then look like this:
find /lib /usr/lib /usr/local/lib -iname "*.so*" | while read lib_name; do
if ldd -r "$lib_name" 2>&1 | grep -qF "undefined symbol: "; then
echo "library \"$lib_name\" seems to be broken"
fi
done
I just wrote this out of my head, might contain minor synax/typing errors.
As I said earlier, this will also work on executables, in case you need it.
In case you need to extend your library search path, you can use the environment variable "LD_LIBRARY_PATH" for that. Just do:
export LD_LIBRARY_PATH=/path/to/my/libs
Since you specifically stated, that ldd will "only" work on dynamic libraries:
Well, a statically linked binary (lib or exe), has no dependencies on other binaries (except for the linux kernel). So I'm not sure what you are looking for in this case ... ?
ldd works for .so files as well
Try:
cd /usr/lib
ldd *
that will list all dynamic .so files used by the libraries, tries to resolv them, and show you anything that's missing.
Remove
<uses-library android:name="org.apache.commons.lang"/>
This is only for Android Project Libraries not a plain old Jar file. Jar files will have their classes extracted and put into your apk by just including them in the build path.

Setting up an Android build environment for JNI applications

I've got a hold of a proprietary JNI application which I need to build for a MIPS device. I've read "Initializing a Build Environment", parts of the NDK docs, some Google Groups threads and numerous StackOverflow questions, but I'm still short of my answer.
So far, I've checked out the Android source using Google's repo script and have it under ~/AndroidSource. I've also separately downloaded the SDK under ~/AndroidSDK and the NDK under ~/AndroidNDK. The code I'm trying to build is in a separate location. The SDK and NDK binaries are in my path. For building, I tried to use two different versions of the NDK as well as the one under the Android source tree, and experienced different sets of problems. My current setup uses NDK r8b, downloaded separately from the Android source.
The application has its Android.mk and jni/Android.mk. However, several directives in the latter point to paths such as
frameworks/base/include
system/core/include
with no prefixes. I thought these were meant to point to the respective directories in the Android source, so I symlinked them to the current directory. After some more symlinking and makefile and source hacking, I got the application to compile, but am currently stuck on the linking phase with lots of references to missing method bodies. During the whole time I knew I was doing something wrong.
I'm on a Linux x86_64 host, if it is of any concern.
So my question is:
What is the proper method to set up a build environment for JNI applications? What environment variables, symlinks and/or path expansions should I set up? Do I need to call any scripts once or before each ndk-build invocation?
Also, I'd be happy if you corrected me on any concepts or terminology I've gotten wrong.
Your approach wiyh symlinking the AOSP tree for system headers is correct. What you need now are the system libraries compiled for MIPS. The easiest way to get them is to adb pull them from a target device (or emulator image). But you can also build these libraries yourself, as part of the AOSP build (see build instructions for the source tree you downloaded).
If you still have any problems remaining, run your ndk-build with parameter V=1 and publish the link command and its results.
I use the following in my build (YMMV).
Explicitly invoke arm-linux-androideabi-gcc as your compiler or linker (should be in PATH).
NDK_PLATFORM=/path/to/android-ndk-r*/platforms/android-14
Pass -I"$(NDK_PLATFORM)/arch-arm/usr/include" to the compiler
Pass -nostdlib -L"$(NDK_PLATFORM)/arch-arm/usr/lib/" -lgcc -lc -lm to the linker

Categories

Resources