The following program (64-bit YASM) reads 4 bytes from the standard input and exits:
section .data
buf db " " ; Just allocate 16 bytes for string
section .text
global _start
_start:
mov rax, 0 ; READ syscall
mov rdi, 0 ; STDIN
mov rsi, buf ; Address of the string
mov rdx, 4 ; How many bytes to read
syscall
; Exit:
mov rax, 60
mov rdi, 0
syscall
Once compiled
yasm -f elf64 -l hello.lst -o input.o input.asm
ld -o input input.o
If it is run just as
./input
with, say, 123456\n as user input, it will consume 1234, but the end bit, 56\n is sent to bash. So, bash will try to run the command 56... thankfully unsuccessfully. But imagine if the input were 1234rm -f *. However, if I provide the input using re-direction or piping, for example,
echo "123456" | ./input
56 is not sent to bash.
So, how can I prevent unconsumed input to be sent to bash? Do I need to keep consuming it until EOF in some form is encountered? Is this even expected behavior?
The same thing happens in a C program:
#include <unistd.h>
int main()
{
char buf[16];
read(0, buf, 4);
return 0;
}
(I was just wondering if C runtime was somehow clearing STDIN, but no, it doesn't)