Semmle 1.20
Skip to end of metadata
Go to start of metadata

Name: Potentially overrunning write

Description: Buffer write operations that do not control the length of data written may overflow.

ID: cpp/overrunning-write

Kind: problem

Severity: error

Precision: medium

Query: OverrunWrite.ql
/**
 * @name Potentially overrunning write
 * @description Buffer write operations that do not control the length
 *              of data written may overflow.
 * @kind problem
 * @problem.severity error
 * @precision medium
 * @id cpp/overrunning-write
 * @tags reliability
 *       security
 *       external/cwe/cwe-120
 *       external/cwe/cwe-787
 *       external/cwe/cwe-805
 */
import semmle.code.cpp.security.BufferWrite
import semmle.code.cpp.commons.Alloc

// see CWE-120UnboundedWrite.ql for a summary of CWE-120 violation cases

from BufferWrite bw, Expr dest, int destSize
where not bw.hasExplicitLimit() // has no explicit size limit
  and dest = bw.getDest()
  and destSize = getBufferSize(dest, _)
  and // we can deduce that too much data may be copied (even without
      // long '%f' conversions)
      bw.getMaxDataLimited() > destSize
select bw, "This '" + bw.getBWDesc() + "' operation requires "
         + bw.getMaxData() + " bytes but the destination is only "
         + destSize + " bytes."

The program performs a buffer copy or write operation with no upper limit on the size of the copy, and it appears that certain inputs will cause a buffer overflow to occur in this case. In addition to causing program instability, techniques exist which may allow an attacker to use this vulnerability to execute arbitrary code.

Recommendation

Always control the length of buffer copy and buffer write operations. strncpy should be used over strcpy, snprintf over sprintf, and in other cases 'n-variant' functions should be preferred.

Example

void sayHello()
{
	char buffer[10];

	// BAD: this message overflows the buffer
	strcpy(buffer, "Hello, world!");

	MessageBox(hWnd, buffer, "New Message", MB_OK);
}

In this example, the call to strcpy copies a message of 14 characters (including the terminating null) into a buffer with space for just 10 characters. As such, the last four characters overflow the buffer resulting in undefined behavior.

To fix this issue three changes should be made:

  • Control the size of the buffer using a preprocessor define.
  • Replace the call to strcpy with strncpy, specifying the define as the maximum length to copy. This will prevent the buffer overflow.
  • Consider increasing the buffer size, say to 20 characters, so that the message is displayed correctly.
References