Live data from Hacker News

Why bother with argv[0]?

wietzebeukema.nl

21–30 of 277 posts

Re: Why bother with argv[0]?

#21
post #19

Earlier quoted context omitted.

I just learned that rustup/rustc/cargo etc. work like this too. I couldn't understand why the gentoo formula was symlinking the same binary to a bunch of aliases.

On my system, these are hardlinks (regular files with a link count >1 and the same inode) rather than symlinks, though I'm not sure why.

Maybe to avoid broken links if you move the original files? That's the main benefit of hardlinks vs symlinks in my mind at least.

Re: Why bother with argv[0]?

#23
post #4

It is sometimes used to allow one binary to be the symlink target of hundreds of commands. Android does this for most common shell commands. Toybox and busybox are examples of such implementations. https://github.com/landley/toybox https://en.m.wikipedia.org/wiki/BusyBox

Also if you want a program to call itself, which is sometimes useful, this way lets you actually call the same program, rather than assuming the name and path.

Don't do this - if you (reliably) want the path to the current executable there is no portable way to do it, but on Linux you need to readlink /proc/self/exe and on MacOS you call _NSGetExecutablePath. I forget the API on Windows.

Re: Why bother with argv[0]?

#24

Earlier quoted context omitted.

Also if you want a program to call itself, which is sometimes useful, this way lets you actually call the same program, rather than assuming the name and path.

You can do this without assuming the name by execing /proc/$PID/exe. Then you're not vulnerable to the argv[0] spoofing described in the article. (But of course since argv[0] does exist, you should set it properly and pass through your own argv[0] unchanged.)

That's not portable, though. OpenBSD, for example, doesn't have /proc.

Re: Why bother with argv[0]?

#25
post #23

Earlier quoted context omitted.

Also if you want a program to call itself, which is sometimes useful, this way lets you actually call the same program, rather than assuming the name and path.

Don't do this - if you (reliably) want the path to the current executable there is no portable way to do it, but on Linux you need to readlink /proc/self/exe and on MacOS you call _NSGetExecutablePath. I forget the API on Windows.

There's also this very handy and tiny cross-platform library:

https://github.com/gpakosz/whereami

Re: Why bother with argv[0]?

#26
This article seems to be an example of how some common security practices are kind of surface level. If you want to limit what a box can access on the network, do it in the network. Why is security looking for bad urls in the argv; if you know they are bad just block them? Or better yet if they aren't good, don't allow them. And if you want to know what a process is doing, ask the kernel to log its syscalls. If you take away argv 0 you will lose some valuable stuff (cute little busybox links, error logs that have argv[0] in them, and attackers will just name payload.exe ls.exe. And if your network is allow all, they will still reach CNC or collector end point.

Re: Why bother with argv[0]?

#28

This lost me at "goes against modern design principles" without citing what principle(s) the author had in mind that would proscribe it.

Given the tone and assumptions the article makes, and the things that are explicitly explained, this seems to be one of those articles where a novice learnt something new and then decided to write an article about it, despite not having fully grasped the concept yet.

As a result, the author has such strange, absolute positions, calling it a legacy that should be abolished (only tangentially knowing some actual use cases), or that strange quote about design principles.

Despite all the talk about security, the whole debacle that argc can be 0 (and argv[0] can be NULL), is completely left aside. This has caused actual security issues quite recently[1].

[1] https://lwn.net/Articles/882799/

Re: Why bother with argv[0]?

#29

I also use argv[0] for the -h help text, to show examples how to use the command.

There is also a neat little BSD extension, also supported on a number of other Unix-like systems and GNU userspace (i.e. glibc, but also other libcs like Musl): extern char *__progname; which holds the program name without the (optional) invocation path in front of it. Basically the last path component of argv[0].

Nice, thank you.
Post reply on HN