CSC 2045 Week 09 Race Conditions PDF

Summary

This document provides lecture notes on CSC 2045, File I/O and Race Conditions. It covers topics such as file handling, race conditions, and how to avoid them, including examples and practical advice.

Full Transcript

CSC 2045 FILEIO AND RACE CONDITIONS OBJECTIVES AGENDA: WEEK 09 Implement a programming fix 1. File names & File Contents that allows 2. C++ File Handling vulnerabilities associated with File I/O. 3....

CSC 2045 FILEIO AND RACE CONDITIONS OBJECTIVES AGENDA: WEEK 09 Implement a programming fix 1. File names & File Contents that allows 2. C++ File Handling vulnerabilities associated with File I/O. 3. C++ Core Guidelines File IO 4. File Input and Output Streams Identify and analyze race condition problem. 5. Alternating IO on File Stream 6. Close files explicitly Identify rules to develop safe, reliable, and secure systems, by 7. Race Conditions Defined eliminating undefined behaviors 8. Race Condition Examples that can lead to undefined 9. TOCTOU Errors program behaviors and exploitable vulnerabilities. FILE NAMES AND FILE CONTENTS Read the section 5.6 o https://dwheeler.com/secure-programs/Secure-Programs- HOWTO/file-names.html Read the section 5.7 o https://dwheeler.com/secure-programs/Secure-Programs- HOWTO/file-contents.html What do you believe is the main vulnerability with file names and file contents? C++ FILE HANDLING Complete the module, answering the questions within as you go. 6.9. Putting it all Together o Apply std::ios_base_failure exception handling NOTE Since C++11: std::ifstream and std::ofstream file names are compatible with std::string and do NOT need to use C-Strings to open the file. IO.1 DON'T USE CHAR-LEVEL INPUT Read section SL.io.1: SL.io.1: Use character-level input only when you have to Reason Unless you genuinely just deal with individual characters, using character-level input leads to the user code performing potentially error-prone and potentially inefficient composition of tokens out of characters. IO.2 CONSIDER ILL-FORMED INPUT Read section SL.io.2 SL.io.2: When reading, always consider ill-formed input Reason Errors are typically best handled as soon as possible. If input isn’t validated, every function must be written to cope with bad data (and that is not practical). IO.3 PREFER IOSTREAM FOR IO Read section SL.io.3 SL.io.3: Prefer iostreams for I/O Reason iostreams are safe, flexible, and extensible. IO.10 USE STD::CIN AND STD::COUT Read section SL.io.10 SL.io.10: Unless you use printf-family functions call ios_base::sync_with_stdio(false) Reason Synchronizing iostreams with printf-style I/O can be costly. std::cin and std::cout are by default synchronized with printf. IO.50 AVOID STD::ENDL Read section SL.io.50 SL.io.50: Avoid endl Reason The std::endl manipulator is mostly equivalent to '\n' and "\n"; it simply slows down output by doing redundant flush()s. This slowdown can be significant For std::cin/std::cout (and equivalent) interaction, there is no reason to flush; that’s done automatically. For writing to a file, there is rarely a need to flush. FILE INPUT AND OUTPUT STREAMS Manipulating files with iostreams is much easier and safer than using stdio from C. To open a file, create an object and the constructor does the work. You don't need to explicitly close() a file, the destructor will close it when the object goes out of scope, BUT it is best practice to close all files explicitly. In a large program, which runs on long after you have finished reading/writing to the file, not closing it means that your program is still holding the resource. Other processes cannot acquire that file until your program terminates (which may not be what you wish for). ALTERNATING I/O ON FILE STREAM Review the Non-Compliant and Complaint Code o https://wiki.sei.cmu.edu/confluence/display/cplusplus/FIO50- CPP.+Do+not+alternately+input+and+output+from+a+file+stream+ without+an+intervening+positioning+call Alternately inputting and outputting from a stream without an intervening flush or positioning call is undefined behavior. CLOSE FILES EXPLICITLY A call to the std::basic_filebuf::open() function must be matched with a call to std::basic_filebuf::close() before the lifetime of the last pointer that stores the return value of the call has ended or before normal program termination, whichever occurs first. Review the Non-Compliant and Compliant Solutions o https://wiki.sei.cmu.edu/confluence/display/cplusplus/FIO51- CPP.+Close+files+when+they+are+no+longer+needed Failing to properly close files may allow an attacker to exhaust system resources and can increase the risk that data written into in-memory file buffers will not be flushed in the event of abnormal program termination. RACE CONDITIONS DEFINED A race condition exists when changes to the order of two or more events can cause a change in behavior. If the correct order of execution is required for the proper functioning of the program, this is a bug. If an attacker can take advantage of the situation to insert malicious code, change a filename, or otherwise interfere with the normal operation of the program, the race condition is a security vulnerability. Attackers can sometimes take advantage of small time gaps in the processing of code to interfere with the sequence of operations, which they then exploit. RACE CONDITION CODE VULNERABILITY Cause an undesirable timing of events when scheduling dependencies among multiple threads that are not appropriately synchronized. Can have a negative outcome on security if a sequence of events is needed between the two events, but a race happens and the sequence is not ensured by a program. RACE CONDITION MITIGATED Developers should control the synchronization of the threads. In C++ the header file: should be used Atomic types are types that encapsulate a value whose access is guaranteed to not cause data races and can be used to synchronize memory accesses among different threads. EXAMPLES OF RACE CONDITIONS 1. Infinite loops: causes a program to never terminate or return from the flow of control. 2. Deadlocks: occurs if the program is waiting on a resource without proper mechanism for timeout, and the resource or lock is never released. 3. Resource collisions: represent failures to synchronize access to shared resources. This results in resource corruption or privilege escalations. TIME CHECK VERSUS TIME OF USE It is common for an application to need to check some condition before undertaking an action. For example: it might check to see if a file exists before writing to it whether the user has access rights to read a file before opening it for reading If there is a time gap between the check and the use (even though it might be a fraction of a second), an attacker can sometimes use that gap to mount an attack. This is referred to as a time-of-check to time-of-use error. TOCTOU: TIME-OF-CHECK TIME-OF-USE TOCTOU are software errors caused by a race condition. Time-of-check (TOC) is the time at which a process checks a shared resource's state. Time-of-use (TOU) is the time at which a process uses a shared resource. A TOCTOU error occurs when a shared resource's state changes between TOC and TOU in a way that invalidates the result of the resource state check. Since a shared resource is in an unexpected state, a TOCTOU error causes a process to perform incorrect computations. TOCTOU errors can be exploited to gain unauthorized access to system resources, such as read/write access to files. AVOID RACE CONDITIONS Read the section 7.11: o https://dwheeler.com/secure-programs/Secure-Programs- HOWTO/avoid-race.html

Use Quizgecko on...
Browser
Browser