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

Technical questions regarding the xTIMEcomposer, xSOFTip Explorer and Programming with XMOS.
User avatar
aclassifier
Respected Member
Posts: 365
Joined: Wed Apr 25, 2012 8:52 pm

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

Postby aclassifier » Mon Apr 06, 2020 10:59 am

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)
--
Øyvind Teig
Trondheim (Norway)
https://www.teigfam.net/oyvind/home/
User avatar
CousinItt
XCore Addict
Posts: 178
Joined: Wed May 31, 2017 6:55 pm

Postby CousinItt » Tue Apr 07, 2020 4:33 pm

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.
User avatar
aclassifier
Respected Member
Posts: 365
Joined: Wed Apr 25, 2012 8:52 pm

Postby aclassifier » Tue Apr 07, 2020 4:51 pm

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
--
Øyvind Teig
Trondheim (Norway)
https://www.teigfam.net/oyvind/home/
User avatar
CousinItt
XCore Addict
Posts: 178
Joined: Wed May 31, 2017 6:55 pm

Postby CousinItt » Wed Apr 08, 2020 4:49 pm

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.
User avatar
aclassifier
Respected Member
Posts: 365
Joined: Wed Apr 25, 2012 8:52 pm

Postby aclassifier » Wed Apr 08, 2020 6:43 pm

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!
--
Øyvind Teig
Trondheim (Norway)
https://www.teigfam.net/oyvind/home/
fabriceo
Active Member
Posts: 40
Joined: Mon Jan 08, 2018 4:14 pm

Postby fabriceo » Fri Apr 10, 2020 9:38 am

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); }
User avatar
aclassifier
Respected Member
Posts: 365
Joined: Wed Apr 25, 2012 8:52 pm

Postby aclassifier » Fri Apr 10, 2020 9:45 am

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!
--
Øyvind Teig
Trondheim (Norway)
https://www.teigfam.net/oyvind/home/
User avatar
CousinItt
XCore Addict
Posts: 178
Joined: Wed May 31, 2017 6:55 pm

Postby CousinItt » Sat Apr 11, 2020 1:55 pm

Thanks fabriceo. Now I need to understand why.
User avatar
aclassifier
Respected Member
Posts: 365
Joined: Wed Apr 25, 2012 8:52 pm

Postby aclassifier » Sun Apr 12, 2020 10:04 am

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;
}
You do not have the required permissions to view the files attached to this post.
--
Øyvind Teig
Trondheim (Norway)
https://www.teigfam.net/oyvind/home/

Who is online

Users browsing this forum: No registered users and 3 guests