[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#681760: busybox: broken on s390x due to alignment issues



Package: busybox
Version: 1:1.20.0-5
Severity: critical
Tags: d-i upstream patch

busybox is currently broken on s390x to the point of not being usable.
Depending on the configuration, some strings are replaced by empty 
strings. For the current version 1:1.20.0-5, this is the case of at 
least for the banner and the binary path, the later causing all exec
applets to fail to execute. In turns this renders the system 
unbootable:

| $ busybox sh
|
|
|  built-in shell (ash)
| Enter 'help' for a list of built-in commands.
| 
| $ switch_root
| sh: switch_root: not found

busybox-udeb is also affected, I haven't tried yet the impact on d-i, 
but at least essential applets like swapon, syslogd, realpath or uname
are not working.

This is due to aggressive size optimization by chaning the default 
strings alignement in the definitions of the strings in 
libbb/messages.c. Given it is not done in the corresponding declarations
in include/libbb.h, the compiler is free to optimize the access to these
constants with aligned access, which is what GCC does on s390x. This is
why the bug appears and disappears from version to version, as the issue
depends on the size of neighbouring constants and variables.

The patch below, also submitted upstream and adapted to the debian 
package (due to changes in shell-ash-export-HOME.patch) fixes the 
problem.



include/libbb.h: declare messages with ALIGN1

Some messages strings are defined with ALIGN1 in libbb/messages.c
to make sure strings are not aligned and thus to save some bytes. The
corresponding declaration in include/libbb.h should also use ALIGN1,
otherwise the compiler may assume they are aligned and generate wrong
code to access them. This is the case on at least s390x.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 include/libbb.h |   36 ++++++++++++++++++------------------
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/include/libbb.h b/include/libbb.h
index 322a28c..f22e58e 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1612,8 +1612,8 @@ unsigned get_cpu_count(void) FAST_FUNC;
 char *percent_decode_in_place(char *str, int strict) FAST_FUNC;
 
 
-extern const char bb_uuenc_tbl_base64[];
-extern const char bb_uuenc_tbl_std[];
+extern const char bb_uuenc_tbl_base64[] ALIGN1;
+extern const char bb_uuenc_tbl_std[] ALIGN1;
 void bb_uuencode(char *store, const void *s, int length, const char *tbl) FAST_FUNC;
 enum {
 	BASE64_FLAG_UU_STOP = 0x100,
@@ -1694,24 +1694,24 @@ extern const char *applet_name;
  * Therefore now we use #defines.
  */
 /* "BusyBox vN.N.N (timestamp or extra_version)" */
-extern const char bb_banner[];
-extern const char bb_msg_memory_exhausted[];
-extern const char bb_msg_invalid_date[];
+extern const char bb_banner[] ALIGN1;
+extern const char bb_msg_memory_exhausted[] ALIGN1;
+extern const char bb_msg_invalid_date[] ALIGN1;
 #define bb_msg_read_error "read error"
 #define bb_msg_write_error "write error"
-extern const char bb_msg_unknown[];
-extern const char bb_msg_can_not_create_raw_socket[];
-extern const char bb_msg_perm_denied_are_you_root[];
-extern const char bb_msg_you_must_be_root[];
-extern const char bb_msg_requires_arg[];
-extern const char bb_msg_invalid_arg[];
-extern const char bb_msg_standard_input[];
-extern const char bb_msg_standard_output[];
+extern const char bb_msg_unknown[] ALIGN1;
+extern const char bb_msg_can_not_create_raw_socket[] ALIGN1;
+extern const char bb_msg_perm_denied_are_you_root[] ALIGN1;
+extern const char bb_msg_you_must_be_root[] ALIGN1;
+extern const char bb_msg_requires_arg[] ALIGN1;
+extern const char bb_msg_invalid_arg[] ALIGN1;
+extern const char bb_msg_standard_input[] ALIGN1;
+extern const char bb_msg_standard_output[] ALIGN1;
 
 /* NB: (bb_hexdigits_upcase[i] | 0x20) -> lowercase hex digit */
-extern const char bb_hexdigits_upcase[];
+extern const char bb_hexdigits_upcase[] ALIGN1;
 
-extern const char bb_path_wtmp_file[];
+extern const char bb_path_wtmp_file[] ALIGN1;
 
 /* Busybox mount uses either /proc/mounts or /etc/mtab to
  * get the list of currently mounted filesystems */
@@ -1725,10 +1725,10 @@ extern const char bb_path_wtmp_file[];
 #define bb_path_motd_file "/etc/motd"
 
 #define bb_dev_null "/dev/null"
-extern const char bb_busybox_exec_path[];
+extern const char bb_busybox_exec_path[] ALIGN1;
 /* util-linux manpage says /sbin:/bin:/usr/sbin:/usr/bin,
  * but I want to save a few bytes here */
-extern char bb_PATH_root_path[]; /* "PATH=/sbin:/usr/sbin:/bin:/usr/bin" */
+extern char bb_PATH_root_path[] ALIGN1; /* "PATH=/sbin:/usr/sbin:/bin:/usr/bin" */
 #define bb_default_root_path (bb_PATH_root_path + sizeof("PATH"))
 #define bb_default_path      (bb_PATH_root_path + sizeof("PATH=/sbin:/usr/sbin"))
 
@@ -1758,7 +1758,7 @@ extern struct globals *const ptr_to_globals;
  * If you change LIBBB_DEFAULT_LOGIN_SHELL,
  * don't forget to change increment constant. */
 #define LIBBB_DEFAULT_LOGIN_SHELL  "-/bin/sh"
-extern const char bb_default_login_shell[];
+extern const char bb_default_login_shell[] ALIGN1;
 /* "/bin/sh" */
 #define DEFAULT_SHELL              (bb_default_login_shell+1)
 /* "sh" */

-- System Information:
Debian Release: wheezy/sid
  APT prefers testing
  APT policy: (500, 'testing')
Architecture: s390x

Kernel: Linux 3.2.0-3-s390x (SMP w/2 CPU cores)
Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages busybox depends on:
ii  libc6  2.13-33

busybox recommends no packages.

busybox suggests no packages.

-- no debconf information


Reply to: