Understanding Undefined Behavior

Similar documents
Finding Bugs Using Xcode Runtime Tools

Thread Sanitizer and Static Analysis

Advanced Debugging and the Address Sanitizer

A program execution is memory safe so long as memory access errors never occur:

Static Analysis in C/C++ code with Polyspace

Undefined Behaviour in C

C++ Undefined Behavior What is it, and why should I care?

Verification & Validation of Open Source

C and C++ Secure Coding 4-day course. Syllabus

What s New in Xcode App Signing

C++ Undefined Behavior

Optimizing Swift Performance Session 409

CS527 Software Security

A brief introduction to C programming for Java programmers

Buffer overflow prevention, and other attacks

Memory Safety for Embedded Devices with nescheck

Pointers. 1 Background. 1.1 Variables and Memory. 1.2 Motivating Pointers Massachusetts Institute of Technology

Using and Extending the Xcode Source Editor

Black Hat Webcast Series. C/C++ AppSec in 2014

Introduction to Programming Using Java (98-388)

Introduce C# as Object Oriented programming language. Explain, tokens,

Using Grouped Notifications

Principles of Software Construction: Objects, Design, and Concurrency (Part 2: Designing (Sub )Systems)

C#: framework overview and in-the-small features

CSE 565 Computer Security Fall 2018

Synopsys Static Analysis Support for SEI CERT C Coding Standard

What s New in Swift #WWDC18. Ted Kremenek, Languages & Runtimes Manager Slava Pestov, Swift Compiler Engineer

Page 1. Stuff. Last Time. Today. Safety-Critical Systems MISRA-C. Terminology. Interrupts Inline assembly Intrinsics

[0569] p 0318 garbage

Lecture 9 Assertions and Error Handling CS240

Honours/Master/PhD Thesis Projects Supervised by Dr. Yulei Sui

Your Apps and the Future of macos Security

CPSC 3740 Programming Languages University of Lethbridge. Data Types

Overview AEG Conclusion CS 6V Automatic Exploit Generation (AEG) Matthew Stephen. Department of Computer Science University of Texas at Dallas

Pierce Ch. 3, 8, 11, 15. Type Systems

MISRA-C. Subset of the C language for critical systems

Object Oriented Programming Exception Handling

CS 430 Spring Mike Lam, Professor. Data Types and Type Checking

AP COMPUTER SCIENCE JAVA CONCEPTS IV: RESERVED WORDS

Metal for OpenGL Developers

Building Faster in Xcode

Core ML in Depth. System Frameworks #WWDC17. Krishna Sridhar, Core ML Zach Nation, Core ML

BASIC COMPUTATION. public static void main(string [] args) Fundamentals of Computer Science I

Optimizing for Bugs Fixed

Page 1. Today. Last Time. Is the assembly code right? Is the assembly code right? Which compiler is right? Compiler requirements CPP Volatile

Low level security. Andrew Ruef

Pointers and Memory 1

Outline. Classic races: files in /tmp. Race conditions. TOCTTOU example. TOCTTOU gaps. Vulnerabilities in OS interaction

Important From Last Time

Lecture Notes on Memory Layout

BIT Java Programming. Sem 1 Session 2011/12. Chapter 2 JAVA. basic

18-642: Code Style for Compilers

Enabling Your App for CarPlay

Type Checking and Type Equality

Introducing On Demand Resources

MEMORY MANAGEMENT TEST-CASE GENERATION OF C PROGRAMS USING BOUNDED MODEL CHECKING

Copyright 2015 MathEmbedded Ltd.r. Finding security vulnerabilities by fuzzing and dynamic code analysis

Vector and Free Store (Pointers and Memory Allocation)

G52CPP C++ Programming Lecture 7. Dr Jason Atkin

What s New in MapKit. App Frameworks #WWDC17. Fredrik Olsson

Undefined Behavior is Not an Error. Barbara Geller & Ansel Sermersheim C++ London 2019

CSC System Development with Java. Exception Handling. Department of Statistics and Computer Science. Budditha Hettige

What s New in Core Data?

Hacking in C. Pointers. Radboud University, Nijmegen, The Netherlands. Spring 2019

Important From Last Time

SoK: Eternal War in Memory

Page 1. Today. Important From Last Time. Is the assembly code right? Is the assembly code right? Which compiler is right?

Lecture 07 Debugging Programs with GDB

CS-527 Software Security

C Language Part 1 Digital Computer Concept and Practice Copyright 2012 by Jaejin Lee

Important From Last Time

In Java we have the keyword null, which is the value of an uninitialized reference type

Chapter 1 GETTING STARTED. SYS-ED/ Computer Education Techniques, Inc.

EXP54-CPP. Do not access an object outside of its lifetime

INITIALISING POINTER VARIABLES; DYNAMIC VARIABLES; OPERATIONS ON POINTERS

Secure Programming. An introduction to Splint. Informatics and Mathematical Modelling Technical University of Denmark E

RELIABLE SOFTWARE SYSTEMS

Pointers, Dynamic Data, and Reference Types

The Compiler So Far. CSC 4181 Compiler Construction. Semantic Analysis. Beyond Syntax. Goals of a Semantic Analyzer.

CSI33 Data Structures

What s New in Testing

Introduction To C#.NET

Secure Programming I. Steven M. Bellovin September 28,

Putting the Checks into Checked C

Lectures 5-6: Introduction to C

Lecture 3 Notes Arrays

UNDEFINED BEHAVIOR IS AWESOME

ESBMC 1.22 (Competition Contribution) Jeremy Morse, Mikhail Ramalho, Lucas Cordeiro, Denis Nicole, Bernd Fischer

Buffer overflow background

Strings Investigating Memory Allocation Pointers Fixed-Point Arithmetic. Memory Matters. Embedded Systems Interfacing.

Chapter 17 vector and Free Store. Bjarne Stroustrup

TYPES, VALUES AND DECLARATIONS

Securing Software Applications Using Dynamic Dataflow Analysis. OWASP June 16, The OWASP Foundation

Managing Documents In Your ios Apps

What s New in LLDB. Debug your way to fame and glory #WWDC15. Developer Tools. Session 402

18-642: Code Style for Compilers

Announcements. 1. Forms to return today after class:

Engineering for Testability

Introduction. Background. Document: WG 14/N1619. Text for comment WFW-1 of N1618

Media and Gaming Accessibility

Transcription:

Session Developer Tools #WWDC17 Understanding Undefined Behavior 407 Fred Riss, Clang Team Ryan Govostes, Security Engineering and Architecture Team Anna Zaks, Program Analysis Team 2017 Apple Inc. All rights reserved. Redistribution or public display not permitted without written permission from Apple.

What is undefined behavior? The compiler and undefined behavior Security implications Tools can help Swift is safer by default

What Is Undefined Behavior?

undefined behavior: behavior for which this International Standard imposes no requirements. ISO C++14 Standard

What Can the Compiler Do with Undefined Behavior?

What Can the Compiler Do with Undefined Behavior? Diagnose using warnings or errors

What Can the Compiler Do with Undefined Behavior? Diagnose using warnings or errors Act in a documented manner

What Can the Compiler Do with Undefined Behavior? Diagnose using warnings or errors Act in a documented manner Produce unpredictable results

Shift by negative value Modification of a string literal Type mismatch Signed integer overflow Invalid conversions Invalid enum value Out-of-bounds array subscript Data races NULL dereference Use of uninitialized values C++ dynamic type violation Division by 0 Shift amounts bigger than type Misaligned access Access to an object past end of lifetime Missing return statement

Undefined Behavior Is About Tradeoffs Performance over safety

Some Undefined Behavior Examples Use of an uninitialized variable int uninitialized_variable(int arg) { int value; if (arg <= 0) value = 42; } return arg + value;

Some Undefined Behavior Examples Use of an uninitialized variable int uninitialized_variable(int arg) { int value; if (arg <= 0) value = 42; } return arg + value;

Some Undefined Behavior Examples Use of an uninitialized variable int uninitialized_variable(int arg) { int value; if (arg <= 0) value = 42; } return arg + value;

Some Undefined Behavior Examples Use of an uninitialized variable int uninitialized_variable(int arg) { int value; if (arg <= 0) value = 42; } return arg + value;

Some Undefined Behavior Examples Use of an uninitialized variable int uninitialized_variable(int arg) { int value; if (arg <= 0) value = 42; Variable value is used uninitialized whenever the if condition is false } return arg + value; Compiler warnings

Some Undefined Behavior Examples Use of an uninitialized variable int uninitialized_variable(int arg) { int value; if (arg <= 0) value = 42; Variable value is used uninitialized whenever the if condition is false } return arg + value; Compiler warnings Static analyzer

Some Undefined Behavior Examples Misaligned pointers char *serialize_misaligned(char *buffer, int a, int b) { *(int *)buffer = a; buffer += sizeof(a); *(int *)buffer = b; buffer += sizeof(b); return buffer; } Keep this brace MM!

Some Undefined Behavior Examples Misaligned pointers char *serialize_misaligned(char *buffer, int a, int b) { *(int *)buffer = a; buffer += sizeof(a); *(int *)buffer = b; buffer += sizeof(b); return buffer; } Keep this brace MM!

Some Undefined Behavior Examples Misaligned pointers char *serialize_misaligned(char *buffer, int a, int b) { *(int *)buffer = a; buffer += sizeof(a); *(int *)buffer = b; buffer += sizeof(b); return buffer; } Keep this brace MM!

Some Undefined Behavior Examples Misaligned pointers char *serialize_misaligned(char *buffer, int a, int b) { *(int *)buffer = a; buffer += sizeof(a); *(int *)buffer = b; buffer += sizeof(b); return buffer; } Keep this brace MM! buffer int a int b

Some Undefined Behavior Examples Misaligned pointers char *serialize_misaligned(char *buffer, int a, int b) { *(int *)buffer = a; buffer += sizeof(a); *(int *)buffer = b; buffer += sizeof(b); return buffer; } Keep this brace MM! buffer int a int b

Some Undefined Behavior Examples Misaligned pointers char *serialize_misaligned(char *buffer, int a, int b) { *(int *)buffer = a; buffer += sizeof(a); *(int *)buffer = b; buffer += sizeof(b); return buffer; } Keep this brace MM! buffer int a int b

Some Undefined Behavior Examples Misaligned pointers char *serialize_misaligned(char *buffer, int a, int b) { *(int *)buffer = a; buffer += sizeof(a); *(int *)buffer = b; buffer += sizeof(b); return buffer; } Keep this brace MM! buffer int a int b

Some Undefined Behavior Examples Misaligned pointers char *serialize_misaligned(char *buffer, int a, int b) { *(int *)buffer = a; Store of misaligned address 0x7fff5fbff642 for type 'int', which requires 4 byte alignment buffer += sizeof(a); *(int *)buffer = b; Store of misaligned address 0x7fff5fbff646 for type 'int', which requires 4 byte alignment buffer += sizeof(b); return buffer; } Keep this brace MM! Undefined Behavior Sanitizer

Some Undefined Behavior Examples Access to an object past end of lifetime int lifetime_issue(int *value) { if (value == NULL) { int default_value = 42; value = &default_value; } return *value; }

Some Undefined Behavior Examples Access to an object past end of lifetime int lifetime_issue(int *value) { if (value == NULL) { int default_value = 42; value = &default_value; } return *value; }

Some Undefined Behavior Examples Access to an object past end of lifetime int lifetime_issue(int *value) { if (value == NULL) { int default_value = 42; value = &default_value; } return *value; }

Some Undefined Behavior Examples Access to an object past end of lifetime int lifetime_issue(int *value) { if (value == NULL) { int default_value = 42; value = &default_value; } return *value; } Thread 1: Use of out of scope stack memory Address Sanitizer

The Compiler and Undefined Behavior

Undefined Behavior Provides Information

Undefined Behavior Provides Information Undefined Behavior Information Signed integers cannot overflow x < x+1

Undefined Behavior Provides Information Undefined Behavior Information Signed integers cannot overflow x < x+1 Pointers are naturally aligned Can use vector instructions

Undefined Behavior Provides Information Undefined Behavior Information Signed integers cannot overflow x < x+1 Pointers are naturally aligned Can use vector instructions NULL cannot be dereferenced A dereferenced pointer cannot be NULL

Undefined Behavior Provides Information Undefined Behavior Information Signed integers cannot overflow x < x+1 Pointers are naturally aligned Can use vector instructions NULL cannot be dereferenced A dereferenced pointer cannot be NULL

The Compiler Executes an Optimization Pipeline Analyze Source code.c,.m,.cpp,.mm Intermediate representation Optimize Object file.o

Dereferencing NULL Might Not Always Crash Source code.c,.m,.cpp,.mm Dead Code Compiler 2 Elimination Object file.o

Dereferencing NULL Might Not Always Crash Source code.c,.m,.cpp,.mm Dead Code Compiler 2 Elimination Object file.o int foo(int *P) { int var = *P; return 42; } Keep the closing brace MM

Dereferencing NULL Might Not Always Crash Source code.c,.m,.cpp,.mm Dead Code Compiler 2 Elimination Object file.o int foo(int *P) { int var = *P; return 42; } Keep the closing brace MM Dead Code Elimination int foo(int *P) { int var = *P; return 42; } KeepM

Dereferencing NULL Might Not Always Crash Source code.c,.m,.cpp,.mm Dead Code Compiler 2 Elimination Object file.o int foo(int *P) { int var = *P; return 42; } Keep the closing brace MM Dead Code Elimination int foo(int *P) { return 42; } KeepM

Let s Experiment: A Very Simple Optimization Pipeline Compiler 1 Source code.c,.m,.cpp,.mm Redundant Null Compiler 2 Check Elimination Dead Code Elimination Object file.o void contains_null_check(int *P) { int unused = *P; Hidden text for MM if (P == NULL) return; *P = 4; } Keep the closing brace MM

Let s Experiment: A Very Simple Optimization Pipeline Compiler 1 Source code.c,.m,.cpp,.mm Redundant Null Compiler 2 Check Elimination Dead Code Elimination Object file.o void contains_null_check(int *P) { int unused = *P; Hidden text for MM if (P == NULL) return; *P = 4; } Keep the closing brace MM

Let s Experiment: A Very Simple Optimization Pipeline Compiler 1 Source code.c,.m,.cpp,.mm Redundant Null Compiler 2 Check Elimination Dead Code Elimination Object file.o void contains_null_check(int *P) { int unused = *P; Hidden text for MM if (P == NULL) return; *P = 4; } Keep the closing brace MM Redundant Null Check Elimination void contains_null_check(int *P) { int unused = *P; Hidden text for MM if (P == NULL) return; *P = 4; } Keep the brace in MM

Let s Experiment: A Very Simple Optimization Pipeline Compiler 1 Source code.c,.m,.cpp,.mm Redundant Null Compiler 2 Check Elimination Dead Code Elimination Object file.o void contains_null_check(int *P) { int unused = *P; Hidden text for MM if (P == NULL) return; *P = 4; } Keep the closing brace MM Redundant Null Check Elimination void contains_null_check(int *P) { int unused = *P; Hidden text for MM *P = 4; } Keep the brace in MM

Let s Experiment: A Very Simple Optimization Pipeline Compiler 1 Source code.c,.m,.cpp,.mm Redundant Null Compiler 2 Check Elimination Dead Code Elimination Object file.o void contains_null_check(int *P) { int unused = *P; Hidden text for MM *P = 4; } Keep the brace in MM

Let s Experiment: A Very Simple Optimization Pipeline Compiler 1 Source code.c,.m,.cpp,.mm Redundant Null Compiler 2 Check Elimination Dead Code Elimination Object file.o void contains_null_check(int *P) { int unused = *P; Hidden text for MM *P = 4; } Keep the brace in MM Dead Code Elimination void contains_null_check(int *P) { int unused = *P; Hidden text for MM *P = 4; } Keep closing brace in MM

Let s Experiment: A Very Simple Optimization Pipeline Compiler 1 Source code.c,.m,.cpp,.mm Redundant Null Compiler 2 Check Elimination Dead Code Elimination Object file.o void contains_null_check(int *P) { int unused = *P; Hidden text for MM *P = 4; } Keep the brace in MM Dead Code Elimination void contains_null_check(int *P) { Hidden text for MM *P = 4; } Keep closing brace in MM

Let s Experiment: A Very Simple Optimization Pipeline Compiler 1 Source code.c,.m,.cpp,.mm Redundant Null Compiler 2 Check Elimination Dead Code Elimination Object file.o void contains_null_check(int *P) { int unused = *P; Hidden text for MM if (P == NULL) return; *P = 4; } Keep brace during MM Compiler 1 void contains_null_check(int *P) { Hidden text for MM *P = 4; } Keep closing brace in MM

Let s Experiment: A Very Simple Optimization Pipeline Compiler 1 Source code.c,.m,.cpp,.mm Redundant Null Compiler 2 Check Elimination Dead Code Elimination Object file.o void contains_null_check(int *P) { int unused = *P; Hidden text for MM if (P == NULL) return; *P = 4; } Keep brace during MM Compiler 1 void contains_null_check(int *P) { Hidden text for MM *P = 4; } Keep closing brace in MM

Let s Experiment: A Very Simple Optimization Pipeline Compiler 2 Source code.c,.m,.cpp,.mm Dead Code Elimination Redundant Null Check Elimination Object file.o void contains_null_check(int *P) { int unused = *P; Hidden text for MM if (P == NULL) return; *P = 4; } Keep brace during MM

Let s Experiment: A Very Simple Optimization Pipeline Compiler 2 Source code.c,.m,.cpp,.mm Dead Code Elimination Redundant Null Check Elimination Object file.o void contains_null_check(int *P) { int unused = *P; Hidden text for MM if (P == NULL) return; *P = 4; } Keep brace during MM

Let s Experiment: A Very Simple Optimization Pipeline Compiler 2 Source code.c,.m,.cpp,.mm Dead Code Elimination Redundant Null Compiler 2 Check Elimination Object file.o void contains_null_check(int *P) { int unused = *P; Hidden text for MM if (P == NULL) return; *P = 4; } Keep brace during MM Dead Code Elimination void contains_null_check(int *P) { int unused = *P; Hidden text for MM if (P == NULL) return; *P = 4; } Please keep the brace MM

Let s Experiment: A Very Simple Optimization Pipeline Compiler 2 Source code.c,.m,.cpp,.mm Dead Code Elimination Redundant Null Compiler 2 Check Elimination Object file.o void contains_null_check(int *P) { int unused = *P; Hidden text for MM if (P == NULL) return; *P = 4; } Keep brace during MM Dead Code Elimination void contains_null_check(int *P) { Hidden text for MM if (P == NULL) return; *P = 4; } Please keep the brace MM

Let s Experiment: A Very Simple Optimization Pipeline Compiler 2 Source code.c,.m,.cpp,.mm Dead Code Elimination Redundant Null Compiler 2 Check Elimination Object file.o void contains_null_check(int *P) { Hidden text for MM if (P == NULL) return; *P = 4; } Please keep the brace MM

Let s Experiment: A Very Simple Optimization Pipeline Compiler 2 Source code.c,.m,.cpp,.mm Dead Code Elimination Redundant Null Compiler 2 Check Elimination Object file.o void contains_null_check(int *P) { Hidden text for MM if (P == NULL) return; *P = 4; } Please keep the brace MM Redundant Null Check Elimination void contains_null_check(int *P) { Hidden text for MM if (P == NULL) return; *P = 4; } Please keep me MM!

Let s Experiment: A Very Simple Optimization Pipeline Compiler 2 Source code.c,.m,.cpp,.mm Dead Code Elimination Redundant Null Compiler 2 Check Elimination Object file.o void contains_null_check(int *P) { int unused = *P; Hidden text for MM if (P == NULL) return; *P = 4; } Keep brace during MM Compiler 2 void contains_null_check(int *P) { Hidden text for MM if (P == NULL) return; *P = 4; } Please keep me MM!

Let s Experiment: A Very Simple Optimization Pipeline Compiler 2 Source code.c,.m,.cpp,.mm Dead Code Elimination Redundant Null Compiler 2 Check Elimination Object file.o void contains_null_check(int *P) { int unused = *P; Hidden text for MM if (P == NULL) return; *P = 4; } Keep brace during MM Compiler 2 void contains_null_check(int *P) { Hidden text for MM if (P == NULL) return; *P = 4; } Please keep me MM!

Let s Experiment: A Very Simple Optimization Pipeline A surprising result void contains_null_check(int *P) { int unused = *P; if (P == NULL) return; *P = 4; } Keep brace during MM Compiler 2 void contains_null_check(int *P) { } if (P == NULL) return; *P = 4;

Let s Experiment: A Very Simple Optimization Pipeline A surprising result void contains_null_check(int *P) { int unused = *P; if (P == NULL) return; *P = 4; } Keep brace during MM void contains_null_check(int *P) { int unused = *P; if (P == NULL) return; *P = 4; } Keep brace during MM Compiler 1 Compiler 2 void contains_null_check(int *P) { *P = 4; } Keep closing brace in MM void contains_null_check(int *P) { } if (P == NULL) return; *P = 4;

Compiler Behavior Changes More Often Than You Think

Compiler Behavior Changes More Often Than You Think

Compiler Behavior Changes More Often Than You Think

Compiler Behavior Changes More Often Than You Think

Issues with Undefined Behavior

Issues with Undefined Behavior Undefined behavior is unpredictable

Issues with Undefined Behavior Undefined behavior is unpredictable Consequences can affect the whole program

Issues with Undefined Behavior Undefined behavior is unpredictable Consequences can affect the whole program Bugs may be dormant

Security Implications of Undefined Behavior Ryan Govostes, Security Engineering and Architecture Team

Private Keys E-mails Passwords Business Documents Application State Photos

Undefined behavior is at the heart of many security vulnerabilities

Examples of Security Vulnerabilities

Examples of Security Vulnerabilities Buffer overflow

Examples of Security Vulnerabilities Buffer overflow Use of uninitialized variable

Examples of Security Vulnerabilities Buffer overflow Use of uninitialized variable Use-after-free

Examples of Security Vulnerabilities Buffer overflow Use of uninitialized variable Use-after-free Double free

Examples of Security Vulnerabilities Buffer overflow Use of uninitialized variable Use-after-free Double free Race condition

Defend Your Users Build secure apps Protect your reputation Framework bugs are inherited

Tools Can Help

How Address Sanitizer Saved macos Yosemite

CFString

CFString /Users/tim /Library/Caches /com.apple.hypercard /startup.db

CFString /Users/tim /Library/Caches /com.apple.hypercard /startup.db Character Buffer

CFString /Users/tim /Library/Caches /com.apple.hypercard /startup.db Character Buffer

CFString /Users/tim /Library/Caches /com.apple.hypercard /startup.db Character Buffer / U s e r s / t i m / L i b r a r y / C a c h e s / c o m. a p p l e. h y p e r c a r d / s t a r t u p. d b

CFString /Users/tim /Library/Caches /com.apple.hypercard /startup.db Character Buffer / U s e r s / t i m / L i b r a r y / C a c h e s / c o m. a p p l e. h y p e r c a r d / s t a r t u p. d b NUL

CFString /Users/tim /Library/Caches /com.apple.hypercard /startup.db Character Buffer / U s e r s / t i m / L i b r a r y / C a c h e s / c o m. a p p l e. h y p e r c a r d / s t a r t u p. d b

CFString /Users/tim /Library/Caches /com.apple.hypercard /startup.db Character Buffer / U s e r s / t i m / L i b r a r y / C a c h e s / c o m. a p p l e. h y p e r c a r d / s t a r t u p. d b NUL

CFString /Users/tim /Library/Caches /com.apple.hypercard /startup.db Character Buffer / U s e r s / t i m / L i b r a r y / C a c h e s / c o m. a p p l e. h y p e r c a r d / s t a r t u p. d b NUL

CFString /Users/jappleseed4 /Library/Caches /com.apple.hypercard /startup.db Character Buffer / U s e r s / j a p p l e / L i b r a r y / C a c h e s / c o m. a p p l e. h y p e r c a r d / s t a r t u p. d b NUL

CFString /Users/jappleseed4 /Library/Caches /com.apple.hypercard /startup.db Character Buffer / U s e r s / j a p p l e s e e d / L i b r a r y / C a c h e s / c o m. a p p l e. h y p e r c a r d / s t a r t u p. d b NUL

CFString /Users/jappleseed4 /Library/Caches /com.apple.hypercard /startup.db Character Buffer / U s e r s / j a p p l e s e e d 4 / L i b r a r y / C a c h e s / c o m. a p p l e. h y p e r c a r d / s t a r t u p. d b NUL

CFString /Users/jappleseed4 /Library/Caches /com.apple.hypercard /startup.db Character Buffer / U s e r s / j a p p l e s e e d 4 / L i b r a r y / C a c h e s / c o m. a p p l e. h y p e r c a r d / s t a r t u p. d b NUL

Tools for Addressing Undefined Behavior

Tools for Addressing Undefined Behavior Compiler

Tools for Addressing Undefined Behavior Compiler Static Analyzer

Tools for Addressing Undefined Behavior Compiler Static Analyzer Address Sanitizer

Tools for Addressing Undefined Behavior Compiler Static Analyzer Address Sanitizer Thread Sanitizer

Tools for Addressing Undefined Behavior Compiler Static Analyzer Address Sanitizer Thread Sanitizer Undefined Behavior Sanitizer

Trust the Compiler Pay attention to compiler warnings Every release of Xcode has better warnings Modernize your project (Editor Validate Settings)

Trust the Compiler Pay attention to compiler warnings Every release of Xcode has better warnings Modernize your project (Editor Validate Settings) What s New in LLVM Hall 2 Thursday 4:10PM

Run the Static Analyzer Explores your code Analyze during every build Analyze in Continuous Integration

Run the Static Analyzer Explores your code Analyze during every build Analyze in Continuous Integration

Use the Runtime Sanitizers

Use the Runtime Sanitizers Tool Undefined Behavior

Use the Runtime Sanitizers Tool Undefined Behavior Address Sanitizer buffer overflow, use-after-free, double free, use after end of scope

Use the Runtime Sanitizers Tool Undefined Behavior Address Sanitizer buffer overflow, use-after-free, double free, use after end of scope Thread Sanitizer data race

Use the Runtime Sanitizers Tool Undefined Behavior Address Sanitizer buffer overflow, use-after-free, double free, use after end of scope Thread Sanitizer data race Undefined Behavior Sanitizer misaligned pointer, null pointer dereference, integer overflow, type mismatch, and more NEW

Turn on Sanitizers Edit scheme diagnostics tab

Turn on Sanitizers Edit scheme diagnostics tab Finding Bugs Using Xcode Runtime Tools WWDC17

Tools for Addressing Undefined Behavior Compiler Static Analyzer Address Sanitizer Thread Sanitizer Undefined Behavior Sanitizer Language

Tools for Addressing Undefined Behavior Compiler Static Analyzer Address Sanitizer Thread Sanitizer Undefined Behavior Sanitizer Language

Use Safe Language Features Prefer safe constructs Automatic Reference Counting C++ smart pointers (std::shared_ptr, std::unique_ptr) Bounds-checked containers (NSArray)

Use Safe Language Features Prefer safe constructs Automatic Reference Counting C++ smart pointers (std::shared_ptr, std::unique_ptr) Bounds-checked containers (NSArray) Consider using Swift

Swift Is Safer by Default Anna Zaks, Program Analysis Team

Undefined behavior is the enemy of safety

Safety Enforced on Many Levels

Safety Enforced on Many Levels C Language Family Swift Null pointer dereferences Stricter type system - Optionals Use of uninitialized variables Definite initialization Buffer and integer overflows Runtime checks Use-after-free ARC (Automatic Reference Counting)

Optionals Answer to NULL pointer dereferences

Optionals Answer to NULL pointer dereferences Non-optional and optional are different kinds of types Cake Cake?

Optionals Answer to NULL pointer dereferences Need to check before using func receivepackage() -> Cake? guard let cake = receivepackage() else { // The cake is a lie. return } print("jump with joy! Eat \(cake.kind)!")

Optionals Do not abuse forced unwrap

Optionals Do not abuse forced unwrap Optional return type, means the API can return nil cake = receivepackage()!

Optionals Do not abuse forced unwrap Optional return type, means the API can return nil cake = receivepackage()! Use forced unwrap only if: You can guarantee the value is never nil Cannot encode this in the type system For example: loading an image asset from the app bundle

Optionals Implicitly-unwrapped optional (Cake!)

Optionals Implicitly-unwrapped optional (Cake!) Compiler does not enforce that value is checked before use

Optionals Implicitly-unwrapped optional (Cake!) Compiler does not enforce that value is checked before use Safer than a pointer type in C Defined behavior Guaranteed to stop on nil

Optionals Implicitly-unwrapped optional (Cake!) Compiler does not enforce that value is checked before use Safer than a pointer type in C Defined behavior Guaranteed to stop on nil Useful for delayed initialization

Optionals Implicitly-unwrapped optional (Cake!) Compiler does not enforce that value is checked before use Safer than a pointer type in C Defined behavior Guaranteed to stop on nil Useful for delayed initialization May come from Objective-C APIs

Optionals Nullability annotations for safer ecosystem

Optionals Nullability annotations for safer ecosystem Nullability in C languages affects Swift interfaces Nullability in C languages affects Swift interfaces - (nullable NSView *)ancestorsharedwithview:(nonnull NSView *)aview; // Objective-C func ancestorshared(with view: NSView) -> NSView? // Swift

Optionals Nullability annotations for safer ecosystem Nullability in C languages affects Swift interfaces Nullability in C languages affects Swift interfaces - (nullable NSView *)ancestorsharedwithview:(nonnull NSView *)aview; // Objective-C func ancestorshared(with view: NSView) -> NSView? // Swift

Optionals Nullability annotations for safer ecosystem Nullability in C languages affects Swift interfaces Nullability in C languages affects Swift interfaces - (nullable NSView *)ancestorsharedwithview:(nonnull NSView *)aview; // Objective-C func ancestorshared(with view: NSView) -> NSView? // Swift

Optionals Nullability annotations for safer ecosystem Nullability in C languages affects Swift interfaces Nullability in C languages affects Swift interfaces - (nullable NSView *)ancestorsharedwithview:(nonnull NSView *)aview; // Objective-C func ancestorshared(with view: NSView) -> NSView? // Swift

Optionals Nullability annotations for safer ecosystem Nullability in C languages affects Swift interfaces Nullability in C languages affects Swift interfaces - (nullable NSView *)ancestorsharedwithview:(nonnull NSView *)aview; // Objective-C func ancestorshared(with view: NSView) -> NSView? // Swift Apple APIs are annotated for nullability

Optionals Nullability annotations for safer ecosystem Nullability in C languages affects Swift interfaces Nullability in C languages affects Swift interfaces - (nullable NSView *)ancestorsharedwithview:(nonnull NSView *)aview; // Objective-C func ancestorshared(with view: NSView) -> NSView? // Swift Apple APIs are annotated for nullability Use nullability on your Objective-C code!

Optionals Nullability annotations for safer ecosystem Nullability in C languages affects Swift interfaces Nullability in C languages affects Swift interfaces - (nullable NSView *)ancestorsharedwithview:(nonnull NSView *)aview; // Objective-C func ancestorshared(with view: NSView) -> NSView? // Swift Apple APIs are annotated for nullability Use nullability on your Objective-C code! Find nullability inconsistencies with tools Static Analyzer, -Wnullability, Undefined Behavior Sanitizer

Definite Initialization Answer to use of uninitialized variables

Definite Initialization Answer to use of uninitialized variables Checks that all values are initialized before use

Definite Initialization Answer to use of uninitialized variables Checks that all values are initialized before use var myinstance: MyClass if x > 42 { myinstance = MyClass(intValue: 13) } else { myinstance = MyClass(floatValue: 92.3) } // myinstance has been initialized on all branches leading here! myinstance.printit()

Definite Initialization Answer to use of uninitialized variables Checks that all values are initialized before use var myinstance: MyClass if x > 42 { myinstance = MyClass(intValue: 13) } else { myinstance = MyClass(floatValue: 92.3) } // myinstance has been initialized on all branches leading here! myinstance.printit()

Definite Initialization Answer to use of uninitialized variables Checks that all values are initialized before use var myinstance: MyClass if x > 42 { myinstance = MyClass(intValue: 13) } else { myinstance = MyClass(floatValue: 92.3) } // myinstance has been initialized on all branches leading here! myinstance.printit()

Definite Initialization Answer to use of uninitialized variables Checks that all values are initialized before use var myinstance: MyClass if x > 42 { myinstance = MyClass(intValue: 13) } else { myinstance = MyClass(floatValue: 92.3) } // myinstance has been initialized on all branches leading here! myinstance.printit()

Definite Initialization Answer to use of uninitialized variables Checks that all values are initialized before use var myinstance: MyClass if x > 42 { myinstance = MyClass(intValue: 13) } else { myinstance = MyClass(floatValue: 92.3) } // myinstance has been initialized on all branches leading here! myinstance.printit()

Runtime Checks Answer to buffer and integer overflows

Runtime Checks Answer to buffer and integer overflows Execution ends on Array and Int overflows

Runtime Checks Answer to buffer and integer overflows Execution ends on Array and Int overflows Runtime checking is better than undefined behavior Predictable Provides security guarantees

Runtime Checks Answer to buffer and integer overflows Execution ends on Array and Int overflows Runtime checking is better than undefined behavior Predictable Provides security guarantees Integer wrapping behavior with &+, &-, &*

Does undefined behavior exist in Swift?

Unsafe Types

Unsafe Types Need interoperability with C APIs

Unsafe Types Need interoperability with C APIs UnsafePointer<T>, UnsafeMutableRawBufferPointer

Unsafe Types Need interoperability with C APIs UnsafePointer<T>, UnsafeMutableRawBufferPointer

Unsafe Types Need interoperability with C APIs UnsafePointer<T>, UnsafeMutableRawBufferPointer Use Address Sanitizer

Exclusive Memory Accesses Enforcement in Swift 4

Exclusive Memory Accesses Enforcement in Swift 4 func have(_ x: inout Cake, andeat y: inout Cake)

Exclusive Memory Accesses Enforcement in Swift 4 func have(_ x: inout Cake, andeat y: inout Cake) have(&cake, andeat: &cake) Triple Chocolate Delight x y

Exclusive Memory Accesses Enforcement in Swift 4 func have(_ x: inout Cake, andeat y: inout Cake) have(&cake, andeat: &cake) Triple Chocolate Delight x y Similar to restrict in C but with different default behavior

Exclusive Memory Accesses Enforcement in Swift 4 func have(_ x: inout Cake, andeat y: inout Cake) have(&cake, andeat: &cake) Triple Chocolate Delight x y Similar to restrict in C but with different default behavior What s New in Swift WWDC 2017

Enforcement of Exclusive Memory Accesses Options considered Declare to be undefined behavior (like C) Provide language guarantees

Enforcement of Exclusive Memory Accesses Intricate balancing act

Enforcement of Exclusive Memory Accesses Proposed solution Enforce a slightly stricter language rule Enforcement at compile time Enforcement at run time Guarantee exclusive access within a thread

Enforcement of Exclusive Access Across Threads Too expensive to check by default Access races can lead to memory corruption in Swift Thread Sanitizer catches most violations

Enforcement of Exclusive Access Across Threads Too expensive to check by default Access races can lead to memory corruption in Swift Thread Sanitizer catches most violations Finding Bugs Using Xcode Runtime Tools WWDC17

Summary C languages rely on undefined behavior Leads to unpredictability and security issues Swift is safer by default Use tools to make your code safe and reliable

More Information https://developer.apple.com/wwdc17/407

Related Sessions Finding Bugs Using Xcode Runtime Tools What s New in Swift WWDC17 WWDC17 What s New in LLVM Hall 2 Thursday 4:10PM

Labs Performance Profiling and Runtime Analysis Tools Lab Technology Lab K Thur 1:00PM 4:10PM LLVM Compiler, Objective-C, and C++ Lab Technology Lab E Fri 9:00AM 11:00AM