[Bug 223653] Extremely serious string manipulation problem in -HEAD

bugzilla-noreply at freebsd.org bugzilla-noreply at freebsd.org
Mon Nov 13 15:38:40 UTC 2017


https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=223653

            Bug ID: 223653
           Summary: Extremely serious string manipulation problem in -HEAD
           Product: Base System
           Version: CURRENT
          Hardware: arm64
                OS: Any
            Status: New
          Severity: Affects Some People
          Priority: ---
         Component: arm
          Assignee: freebsd-arm at FreeBSD.org
          Reporter: karl at denninger.net

Take the following tiny code snippet:

#include        <stdio.h>
#include        <string.h>

int     main(argc, argv)
int     argc;
char    *argv[];

{
        char    tmp[132];
        char    tmp2[132];

        strcpy(tmp, "00 01 02 03 04 05 06");

        printf("First: [%s]\n", tmp);

        strcpy(tmp, &tmp[3]);
        printf("Second: [%s]\n", tmp);

        strcpy(tmp, &tmp[3]);
        printf("Third: [%s]\n", tmp);

        strcpy(tmp, &tmp[3]);
        printf("Fourth: [%s]\n", tmp);

        strcpy(tmp, "00 01 02 03 04 05 06");

        printf("2-First: [%s]\n", tmp);

        strcpy(tmp2, &tmp[3]);
        strcpy(tmp, tmp2);
        printf("2-Second: [%s]\n", tmp);

        strcpy(tmp2, &tmp[3]);
        strcpy(tmp, tmp2);
        printf("2-Third: [%s]\n", tmp);

        strcpy(tmp2, &tmp[3]);
        strcpy(tmp, tmp2);
        printf("2-Fourth: [%s]\n", tmp);
}


Compile it on FreeBSD 12.0-CURRENT #0 r325754: Mon Nov 13 08:02:13 CST 2017 on
an RPI3 and run it.

root at rpi3:/data/HD-MCP # ./test2
First: [00 01 02 03 04 05 06]
Second: [02 04 05 05 06 06]
Third: [04 05 05 06 06]
Fourth: [05 05 06 06]
2-First: [00 01 02 03 04 05 06]
2-Second: [01 02 03 04 05 06]
2-Third: [02 03 04 05 06]
2-Fourth: [03 04 05 06]
root at rpi3:/data/HD-MCP #

Yes, I'm aware that strcpy with overlapping strings is not safe in all
instances (strcpy is of course unsafe if the source can be longer than where
you are copying into) but historically it has been safe when used to remove
some number of bytes from the left side ("front") of a string as the
destination cannot overflow and on a byte-wise copy code that is generated it
stops as expected after the trailing null is copied over.

There's also no note in the current man page that this is unsafe.  Rewriting
the strcpys to use memmove corrects the above problem (memmove specifically is
ok to use in all cases of overlapping storage of course) but this change is
likely to bite a material number of people and has not been a problem on any
architecture I've seen under FreeBSD until fairly recently (it did not cause
problems with a February build of -HEAD on the RPI3/arm64, for example.)

I note that if I try to link OPENSSL into a piece of code I have here I get a
trap immediately on an "illegal opcode" when I try to execute the resulting
binary, which may be due to this happening somewhere in the initialization
code.  I get no frame labels on the backtrace, and the trap occurs before
main() starts executing (a breakpoint set on the first actual instruction in
main() fails to be reached) so unfortunately I do not have a better trace on
what's going on.  I suspect the behavior above, or some other artifact of the
same change, is responsible for the below; the code in question has been
running on an RPI2 (which right now I am using under FreeBSD 11.0-STABLE #1
r313159M) and various Intel (i386 and Amd64) architectures, also under
11-Stable, for a long period of time:

root at rpi3:/data/HD-MCP # lldb hd-mcp
(lldb) target create "hd-mcp"
Current executable set to 'hd-mcp' (aarch64).
(lldb) run -n
Process 924 launching
Process 924 launched: '/data/HD-MCP/hd-mcp' (aarch64)
Process 924 stopped
* thread #1, name = 'hd-mcp', stop reason = signal SIGILL: illegal trap
    frame #0: 0x00000000403342e8
->  0x403342e8: .long  0x0ee0e000                ; unknown opcode
    0x403342ec: ret
    0x403342f0: stp    x28, x19, [sp, #-0x20]!
    0x403342f4: stp    x29, x30, [sp, #0x10]
(lldb) bt
* thread #1, name = 'hd-mcp', stop reason = signal SIGILL: illegal trap
  * frame #0: 0x00000000403342e8
    frame #1: 0x0000000040082ad8
    frame #2: 0x0000000040081ab4
(lldb)

If I leave OpenSSL out (I have a "no security" version that #ifdef's it out)
then the code compiles and runs fine.

-- 
You are receiving this mail because:
You are the assignee for the bug.


More information about the freebsd-arm mailing list