Page 1 of 1

Is it possible to detect use of "unsafe" by inspecting the object code?

Posted: Mon Apr 06, 2020 10:59 am
by aclassifier
Is it possible to detect use of unsafe (etc.) by inspecting the object code?

This was a question that came to me just now when I sit here doing some blogging over that theme. Over this book, actually [1].

Could some external program be made to clinically analyse the binary image and see that there may be security holes? Assuming unsafe might constitute one of those.
Off Topic
Provided that it were possible to get the binary out of the xCORE chip. I always get

Code: Select all

Warning: F03098 Factory image and boot loader cannot be write-protected on flash device on node 0
but then that's ok for my boxes. I assume I would have to pay licence to get that enabled?
[1] The Huawei and Snowden Questions. Can Electronic Equipment from Untrusted Vendors be Verified? Can an Untrusted Vendor Build Trust into Electronic Equipment? by Olav Lysne (2017)

Re: Is it possible to detect use of "unsafe" by inspecting the object code?

Posted: Tue Apr 07, 2020 4:33 pm
by CousinItt
I'm not sure that it would be detectable in all cases: if the compiler can be sure that a safe pointer is being used safely then there would be no need to include any run-time overhead. If that safe pointer is then changed to an unsafe one, I don't see why the compiler would need to drop different code.

However, in the case that a safe pointer is used for access to an array and the compiler can't be sure of safe access, there has to be some run-time bounds-checking code included. See the XMOS programming guide 5.2.2.

Re: Is it possible to detect use of "unsafe" by inspecting the object code?

Posted: Tue Apr 07, 2020 4:51 pm
by aclassifier
Thanks!

But is an unsafe pointer any different from a safe pointer in the object code? I would be surprised if it were.

Plus, will the compiler always include bounds checking for an unsafe used unsafely?
Off Topic
I know I could do research and try to figure it out myself, but then I wouldn't be able to lean on the knowledge this forum has

Re: Is it possible to detect use of "unsafe" by inspecting the object code?

Posted: Wed Apr 08, 2020 4:49 pm
by CousinItt
As far as I know there's no difference in the way a pointer is stored - it's the code that uses it that would vary.

There's no checking for an unsafe pointer, whether it's used safely or not. An unsafe declaration is telling the compiler that you're taking responsibility.

Re: Is it possible to detect use of "unsafe" by inspecting the object code?

Posted: Wed Apr 08, 2020 6:43 pm
by aclassifier
Thanks, again. I conclude that it is not possible to be able to distinguish a potentially "safe" object image from a potentially "unsafe".

I don't even know enough about this to know if it would be possible. I assume the means then is to protect that image as much as possible by making it not accessible in some way or another, or not useful, even for somebody attempting to try a trojan strategy. I would be surprised if the xcore.ai (AIoT) architecture would not have some interesting things to add.

I am satisfied by having scratched the surface on this theme.

Thanks!

Re: Is it possible to detect use of "unsafe" by inspecting the object code?

Posted: Fri Apr 10, 2020 9:38 am
by fabriceo
Hi Guys, as you may know, unsafe pointer takes only 4 bytes memory whereas others takes 12. see code below for proof:

Code: Select all

void testptr(int *p){
    printf("sizeof p = %d\n",sizeof(p));  }

void testunsafe(int * unsafe p){
    printf("sizeof p = %d\n",sizeof(p)); }

void task1(){
int X = 3;
    testptr(&X);
    unsafe { testunsafe(&X); }

Re: Is it possible to detect use of "unsafe" by inspecting the object code?

Posted: Fri Apr 10, 2020 9:45 am
by aclassifier
No, I did not know! Great! Now we need to look at the instructions. I could do that today, if nobody beats me.

And then somebody could tell whether that unsafe pointer instruction is used elsewhere.

It is probably not very fruitful to proceed, but it is very interesting since it's always nice to know more than one thinks one need to know. So hang on!

Re: Is it possible to detect use of "unsafe" by inspecting the object code?

Posted: Sat Apr 11, 2020 1:55 pm
by CousinItt
Thanks fabriceo. Now I need to understand why.

Re: Is it possible to detect use of "unsafe" by inspecting the object code?

Posted: Sun Apr 12, 2020 10:04 am
by aclassifier
I did the following source from fabriceo's original code, and then compiled different versions.

I have attached the project and the two interesting results in two external directories, containing ..map.txt and .s and .xi files. Just download and do a compare.

I am not able to analyse the build files. But I see the for the safe version it does an out of range check of the pointer.

Might the not-unsafe pointer of 4*3 bytes contain the pointer plus full range (low and high)?

The .xi files just shows the difference in what's compiled.
The .s files are vastly different. I don't know the assembler, so I would be blank. I always get impressed by these files!
The ..map.txt files are equal except for one value: 000400f4 00000000 .text $d.46 or $d.59

I took out the printing for these builds, to hold that code away.
And I wanted to just do something (increment) to make sure(?) that the functions were not optimized away.
The code looks like this. I have stored away for TEST_SAFE 1 only and TEST_UNSAFE 1 only.

Code: Select all

 #include <stdio.h>    // printf

// ---
// Control printing
// See https://stackoverflow.com/questions/1644868/define-macro-for-debug-printing-in-c
// ---
#define DEBUG_PRINT_TEST 0
#define debug_print(fmt, ...) do { if(DEBUG_PRINT_TEST) printf(fmt, __VA_ARGS__); } while (0)

// See Fabriceo 10Apr2020 at https://xcore.com/viewtopic.php?f=26&t=7886#top

#define TEST_SAFE   0
#define TEST_UNSAFE 1

#if (TEST_SAFE == 1)
    void test_ptr (int *ptr) {
        debug_print ("sizeof ptr = %d\n",sizeof(ptr));
        *ptr++; // Just do something
    }
#endif

#if (TEST_UNSAFE == 1)
    void test_unsafe_ptr (int * unsafe ptr) {
        debug_print ("sizeof unsafe ptr = %d\n",sizeof(ptr));
        unsafe {
            *ptr++; // Just do something
        }
    }
#endif

// === Prints ===
// sizeof ptr = 12
// sizeof unsafe ptr = 4

void task1 () {
    int x_val = 0;

    #if (TEST_SAFE == 1)
        test_ptr (&x_val);
    #endif

    #if (TEST_UNSAFE == 1)
        unsafe {
            test_unsafe_ptr (&x_val);
        }
    #endif
}

// xTIMEcomposer 14.4.1
//     DEBUG_PRINT_TEST
//       TEST_SAFE
//         TEST_UNSUAFE
//     0 1 1   Constraints: C:8/1 T:10/1 C:32/0 M:2768 S:348 C:1972 D:448
//     1 1 1   Constraints: C:8/1 T:10/1 C:32/0 M:8320 S:596 C:7104 D:620
//     0 1 0   Constraints: C:8/1 T:10/1 C:32/0 M:2768 S:348 C:1972 D:448 strange
//     0 0 1   Constraints: C:8/1 T:10/1 C:32/0 M:2768 S:348 C:1972 D:448 strange
//     0 0 0   Constraints: C:8/1 T:10/1 C:32/0 M:880  S:348 C:456  D:76

// This costs no extra code, as compared to just making task1 the main
// But it looks more idiomatic XC:

int main() {
    par {
        task1 ();
    }
    return 0;
}