Re: sshd broken with UsePrivilegeSeparation=yes on sparc64

From: Michiel Boland <michiel_at_boland.org>
Date: Wed, 8 Aug 2007 02:04:49 +0200 (CEST)
On Sun, 15 Jul 2007, Poul-Henning Kamp wrote:

>>         fd = (*(int *)CMSG_DATA(cmsg));
>>
>> So, obviously a gcc bug. I will try to generate a smaller test-case for
>> this.
>
> I'm not convinced that CMSG_DATA is entirely kosher.

The problem with the openssh code appears to be the following.

In /usr/src/crypto/openssh/monitor_fdpass.c, there are two functions,
mm_receive_fd and mm_send_fd that do roughly the following

 int mm_receive_fd(int sock)
 {
        struct msghdr msg;
        char tmp[CMSG_SPACE(sizeof(int))];
        [...]
        msg.msg_control = tmp;
        msg.msg_controllen = sizeof(tmp);
        recvmsg(sock, &msg, 0);
        etc.

Now, there is no guarantee that the 'tmp' array is aligned on a word
boundary. Perhaps on i386/amd64, but not on sparc64.

As a hack-bandaid, you can more or less fix alignment with this patch

--- monitor_fdpass.c.orig	2006-11-10 17:38:34.000000000 +0100
+++ monitor_fdpass.c	2007-08-08 01:37:44.000000000 +0200
_at__at_ -91,7 +91,7 _at__at_
 	struct msghdr msg;
 	struct iovec vec;
 	ssize_t n;
-	char ch;
+	int ch;
 	int fd;
 #ifndef HAVE_ACCRIGHTS_IN_MSGHDR
 	char tmp[CMSG_SPACE(sizeof(int))];

then recompile /usr/src/secure/lib/libssh

A better solution would probably be something like using
 tmp = malloc(CMSG_SPACE(sizeof(int))])
to really guarantee alignment.

But I don't really understand why the original code did not crash with
SIGBUS or something, but just returned bogus values for fd.

Cheers
Michiel
Received on Tue Aug 07 2007 - 22:24:06 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:16 UTC