| 
									
										
										
										
											2019-05-09 13:18:19 +01:00
										 |  |  | =======================
 | 
					
						
							|  |  |  | Secure Coding Practices
 | 
					
						
							|  |  |  | =======================
 | 
					
						
							|  |  |  | This document covers topics that both developers and security researchers must
 | 
					
						
							|  |  |  | be aware of so that they can develop safe code and audit existing code
 | 
					
						
							|  |  |  | properly.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Reporting Security Bugs
 | 
					
						
							|  |  |  | -----------------------
 | 
					
						
							|  |  |  | For details on how to report security bugs or ask questions about potential
 | 
					
						
							|  |  |  | security bugs, see the `Security Process wiki page
 | 
					
						
							|  |  |  | <https://wiki.qemu.org/SecurityProcess>`_.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | General Secure C Coding Practices
 | 
					
						
							|  |  |  | ---------------------------------
 | 
					
						
							|  |  |  | Most CVEs (security bugs) reported against QEMU are not specific to
 | 
					
						
							|  |  |  | virtualization or emulation.  They are simply C programming bugs.  Therefore
 | 
					
						
							|  |  |  | it's critical to be aware of common classes of security bugs.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | There is a wide selection of resources available covering secure C coding.  For
 | 
					
						
							|  |  |  | example, the `CERT C Coding Standard
 | 
					
						
							|  |  |  | <https://wiki.sei.cmu.edu/confluence/display/c/SEI+CERT+C+Coding+Standard>`_
 | 
					
						
							|  |  |  | covers the most important classes of security bugs.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Instead of describing them in detail here, only the names of the most important
 | 
					
						
							|  |  |  | classes of security bugs are mentioned:
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * Buffer overflows
 | 
					
						
							|  |  |  | * Use-after-free and double-free
 | 
					
						
							|  |  |  | * Integer overflows
 | 
					
						
							|  |  |  | * Format string vulnerabilities
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Some of these classes of bugs can be detected by analyzers.  Static analysis is
 | 
					
						
							|  |  |  | performed regularly by Coverity and the most obvious of these bugs are even
 | 
					
						
							|  |  |  | reported by compilers.  Dynamic analysis is possible with valgrind, tsan, and
 | 
					
						
							|  |  |  | asan.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Input Validation
 | 
					
						
							|  |  |  | ----------------
 | 
					
						
							|  |  |  | Inputs from the guest or external sources (e.g. network, files) cannot be
 | 
					
						
							|  |  |  | trusted and may be invalid.  Inputs must be checked before using them in a way
 | 
					
						
							|  |  |  | that could crash the program, expose host memory to the guest, or otherwise be
 | 
					
						
							|  |  |  | exploitable by an attacker.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The most sensitive attack surface is device emulation.  All hardware register
 | 
					
						
							|  |  |  | accesses and data read from guest memory must be validated.  A typical example
 | 
					
						
							|  |  |  | is a device that contains multiple units that are selectable by the guest via
 | 
					
						
							|  |  |  | an index register::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   typedef struct {
 | 
					
						
							|  |  |  |       ProcessingUnit unit[2];
 | 
					
						
							|  |  |  |       ...
 | 
					
						
							|  |  |  |   } MyDeviceState;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   static void mydev_writel(void *opaque, uint32_t addr, uint32_t val)
 | 
					
						
							|  |  |  |   {
 | 
					
						
							|  |  |  |       MyDeviceState *mydev = opaque;
 | 
					
						
							|  |  |  |       ProcessingUnit *unit;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       switch (addr) {
 | 
					
						
							|  |  |  |       case MYDEV_SELECT_UNIT:
 | 
					
						
							|  |  |  |           unit = &mydev->unit[val];   <-- this input wasn't validated!
 | 
					
						
							|  |  |  |           ...
 | 
					
						
							|  |  |  |       }
 | 
					
						
							|  |  |  |   }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If ``val`` is not in range [0, 1] then an out-of-bounds memory access will take
 | 
					
						
							|  |  |  | place when ``unit`` is dereferenced.  The code must check that ``val`` is 0 or
 | 
					
						
							|  |  |  | 1 and handle the case where it is invalid.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Unexpected Device Accesses
 | 
					
						
							|  |  |  | --------------------------
 | 
					
						
							|  |  |  | The guest may access device registers in unusual orders or at unexpected
 | 
					
						
							|  |  |  | moments.  Device emulation code must not assume that the guest follows the
 | 
					
						
							|  |  |  | typical "theory of operation" presented in driver writer manuals.  The guest
 | 
					
						
							|  |  |  | may make nonsense accesses to device registers such as starting operations
 | 
					
						
							|  |  |  | before the device has been fully initialized.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | A related issue is that device emulation code must be prepared for unexpected
 | 
					
						
							|  |  |  | device register accesses while asynchronous operations are in progress.  A
 | 
					
						
							|  |  |  | well-behaved guest might wait for a completion interrupt before accessing
 | 
					
						
							|  |  |  | certain device registers.  Device emulation code must handle the case where the
 | 
					
						
							|  |  |  | guest overwrites registers or submits further requests before an ongoing
 | 
					
						
							|  |  |  | request completes.  Unexpected accesses must not cause memory corruption or
 | 
					
						
							|  |  |  | leaks in QEMU.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Invalid device register accesses can be reported with
 | 
					
						
							|  |  |  | ``qemu_log_mask(LOG_GUEST_ERROR, ...)``.  The ``-d guest_errors`` command-line
 | 
					
						
							|  |  |  | option enables these log messages.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Live Migration
 | 
					
						
							|  |  |  | --------------
 | 
					
						
							|  |  |  | Device state can be saved to disk image files and shared with other users.
 | 
					
						
							|  |  |  | Live migration code must validate inputs when loading device state so an
 | 
					
						
							|  |  |  | attacker cannot gain control by crafting invalid device states.  Device state
 | 
					
						
							|  |  |  | is therefore considered untrusted even though it is typically generated by QEMU
 | 
					
						
							|  |  |  | itself.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Guest Memory Access Races
 | 
					
						
							|  |  |  | -------------------------
 | 
					
						
							|  |  |  | Guests with multiple vCPUs may modify guest RAM while device emulation code is
 | 
					
						
							|  |  |  | running.  Device emulation code must copy in descriptors and other guest RAM
 | 
					
						
							|  |  |  | structures and only process the local copy.  This prevents
 | 
					
						
							|  |  |  | time-of-check-to-time-of-use (TOCTOU) race conditions that could cause QEMU to
 | 
					
						
							|  |  |  | crash when a vCPU thread modifies guest RAM while device emulation is
 | 
					
						
							|  |  |  | processing it.
 | 
					
						
							| 
									
										
										
										
											2021-06-01 18:25:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | Use of null-co block drivers
 | 
					
						
							|  |  |  | ----------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The ``null-co`` block driver is designed for performance: its read accesses are
 | 
					
						
							|  |  |  | not initialized by default. In case this driver has to be used for security
 | 
					
						
							|  |  |  | research, it must be used with the ``read-zeroes=on`` option which fills read
 | 
					
						
							|  |  |  | buffers with zeroes. Security issues reported with the default
 | 
					
						
							|  |  |  | (``read-zeroes=off``) will be discarded.
 |