-
Notifications
You must be signed in to change notification settings - Fork 386
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
Fix unintended command execution by "_quote_readline_by_ref" #492
Fix unintended command execution by "_quote_readline_by_ref" #492
Conversation
Today I found that #189 is actually the same issue as the one that this PR aims to solve. @scop May I ask why this pull request (PR) isn't reviewed for a long time even though all the other PRs after this have already received comments or have been merged? If something necessary to be reviewed is missing, could you please let me know that? (Note that the CI errors in this PR also happen in the master branch and all the other PRs so are not caused by this PR.) Thank you. |
Mainly because the code this PR touches is something a) I wish didn't exist in the first place, and b) I haven't ever dug into it to actually understand it in depth, and have trouble finding motivation for, kind of due to a). So I'm not in a place where I would be comfortable with reviewing this, and nobody else has stepped up. Those two mentioned things combined plus the fact that this PR does not contain any tests to reproduce the problem or to demonstrate the fix, and that we have close to zero existing coverage at least for this particular function in the test suite (it could be tested by some other tests, but I can't tell that offhand) makes it all too easy for this to slip under my radar. The thorough description is appreciated, but implementing that as tests for the test suite instead would be more that. Even more would be a PR that removes this stuff (ditto everything else that uses |
c0e9459
to
09307f8
Compare
a8110eb
to
a28fb29
Compare
@scop Sorry for the late reply. I was a bit busy recently. I have updated the PR. Could you now review the PR?
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your work, much happier with this now. Added some test code related wishes.
I actually have another question. If we want to perform tests in a specific directory, or if we want to perform the tests under a certain shell setting, what is the proper way to do that?
By the way, why is the environment variable bash-completion/test/t/conftest.py Lines 391 to 392 in 23382c0
|
Re working dir, the For shell settings, env changes etc, But then again, the above might not help much after all, depends :) Re temp dir usage, I've had the intention to look into using pytest's Re terminal size, I'm afraid I don't remember the details. Changing |
5a9fdf1
to
ac83f28
Compare
ac83f28
to
7232cc3
Compare
7232cc3
to
59ae8ff
Compare
I have updated the tests and rebased. I decided to perform the entire tests in Change to conftest.py No. 1 (cc55970): ensure to call the cleanup codesBefore modifying diff --git a/test/t/conftest.py b/test/t/conftest.py
index 3386b9ff..551f08a7 100644
--- a/test/t/conftest.py
+++ b/test/t/conftest.py
@@ -195,6 +195,8 @@ def bash(request) -> pexpect.spawn:
)
)
+ bash = None
+ try:
fixturesdir = os.path.join(testdir, "fixtures")
os.chdir(fixturesdir)
@@ -237,6 +239,7 @@ def bash(request) -> pexpect.spawn:
pass
else:
bash.close()
+ bash = None
pytest.skip(skipif)
xfail = marker.kwargs.get("xfail")
if xfail:
@@ -273,7 +276,9 @@ def bash(request) -> pexpect.spawn:
for post_cmd in marker.kwargs.get("post_cmds", []):
assert_bash_exec(bash, post_cmd, want_output=None)
+ finally:
# Clean up
+ if bash:
bash.close()
if logfile and logfile != sys.stdout:
logfile.close() Change to conftest.py No. 2 (426f855): Class decorator
|
When the tested command (i.e., the string sent to the Bash stdin) is longer than the terminal width, Bash will output
while
Because
OK. If it is not too hard, maybe I'll do that after this PR is settled. Thank you for your all comments so far. |
Awesome work, thanks for that, and your patience! |
I have a nagging feeling that overly wide terminal might cause issues related to receiving output from some commands. But I'm up to trying that out, guess we'd witness those pretty much instantly. PR's welcome :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you! I have a comment on a lint fix.
I have run the entire test by |
_quote_readline_by_ref
inbash_completion
has a problem similar to the code injection vulnerability. This PR solves the problem.Edit (2021-03-16): There was already a related issue #189, so let me mark as [ Fix #189 ].
Repeat-By
Here I describe a simple reproducer. With the following operation, a command
touch file
is unintendedly executed inside the completion function.In the above code block,
[TAB]
represents pressing TAB key. When TAB is pressed, the commandtouch file
is executed, which can be confirmed by an unintended new filefile
.For a more practical example (in which I noticed this problem), a file named
0.0
is created by the following operation:awk '$1 > 0.0[TAB]
Investigation
This is caused by the implementation of the function
_quote_readline_by_ref
:When the completed word has the form
'$...
, a commandcur=$...
is executed. First, inside the completion function,_quote_readline_by_ref
is called in the following ways:Then, after the first
printf %s
in_quote_readline_by_ref
, the variablecur
has the value such like$(touch file)
or$1 > 0.0
. Finally, in the last line of_quote_readline_by_ref
,cur=$(touch file)
orcur=$1 > 0.0
is executed.Fix
As described in the code comment, the purpose of the last line
[[ ${!2} == \$* ]] && eval $2=${!2}
seems to be the removal of the additional quote of the form$'string'
which would be only resulted fromprintf %q
. Here, I suggest moving the last line inside theif
statement so that the additional quote removal is only performed for the result ofprintf %q
.Thank you!