pointer subtraciton on arm for 8.3p1

Sandy Patterson xandey at gmail.com
Sat Jun 13 02:13:56 AEST 2020


Hi Damien,

Thanks for the suggestions. It seems someone beat me to the gcc bug:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81801
There are quite a lot of referenced bugs and it seems pointer subtraction over
the boundary is a tricky problem.

This one mentions other compilers doing similar things:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63303

There doesn't appear to be any resolution to the openssh bug, and they filed
it against gcc8. Something breaks on our system in gcc8+ so I don't
think i can test further
there.

-fwrapv does seem like a good workaround for us and it solves my
problem. I don't know
autotools well enough to propose a patch that sets this when necessary
and i'm not sure
you'd consider one anyway.

Sandy



On Thu, Jun 11, 2020 at 10:33 PM Damien Miller <djm at mindrot.org> wrote:
>
> On Thu, 11 Jun 2020, Sandy Patterson wrote:
>
> > I use OpenSSH server on an embedded arm using GCC7 cross toolchain. I
> > found that spamming connection attempts sometimes causes aborts in
> > sshd. Upon getting this up in gdb I found that the pointer subtraction
> > inside openbsd-compat/{strlcat.c,strlcpy.c} (and maybe elsewhere)
> > causes the 32 bit pointer difference to wrap which triggers the abort
> > because of the -ftrapv option.
> >
> > This example illustrates the problem, I get an abort when I compile
> > for 32 bit arm.
> >
> > > #include <stdio.h>
> > > int main(int argc, char** argv) {
> > >     char* src = (char*)0x7ffffec0;
> > >     char* s = (char*)0x80000049;
> > >     printf("%ld\n",s - src);
> > >     return 0;
> > > }
> >
> >
> > inside the strlcpy.c for example we have:
> > > return(s - src - 1); /* count does not include NUL */
> >
> > It is somewhat infrequent as the array has to straddle the 0x80000000 boundary.
> >
> > I can clearly disable hardening or hack out ftrapv from my system, but
> > was wondering if you guys have some advice on how to fix openssh for
> > this platform?
>
> Your compiler might be broken. C11 s6.5.6/9 says that pointer
> subtraction should work so long as 1) the pointers are to the same array
> object and 2) the difference must be representable in a ptrdiff_t. In
> this case, AFAIK both conditions are true (the pointers relate to the same
> array and the difference is <2^31).
>
> Now, I'm not sure whether the compiler problem is limited to ftrapv
> or is actually worse. Signed over/underflow is AFAIK undefined behaviour
> and the compiler is allowed to do all sorts of crazy stuff when it is
> encountered (including optimising away checks and creating security
> problems, e,g, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=30475)
>
> I'd suggest filing a gcc bug, and then trying a newer gcc or perhaps a
> recent clang, but I understand what a hassle that can be on embedded
> platforms.
>
> If you can't do this, then I'd recommend compiling *everything* with
> -fwrapv, that at least should remove the undefined behaviour element
> here. FWIW, OpenBSD makes -fwrapv the default in its toolchain.
>
> -d


More information about the openssh-unix-dev mailing list