[PATCH libxxtrans 2/2] Fix alignment issues in FD passing code

Matthieu Herrb matthiey at herrb.eu
Mon Nov 11 22:21:19 PST 2013


On Mon, Nov 11, 2013 at 11:22:56PM +0100, Mark Kettenis wrote:
> From: Mark Kettenis <kettenis at openbsd.org>
> 
> A char array on the stack is not guaranteed to have more than byte
> alignment.  This means that casting it to a 'struct cmsghdr' and
> accessing its members may result in unaligned access.  This will
> generate SIGBUS on strict alignment architectures like OpenBSD/sparc64.
> The solution is to use a union to force proper alignment.
> 
> Signed-off-by: Mark Kettenis <kettenis at openbsd.org>

Reviewed-by: Matthieu Herrb <matthieu at herrb.eu>
> ---
>  Xtranssock.c | 16 ++++++++--------
>  1 file changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/Xtranssock.c b/Xtranssock.c
> index 0370119..fdf1dd7 100644
> --- a/Xtranssock.c
> +++ b/Xtranssock.c
> @@ -2197,9 +2197,9 @@ TRANS(SocketSendFdInvalid)(XtransConnInfo ciptr, int fd, int do_close)
>  
>  #define MAX_FDS		128
>  
> -struct fd_pass {
> +union fd_pass {
>  	struct cmsghdr	cmsghdr;
> -	int		fd[MAX_FDS];
> +	char		buf[CMSG_SPACE(MAX_FDS * sizeof(int))];
>  };
>  
>  #endif /* XTRANS_SEND_FDS */
> @@ -2225,13 +2225,13 @@ TRANS(SocketRead) (XtransConnInfo ciptr, char *buf, int size)
>              .iov_base = buf,
>              .iov_len = size
>          };
> -        char            cmsgbuf[CMSG_SPACE(sizeof(int) * MAX_FDS)];
> +        union fd_pass   cmsgbuf;
>          struct msghdr   msg = {
>              .msg_name = NULL,
>              .msg_namelen = 0,
>              .msg_iov = &iov,
>              .msg_iovlen = 1,
> -            .msg_control = cmsgbuf,
> +            .msg_control = cmsgbuf.buf,
>              .msg_controllen = CMSG_LEN(MAX_FDS * sizeof(int))
>          };
>  
> @@ -2266,13 +2266,13 @@ TRANS(SocketReadv) (XtransConnInfo ciptr, struct iovec *buf, int size)
>  
>  #if XTRANS_SEND_FDS
>      {
> -        char            cmsgbuf[CMSG_SPACE(sizeof(int) * MAX_FDS)];
> +        union fd_pass   cmsgbuf;
>          struct msghdr   msg = {
>              .msg_name = NULL,
>              .msg_namelen = 0,
>              .msg_iov = buf,
>              .msg_iovlen = size,
> -            .msg_control = cmsgbuf,
> +            .msg_control = cmsgbuf.buf,
>              .msg_controllen = CMSG_LEN(MAX_FDS * sizeof(int))
>          };
>  
> @@ -2308,7 +2308,7 @@ TRANS(SocketWritev) (XtransConnInfo ciptr, struct iovec *buf, int size)
>  #if XTRANS_SEND_FDS
>      if (ciptr->send_fds)
>      {
> -        char                    cmsgbuf[CMSG_SPACE(sizeof(int) * MAX_FDS)];
> +        union fd_pass           cmsgbuf;
>          int                     nfd = nFd(&ciptr->send_fds);
>          struct _XtransConnFd    *cf = ciptr->send_fds;
>          struct msghdr           msg = {
> @@ -2316,7 +2316,7 @@ TRANS(SocketWritev) (XtransConnInfo ciptr, struct iovec *buf, int size)
>              .msg_namelen = 0,
>              .msg_iov = buf,
>              .msg_iovlen = size,
> -            .msg_control = cmsgbuf,
> +            .msg_control = cmsgbuf.buf,
>              .msg_controllen = CMSG_LEN(nfd * sizeof(int))
>          };
>          struct cmsghdr          *hdr = CMSG_FIRSTHDR(&msg);
> -- 
> 1.8.4.2
> 
> _______________________________________________
> xorg-devel at lists.x.org: X.Org development
> Archives: http://lists.x.org/archives/xorg-devel
> Info: http://lists.x.org/mailman/listinfo/xorg-devel

-- 
Matthieu Herrb


More information about the xorg-devel mailing list