From: Rudolf Polzer <[email protected]>
If more than `BUF_SIZE-2` bytes are read from the user, appending a
newline and a zero byte overflows `userinputaux`, likely running into
`userinputready` which _looks_ at least harmless, but is still undefined
behavior. However, an assert exists to detect that and crash the engine:
```
$ perl -e 'syswrite STDOUT, "e4\n" x 5000' | src/gnuchess --uci
GNU Chess
gnuchess: engine.cc:520: void ForwardUserInputToEngine(): Assertion `nread+1 <
BUF_SIZE-1' failed.
zsh: done perl -e 'syswrite STDOUT, "e4\n" x 5000' |
zsh: IOT instruction src/gnuchess --uci
```
This change fixes the crash by reading the correct amount of bytes.
---
src/frontend/engine.cc | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/src/frontend/engine.cc b/src/frontend/engine.cc
index 85e15fb..e8fb3a2 100644
--- a/src/frontend/engine.cc
+++ b/src/frontend/engine.cc
@@ -514,15 +514,18 @@ void ForwardUserInputToEngine( void )
printf( "Error reading user input.\n" );
} else if ( userinputready > 0 ) {
/* There are some data from the user. Read the data */
- strncpy( userinputaux, zerochar, BUF_SIZE );
- nread = read( STDIN_FILENO, userinputaux, BUF_SIZE );
- /* Send the data to the engine */
- assert( nread+1 < BUF_SIZE-1 );
- if ( strcmp(userinputaux,"quit") == 0 || strcmp(userinputaux,"quit\n") ==
0 ) {
- SET (flags, QUIT);
+ nread = read( STDIN_FILENO, userinputaux, BUF_SIZE-2 );
+ if ( nread == -1 ) {
+ printf( "Error reading message from user.\n" );
+ return;
}
+ /* Send the data to the engine */
+ assert( nread <= BUF_SIZE-2 );
userinputaux[nread] = '\n';
userinputaux[nread+1] = '\0';
+ if ( strcmp(userinputaux,"quit\n") == 0 || strcmp(userinputaux,"quit\n\n")
== 0 ) {
+ SET (flags, QUIT);
+ }
int outError=0;
int msg_count=0;
msg_count = write( pipefd_a2e[1], userinputaux, nread+1 );
--
2.39.5