consider the following java code race conditions public class shared { private int data; public...

14
onsider the following Java code Race Conditions public class Shared { private int data; public Shared() { data = 0; } public void setData(int r) { data = r; } public int getData() { return data; } } int localData = theShared.getData(); localData++; theShared.setData(localData); After executing this code what value is stored in Shared.data?

Upload: brook-french

Post on 02-Jan-2016

221 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Consider the following Java code Race Conditions public class Shared { private int data; public Shared() { data = 0; } public void setData(int r) { data

Consider the following Java code

Race ConditionsRace Conditions

public class Shared { private int data;

public Shared() { data = 0; }

public void setData(int r) { data = r; }

public int getData() { return data; }}

public class Shared { private int data;

public Shared() { data = 0; }

public void setData(int r) { data = r; }

public int getData() { return data; }}

int localData = theShared.getData();localData++;theShared.setData(localData);

int localData = theShared.getData();localData++;theShared.setData(localData);

After executing this code what value is stored in Shared.data?

Page 2: Consider the following Java code Race Conditions public class Shared { private int data; public Shared() { data = 0; } public void setData(int r) { data

What is a thread / process / task?

public class Driver { private Shared theShared; private MyThread threadA, threadB;

public Driver() { theShared = new Shared(); threadA = new MyThread(theShared); threadB = new MyThread(theShared); threadA.start(); threadB.start(); try { threadA.join(); threadB.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(theShared.getData()); } }

public static void main(String[] args) { new Driver(); }}

public class Driver { private Shared theShared; private MyThread threadA, threadB;

public Driver() { theShared = new Shared(); threadA = new MyThread(theShared); threadB = new MyThread(theShared); threadA.start(); threadB.start(); try { threadA.join(); threadB.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(theShared.getData()); } }

public static void main(String[] args) { new Driver(); }}

Threaded variation of the last program.

public class MyThread extends Thread { private Shared theShared;

public MyThread(Shared s) { theShared = s; }

public void run() { int localData = theShared.getData(); localData++; theShared.setData(localData); } }

public class MyThread extends Thread { private Shared theShared;

public MyThread(Shared s) { theShared = s; }

public void run() { int localData = theShared.getData(); localData++; theShared.setData(localData); } }

Page 3: Consider the following Java code Race Conditions public class Shared { private int data; public Shared() { data = 0; } public void setData(int r) { data

int localData = theShared.getData(); //1localData++; //2theShared.setData(localData); //3

int localData = theShared.getData(); //1localData++; //2theShared.setData(localData); //3

Code shared bythreadA and threadB

threadA -- execute //1threadA -- execute //2threadA -- execute //3threadB -- execute //1threadB -- execute //2threadB -- execute //3

Execution Scenario 1:threadB -- execute //1threadB -- execute //2threadB -- execute //3threadA -- execute //1threadA -- execute //2threadA -- execute //3

Execution Scenario 2:

threadA -- execute //1threadB -- execute //1threadB -- execute //2threadB -- execute //3threadA -- execute //2threadA -- execute //3

Execution Scenario 3:

Whenever the potential order of execution can alter the outcome, this is called a _________ or ___________.

Page 4: Consider the following Java code Race Conditions public class Shared { private int data; public Shared() { data = 0; } public void setData(int r) { data

Three essential properties for a race condition

_________ Property Two or more flows of control must execute concurrently/in parallel.

_____________ Property Some resource must be shared by the concurrent flows.

_____________ Property At least one of the concurrent flows must alter the state of the shared resource.

Page 5: Consider the following Java code Race Conditions public class Shared { private int data; public Shared() { data = 0; } public void setData(int r) { data

Solution to a race conditionSolution to a race conditioneliminate the concurrent access

The “trick” is to use an atomic operation, such as a lock.

Page 6: Consider the following Java code Race Conditions public class Shared { private int data; public Shared() { data = 0; } public void setData(int r) { data

import java.util.concurrent.locks.ReentrantLock;public class Driver { private Shared theShared; private MyThread threadA, threadB; private ReentrantLock theLock;

public Driver() { theShared = new Shared(); theLock = new ReetrantLock(); threadA = new MyThread(theShared, theLock); threadB = new MyThread(theShared, theLock); threadA.start(); threadB.start(); try { threadA.join(); threadB.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(theShared.getData()); } }

public static void main(String[] args) { new Driver(); }}

import java.util.concurrent.locks.ReentrantLock;public class Driver { private Shared theShared; private MyThread threadA, threadB; private ReentrantLock theLock;

public Driver() { theShared = new Shared(); theLock = new ReetrantLock(); threadA = new MyThread(theShared, theLock); threadB = new MyThread(theShared, theLock); threadA.start(); threadB.start(); try { threadA.join(); threadB.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(theShared.getData()); } }

public static void main(String[] args) { new Driver(); }}

import java.util.concurrent.locks.ReentrantLock;public class MyThread extends Thread { private Shared theShared; private ReentrantLock theLock;

public MyThread(Shared s) { theShared = s; }

public void run() { theLock.lock(); int localData = theShared.getData(); localData++; theShared.setData(localData); theLock.unlock(); } }

import java.util.concurrent.locks.ReentrantLock;public class MyThread extends Thread { private Shared theShared; private ReentrantLock theLock;

public MyThread(Shared s) { theShared = s; }

public void run() { theLock.lock(); int localData = theShared.getData(); localData++; theShared.setData(localData); theLock.unlock(); } }

Page 7: Consider the following Java code Race Conditions public class Shared { private int data; public Shared() { data = 0; } public void setData(int r) { data

Locks lead to another problem…Locks lead to another problem…

_________

What if one thread terminates inside a critical section?lockSharedResource(); // the critical sectionunlockSharedResource();

A thread is deadlocked when it is impossible forit to resume execution even though the expectedexecution for the thread is incomplete.

Potential Deadlock on two resources (A and B)

lockSharedResourceA(); lockSharedResourceB(); // the critical section unlockSharedResourceB();unlockSharedResourceA();

lockSharedResourceB(); lockSharedResourceA(); // the critical section unlockSharedResourceA();unlockSharedResourceB();

Process 1 Process 2

Page 8: Consider the following Java code Race Conditions public class Shared { private int data; public Shared() { data = 0; } public void setData(int r) { data

How can an attacker exploit race conditions?How can an attacker exploit race conditions?

Deadlock leads to _____.

Example: 2004 Apache HTTP Server http://www.kb.cert.org/vuls/id/132110

Concurrency, and therefore, race conditions are sensitive to …

processor speedsprocess/thread scheduling algorithmsmemory constraintsasynchronous eventsstate of unrelated processes

Page 9: Consider the following Java code Race Conditions public class Shared { private int data; public Shared() { data = 0; } public void setData(int r) { data

What about loosely coupled (untrusted) processes?

File targetFile = new File("/tmp/test");if (targetFile.exists() && targetFile.canRead()) { try { FileInputStream = new FileInputStream(targetFile); inFile.read( someBuffer ); ... inFile.close(); } catch (IOException e) { e.printStackTrace(); }}

File targetFile = new File("/tmp/test");if (targetFile.exists() && targetFile.canRead()) { try { FileInputStream = new FileInputStream(targetFile); inFile.read( someBuffer ); ... inFile.close(); } catch (IOException e) { e.printStackTrace(); }}

_________ (Time of Check, Time of Use)the window from TOC through TOU can leadto a race vulnerability

Page 10: Consider the following Java code Race Conditions public class Shared { private int data; public Shared() { data = 0; } public void setData(int r) { data

TOCTOU MitigationTOCTOU Mitigation________the file from other access.

File targetFile = new File("/tmp/test");if (targetFile.exists()) { try { FileChannel channel = null; FileLock lock = null; try { channel = new RandomAccessFile(targetFile,"rw").getChannel(); lock = channel.tryLock(); if (lock != null) { ByteBuffer bytes = ByteBuffer.allocate(100); channel.read(bytes); ... lock.release(); } else // file is already locked } catch (OverlappingFileLockException e) { // file is already locked } finally { channel.close(); } } catch (IOException e) { e.printStackTrace();}

File targetFile = new File("/tmp/test");if (targetFile.exists()) { try { FileChannel channel = null; FileLock lock = null; try { channel = new RandomAccessFile(targetFile,"rw").getChannel(); lock = channel.tryLock(); if (lock != null) { ByteBuffer bytes = ByteBuffer.allocate(100); channel.read(bytes); ... lock.release(); } else // file is already locked } catch (OverlappingFileLockException e) { // file is already locked } finally { channel.close(); } } catch (IOException e) { e.printStackTrace();}

Page 11: Consider the following Java code Race Conditions public class Shared { private int data; public Shared() { data = 0; } public void setData(int r) { data

A non-TOCTOU race condition: walking trees

...chdir( “/tmp/a” );chdir( “b” );chdir( “c” );// race windowchdir( “..” );unlink( “*” ); //delete all files...

...chdir( “/tmp/a” );chdir( “b” );chdir( “c” );// race windowchdir( “..” );unlink( “*” ); //delete all files...

Example (GNU utilities) file tree

Page 12: Consider the following Java code Race Conditions public class Shared { private int data; public Shared() { data = 0; } public void setData(int r) { data

A non-TOCTOU race condition: walking trees

...chdir( “/tmp/a” );chdir( “b” );chdir( “c” );// race windowchdir( “..” );unlink( “*” ); //delete all files...

...chdir( “/tmp/a” );chdir( “b” );chdir( “c” );// race windowchdir( “..” );unlink( “*” ); //delete all files...

Example (GNU utilities)

the exploit

mv /tmp/a/b/c /tmp/c

file tree

Page 13: Consider the following Java code Race Conditions public class Shared { private int data; public Shared() { data = 0; } public void setData(int r) { data

MitigationMitigation avoid the use of relative path names

use and verify ___________________

“..” and “.” in file names and URLs must be disallowed.

avoid using shared access containers

Page 14: Consider the following Java code Race Conditions public class Shared { private int data; public Shared() { data = 0; } public void setData(int r) { data

Mitigation – All Race ConditionsMitigation – All Race ConditionsClosing the race window

identify all shared resources

use mutual exclusion via locks, semaphores, monitors, etc.

Eliminating the race (shared) resource

be permission, authorization and privilege aware

Controlling access to the race (shared) resource

use “thread safe” threads

check file properties securely

use canonical full path names

use trustworthy containers

static and dynamic detection tools can find some race conditions