x86-64汇编read系统调用缓冲区溢出致Shell执行多余输入问题
x86-64汇编程序输入异常问题分析与修复
问题背景
在Linux x86-64汇编程序中,.bss段预留了16字节的name缓冲区用于读取用户姓名并输出问候信息。当输入字符超过16个时,多余的字符会被zsh立即执行。需要解答以下问题:
- 这是否属于缓冲区溢出?
- 为何多余字符会被执行而非程序崩溃?
- 这些字符存储在何处?
- 如何修复该问题?
程序源码
section .data question1 db "What is your name? " greeting db "Hello, " section .bss name resb 16 ; Reserve 16 bytes in memory for "name" section .text global _start ; 定义程序入口标签 _start: call _printQuestion call _getName call _printGreeting call _printName ; 调用sys_exit退出程序 mov rax, 60 ; sys_exit的系统调用号 mov rdi, 0 ; 错误码:0表示无错误 syscall ; 执行系统调用 _getName: mov rax, 0 ; sys_read的系统调用号 mov rdi, 0 ; 标准输入文件描述符 mov rsi, name mov rdx, 16 ; 最多读取16字节 syscall ret _printQuestion: mov rax, 1 ; sys_write的系统调用号 mov rdi, 1 ; 标准输出文件描述符 mov rsi, question1 mov rdx, 19 ; 输出字符串长度 syscall ret _printGreeting: mov rax, 1 mov rdi, 1 mov rsi, greeting mov rdx, 7 ; 输出字符串长度 syscall ret _printName: mov rax, 1 mov rdi, 1 mov rsi, name mov rdx, 16 ; 输出最多16字节 syscall ret
问题解答
1. 是否属于缓冲区溢出?
不属于传统意义上导致程序内存被破坏的缓冲区溢出。你的程序中sys_read明确指定了读取16字节,内核会严格按照这个长度将数据写入name缓冲区,不会超出16字节覆盖程序内存的其他区域。你看到的异常是终端输入缓冲区的剩余数据被shell读取执行的行为,并非程序内存溢出导致的代码执行。
2. 为何多余字符会被执行而非程序崩溃?
Linux终端默认处于行缓冲模式:用户输入的整行字符(直到按下回车)会先被内核tty子系统存入输入队列。你的程序调用sys_read只读取了前16字节,剩余字符仍留在内核的终端输入队列中。当程序调用sys_exit退出后,父进程zsh会恢复终端控制权,然后从输入队列中读取剩余字符,将其当作shell命令执行——这就是你看到“多余字符被立即执行”的原因,并非程序本身执行了这些字符。
3. 这些字符存储在何处?
- 程序读取的前16字节存储在
.bss段的name缓冲区中; - 未被程序读取的多余字符存储在**内核管理的终端输入队列(tty输入缓冲区)**里,不属于你的程序进程内存空间。
4. 如何修复该问题?
核心思路是在程序退出前清空终端输入队列中剩余的未读取字符,避免shell读取这些字符当作命令。可以在_start的sys_exit前添加以下逻辑:
; 清空终端输入缓冲区的剩余字符 _flushInput: mov rax, 0 ; sys_read系统调用号 mov rdi, 0 ; 标准输入文件描述符 mov rsi, name ; 复用name缓冲区(无需保存数据) mov rdx, 1 ; 每次读取1字节 syscall cmp al, 0xA ; 判断是否读到换行符(用户输入的回车) jne _flushInput ; 未读到换行则继续读取
修改后的_start部分:
_start: call _printQuestion call _getName call _printGreeting call _printName ; 清空终端输入缓冲区剩余字符 _flushInput: mov rax, 0 mov rdi, 0 mov rsi, name mov rdx, 1 syscall cmp al, 0xA jne _flushInput ; 退出程序 mov rax, 60 mov rdi, 0 syscall
这个逻辑会持续读取输入直到遇到换行符,把用户输入的整行剩余字符全部读完,程序退出后shell的输入队列即为空,不会执行多余字符。
内容的提问来源于stack exchange,提问作者L. Landgraf
相关产品推荐
相关产品推荐

