-
-
Notifications
You must be signed in to change notification settings - Fork 162
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
autoconf $(( $* ))
requires shopt -s eval_unsafe_arith
#1450
Comments
Oof, I reproduced this. So this one can actually be fixed by setting The issue is that this kind of dynamic arithmetic can be unsafe in certain contexts with shells like ksh / bash that have array references. i.e. the https://github.com/oilshell/blog-code/tree/master/crazy-old-bug I reported this to OpenBSD ksh awhile ago, and they disallowed it as well. But OSH is stricter than what they did -- we disallow all implicit parsing of data as code, not just array references
I guess we should test more besides CPython's. CPython I also reproduced the IFS bug, so let's look at that and then circle back |
I guess the minimum we should do is actually put But yeah I would say autoconf compatibility without extra flags is pretty clearly essential |
Well, what autoconf (technically, the M4sh layer) is trying to do with this construct, is use
with the expectation that later it will be able to do things like
This is much more commonly used in Autoconf's test harness (which is an even gnarlier generated shell script than anything autoconf proper is likely to produce, see "Generating Test Suites with Autotest") than in autoconf-generated It would not be a completely crazy notion to add OSH-specific smarts to M4sh. For instance, if something not entirely unlike
would work in OSH (without turning on all the rest of Oil ;-) then we could detect OSH and use that. The big downside of going this route would of course be that some existing autoconf scripts, and all existing autotest scripts, would not work under OSH until regenerated, but perhaps that would be acceptable, given that nobody outside of the Oil project is really expecting OSH to be usable for autoconf scripts at the moment. |
Also, Autoconf proper never uses arrays (since not all shells have them) but I can't guarantee the same for all existing configure scripts and third-party .m4 files, many of which have never been tested on the more unusual systems that Autoconf proper tries to support. |
(In case you're wondering, the weird |
Hm actually this makes me wonder if a reason OSH is running Python's Right, I think practically speaking, since autoconf is released infrequently, it makes sense to do things on the OSH side. As far as I know autoconf scripts should be "easy" to run because they already run in dash / bash / BSD ksh and more. Anything that runs in all those shells should run in OSH I don't see any reason we shouldn't be able to run all the old bash and Python configure scripts going back a decade or more ... The scripts that only run in bash are the hard ones, and sometimes those need to be modified. I want to find a minimal distro to build from source with only OSH on the disk ... So presumably this bug might occur in that context, or maybe it just slows everything down ... It would be annoying to change how our arithmetic is parsed but it's definitely possible. We can parse dynamically and then look for the |
I'm not sure I understand the security problem here, but would it be sufficient to say that if you encounter |
$(( $* ))
inside a shell function$(( $* ))
requires shopt -s eval_unsafe_arith
That rule would still have problems for shells with ksh arrays, which includes bash and OSH. (e.g. see the links on https://github.com/oilshell/blog-code/tree/master/crazy-old-bug ) We can obviously do it because we have But I also want to run autoconf with default settings. So I guess I would want to fix any remaining autoconf issues, and then circle back to this one. I found another one last night while running bash Unfortunately it's a bit hard for me to debug that ...
But I haven't looked at why the variable is empty in OSH and not bash. The configure completes, but I think it probably gives different results, which is not good. Not sure if we need to set up a better debugging / test harness ... I would like to make fixing these "mechanical" and knock a buch of bugs off. I guess fixing things through the autoconf test suite could be a better option than trying to fix generated autoconf scripts. I would definitely be interested in more bug reports ! |
An idea I thought of that might be easy to implement
Array references are what cause the security issue, and dash / POSIX shell doesn't have arrays, so autoconf should work fine. This might slow things down a little, but also might be a pretty effective and simple solution |
Unfortunately, because this issue breaks the autoconf test suite's driver, I'm unable to isolate any more autoconf-related issues until it's resolved. I don't understand why the rule I suggested above -- "if you encounter |
Ah OK, I can probably prioritize a fix ... I'm working sort of in this area now. The way our parsing and evaluation works, these are all the same:
So let's put some code inside data. There is no problem here, bash and other shells give an error:
Now let's change it to an ksh-array reference:
That's just the way all ksh-derived shells work, which is very surprising. I think your rule is pretty close to what we'll end up doing, but it's not the way I think of it. OSH doesn't really have a notion of "expansion" -- it has parsing and evaluation, more like what's described in books about Lisp. (These are organized in the files The parsing is static (done without reference to variables at runtime), unlike other shells which mix the two stages. The surprising thing is that this slightly different architecture can be highly compatible, but this is one area where it causes differing behavior. Not sure if I mentioned this already: How to Parse Shell Like a Programming Language POSIX shell arithmetic is inherently dynamic -- it comes AFTER variable expansion. We are able to emulate that with "dynamic parsing" and evaluation Evaluation includes both:
So basically for autoconf to work, we need the evaluation of But to avoid the security issue, we do NOT want the evaluation of I think this should be possible -- I'll update this bug Thanks! |
Also to get a feel for how it parses and evaluates, you can do
|
OK, I think I understand what the problem is now. I phrased things in terms of conventional shell "expansion" operations, but what I was trying to communicate is the limited subset of variable-inside-arithmetic-parentheses constructs that Autoconf needs to work. A better way to put it is, perhaps, that Autoconf only wants to use For example:
Does that help? |
Yes that makes sense for sure. We want to allow OSH is technically being too strict -- there is no real security problem with parsing and evaluating (i.e. most programming languages don't have implicit "expansion" of data into code, without I did notice the So I conjectured that's part of the reason it's running more slowly! There seem to be a bunch of other differences I haven't debugged yet either ... it's very hard to debug the entire generated script, so I think it will help to get the test suite running and giving a report, since presumably it will give more localized failures! Thanks for the help |
This is to issue #1450, related to autoconf. Instead of disallowing dynamic parsing in $(( x )) unconditionally, we parse, and then disallow command subs, e.g. a[$(echo 42 | tee PWNED)]=1 in DATA as opposed to code. I split shopt allow_csub_psub into _allow_command_sub _allow_process sub to implement this. Makes a bunch of spec tests pass.
This is related to the fix for #1450. It relaxes eval_unsafe_arith in the remaining places. One more test in spec/nix-idioms now fails. It passed for the wrong reason -- it because 'foo[@]' wasn't a valid var ref, not because we implemented the weird and arguably buggy "empty array + var ref" rule that bash has. Also: - Remove eval_unsafe_arith from almost all spec tests. - Update docs.
With a new option shopt -u parse_sh_arith It was already disallowed in most places with shopt -u parse_dparen shopt -u parse_sh_assign The remaining places are the static: echo $(( a[i] )) echo ${a[i]} And the dynamic: unset a[i] printf -v a[i] ${!ref} declare -n not fully implemented Follow-up to #1450.
With a new option shopt -u parse_sh_arith It was already disallowed in most places with shopt -u parse_dparen shopt -u parse_sh_assign The remaining places are the static: echo $(( a[i] )) echo ${a[i]} And the dynamic: unset a[i] printf -v a[i] ${!ref} declare -n not fully implemented Follow-up to #1450. With test/lint fix.
Hi @zackw , sorry for the delay, I fixed this a couple weeks ago, and just released it. I would appreciate testing: https://www.oilshell.org/release/0.14.2/
It disallows the unsafe constructs by default:
But allows you to opt in:
It should work in both the slow Python tarball, and the fast BTW I'm writing a release announcement right now and this will be mentioned. I'll probably call it Oil 0.14.2 - Interactive Shell; Conceding to Reality Running autoconf without any The Oil language is and will always be statically parsed, but OSH arithmetic is now compatible and dynamically parsed (Technically it's a little different since it doesn't involve "expansion" / string rewriting, but rather dynamic parsing and evaluation, so that's why we need testing !!!) I'm going to make a call for more testing like this -- it will be bad if we can't run autoconf because as I understand it runs under like 10 shells. But I think we can! |
BTW this was not very hard to fix, took about a day or so, including updating some docs ... Also I implemented It's just that there dozens of other things to do on the project :) But I consider autoconf very important |
Here's another fun word-splitting problem exposed by Autoconf's test suite.
prints "2" when executed by ksh, dash, or bash, but when executed by osh it prints
Since this is a use of
$*
, not within double quotes, I think IFS should be irrelevant.The text was updated successfully, but these errors were encountered: