Edit: Title changed, as @Gunner pointed out that this is not a buffer overflow.
In reading user input from stdin
with NR_read
in Linux 64-bit Intel assembly, I wonder how can I avoid that the input that does not fit in the input buffer being sent to Linux shell eg. bash? For example in this example program I have defined an input buffer of 255 bytes (the size of the buffer can be whatever >= 1). The rest of an input longer than 255 bytes is sent to bash (if running from bash) and and this is obviously a serious vulnerability. How should input be read in Linux 64-bit assembly to avoid this vulnerability?
Here's my code:
[bits 64]
section .text
global _start
; can be compiled eg. with nasm or yasm.
; nasm:
; nasm -f elf64 read_stdin_64.asm; ld read_stdin_64.o -o read_stdin_64
; yasm:
; yasm -f elf64 -m amd64 read_stdin_64.asm -o read_stdin_64.o; ld read_stdin_64.o -o read_stdin_64
NR_read equ 0
NR_exit equ 60
STDIN equ 1
; input:
; rax number of syscall
; rdi parameter 1
; rsi parameter 2
; rdx parameter 3
; r10 parameter 4
; r8 parameter 5
; r9 parameter 6
;
; output:
; rax syscall's output
@do_syscall:
push rcx
push r11
syscall ; 64-bit syscall, overwrites rcx and r11
pop r11 ; syscall's return value in rax
pop rcx
ret
@read_stdin:
push rdi
push rsi
push rdx
mov rdi,STDIN ; file handle to read. STDIN = 1.
lea rsi,[input_buffer]
mov rdx,input_buffer_length ; length of string
mov rax,NR_read ; number of syscall (0)
call @do_syscall
sub rax,1 ; get the number of writable characters.
pop rdx
pop rsi
pop rdi
ret
_start: ; linker entry point
call @read_stdin
@end_program:
xor rdi,rdi
mov rax,NR_exit ; number of syscall (60)
syscall
section .data
input_buffer times 255 db 0
input_buffer_length equ $-input_buffer
input_buffer_length
in, you make sure it don't excess your buffer size. – J-16 SDiZinput_buffer_length
limits only the number of bytes to be read into my program. The rest of the input goes to Linux shell eg. bash and gets executed, and that is what I'm trying to avoid. In DOS most matters with keyboard could be handled with hooking the keyboard interrupt and using a custom keyboard interrupt, but it seems to me that that's not a correct way to do it in Linux (or is it even possible for non-root programs?). – nrz