[vlc-devel] [PATCH 1/2] compat: Workaround sendmsg bug on some ArmV8 Android devices

Thomas Guillem thomas at gllm.fr
Fri Mar 29 13:38:38 CET 2019


On Fri, Mar 29, 2019, at 11:35, Hugo Beauzée-Luyssen wrote:
> On some devices (at least up to Android 6) sendmsg will return its error
> code on 32bits instead of 64.

Sad... Android 6 will still be supported by VLC 4.0, so we need the work-around for 4.0 and 3.0.

> Most likely some code is storing the ssize_t on a size_t, getting rid of
> the sign bit and therefore of the sign extension afterward.
> This causes us to use 0xFFFFFFFF as a very large number of bytes instead
> of an error.
> This patch works around the issue and assumes that 0xFFFFFFFF with a non
> 0 errno is an error and forces it to be returned on 64bits.
> ---
>  compat/sendmsg.c      | 24 ++++++++++++++++++++++++
>  configure.ac          |  3 +++
>  include/vlc_network.h |  6 ++++++
>  3 files changed, 33 insertions(+)
> 
> diff --git a/compat/sendmsg.c b/compat/sendmsg.c
> index 0b08ce0942..2ef542eb7b 100644
> --- a/compat/sendmsg.c
> +++ b/compat/sendmsg.c
> @@ -133,6 +133,30 @@ ssize_t sendmsg(int fd, const struct msghdr *msg, 
> int flags)
>      free(data);
>      return res;
>  }
> +#elif defined(__ANDROID__) && defined(__aarch64__)
> +
> +#undef sendmsg
> +
> +#include <sys/types.h>
> +#include <sys/socket.h>
> +
> +/**
> + * Since we bumped the NDK version from 14 to 18, some devices (at 
> least up to
> + * Android 6) are returning errors on 4 bytes, even though ssize_t is 
> actually
> + * 8 bytes. This causes `value < 0` checks to yield false, and 
> consider the value
> + * as a non error.
> + * As the patch lies in either the NDK or the Android kernel, or the 
> device libc
> + * we can only work around it. If errno is not 0 & we receive -1, on 
> 32bits or
> + * 64bits, we assume an error was returned.
> + */
> +ssize_t vlc_sendmsg(int fd, const struct msghdr *msg, int flags)
> +{
> +    errno = 0;
> +    ssize_t ret = sendmsg(fd, msg, flags);
> +    if ((ret < 0 || ret == 0xFFFFFFFF) && errno != 0)
> +        return -1;
> +    return ret;
> +}

I don't think this a good place for a vlc_ function. Indeed, the compat/ folder contains only functions with the original prototype.

>  
>  #else
>  #error sendmsg not implemented on your platform!
> diff --git a/configure.ac b/configure.ac
> index 1bd42678b8..0bb12f4305 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -402,6 +402,9 @@ AS_IF([test "$SYS" = linux],[
>      ],[
>        HAVE_ANDROID="1"
>        AC_MSG_RESULT([yes])
> +      AS_IF([test "${host_cpu}" = "aarch64"], [
> +          AC_LIBOBJ([sendmsg])
> +      ])
>      ],[
>        AC_MSG_RESULT([no])
>      ])
> diff --git a/include/vlc_network.h b/include/vlc_network.h
> index 7cc384587a..d75905ea3f 100644
> --- a/include/vlc_network.h
> +++ b/include/vlc_network.h
> @@ -280,6 +280,12 @@ static inline int net_GetPeerAddress( int fd, char 
> *address, int *port )
>  
>  VLC_API char *vlc_getProxyUrl(const char *);
>  
> +#if defined(__ANDROID__) && defined(__aarch64__)
> +struct msghdr;
> +ssize_t vlc_sendmsg(int fd, const struct msghdr *msg, int flags);
> +#define sendmsg(a, b, c) vlc_sendmsg(a,b,c)
> +#endif

Maybe put it here in a static inline ?

> +
>  # ifdef __cplusplus
>  }
>  # endif
> -- 
> 2.20.1
> 
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel


More information about the vlc-devel mailing list