[PATCH] vi: discover window size even on serial consoles

Rob Landley rob at landley.net
Tue Apr 27 05:31:06 UTC 2010


On Monday 26 April 2010 07:36:59 Denys Vlasenko wrote:
> On Thu, Apr 22, 2010 at 6:39 AM, Rob Landley <rob at landley.net> wrote:
> > Admittedly a specific narrow race condition in the pattern of user input
> > (not the cat stuff above which would be inputting data while the prompt
> > printed) can type something like "x" "enter" and have a spurious escape
> > sequence fed to x. But the same is true if you typo a key like "cursor
> > up" after hitting enter. Not the end of the world.
>
> The race is not narrow at all.
>
> "sleep 1; ash" + hold down [Enter] is quite an easy way to make ash emit
> the "where is cursor" sequence, then see '\n' on input,

Not if ash peeks the input before emitting the sequence, and only emits the 
sequence when there's no pending input.  We know how to do this because the VI 
escape sequence parsing code currently does a time-sensitive peek for escape 
sequence assembly.  It behaves differently when input is waiting vs when no 
input is waiting.

So if they start typing during the sleep 1, then the input is buffered and 
waiting as soon as ash starts looking for it.  So the race only happens when 
they produce _new_ input between the time ash emits the sequence and the time 
ash reads back the result, and it only matters if that input includes a 
newline, and if _all_ they typed is a newline then it's a blank line and ash 
gets control back immediately.  That's the "narrow window" I was referring to.

Also, after the first time ash gets a response, it can set a flag saying to 
expect that response, so technicaly if you wanted to get fancy ash could emit 
the newline at the first significant (1/10th second, or 0 if we peek and get no 
input right at the start) pause in each line's command input, and then 
continue reading after the newline until it gets the sequence because it can 
depend on it being there.  So if in the oddball corner case that:

A) Their input prompt isn't left justified because the previous thing left 
debris on the screen without a newline.
B) They already started typing input before they got the prompt

We could still allow them to backspace properly at the end of the line.  And 
then even if they've _almost_ finished typing the new line, with only the enter 
left, and they hit enter right as we send the query sequence, we could still 
expect and consume the query sequence if it's the next thing right after the 
newline.

(And if the next character we read isn't escape, or we get nothing for 1/3 
second despite having a pause in the input at the right spot to trigger the 
pathological probing case, we pass the rest of the input on to the child 
program unmolested.)

(Oh, the 1/10th second pause mentioned above is just in case serial input de-
aggregates what's otherwise a continuous stream again, ala getting vi cursor 
parsing right.)

I'm not saying it's perfect, but I'm saying the race condition can be narrowed 
to a really obscure window, and the downside of it triggering isn't the end of 
the world.

> and have no choice
> but stop reading and execute the command even though ash has strong
> suspicion that next input chars will be the answerback sequence.
> ash can't peek ahead and read it - what if it will see something
> different??!! That would destroy next command's input - BAD.

That would only happen if A) We'd seen the probe responses before (would that 
ever be the case if the shell was running as a tcl/expect slave process?), B) 
we had a specific series of pauses in the input to trigger the behavior (so it 
won't happen for cat shellscript.sh | /bin/sh), C) we've already polluted the 
next command's input so are more likely to fix it by extracting expected data 
than damage it by reading unexpected data.

> In this particular case, though, it narrowly escapes, since command is
> an empty string, and ash goes back to reading next command instead of
> running a real, input-eating command like "cat".
>
> But think about "sleep 1; ash" + paste "cat\ncat\ncat\ncat\n" with mouse...
> KABOOM.

In which case the peeking behavior tells us whether or not there is input 
waiting so we can avoid sending the probe in the first place when we know the 
probe reply won't be the next thing we read.

Rob
-- 
Latency is more important than throughput. It's that simple. - Linus Torvalds


More information about the busybox mailing list