qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 07/10] linux-user: unix sockets - fix running db


From: Aurelien Jarno
Subject: Re: [Qemu-devel] [PATCH 07/10] linux-user: unix sockets - fix running dbus
Date: Wed, 15 Apr 2009 18:14:00 +0200
User-agent: Mutt/1.5.18 (2008-05-17)

On Sun, Apr 05, 2009 at 11:59:23PM +0300, address@hidden wrote:
> From: Riku Voipio <address@hidden>
> 
> dbus sends too short (according to man 7 unix) addrlen for it's
> unix socket. I've been told that happens with other applications
> as well. Linux kernel doesn't appear to mind, so I guess
> we whould be tolerant as well. Expand sockaddr with +1 to fit
> the \0 of the pathname passed.
> 
> (scratchbox1 qemu had a very different workaround for the same issue).
> 
> Signed-off-by: Riku Voipio <address@hidden>
> ---
>  linux-user/syscall.c |   29 +++++++++++++++++++++++++++--
>  1 files changed, 27 insertions(+), 2 deletions(-)

Thanks, applied.

> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 30bb617..8d1d12b 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -44,6 +44,7 @@
>  #include <signal.h>
>  #include <sched.h>
>  #include <sys/socket.h>
> +#include <sys/un.h>
>  #include <sys/uio.h>
>  #include <sys/poll.h>
>  #include <sys/times.h>
> @@ -735,13 +736,37 @@ static inline abi_long target_to_host_sockaddr(struct 
> sockaddr *addr,
>                                                 abi_ulong target_addr,
>                                                 socklen_t len)
>  {
> +    const socklen_t unix_maxlen = sizeof (struct sockaddr_un);
> +    sa_family_t sa_family;
>      struct target_sockaddr *target_saddr;
>  
>      target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
>      if (!target_saddr)
>          return -TARGET_EFAULT;
> +
> +    sa_family = tswap16(target_saddr->sa_family);
> +
> +    /* Oops. The caller might send a incomplete sun_path; sun_path
> +     * must be terminated by \0 (see the manual page), but
> +     * unfortunately it is quite common to specify sockaddr_un
> +     * length as "strlen(x->sun_path)" while it should be
> +     * "strlen(...) + 1". We'll fix that here if needed.
> +     * Linux kernel has a similar feature.
> +     */
> +
> +    if (sa_family == AF_UNIX) {
> +        if (len < unix_maxlen && len > 0) {
> +            char *cp = (char*)target_saddr;
> +
> +            if ( cp[len-1] && !cp[len] )
> +                len++;
> +        }
> +        if (len > unix_maxlen)
> +            len = unix_maxlen;
> +    }
> +
>      memcpy(addr, target_saddr, len);
> -    addr->sa_family = tswap16(target_saddr->sa_family);
> +    addr->sa_family = sa_family;
>      unlock_user(target_saddr, target_addr, 0);
>  
>      return 0;
> @@ -1195,7 +1220,7 @@ static abi_long do_bind(int sockfd, abi_ulong 
> target_addr,
>      if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
>          return -TARGET_EINVAL;
>  
> -    addr = alloca(addrlen);
> +    addr = alloca(addrlen+1);
>  
>      target_to_host_sockaddr(addr, target_addr, addrlen);
>      return get_errno(bind(sockfd, addr, addrlen));
> -- 
> 1.6.2.1
> 
> 
> 
> 

-- 
Aurelien Jarno                          GPG: 1024D/F1BCDB73
address@hidden                 http://www.aurel32.net




reply via email to

[Prev in Thread] Current Thread [Next in Thread]