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

Name: Badly bounded write

Description: Buffer write operations with a length parameter that does not match the size of the destination buffer may overflow.

ID: cpp/badly-bounded-write

Kind: problem

Severity: error

Precision: high

Query: BadlyBoundedWrite.ql
/**
 * @name Badly bounded write
 * @description Buffer write operations with a length parameter that
 *              does not match the size of the destination buffer may
 *              overflow.
 * @kind problem
 * @problem.severity error
 * @precision high
 * @id cpp/badly-bounded-write
 * @tags reliability
 *       security
 *       external/cwe/cwe-120
 *       external/cwe/cwe-787
 *       external/cwe/cwe-805
 */
import semmle.code.cpp.security.BufferWrite

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

from BufferWrite bw, int destSize
where bw.hasExplicitLimit()                     // has an explicit size limit
  and destSize = getBufferSize(bw.getDest(), _)
  and (bw.getExplicitLimit() > destSize)        // but it's larger than the destination
select bw, "This '" + bw.getBWDesc() + "' operation is limited to " + bw.getExplicitLimit() + " bytes but the destination is only " + destSize + " bytes."

The program performs a buffer copy or write operation with an incorrect upper limit on the size of the copy. A sufficiently long input will overflow the target buffer. In addition to causing program instability, techniques exist which may allow an attacker to use this vulnerability to execute arbitrary code.

Recommendation

Use preprocessor defines to specify the size of buffers, and use the same defines as arguments to strncpy, snprintf etc. This technique will ensure that buffer sizes are always specified correctly so that no overflow occurs.

Example

void congratulateUser(const char *userName)
{
	char buffer[80];

	// BAD: even though snprintf is used, this could overflow the buffer
	// because the size specified is too large.
	snprintf(buffer, 256, "Congratulations, %s!", userName);

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

In this example, the developer has used snprintf to control the maximum number of characters that can be written to buffer. Unfortunately, perhaps due to modifications since the code was first written, a limited buffer overrun can still occur because the size argument to snprintf is larger than the actual size of the buffer.

To fix the problem, either the second argument to snprintf should be changed to 80, or the buffer extended to 256 characters. A further improvement is to use a preprocessor define so that the size is only specified in one place, potentially preventing future recurrence of this issue.

References
  • Common Weakness Enumeration: CWE-120.
  • Common Weakness Enumeration: CWE-787.
  • Common Weakness Enumeration: CWE-805.