Local label in assembly file can cause dynamic loader to crash (OS X x86_64)

Originator:Per.Mildner.usenet
Number:rdar://29265701 Date Originated:15-Nov-2016 11:43 AM
Status:Open Resolved:
Product:Developer Tools Product Version:
Classification: Reproducible:Always
 
Summary:
If a local label has the same location as a global (.globl) label then jumps to the local label can go via a dynamic loader stub and crash if the stack is not SysV ABI aligned. This happens even if the global label is unused, and the jump to the local label is from within the same assembly file.

Steps to Reproduce:
Install Xcode 8.
Build a flat_namespace bundle from an assembly file that jumps to a local label (and ensure a global label has the same value as the local label).
Load with dlopen(RTLD_LAZY).
Call into code in the loaded bundle that does a plain local jump the local label.
The local jump will invoke the dynamic stub resolver and crash if the stack does not adhere to SysV ABI conventions.


Transcript:
bash$ uname -a
Darwin dhcpu06.sics.se 15.6.0 Darwin Kernel Version 15.6.0: Thu Sep  1 15:01:16 PDT 2016; root:xnu-3248.60.11~2/RELEASE_X86_64 x86_64
bash$ /usr/bin/as --version
Apple LLVM version 8.0.0 (clang-800.0.38)
Target: x86_64-apple-darwin15.6.0
Thread model: posix
InstalledDir: /Applications/Xcode_8_0_0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
bash$ cc --version
Apple LLVM version 8.0.0 (clang-800.0.38)
Target: x86_64-apple-darwin15.6.0
Thread model: posix
InstalledDir: /Applications/Xcode_8_0_0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
bash$ cat asbug.s
	.text	

	.p2align 4,,15
	.globl	_test
_test:
	# _test is called using SysV ABI, so %rsp is 8 (mod 16) here
	sub	$8, %rsp
	# non-API "call" to LOCAL label (SysV ABI would require %rsp 0 (mod 16) here
	#
	# NOTE: Jumping to a local label should not put any
	# requirements on stack layout. In particular, SysV ABI calling
	# conventions should be irrelevant.
	#
	jne _bad_local
	# Restore stack pointer
	add	$8, %rsp
	# return to C
	ret

	.p2align 4,,15
	.globl	_bad_globl
	# The ".globl"-declared label _bad_globl is not used anywhere. Only the plain label _bad_local is used.
_bad_globl:
_bad_local:
	# Restore stack pointer
	add	$8, %rsp
	# return to C
	ret

bash$ cat asbug_main.c
/*
/usr/bin/as -arch x86_64  asbug.s -o asbug.o && cc -Wl,-flat_namespace -bundle -Wall -Werror asbug.o -o asbug.bundle && otool -rtV asbug.bundle && cc -Wall -Werror asbug_main.c -o asbug && { ./asbug || echo "bomb $?"; }
*/

#include <stdlib.h>
#include <dlfcn.h>

typedef void void_fun(void);

int main(int argc, char* argv[])
{
  void *test;

  void *handle = dlopen("asbug.bundle", RTLD_LAZY);
  if (handle == NULL) exit(42);

  test = dlsym(handle, "test");
  if (test == NULL) exit(43);

  ((void_fun*)test)();

  (void)argc; (void)argv;

  return 0;
}
bash$ /usr/bin/as -arch x86_64 asbug.s -o asbug.o && cc -Wl,-flat_namespace -bundle -Wall -Werror asbug.o -o asbug.bundle && otool -rtV asbug.bundle && cc -Wall -Werror asbug_main.c -o asbug && { ./asbug || echo "bomb $?"; }
asbug.bundle:
(__TEXT,__text) section
_test:
0000000000000f80	subq	$0x8, %rsp
0000000000000f84	jne	0xf96 ## symbol stub for: _bad_globl <<< BUG, should be plain "jne _bad_local"
0000000000000f8a	addq	$0x8, %rsp
0000000000000f8e	retq
0000000000000f8f	nop
_bad_local:
_bad_globl:
0000000000000f90	addq	$0x8, %rsp
0000000000000f94	retq
Segmentation fault: 11
bomb 139
bash$ 

Expected Results:
Jumps within an assembly file to local labels in the same assembly file should never cause the dynamic loader to be invoked (or to crash).

Actual Results:
The dynamic loader is involved for resolving a stub, and crashes if the stack violates the SysV ABI alignment requirements.

Version:
Xcode 8.0.0, OS X 10.11.6 (15G1108)

Notes:
A workaround is to never locate global labels at the same place as local labels, and never use global labels in in assembly file unless they are called in a SysV compliant manner.

A separate bug is that the Assembler reference claims "The .globl directive ... If symbol_name is otherwise defined (by ... a label), it acts within the assembly EXACTLY as if the .globl statement was not given" (my emph), which is clearly incorrect here. https://developer.apple.com/library/content/documentation/DeveloperTools/Reference/Assembler/040-Assembler_Directives/asm_directives.html

Configuration:


Attachments:

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!