无法为 Android 构建 OpenSSH 9.3p

问题描述 投票:0回答:1

我正在尝试为 Android 构建 OpenSSH。我正在使用当前(截至撰写本文时)版本,即 9.3p。这是我所做的(主要取自Building OpenSSH for Android):

export ANDROID_NDK_ROOT=$ANDROID_HOME/ndk/21.0.6113669
export PATH=$PATH:$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin
cd ~/src

git clone [email protected]:openssh/openssh-portable.git
cd github-portable
git checkout V_9_3_P1
mkdir -p build/android-arm
autoreconf
# for the moment, build a stripped-down version without zlib and openssl
CHOST="arm-linux-androideabi" \
  CHOST2="armv7a-linux-androideabi17" \
  CC="${CHOST2}-clang" \
  CXX="${CHOST2}-clang++" \
  CFLAGS="-DHAVE_ATTRIBUTE__SENTINEL__=1" \
  CXXFLAGS="-DHAVE_ATTRIBUTE__SENTINEL__=1" \
  RANLIB="${CHOST}-ranlib" \
  LD="${CHOST}-ld" \
  AR="${CHOST}-ar" \
  ARFLAGS="cr" \
  CHOST="${CHOST}" \
  ./configure --host=arm-linux-androideabi --with-libs --without-zlib --without-openssl --prefix=$PWD/build/android-arm
make ssh

CFLAGS
CXXFLAGS
是另一个构建问题的解决方法,在对上述问题的评论以及https://github.com/android/ndk/issues/1362#issuecomment-712437159中进行了描述。

构建失败并出现错误,显然是由于 OpenSSH 与 NDK 中包含的头文件之一之间存在一些不兼容:

armv7a-linux-androideabi26-clang -DHAVE_ATTRIBUTE__SENTINEL__=1 -pipe -Wunknown-warning-option -Qunused-arguments -Wall -Wpointer-arith -Wuninitialized -Wsign-compare -Wformat-security -Wsizeof-pointer-memaccess -Wno-pointer-sign -Wno-unused-result -Wimplicit-fallthrough -fno-strict-aliasing -mretpoline -D_FORTIFY_SOURCE=2 -ftrapv -fno-builtin-memset -fstack-protector-strong   -fPIC -I. -I.. -I. -I./..  -DHAVE_CONFIG_H -c bsd-misc.c
bsd-misc.c:392:7: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
bzero(void *b, size_t n)
      ^
bsd-misc.c:392:16: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
bzero(void *b, size_t n)
               ^
bsd-misc.c:392:1: error: at most one overload for a given name may lack the 'overloadable' attribute
bzero(void *b, size_t n)
^
/home/user149408/tools/android-sdk-linux_86/ndk/21.0.6113669/toolchains/llvm/prebuilt/linux-x86_64/bin/../sysroot/usr/include/strings.h:61:23: note: expanded from macro 'bzero'
#define bzero(b, len) __bionic_bzero((b), (len))
                      ^
/home/user149408/tools/android-sdk-linux_86/ndk/21.0.6113669/toolchains/llvm/prebuilt/linux-x86_64/bin/../sysroot/usr/include/strings.h:62:40: note: previous unmarked overload of function is here
static __inline__ __always_inline void __bionic_bzero(void* b, size_t len) {
                                       ^
bsd-misc.c:392:7: error: parameter name omitted
bzero(void *b, size_t n)
      ^
bsd-misc.c:392:16: error: parameter name omitted
bzero(void *b, size_t n)
               ^
bsd-misc.c:394:15: error: use of undeclared identifier 'b'
        (void)memset(b, 0, n);
                     ^
bsd-misc.c:394:21: error: use of undeclared identifier 'n'
        (void)memset(b, 0, n);
                           ^
2 warnings and 5 errors generated.
make[1]: *** [Makefile:106: bsd-misc.o] Error 1
make[1]: Leaving directory '/home/user149408/src/openssh-portable/openbsd-compat'
make: *** [Makefile:199: openbsd-compat/libopenbsd-compat.a] Error 2

可以为主机平台(Ubuntu 22.04 x86_64)进行本机构建。

这是怎么回事,我能做什么?

android android-ndk cross-compiling openssh
1个回答
0
投票

我刚刚构建了一个成功运行的 openssh-9.4p1 ssh 客户端。 (使用 openssl-3.0.10 和 ldns-1.8.3 因为我需要安全连接,但这与这个问题无关......)

我想你应该声明你有 bzero(),因为 openbsd-compat/explicit_bzero.c 需要 bzero()。 (explicit_bzero.c有3种explicit_bzero()的实现,一种需要explicit_memset(),一种需要memset_s(),一种需要bzero(),而android没有explicit_memset()也没有memset_s())

那么,

cat >zzconfig.cache <<EOF
ac_cv_func_mblen=yes
ac_cv_func_bzero=yes
ac_cv_have_decl_bzero=yes
ac_cv_member_struct_passwd_pw_gecos=no
EOF

ac_cv_member_struct_passwd_pw_gecos=no
用于为ILP32构建ssh客户端。LP64应该不需要这个,但我没有检查LP64。请参阅sysroot中的某个地方的pwd.h。)

然后做

configure --cache-file=`pwd`/zzconfig.cache ...

问题是 android bzero() 不是一个函数,而是 __bionic_bzero() 的一个类似函数的宏。所以要么需要在 openbsd-compat/explicit_bzero.c 中修复这个问题

static void (* volatile ssh_bzero)(void *, size_t) = bzero;

或将其添加到某处

#undef bzero
void bzero(void* b, size_t len) {
  __bionic_bzero(b, len);
}

我想您遇到的下一个问题是 getrrsetbyname()。 getrrsetbyname() 有两种实现,一种需要 libresolv,一种需要带有 SSL 的 ldns(或者具有 ldns_verify_trusted() 函数的 ldns。)我使用后者,因为 IIRC android 没有可用的 libresolv,而我实际上已经有了后者。

最后,构建还需要 getifaddrs() 和 freeifaddrs() 但你可以在某个地方获取它们。我从 dhcpd for android 那里得到了我的。

并且您有一个可用的 ssh 客户端。

2024-01-31 我不知道我的帖子是否有任何帮助,但无论如何,今天我构建了 LP64 版本的 ssh 客户端,发现 LP64 版本的

struct passwd
确实有
pw_gecos
成员(所以您需要为 LP64 版本设置
ac_cv_member_struct_passwd_pw_gecos=yes
),但是,它的值设置为 NULL,导致 SEGV,至少在 uid = AID_SHELL (2000) 的 Android 8.0 设备上。 所以你需要像这样修复源。

diff -rup openssh-9.6p1/misc.c openssh-9.6p1-droid-p01/misc.c
--- openssh-9.6p1/misc.c        2023-12-18 23:59:50.000000000 +0900
+++ openssh-9.6p1-droid-p01/misc.c      2024-01-31 17:10:46.530066587 +0900
@@ -488,7 +488,7 @@ pwcopy(struct passwd *pw)
        copy->pw_name = xstrdup(pw->pw_name);
        copy->pw_passwd = xstrdup(pw->pw_passwd == NULL ? "*" : pw->pw_passwd);
 #ifdef HAVE_STRUCT_PASSWD_PW_GECOS
-       copy->pw_gecos = xstrdup(pw->pw_gecos);
+       copy->pw_gecos = xstrdup(pw->pw_gecos == NULL ? "null" : pw->pw_gecos);
 #endif
        copy->pw_uid = pw->pw_uid;
        copy->pw_gid = pw->pw_gid;
© www.soinside.com 2019 - 2024. All rights reserved.