Why an ELF executable could have 4 LOAD segments? - unix

There is a remote 64-bit *nix server that can compile a user-provided code (which should be written in Rust, but I don't think it matters since it uses LLVM). I don't know which compiler/linker flags it uses, but the compiled ELF executable looks weird - it has 4 LOAD segments:
$ readelf -e executable
...
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
...
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000004138 0x0000000000004138 R 0x1000
LOAD 0x0000000000005000 0x0000000000005000 0x0000000000005000
0x00000000000305e9 0x00000000000305e9 R E 0x1000
LOAD 0x0000000000036000 0x0000000000036000 0x0000000000036000
0x000000000000d808 0x000000000000d808 R 0x1000
LOAD 0x0000000000043da0 0x0000000000044da0 0x0000000000044da0
0x0000000000002290 0x00000000000024a0 RW 0x1000
...
On my own system all executables that I was looking at only have 2 LOAD segments:
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
...
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x00000000003000c0 0x00000000003000c0 R E 0x200000
LOAD 0x00000000003002b0 0x00000000005002b0 0x00000000005002b0
0x00000000000776c8 0x000000000009b200 RW 0x200000
...
What are the circumstances (compiler/linker versions, flags etc) under which a compiler might build an ELF with 4 LOAD segments?
What is the point of having 4 LOAD segments? I imagine that having a segment with read but not execute permission might help against certain exploits, but why have two such segments?

A typical BFD-ld or Gold linked Linux executable has 2 loadable segments, with the ELF header merged with .text and .rodata into the first RE segment, and .data, .bss and other writable sections merged into the second RW segment.
Here is the typical section to segment mapping:
$ echo "int foo; int main() { return 0;}" | clang -xc - -o a.out-gold -fuse-ld=gold
$ readelf -Wl a.out-gold
Elf file type is EXEC (Executable file)
Entry point 0x400420
There are 9 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000040 0x0000000000400040 0x0000000000400040 0x0001f8 0x0001f8 R 0x8
INTERP 0x000238 0x0000000000400238 0x0000000000400238 0x00001c 0x00001c R 0x1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x000000 0x0000000000400000 0x0000000000400000 0x0006b0 0x0006b0 R E 0x1000
LOAD 0x000e18 0x0000000000401e18 0x0000000000401e18 0x0001f8 0x000200 RW 0x1000
DYNAMIC 0x000e28 0x0000000000401e28 0x0000000000401e28 0x0001b0 0x0001b0 RW 0x8
NOTE 0x000254 0x0000000000400254 0x0000000000400254 0x000020 0x000020 R 0x4
GNU_EH_FRAME 0x00067c 0x000000000040067c 0x000000000040067c 0x000034 0x000034 R 0x4
GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0x10
GNU_RELRO 0x000e18 0x0000000000401e18 0x0000000000401e18 0x0001e8 0x0001e8 RW 0x8
Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp .note.ABI-tag .dynsym .dynstr .gnu.hash .hash .gnu.version .gnu.version_r .rela.dyn .init .text .fini .rodata .eh_frame .eh_frame_hdr
03 .fini_array .init_array .dynamic .got .got.plt .data .bss
04 .dynamic
05 .note.ABI-tag
06 .eh_frame_hdr
07
08 .fini_array .init_array .dynamic .got .got.plt
This optimizes the number of mmaps that the kernel must perform to load such executable, but at a security cost: the data in .rodata shouldn't be executable, but is (because it's merged with .text, which must be executable). This may significantly increase the attack surface for someone trying to hijack a process.
Newer Linux systems, in particular using LLD to link binaries, prioritize security over speed, and put ELF header and .rodata into the first R-only segment, resulting in 3 load segments and improved security. Here is a typical mapping:
$ echo "int foo; int main() { return 0;}" | clang -xc - -o a.out-lld -fuse-ld=lld
$ readelf -Wl a.out-lld
Elf file type is EXEC (Executable file)
Entry point 0x201000
There are 10 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000040 0x0000000000200040 0x0000000000200040 0x000230 0x000230 R 0x8
INTERP 0x000270 0x0000000000200270 0x0000000000200270 0x00001c 0x00001c R 0x1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x000000 0x0000000000200000 0x0000000000200000 0x000558 0x000558 R 0x1000
LOAD 0x001000 0x0000000000201000 0x0000000000201000 0x000185 0x000185 R E 0x1000
LOAD 0x002000 0x0000000000202000 0x0000000000202000 0x001170 0x002005 RW 0x1000
DYNAMIC 0x003010 0x0000000000203010 0x0000000000203010 0x000150 0x000150 RW 0x8
GNU_RELRO 0x003000 0x0000000000203000 0x0000000000203000 0x000170 0x001000 R 0x1
GNU_EH_FRAME 0x000440 0x0000000000200440 0x0000000000200440 0x000034 0x000034 R 0x1
GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0
NOTE 0x00028c 0x000000000020028c 0x000000000020028c 0x000020 0x000020 R 0x4
Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp .note.ABI-tag .rodata .dynsym .gnu.version .gnu.version_r .gnu.hash .hash .dynstr .rela.dyn .eh_frame_hdr .eh_frame
03 .text .init .fini
04 .data .tm_clone_table .fini_array .init_array .dynamic .got .bss
05 .dynamic
06 .fini_array .init_array .dynamic .got
07 .eh_frame_hdr
08
09 .note.ABI-tag
Not to be left behind, the newer BFD-ld (my version is 2.31.1) also makes ELF header and .rodata read-only, but fails to merge two R-only segments into one, resulting in 4 loadable segments:
$ echo "int foo; int main() { return 0;}" | clang -xc - -o a.out-bfd -fuse-ld=bfd
$ readelf -Wl a.out-bfd
Elf file type is EXEC (Executable file)
Entry point 0x401020
There are 11 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000040 0x0000000000400040 0x0000000000400040 0x000268 0x000268 R 0x8
INTERP 0x0002a8 0x00000000004002a8 0x00000000004002a8 0x00001c 0x00001c R 0x1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x000000 0x0000000000400000 0x0000000000400000 0x0003f8 0x0003f8 R 0x1000
LOAD 0x001000 0x0000000000401000 0x0000000000401000 0x00018d 0x00018d R E 0x1000
LOAD 0x002000 0x0000000000402000 0x0000000000402000 0x000110 0x000110 R 0x1000
LOAD 0x002e40 0x0000000000403e40 0x0000000000403e40 0x0001e8 0x0001f0 RW 0x1000
DYNAMIC 0x002e50 0x0000000000403e50 0x0000000000403e50 0x0001a0 0x0001a0 RW 0x8
NOTE 0x0002c4 0x00000000004002c4 0x00000000004002c4 0x000020 0x000020 R 0x4
GNU_EH_FRAME 0x002004 0x0000000000402004 0x0000000000402004 0x000034 0x000034 R 0x4
GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0x10
GNU_RELRO 0x002e40 0x0000000000403e40 0x0000000000403e40 0x0001c0 0x0001c0 R 0x1
Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp .note.ABI-tag .hash .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn
03 .init .text .fini
04 .rodata .eh_frame_hdr .eh_frame
05 .init_array .fini_array .dynamic .got .got.plt .data .bss
06 .dynamic
07 .note.ABI-tag
08 .eh_frame_hdr
09
10 .init_array .fini_array .dynamic .got
Finally, some of these choices are affected by the --(no)rosegment (or -Wl,z,noseparate-code for BFD ld) linker option.

Related

JavaFx Scenebuilder.exe won't start and it looks like the included JVM won't run. How can I fix it?

Scenebuilder.exe will not start on my new PC either from IntelliJ, Windows explorer, or command line. It gives no errors and terminates instantly. On a hunch I tried running the included JVM in
C:\Program Files\SceneBuilder\runtime\bin
java --version
I get the log below and it shows an access exception that looks like a bug in the underlying JVM itself, not in the execution of the SceneBuilder code. I've been running JDK 11 on this AMD Ryzen just fine, and there are no DLLs sneaking in that do not belong there. I need help, thanks!
C:\Program Files\SceneBuilder\runtime\bin>java --version
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ff8e3bf8f29, pid=12296, tid=11532
#
# JRE version: (11.0.1+13) (build )
# Java VM: Java HotSpot(TM) 64-Bit Server VM (11.0.1+13-LTS, mixed mode, aot, sharing, tiered, compressed oops, g1 gc, windows-amd64)
# Problematic frame:
# V [jvm.dll+0x1e8f29]
#
# No core dump will be written. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# C:\Users\Tim\AppData\Local\Temp\\hs_err_pid12296.log
#
# If you would like to submit a bug report, please visit:
# http://bugreport.java.com/bugreport/crash.jsp
#
C:\Program Files\SceneBuilder\runtime\bin>type C:\Users\Tim\AppData\Local\Temp\\hs_err_pid12296.log
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ff8e3bf8f29, pid=12296, tid=11532
#
# JRE version: (11.0.1+13) (build )
# Java VM: Java HotSpot(TM) 64-Bit Server VM (11.0.1+13-LTS, mixed mode, aot, sharing, tiered, compressed oops, g1 gc, windows-amd64)
# Problematic frame:
# V [jvm.dll+0x1e8f29]
#
# No core dump will be written. Minidumps are not enabled by default on client versions of Windows
#
# If you would like to submit a bug report, please visit:
# http://bugreport.java.com/bugreport/crash.jsp
#
--------------- S U M M A R Y ------------
Command Line:
Host: AMD Ryzen 5 2600 Six-Core Processor , 12 cores, 15G, Windows 10 , 64 bit Build 18362 (10.0.18362.778)
Time: Sat Apr 25 09:02:07 2020 Eastern Daylight Time elapsed time: 0 seconds (0d 0h 0m 0s)
--------------- T H R E A D ---------------
Current thread (0x000002312e8c6000): JavaThread "Unknown thread" [_thread_in_vm, id=11532, stack(0x0000005029100000,0x0000005029200000)]
Stack: [0x0000005029100000,0x0000005029200000], sp=0x00000050291feee0, free space=1019k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V [jvm.dll+0x1e8f29]
V [jvm.dll+0x1e73d3]
V [jvm.dll+0x37524b]
V [jvm.dll+0x7394a9]
V [jvm.dll+0x3e467d]
V [jvm.dll+0x3e6951]
C [java.exe+0x3603]
C [java.exe+0x178dc]
C [KERNEL32.DLL+0x17bd4]
C [ntdll.dll+0x6ce51]
siginfo: EXCEPTION_ACCESS_VIOLATION (0xc0000005), reading address 0x0000000000000000
Registers:
RAX=0x0000a780aacf8fcc, RBX=0x0000000000000000, RCX=0x0000000000000000, RDX=0x0000000000000006
RSP=0x00000050291feee0, RBP=0x0000000000000000, RSI=0x000002312e8c6000, RDI=0x0000000000000000
R8 =0x0000000000000006, R9 =0x0000000000000006, R10=0x0000000000000006, R11=0x00000050291fe750
R12=0x0000000000000000, R13=0x00007ff8e3ff6d90, R14=0x000002312c602d98, R15=0x00000050291ff938
RIP=0x00007ff8e3bf8f29, EFLAGS=0x0000000000010256
Top of Stack: (sp=0x00000050291feee0)
0x00000050291feee0: 000002312c60db10 00007ff94e71c6c0
0x00000050291feef0: 00000050291ff938 000002312c602d98
0x00000050291fef00: 0000000000000000 0000000000000400
0x00000050291fef10: 00006181910f784b 00007ff8e3ff6d90
0x00000050291fef20: 0000000000000000 00000050291ff938
0x00000050291fef30: 000002312c602d98 00007ff8e3ff6d90
0x00000050291fef40: 0000000000000000 00007ff92e470000
0x00000050291fef50: 00007ff8e4282558 0000000000000000
0x00000050291fef60: 00007ff8e3bf7277 00007ff94e6d1b1c
0x00000050291fef70: 0000000000000000 00007ff8e40745dd
0x00000050291fef80: 0000a780aacf8fcc 000002312c602d98
0x00000050291fef90: 00007ff800000000 00007ff8e3ff6d90
0x00000050291fefa0: 000002312e8c6000 00000050291ff0c0
0x00000050291fefb0: 0000000000000000 00007ff8e3bf73d3
0x00000050291fefc0: 00007ff92e450000 00007ff92e47d088
0x00000050291fefd0: 00000050291ff0c0 000002312e8c6000
Instructions: (pc=0x00007ff8e3bf8f29)
0x00007ff8e3bf8f09: b8 00 00 00 48 8b 05 bc 40 85 00 48 33 c4 48 89
0x00007ff8e3bf8f19: 84 24 a0 00 00 00 48 8b e9 48 83 cb ff 48 ff c3
0x00007ff8e3bf8f29: 80 3c 0b 00 75 f7 33 f6 c6 44 24 30 01 40 38 35
0x00007ff8e3bf8f39: c2 62 88 00 74 17 40 38 35 a3 c9 87 00 75 0e 33
--------------- P R O C E S S ---------------
Threads class SMR info:
_java_thread_list=0x000002312c602d50, length=0, elements={
}
Java Threads: ( => current thread )
Other Threads:
[error occurred during error reporting (printing all threads), id 0xc0000005, EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ff8e414e1fd]
VM state:not at safepoint (not fully initialized)
VM Mutex/Monitor currently owned by a thread: None
[error occurred during error reporting (printing compressed oops mode), id 0xc0000005, EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ff8e4163b67]
Deoptimization events (0 events):
No events
Classes redefined (0 events):
No events
Internal exceptions (0 events):
No events
Events (0 events):
No events
Dynamic libraries:
0x00007ff6af5a0000 - 0x00007ff6af5e7000 C:\Program Files\SceneBuilder\runtime\bin\java.exe
0x00007ff9512e0000 - 0x00007ff9514d0000 C:\WINDOWS\SYSTEM32\ntdll.dll
0x00007ff950230000 - 0x00007ff9502e2000 C:\WINDOWS\System32\KERNEL32.DLL
0x00007ff94e6c0000 - 0x00007ff94e963000 C:\WINDOWS\System32\KERNELBASE.dll
0x00007ff94fb00000 - 0x00007ff94fba3000 C:\WINDOWS\System32\ADVAPI32.dll
0x00007ff9502f0000 - 0x00007ff95038e000 C:\WINDOWS\System32\msvcrt.dll
0x00007ff951200000 - 0x00007ff951297000 C:\WINDOWS\System32\sechost.dll
0x00007ff94f9e0000 - 0x00007ff94fb00000 C:\WINDOWS\System32\RPCRT4.dll
0x00007ff94f390000 - 0x00007ff94f524000 C:\WINDOWS\System32\USER32.dll
0x00007ff94f2e0000 - 0x00007ff94f301000 C:\WINDOWS\System32\win32u.dll
0x00007ff94f530000 - 0x00007ff94f556000 C:\WINDOWS\System32\GDI32.dll
0x00007ff94e520000 - 0x00007ff94e6b4000 C:\WINDOWS\System32\gdi32full.dll
0x00007ff94f240000 - 0x00007ff94f2de000 C:\WINDOWS\System32\msvcp_win.dll
0x00007ff94e270000 - 0x00007ff94e36a000 C:\WINDOWS\System32\ucrtbase.dll
0x00007ff942260000 - 0x00007ff9424e5000 C:\WINDOWS\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.18362.778_none_e6c6b761130d4fb8\COMCTL32.dll
0x00007ff947e60000 - 0x00007ff947e6a000 C:\WINDOWS\SYSTEM32\VERSION.dll
0x00007ff94f640000 - 0x00007ff94f976000 C:\WINDOWS\System32\combase.dll
0x00007ff94e370000 - 0x00007ff94e3f0000 C:\WINDOWS\System32\bcryptPrimitives.dll
0x00007ff950df0000 - 0x00007ff950e1e000 C:\WINDOWS\System32\IMM32.DLL
0x00007ff94aa90000 - 0x00007ff94aaa6000 C:\Program Files\SceneBuilder\runtime\bin\vcruntime140.dll
0x00007ff932a30000 - 0x00007ff932ada000 C:\Program Files\SceneBuilder\runtime\bin\msvcp140.dll
0x00007ff8e3a10000 - 0x00007ff8e4552000 C:\Program Files\SceneBuilder\runtime\bin\server\jvm.dll
0x00007ff950220000 - 0x00007ff950228000 C:\WINDOWS\System32\PSAPI.DLL
0x00007ff94ae30000 - 0x00007ff94ae54000 C:\WINDOWS\SYSTEM32\WINMM.dll
0x00007ff93c080000 - 0x00007ff93c089000 C:\WINDOWS\SYSTEM32\WSOCK32.dll
0x00007ff950d80000 - 0x00007ff950def000 C:\WINDOWS\System32\WS2_32.dll
0x00007ff94ae00000 - 0x00007ff94ae2d000 C:\WINDOWS\SYSTEM32\WINMMBASE.dll
0x00007ff94e4d0000 - 0x00007ff94e51a000 C:\WINDOWS\System32\cfgmgr32.dll
0x00007ff94e250000 - 0x00007ff94e261000 C:\WINDOWS\System32\kernel.appcore.dll
0x00007ff94a980000 - 0x00007ff94a991000 C:\Program Files\SceneBuilder\runtime\bin\verify.dll
0x00007ff93d1a0000 - 0x00007ff93d394000 C:\WINDOWS\SYSTEM32\DBGHELP.DLL
0x00007ff93cf30000 - 0x00007ff93cf5a000 C:\WINDOWS\SYSTEM32\dbgcore.DLL
0x00007ff92e470000 - 0x00007ff92e499000 C:\Program Files\SceneBuilder\runtime\bin\java.dll
0x00007ff92e450000 - 0x00007ff92e466000 C:\Program Files\SceneBuilder\runtime\bin\zip.dll
0x00007ff94aa80000 - 0x00007ff94aa8a000 C:\Program Files\SceneBuilder\runtime\bin\jimage.dll
dbghelp: loaded successfully - version: 4.0.5 - missing functions: none
symbol engine: initialized successfully - sym options: 0x614 - pdb path: .;C:\Program Files\SceneBuilder\runtime\bin;C:\WINDOWS\SYSTEM32;C:\WINDOWS\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.18362.778_none_e6c6b761130d4fb8;C:\Program Files\SceneBuilder\runtime\bin\server
VM Arguments:
java_command: <unknown>
java_class_path (initial): <not set>
Launcher Type: SUN_STANDARD
[Global flags]
uint G1ConcRefinementThreads = 10 {product} {ergonomic}
uintx GCDrainStackTargetSize = 64 {product} {ergonomic}
size_t InitialHeapSize = 267632960 {product} {ergonomic}
size_t MaxHeapSize = 4282127360 {product} {ergonomic}
uintx ReservedCodeCacheSize = 251658240 {pd product} {ergonomic}
bool SegmentedCodeCache = true {product} {ergonomic}
bool UseCompressedClassPointers = true {lp64_product} {ergonomic}
bool UseCompressedOops = true {lp64_product} {ergonomic}
bool UseG1GC = true {product} {ergonomic}
bool UseLargePagesIndividualAllocation = false {pd product} {ergonomic}
Logging:
Log output configuration:
#0: stdout all=warning uptime,level,tags
#1: stderr all=off uptime,level,tags
Environment Variables:
JAVA_HOME=C:\Users\Tim\jdk-13.0.2
PATH=...
USERNAME=Tim
OS=Windows_NT
PROCESSOR_IDENTIFIER=AMD64 Family 23 Model 8 Stepping 2, AuthenticAMD
--------------- S Y S T E M ---------------
OS: Windows 10 , 64 bit Build 18362 (10.0.18362.778)
CPU:total 12 (initial active 12)
Memory: 4k page, system-wide physical 16335M (7401M free)
TotalPageFile size 38863M (AvailPageFile size 26823M)
current process WorkingSet (physical memory assigned to process): 8M, peak: 8M
current process commit charge ("private bytes"): 3M, peak: 3M
vm_info: Java HotSpot(TM) 64-Bit Server VM (11.0.1+13-LTS) for windows-amd64 JRE (11.0.1+13-LTS), built on Oct 6 2018 13:20:16 by "mach5one" with MS VC++ 15.5 (VS2017)
END.

eBPF: global variables and structs

So I have a simple eBPF code:
my.h:
#ifndef __MY_COMMON_H__
#define __MY_COMMON_H__
#include <linux/types.h>
struct foo {
int a;
int b;
int c;
int d;
};
#endif /* __MY_COMMON_H__ */
my_kern.c:
...
struct bpf_map_def SEC("maps") my_map = {
.type = BPF_MAP_TYPE_HASH,
.key_size = ...,
.value_size = ...,
.max_entries = MAX_ENTRIES,
};
struct foo my_foo = {
.a = 150000,
.b = 100,
.c = 10,
.d = 40,
};
SEC("sockops")
int my_bpf(struct bpf_sock_ops *sk_ops)
{
...
};
char _license[] SEC("license") = "GPL";
u32 _version SEC("version") = LINUX_VERSION_CODE;
I build the code with llvm-5.0, with no errors/warnings, however bpftool prog load ... fails:
libbpf: Program 'sockops' contains non-map related relo data pointing to section 6
Error: failed to load program
$ llvm-readelf-5.0 -s my_kern.o
There are 12 section headers, starting at offset 0xa90:
Section Headers:
[Nr] Name Type Address Off Size ES Flg Lk Inf Al
[ 0] NULL 0000000000000000 000000 000000 00 0 0 0
[ 1] .strtab STRTAB 0000000000000000 0009c0 0000cc 00 0 0 1
[ 2] .text PROGBITS 0000000000000000 000040 000000 00 AX 0 0 4
[ 3] sockops PROGBITS 0000000000000000 000040 0006e0 00 AX 0 0 8
[ 4] .relsockops REL 0000000000000000 000980 000040 10 11 3 8
[ 5] maps PROGBITS 0000000000000000 000720 00001c 00 WA 0 0 4
[ 6] .data PROGBITS 0000000000000000 00073c 00001c 00 WA 0 0 4
[ 7] .rodata.str1.16 PROGBITS 0000000000000000 000760 000093 01 AMS 0 0 16
[ 8] .rodata.str1.1 PROGBITS 0000000000000000 0007f3 00001d 01 AMS 0 0 1
[ 9] license PROGBITS 0000000000000000 000810 000004 00 WA 0 0 1
[10] version PROGBITS 0000000000000000 000814 000004 00 WA 0 0 4
[11] .symtab SYMTAB 0000000000000000 000818 000168 18 1 10 8
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
$
Section 6 contains my my_foo structure, I could dump its contents with llvm-objdump.
This error does not happen if I define my_foo inside main() function for instance. Does it mean such global declarations are not permitted by eBPF convention?
eBPF knows nothing about global variables. When bpftool sends your program to the kernel, it only sends one piece of bytecode instructions that is supposed to be “self-contained” (at least if you don't use eBPF function calls, but eBPF functions are not yet supported by libbpf and bpftool so I assume this is not the case).
Anyway: when bpftool calls libbpf to load your program from the ELF file, it expects to find the whole self-contained program in one ELF section. There is an exception for maps, for which some metadata is placed into a specific ELF section. Other than this, libbpf does not know how to get the definition of your global variable my_foo from the .data section and to move it into the main section. This is why it warns you about non-map related relo[cation] data in this .data section.
my_kern.o
+----------------------------+
| ELF header |
+----------------------------+
|sockops |
| |
| eBPF instructions |
| | |
| ->“get my_foo from .data” | <- libbpf: “What am I supposed to do with this??”
| |
+----------------------------+
| Other ELF sections… |
+----------------------------+
|.data | <- libbpf: “I don't care about this section”
| my_foo |
+----------------------------+
I'm a true artist, aren't I?
So the problem actually comes from how clang handles your global variable here. If you move the definition inside the main function, clang apparently does not move it to its own .data section in the object file it creates. I suppose you are trying to move the variable to a header file, possibly to share it with other source files; I don't know if this is possible to have this to compile correctly, there may exist some flags for clang or some preprocessing directives that would help you, but this is beyond my knowledge.
Seems like static global variable relocation works now (kernel 5.4, Clang 10, Ubuntu 20.04). In my code the value of variable test persists between runs of BPF prog.
static __u64 test = 0;
SEC("cgroup_skb/egress")
int cb_pkt(struct __sk_buff *skb)
{
bpf_printk("Packet with size: %d\n", test);
test = skb->len;
return 1;
}

Fatal Error when calling showSaveDialog() and showOpenMultipleDialog()

The JVM is crashing when I run these two lines:
javafx.stage.FileChooser fileChooser = new FileChooser();
File targetFile = fileChooser.showSaveDialog( mainStage );
I am on Ubuntu 16.10, OpenJDK 8 64bit:
openjdk version "1.8.0_131"
OpenJDK Runtime Environment (build 1.8.0_131-8u131-b11-0ubuntu1.16.10.2-b11)
OpenJDK 64-Bit Server VM (build 25.131-b11, mixed mode)
Kernel version:
Linux Joshua-PC 4.8.0-59-generic #64-Ubuntu SMP Thu Jun 29 19:38:34 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
I tried the solution outlined here with no success: https://stackoverflow.com/a/34612376/61248
Here is the top of the error log:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007f8573f34e40, pid=19801, tid=0x00007f850d733700
#
# JRE version: OpenJDK Runtime Environment (8.0_131-b11) (build 1.8.0_131-8u131-b11-0ubuntu1.16.10.2-b11)
# Java VM: OpenJDK 64-Bit Server VM (25.131-b11 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C [libpthread.so.0+0x9e40] pthread_mutex_lock+0x0
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# If you would like to submit a bug report, please visit:
# http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
--------------- T H R E A D ---------------
Current thread (0x00007f856c325800): JavaThread "JavaFX Application Thread" [_thread_in_native, id=19824, stack(0x00007f850d633000,0x00007f850d734000)]
siginfo: si_signo: 11 (SIGSEGV), si_code: 1 (SEGV_MAPERR), si_addr: 0x00000000006e6f84
Registers:
RAX=0x00007f8573f34e40, RBX=0x00007f856c2e1730, RCX=0x000000000000014c, RDX=0x00007f850d72b8b0
RSP=0x00007f850d72b828, RBP=0x00007f850d72b890, RSI=0x00007f850d72b8a0, RDI=0x00000000006e6f74
R8 =0x00007f850d72b890, R9 =0x00007f856c2919fd, R10=0x00007f854dd43387, R11=0x0000000000000065
R12=0x00007f850d72b88c, R13=0x0000000000000000, R14=0x00007f85007b27c8, R15=0x00007f850d72ce20
RIP=0x00007f8573f34e40, EFLAGS=0x0000000000010202, CSGSFS=0x002b000000000033, ERR=0x0000000000000004
TRAPNO=0x000000000000000e
Top of Stack: (sp=0x00007f850d72b828)
0x00007f850d72b828: 00007f854dcd8bda 00007f850d72b8a0
0x00007f850d72b838: 00007f850d72b8b0 00007f851358d510
0x00007f850d72b848: 00007f856c29c720 00007f8518f02cc1
0x00007f850d72b858: 7b2d1296d82fd300 00007f856c29c720
0x00007f850d72b868: 00007f8518f02cc1 00007f8518f04494
0x00007f850d72b878: 00007f854dcb4f56 0000000000000003
0x00007f850d72b888: 00007f850d72b930 00007f8500883400
0x00007f850d72b898: 0000000000004d70 0000014e0000014c
0x00007f850d72b8a8: 00007f8500000000 0000015700000156
0x00007f850d72b8b8: 00007f8500000000 0000000000000000
0x00007f850d72b8c8: 7b2d1296d82fd300 00007f8500882a50
0x00007f850d72b8d8: 00007f8500882a84 00007f856c29c720
0x00007f850d72b8e8: 00007f8518ebd79f 0000000000000000
0x00007f850d72b8f8: 00007f854c3e2078 00007f8500883400
0x00007f850d72b908: 7b2d1296d82fd300 00007f850d72b9ec
0x00007f850d72b918: 00007f8500883fa8 00007f850d72b980
0x00007f850d72b928: 00007f8500883fa8 0000000000000000
0x00007f850d72b938: 00007f85007b27c8 00007f850d72ce20
0x00007f850d72b948: 00007f8518ebfcc0 00007f8500883e80
0x00007f850d72b958: 00007f8518e91487 00007f85007b27c8
0x00007f850d72b968: 00007f850087d250 00007f850d72b9a0
0x00007f850d72b978: 00007f8518e4fd1f 00007f850d72ba00
0x00007f850d72b988: 00007f850d72b9f0 00007f850d72b9e0
0x00007f850d72b998: 00007f84c40127b0 00007f84c4012870
0x00007f850d72b9a8: 00007f854c3e3557 0000000000000000
0x00007f850d72b9b8: 0000000000000000 0000000100000001
0x00007f850d72b9c8: 0000000c0000000c 0000000000000000
0x00007f850d72b9d8: 7b2d1296d82fd300 00007f85007b2600
0x00007f850d72b9e8: 00007f850087d250 0000000000000006
0x00007f850d72b9f8: 00007f8518e52e93 0000000000000000
0x00007f850d72ba08: 000001cc0000000c 0000000000000001
0x00007f850d72ba18: 00000006d82fd300 000000004000000c
Instructions: (pc=0x00007f8573f34e40)
0x00007f8573f34e20: 89 0c 25 e0 02 00 00 64 48 c7 04 25 f0 02 00 00
0x00007f8573f34e30: 00 00 00 00 b8 82 00 00 00 e9 e0 f9 ff ff 66 90
0x00007f8573f34e40: 8b 57 10 89 d1 81 e1 7f 01 00 00 90 89 d0 83 e0
0x00007f8573f34e50: 7c 0f 85 99 00 00 00 48 83 ec 08 85 c9 49 89 f8
Register to memory mapping:
RAX=0x00007f8573f34e40: pthread_mutex_lock+0 in /lib/x86_64-linux-gnu/libpthread.so.0 at 0x00007f8573f2b000
RBX=0x00007f856c2e1730 is an unknown value
RCX=0x000000000000014c is an unknown value
RDX=0x00007f850d72b8b0 is pointing into the stack for thread: 0x00007f856c325800
RSP=0x00007f850d72b828 is pointing into the stack for thread: 0x00007f856c325800
RBP=0x00007f850d72b890 is pointing into the stack for thread: 0x00007f856c325800
RSI=0x00007f850d72b8a0 is pointing into the stack for thread: 0x00007f856c325800
RDI=0x00000000006e6f74 is an unknown value
R8 =0x00007f850d72b890 is pointing into the stack for thread: 0x00007f856c325800
R9 =0x00007f856c2919fd is an unknown value
R10=0x00007f854dd43387: <offset 0xb0387> in /usr/lib/x86_64-linux-gnu/libX11.so.6 at 0x00007f854dc93000
R11=0x0000000000000065 is an unknown value
R12=0x00007f850d72b88c is pointing into the stack for thread: 0x00007f856c325800
R13=0x0000000000000000 is an unknown value
R14=0x00007f85007b27c8 is an unknown value
R15=0x00007f850d72ce20 is pointing into the stack for thread: 0x00007f856c325800
Stack: [0x00007f850d633000,0x00007f850d734000], sp=0x00007f850d72b828, free space=994k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [libpthread.so.0+0x9e40] pthread_mutex_lock+0x0
C 0x0000000000004d70
Full error log here: http://hypnosplayer.org/misc/save-as-error.log
This was being caused by the use of an external library JNativeHook for global hotkeys, particularly this line:
GlobalScreen.registerNativeHook();
and this line:
GlobalScreen.addNativeKeyListener( globalHotkeyListener );
I don't understand why this caused the problem, but removing both of these calls solves the issue. I suppose I'll have to look for a different global hotkey library.
I spoke with the library developer. He reviewed the crash and said it doesn't happen in the library direct, and he indicated that the problem may be with "xcb" and linux. He recommended using an earlier version of the library (v2.0.2 rather than v2.1.0) and that resolved the issue.
Is this reproducible?
The instruction stream looks like this:
0: 89 0c 25 e0 02 00 00 mov %ecx,0x2e0
7: 64 48 c7 04 25 f0 02 movq $0x0,%fs:0x2f0
e: 00 00 00 00 00 00
14: b8 82 00 00 00 mov $0x82,%eax
19: e9 e0 f9 ff ff jmpq 0xfffffffffffff9fe
1e: 66 90 xchg %ax,%ax
This is from the end of the __pthread_mutex_lock_full function in libpthread. The first instruction faults because it attempts to write to the absolute address 0x2e0, which is not mapped. This instruction is the tail of a proper instruction, which writes to the TCB via the %fs register override:
993a: 64 48 89 04 25 e0 02 mov %rax,%fs:0x2e0
9941: 00 00
It's not a simple stray function pointer call, either, because the JVM reports that the faulting instruction is at pthread_mutex_lock+0, i.e., the proper start of the function. So it looks like that the JVM/dynamic linker's view of libpthread are slightly off (shifted by 32 bytes, actually).
EDIT As this is perfectly reproducible, it is not a file rewrite of libpthread.so.0, as I originally suspected. It is likely some sort of memory corruption which flips a bit in a function pointer. If -Xcheck:jni does not provide any hints, this needs an extending debugging session with GDB to identify the root cause (running the JVM under valgrind probably has too many false positives).

Xbee Node Discovery Response

I'm trying to discover devices, from a coordinator, in my network.
So I sent an ND command to the coordinator and I'm correctly receiving response from other Xbee.
The next step will be to store the information I've received in a web application, in oder to send commands and data.
However, what I'm still missing is some parts in the frame respose. So far I've mapped the frame like this:
1 7E start frame
===== =================== MESSAGE LENGHT
2-3 0x00 0x19 -> 25
===== =================== PACKET TYPE
4 88 -> response to a remote AT command
5 02 frame ID
===== =================== AT COMMAND
6-7 0x4E 0x44 "ND"
8 00 status byte (00 -> OK)
===== =================== MY - Remote Address
9-10 0x17 0x85
===== =================== SH - SERIAL NUMBER HIGH
11-14 0x00 0x13 0xA2 0x00
===== =================== SL - SERIAL NUMBER LOW
15-18 0x40 0xB4 0x50 0x23
===== =================== SIGNAL
19 20
= ======== NI - Node Identifier
20 00
21 FF
22 FE
23 01
24 00
25 C1
26 05
27 10
28 1E
===== ===== CHECKSUM (25th bytes from MESSAGE LENGHT)
29 19
So, where I can find in this response the address of the device ?
My guess is in the NI part of the message but, I haven't find any example/information of how the data are organised.
Could someone point me in the right direction?
As someone told me in the dig.com forum
NI<CR> (Variable length)
PARENT_NETWORK ADDRESS (2 Bytes)<CR>
DEVICE_TYPE (1 Byte: 0=Coord, 1=Router, 2=End Device)
STATUS (1 Byte: Reserved)
PROFILE_ID (2 Bytes)
MANUFACTURER_ID (2 Bytes
So, loking to my frame response:
00 --- Node Identifier variable, (here 1 byte = 00 because no value is set up).
FFFE --- parent network address (2 bytes)
01 --- device type
00 --- status
C105 --- profile id
101E --- manufacturing id
This, afaik, means that in this last part of the frame, no information about address of the device are given. Only information are the SL and SH.
The 16-bit network address is what you've labeled "MY" (0x1785), and the 64-bit MAC address is the combination of SH/SL (00 13 A2 00 40 B4 50 23).

How to see variables stored on the stack with GDB

I'm trying to figure out what is stored at a certain place on the stack with GDB. I have a statement:
cmpl $0x176,-0x10(%ebp)
In this function I'm comparing 0x176 to the -0x10(%ebp) and I am wondering if there is a way to see what is stored at -0x10(%ebp).
I am wondering if there is a way to see what is stored at -0x10(%ebp).
Assuming you have compiled with debug info, info locals will tell you about all the local variables in current frame. After that, print (char*)&a_local - (char*)$ebp will tell you the offset from start of a_local to %ebp, and you can usually find out what local is close to 0x176.
Also, if your locals have initializers, you can do info line NN to figure out which assembly instruction range corresponds to initialization of a given local, then disas ADDR0,ADDR1 to see the disassembly, and again understand which local is located at what offset.
Another alternative is to readelf -w a.out, and look for entries like this:
int foo(int x) { int a = x; int b = x + 1; return b - a; }
<1><25>: Abbrev Number: 2 (DW_TAG_subprogram)
<26> DW_AT_external : 1
<27> DW_AT_name : foo
<2b> DW_AT_decl_file : 1
<2c> DW_AT_decl_line : 1
<2d> DW_AT_prototyped : 1
<2e> DW_AT_type : <0x67>
<32> DW_AT_low_pc : 0x0
<36> DW_AT_high_pc : 0x23
<3a> DW_AT_frame_base : 0x0 (location list)
<3e> DW_AT_sibling : <0x67>
<2><42>: Abbrev Number: 3 (DW_TAG_formal_parameter)
<43> DW_AT_name : x
<45> DW_AT_decl_file : 1
<46> DW_AT_decl_line : 1
<47> DW_AT_type : <0x67>
<4b> DW_AT_location : 2 byte block: 91 0 (DW_OP_fbreg: 0)
<2><4e>: Abbrev Number: 4 (DW_TAG_variable)
<4f> DW_AT_name : a
<51> DW_AT_decl_file : 1
<52> DW_AT_decl_line : 1
<53> DW_AT_type : <0x67>
<57> DW_AT_location : 2 byte block: 91 74 (DW_OP_fbreg: -12)
<2><5a>: Abbrev Number: 4 (DW_TAG_variable)
<5b> DW_AT_name : b
<5d> DW_AT_decl_file : 1
<5e> DW_AT_decl_line : 1
<5f> DW_AT_type : <0x67>
<63> DW_AT_location : 2 byte block: 91 70 (DW_OP_fbreg: -16)
This tells you that x is stored at fbreg+0, a at fbreg-12, and b at fbreg-16. Now you just need to examine location list to figure out how to derive fbreg from %ebp. The list for above code looks like this:
Contents of the .debug_loc section:
Offset Begin End Expression
00000000 00000000 00000001 (DW_OP_breg4: 4)
00000000 00000001 00000003 (DW_OP_breg4: 8)
00000000 00000003 00000023 (DW_OP_breg5: 8)
00000000 <End of list>
So for most of the body, fbreg is %ebp+8, which means that a is at %ebp-4. Disassembly confirms:
00000000 <foo>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 83 ec 10 sub $0x10,%esp
6: 8b 45 08 mov 0x8(%ebp),%eax # 'x' => %eax
9: 89 45 fc mov %eax,-0x4(%ebp) # '%eax' => 'a'
...

Resources