Resources

People often ask me "How did you learn how to hack?" The answer: by reading. This page is a collection of the blog posts and other articles that I have accumulated over the years of my journey. Enjoy!

Oracle Multithreading- 1301

OraclePosted 2 Years Ago
  • When writing code that needs to be high performance with multithreading, data may need to be read or written across various threads. If you do not do this securely, then you end up with race conditions, putting the system into weird states. So, these are strategies on how to do it securely.
  • There are three main types of data: stack, global/static and heap. Stacks are per thread and then global/static & heap data is per process. So, locking needs to performed on global/static information.
  • The first method is the most simple: mutual exclusive locks. With this method, there is a variable that is associated with the rest of the data that determines if the information can be accessed. If the data is 0, you can access it but you must acquire the mutex by setting it to 1. Once you're done, release it by setting it to 0. If you come across the lock at 1, then a thread sleeps until it's 0 again.
  • The second pattern is readers/writers locks. This is used in cases where the thread needs multiple readers at the same time with only infrequent writes. To obtain an initial lock, call the function rw_enter. Many users can use this for a read at once.
  • If a thread needs to write, the mutex can be upgraded with a call to rw_tryupgrade. Once done with the write, a call to rw_downgrade can be made to move this to a reader lock. Finally, a call to rw_exit can be used to drop the lock entirely. Although this isn't explicitly stated, I'm guessing that the writers lock waits for all reads to finish and prevents any other future reads from occurring.
  • Semaphores are the final method. Mutex is a binary semaphore. So, semaphores contain an integer with the maximum amount of items that can be shared. These contain two operations: wait and signal.
  • Some datatypes are atomic - meaning that they are updated within a single instruction or operation. This is useful with small datatypes, like integers, across threads.
  • When using locks, there are several things that can go wrong that lead to panics that are not intuitive. First, reentering a mutex from the same thread will pause a kernel panic. Second, releasing a mutex that the thread doesn't hold will also cause a panic. Of course, a common one is forgetting to release the mutex will lead to locks as well.
  • From a security perspective, the mutex or operation needs to be used naturally. If the programmer forgets to use the locking mechanism and accesses the data anything, then threads can still interfere with each other. Denial of services can occur when bad code is written as well, like multi-enters and so forth.