Created attachment 250294 [details] fix sh -c -e cmd as per POSIX POSIX requires sh(1) to handle -c like an option that does not take an argument. We already handle the special case of attached options after -c... $ sh -ce 'echo hello world' hello world ... but these fail: $ sh -c -e 'echo hello world' echo hello world: -e: not found $ sh -c -- 'echo hello world' echo hello world: --: not found NetBSD fixed this 21 years ago. With their fix: $ sh -c -e 'echo hello world' hello world $ sh -c -- 'echo hello world' hello world $ sh -c -e 'echo hello; false; echo world' hello Patch attached. I also added a minimal regression test. I have only tested this on 14-STABLE, but there are no relevant changes between 14-STABLE and 15-CURRENT in sh.
this needs to fix system(3) as well as popen(3) too, as currently they call sh -c <command> with this change, that is no longer safe and needs to call sh -c -- <command> See also: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=274650 (should that bug depend on this one?)
(In reply to Benjamin Takacs from comment #1) Also probably the examples in su(1) where there is a `-c' minefield.
And actually this affects any code that calls `sh -c ....' directly. This is getting dangerously close to a POLA violation, POSIX notwithstanding.
(In reply to Bob Bishop from comment #2) (In reply to Bob Bishop from comment #3) This being such a footgun is why I argue in https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=274650#c1 for just documenting our sh to be *not* posix compatible on some stuff and leave -c alone.
It doesn't break any realistic existing usage of sh -c cmd.
(In reply to Christian Weisgerber from comment #5) I just listed two that became incorrect. system(3) and popen(3). How do you know I don't use - as prefix to mark internal commands and build commandlines run them via system, popen or sh -c?
The patch in https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=220587 has more test cases. Another thing that will break with the fixed -c is the ruby ports (not because of the upstream code but because of scripting in the port itself): https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=222872 .
(In reply to Benjamin Takacs from comment #6) That takes me to my starting point, which was a discussion about shell scripting where somebody was bending over backwards to use POSIX-ly correct code that handled all corner cases, so he used "sh -c --" and was quite astonished when I pointed out that this breaks on FreeBSD. Obviously system(3) and popen(3) will need to be fixed accordingly.