Closed RaisinTen closed 1 year ago
It is indeed a PIE vs non-PIE issue, good catch!
It changes behavior since it will iterate through all shared objects loaded for the program, and would find notes in shared libraries, which could lead to buggy behavior, and/or open security concerns.
From my testing, it looks like running the callback only on the program headers of the current executable works and I think it addresses your blocking concern. I've pushed a commit for that.
unless we just want to avoid the callback mechanism here, using the approach from this PR looks better.
I was playing around with the parsing code and read the elf spec again, specifically how it behaves when PIE come into play.
phdr->p_vaddr
will be relative when compiling with -pie
which is the default, and absolute when -no-pie
, but the original implementation unconditionally adds base_addr
to it :P
so we could fix it by checking if (p_vaddr - p_offset) == 0
and only then adding base_addr
, but it's nice that dl_iterate_phdr
already takes PIE/non-PIE into account
I verified it with the latest Node.js 19.8.1 version, run postject from the windows system, inject my-app.js into the linux node executable file, generate my-app, and then run it successfully under the linux system, no segfault
@targos Looks like this issue has been successfully fixed https://github.com/nodejs/postject/issues/76
[root@vm ~]# ./my-app
{
node: '19.8.1',
acorn: '8.8.2',
ada: '1.0.4',
ares: '1.19.0',
brotli: '1.0.9',
cldr: '42.0',
icu: '72.1',
llhttp: '8.1.0',
modules: '111',
napi: '8',
nghttp2: '1.52.0',
nghttp3: '0.7.0',
ngtcp2: '0.8.1',
openssl: '3.0.8+quic',
simdutf: '3.2.2',
tz: '2022g',
undici: '5.21.0',
unicode: '15.0',
uv: '1.44.2',
uvwasi: '0.0.16',
v8: '10.8.168.25-node.12',
zlib: '1.2.13'
}
[ '/root/my-app', './my-app' ]
(node:394) ExperimentalWarning: Single executable application is an experimental feature and might change at any time
(Use `my-app --trace-warnings ...` to show where the warning was created)
The program headers base address values returned by
getauxval(AT_PHDR)
anddl_iterate_phdr()
are identical only ong++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
. However, the values are totally different onclang version 10.0.0-4ubuntu1
andg++ (GCC) 8.5.0 20210514 (Red Hat 8.5.0-16)
. Since thedl_iterate_phdr()
approach seems to work for all the 3 compilers, I think we should proceed with that.Turns out, this happens because PIE is not enabled by default on the compilers which produce binaries that are crashing.
Fixes: https://github.com/nodejs/postject/issues/70 Refs: https://github.com/nodejs/postject/issues/76 (actually
Fixes:
but I'll addFixes:
on the postject version upgrade PR in Node.js)(Node.js PR to test this - https://github.com/nodejs/node/pull/46868)