On 01/25/13 09:14, Amos Kong wrote:
> FD_SET() and FD_CLR() are used to add and remove one descriptor from a
> set, the 'fd' should be less than FD_SETSIZE. Glibc will give a warning
> and crash the qemu when we set a fd (1024) to a set.
> 
>  # qemu -device virtio-net-pci,netdev=macvtap_netdev,mac=92:ff:8a:11:fe:57
>    -netdev tap,id=macvtap_netdev,fd=1024 1024<>/dev/tap4
> 
> *** buffer overflow detected ***: x86_64-softmmu/qemu-system-x86_64
> terminated
> ======= Backtrace: =========
> /lib64/libc.so.6(__fortify_fail+0x37)[0x7f842a2134a7]
> /lib64/libc.so.6(+0x35e9d08620)[0x7f842a211620]
> /lib64/libc.so.6(+0x35e9d0a417)[0x7f842a213417]
> x86_64-softmmu/qemu-system-x86_64(+0x1901fd)[0x7f842f09f1fd]
> x86_64-softmmu/qemu-system-x86_64(+0x198388)[0x7f842f0a7388]
> x86_64-softmmu/qemu-system-x86_64(main+0xfa9)[0x7f842ef897a9]
> /lib64/libc.so.6(__libc_start_main+0xf5)[0x7f842a12aa05]
> x86_64-softmmu/qemu-system-x86_64(+0x7ed49)[0x7f842ef8dd49]
> ======= Memory map: ========
> ....
> 
> This patch added limitations when init tap device and set fd handler
> for synchronous IO.
> 
> Signed-off-by: Amos Kong <ak...@redhat.com>
> ---
>  iohandler.c |    3 +++
>  net/tap.c   |    3 ++-
>  2 files changed, 5 insertions(+), 1 deletions(-)
> 
> diff --git a/iohandler.c b/iohandler.c
> index 2523adc..c22edab 100644
> --- a/iohandler.c
> +++ b/iohandler.c
> @@ -66,6 +66,9 @@ int qemu_set_fd_handler2(int fd,
>              }
>          }
>      } else {
> +        if (fd >= FD_SETSIZE) {
> +            return 1;
> +        }

qemu_set_fd_handler2() -- and consequently, qemu_set_fd_handler() --
could never fail before. I tried to check their call sites, and most of
those don't bother to check for the return value; they assume these
functions always succeed.

Wouldn't it be better to abort() here (or exit with an error message)
instead of returning 1? (Not suggesting, just asking.)

Thanks,
Laszlo

>          QLIST_FOREACH(ioh, &io_handlers, next) {
>              if (ioh->fd == fd)
>                  goto found;
> diff --git a/net/tap.c b/net/tap.c
> index eb40c42..be856dd 100644
> --- a/net/tap.c
> +++ b/net/tap.c
> @@ -618,7 +618,8 @@ int net_init_tap(const NetClientOptions *opts, const char 
> *name,
>          }
>  
>          fd = monitor_handle_fd_param(cur_mon, tap->fd);
> -        if (fd == -1) {
> +        if (fd == -1 || fd >= FD_SETSIZE) {
> +            error_report("Invalid fd : %d", fd);
>              return -1;
>          }
>  


Reply via email to