swift overflow detection

The swift programming language takes a few steps forward for security in a number of areas over it’s predecessor Objective-C, which itself is a lot less of a footgun by design than C/C++.

One feature it has is by-default wrapping prevention for it’s Int values. The following code in Swift will cause an exception – you’ll break in a debugger or simply terminate the entire app if you’re running on iOS:

var i:Int8 = 100
i = i + 30

How does this work under the covers? The following screenshots from hopper show us a disassembly of the compiled binaries, in x64 and ARM.

swift_x64_2

In the above x64 disassembly, the constant 0x14 (20) is added to the low 8 bits of RAX (AL). The SETO instruction then sets the R8 register (R8B) conditionally if the previous ADD has caused an overflow. This value is then tested using TEST, and finally causes a conditional Jump to 0x100001532 if TEST showed R8 having been set (IE, there was an overflow).

The resulting jump if there has been an overflow is simply to UD2 – UnDefined instruction; raise an invalid opcode exception.

swift_overflow_arm

ARM follows a fairly similar path, with B.VS conditionally jumping based on overflow being set, branching out to a BRK; trigger a debug breakpoint.

Interestingly, both ARM and x64 in particular places use a full 64-bit register which is still capable of catching an overflow condition when the Swift data type is Int8 (IE triggers exception when incremented beyond 127) This likely is necessary to be synthesized on ARM due to a lack of access to lower 16 and 8 bits.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s