sshd broken with UsePrivilegeSeparation=yes on sparc64
Michiel Boland
michiel at boland.org
Tue Aug 7 17:24:06 PDT 2007
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
@@ -91,7 +91,7 @@
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
More information about the freebsd-current
mailing list