You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Running GNU binutilsstrip on a qsave_program/2 standalone ELF binary removes the save state data, resulting in a binary that just drops to a dry swipl REPL, i.e.
$ prog # Works
$ strip prog # This should be harmless, right?
$ prog # Now broken
The standalone binary doesn't contain debug symbols in the first place, so arguably the correct action is to just not use strip in the first place. However, there is at least one previous report on the forums, and in my case, strip is automatically run by a distribution package builder, causing very confusing breakages.
Analysis
The issue is that strip removes any data in an ELF not referenced by an ELF section, and qsave_program/2 produces a Zip archive concatenated to an ELF stub, meaning that the trailing Zip data remains anonymous:
$ binwalk prog
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 ELF, 64-bit LSB executable, AMD x86-64, version 1 (SYSV)
294522 0x47E7A End of Zip archive, footer length: 22
but
$ cp prog prog.stripped
$ strip prog.stripped
$ cmp prog prog.stripped
cmp: EOF on plwm.stripped after byte 14392, in line 2
$ binwalk prog.stripped
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 ELF, 64-bit LSB executable, AMD x86-64, version 1 (SYSV)
This show that strip was a no-op on the ELF stub but removed everything after byte 14392 = 0x3838.
Proof of Concept Fix
The idea for mitigation is simple: just create an ELF section that references the Zip archive data. Below is a manual demonstration of the idea that I have confirmed works:
$ unzip a.out; zip -Dr '$prolog' a.zip # Extract the zip archive
$ strip a.out; mv a.out a.stub # Extract the ELF stub
$ objcopy --add-section .zipdata=a.zip --set-section-flags .zipdata=readonly,data a.stub plwm
Is it reasonable to patch qsave_program/2, or wherever relevant, to add such an ELF section? Other thoughts?
The text was updated successfully, but these errors were encountered:
Overview
Running GNU binutils
strip
on aqsave_program/2
standalone ELF binary removes the save state data, resulting in a binary that just drops to a dry swipl REPL, i.e.The standalone binary doesn't contain debug symbols in the first place, so arguably the correct action is to just not use
strip
in the first place. However, there is at least one previous report on the forums, and in my case,strip
is automatically run by a distribution package builder, causing very confusing breakages.Analysis
The issue is that
strip
removes any data in an ELF not referenced by an ELF section, andqsave_program/2
produces a Zip archive concatenated to an ELF stub, meaning that the trailing Zip data remains anonymous:but
This show that
strip
was a no-op on the ELF stub but removed everything after byte14392 = 0x3838
.Proof of Concept Fix
The idea for mitigation is simple: just create an ELF section that references the Zip archive data. Below is a manual demonstration of the idea that I have confirmed works:
Is it reasonable to patch
qsave_program/2
, or wherever relevant, to add such an ELF section? Other thoughts?The text was updated successfully, but these errors were encountered: