Skip to content

Conversation

@wcampbell-nv
Copy link

@wcampbell-nv wcampbell-nv commented Nov 22, 2025

This is a simple fix for issue #5069, adjusting /proc/self/cmdline emulation for ELFCodeLoader to output the contents of the stack's argv data rather than the stashed argument strings. This means application writes to argv[0] will be visible to in-process /proc/self/cmdline reads. The change is still not visible to external processes.

I've tested that the rename_process.c script attached to the issue now works the same in and out of FEX:

➜ gcc rename_process.c
➜ ./a.out
/proc/self/cmdline: ./a.out
Rewrote argv[0] to RENAMED
/proc/self/cmdline: RENAMED

➜ x86_64-linux-gnu-gcc ./rename_process.c
➜ FEXInterpreter ./a.out
/proc/self/cmdline: ./a.out
Rewrote argv[0] to RENAMED
/proc/self/cmdline: RENAMED

@Sonicadvance1
Copy link
Member

Oh wow, I completely missed that would have been a possible work around. Good job!

@wcampbell-nv
Copy link
Author

I wouldn't have known this was possible without your comment :)

I see one test is failing, but it looks unrelated to my change. Could this be a test issue?

@Sonicadvance1
Copy link
Member

That's definitely a spooky spurious failure.

Comment on lines +61 to +67
const auto& Args = GetApplicationArguments();
const char NullChar {};
// cmdline is an array of null terminated arguments
for (const auto& Arg : Args) {
write(fd, Arg.c_str(), Arg.size());
write(fd, &NullChar, sizeof(uint8_t));
}
Copy link
Member

@neobrain neobrain Nov 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fextl::string is null-terminated:

Suggested change
const auto& Args = GetApplicationArguments();
const char NullChar {};
// cmdline is an array of null terminated arguments
for (const auto& Arg : Args) {
write(fd, Arg.c_str(), Arg.size());
write(fd, &NullChar, sizeof(uint8_t));
}
const auto& Args = GetApplicationArguments();
// cmdline is an array of null terminated arguments
for (const auto& Arg : Args) {
write(fd, Arg.c_str(), Arg.size() + 1);
}

Btw is this implementation used anywhere in practice or do we only ever call the override from ELFCodeLoader.h?

}

void WriteCmdlineFD(int32_t fd) const override {
write(fd, reinterpret_cast<const void*>(StackPointer + ArgumentOffset), ArgumentBackingSize);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line probably merits an explanatory comment.

@neobrain
Copy link
Member

The change is still not visible to external processes

Have you tried using the prctl(PR_SET_MM, PR_SET_MM_MAP, ...) approach that was suggested in the issue? Seems like that would allow us to drop the /proc/self/cmdline hook entirely even.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants