Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ According to the C Standard, the library functions listed in the following table
| ` tmpnam() ` | ` tmpnam_r() ` in POSIX |
| ` mbrtoc16() ` , ` c16rtomb() ` , <br> ` mbrtoc32() ` , ` c32rtomb() ` | Do not call with a null ` mbstate_t * ` argument |

Section 2.9.1 of the *Portable Operating System Interface (POSIX <sup>®</sup> ), Base Specifications, Issue 7* \[ [IEEE Std 1003.1:2013](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-IEEEStd1003.1-2013) \] extends the list of functions that are not required to be thread-safe.
Section 2.9.1 of the *Portable Operating System Interface (POSIX <sup>®</sup> ), Base Specifications, Issue 8* \[ [IEEE Std 1003.1:2024](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-IEEEStd1003.1-2024) \] extends the list of functions that are not required to be thread-safe.

## Noncompliant Code Example

Expand Down Expand Up @@ -248,6 +248,6 @@ CON33-C – CWE-377 =
|--------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------|
| \[ [IEEE Std 1003.1:2013](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-IEEEStd1003.1-2013) \] | Section 2.9.1, "Thread Safety" |
| \[ [ISO/IEC 9899:2024](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-ISO-IEC9899-2024) \] | Subclause 7.26.6.3, "The `strerror` Function" |
| \[ [Open Group 1997](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-OpenGroup97) \] | Section 10.12, "Thread-Safe POSIX.1 and C-Language Functions" |
| \[ [Open Group 2024](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-OpenGroup24) \] | Section 2.9.1, "Thread-Safety" |


Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ C Standard, 7.1.3 paragraph 1 \[ [ISO/IEC 9899:2024](/sei-cert-c-coding-standard

Additionally, subclause 7.33 defines many other reserved identifiers for future library directions.

No other identifiers are reserved. (The POSIX standard extends the set of identifiers reserved by the C Standard to include an open-ended set of its own. See *Portable Operating System Interface \[POSIX <sup>®</sup> \], Base Specifications, Issue 7* , [Section 2.2](http://www.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_02) , "The Compilation Environment" \[ [IEEE Std 1003.1-2013](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-IEEEStd1003.1-2013) \].) The behavior of a program that declares or defines an identifier in a context in which it is reserved or that defines a reserved identifier as a macro name is undefined. (See [undefined behavior 105](/sei-cert-c-coding-standard/back-matter/cc-undefined-behavior#CC.UndefinedBehavior-ub_105) .)
No other identifiers are reserved. (The POSIX standard extends the set of identifiers reserved by the C Standard to include an open-ended set of its own. See *Portable Operating System Interface \[POSIX <sup>®</sup> \], Base Specifications, Issue 8* , [Section 2.2](https://pubs.opengroup.org/onlinepubs/9799919799/functions/V2_chap02.html#tag_16_02) , "The Compilation Environment" \[ [IEEE Std 1003.1-2024](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-IEEEStd1003.1-2024) \].) The behavior of a program that declares or defines an identifier in a context in which it is reserved or that defines a reserved identifier as a macro name is undefined. (See [undefined behavior 105](/sei-cert-c-coding-standard/back-matter/cc-undefined-behavior#CC.UndefinedBehavior-ub_105) .)

## Noncompliant Code Example (Include Guard)

Expand Down Expand Up @@ -332,7 +332,7 @@ Using reserved identifiers can lead to incorrect program operation.

| | |
| --- | --- |
| \[ [IEEE Std 1003.1-2013](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-IEEEStd1003.1-2013) \] | Section 2.2, "The Compilation Environment" |
| \[ [IEEE Std 1003.1-2024](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-IEEEStd1003.1-2024) \] | Section 2.2, "The Compilation Environment" |
| \[ [ISO/IEC 9899:2024](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-ISO-IEC9899-2024) \] | 7.1.3, "Reserved Identifiers" 7.33.14, "Integer Types &lt;stdint.h&gt; " |


Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,13 @@ void func(char *input) {

This compliant solution is significantly different from the preceding noncompliant code example. First, `input` is incorporated into the `args` array and passed as an argument to `execve()` , eliminating concerns about buffer overflow or string truncation while forming the command string. Second, this compliant solution forks a new process before executing `"/usr/bin/any_cmd"` in the child process. Although this method is more complicated than calling `system()` , the added security is worth the additional effort.

The exit status of 127 is the value set by the shell when a command is not found, and POSIX recommends that applications should do the same. XCU, Section 2.8.2, of *Standard for Information Technology—Portable Operating System Interface (POSIX®), Base Specifications, Issue 7* \[ [IEEE Std 1003.1:2013](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-IEEEStd1003.1-2013) \], says
The exit status of 127 is the value set by the shell when a command is not found, and POSIX recommends that applications should do the same. XCU, Section 2.8.2, of *Standard for Information Technology—Portable Operating System Interface (POSIX®), Base Specifications, Issue 8* \[ [IEEE Std 1003.1:2013](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-IEEEStd1003.1-2024) \], says

> If a command is not found, the exit status shall be 127. If the command name is found, but it is not an executable utility, the exit status shall be 126. Applications that invoke utilities without using the shell should use these exit status values to report similar errors.
> The exit status of a command shall be determined as follows:
> If the command is not found, the exit status shall be 127.
> Otherwise, if the command name is found, but it is not an executable utility, the exit status shall be 126.
> Otherwise, if the command terminated due to the receipt of a signal, the shell shall assign it an exit status greater than 128. The exit status shall identify, in an implementation-defined manner, which signal terminated the command. Note that shell implementations are permitted to assign an exit status greater than 255 if a command terminates due to a signal.
> Otherwise, the exit status shall be the value obtained by the equivalent of the WEXITSTATUS macro applied to the status obtained by the wait() function (as defined in the System Interfaces volume of POSIX.1-2024). Note that for C programs, this value is equal to the result of performing a modulo 256 operation on the value passed to _Exit(), _exit(), or exit() or returned from main().

## Compliant Solution (Windows)

Expand Down Expand Up @@ -176,7 +180,7 @@ If the vulnerable program has elevated privileges, an attacker can manipulate th

## Compliant Solution (POSIX)

An alternative to invoking the `system()` call to execute an external program to perform a required operation is to implement the functionality directly in the program using existing library calls. This compliant solution calls the POSIX `unlink()` function to remove a file without invoking the `system()` function \[ [IEEE Std 1003.1:2013](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-IEEEStd1003.1-2013) [\]](https://pubs.opengroup.org/onlinepubs/9699919799/)
An alternative to invoking the `system()` call to execute an external program to perform a required operation is to implement the functionality directly in the program using existing library calls. This compliant solution calls the POSIX `unlink()` function to remove a file without invoking the `system()` function \[ [IEEE Std 1003.1:2024](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-IEEEStd1003.1-2024) [\]](https://pubs.opengroup.org/onlinepubs/9799919799/)

::code-block{quality="good"}
``` c
Expand Down Expand Up @@ -394,7 +398,7 @@ ENV33-C = Union( CWE-78, list), where list =

| | |
| --- | --- |
| \[ [IEEE Std 1003.1:2013](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-IEEEStd1003.1-2013) \] | XSH, System Interfaces, `exec` XSH, System Interfaces, `popen` XSH, System Interfaces, `unlink` |
| \[ [IEEE Std 1003.1:2013](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-IEEEStd1003.1-2024) \] | XSH, System Interfaces, `exec` XSH, System Interfaces, `popen` XSH, System Interfaces, `unlink` |
| \[ [Wheeler 2004](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-Wheeler04) \] | |


Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@ CWE-170 = Union( POS30-C, list) where list =
| |
|---------------------------------------------------------------------------------------------------------------|
| \[ [Ilja 2006](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-ilja06) \] |
| \[ [Open Group 1997a](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-OpenGroup97) \] |
| \[ [Open Group 2004](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-OpenGroup04) \] |
| \[ [Open Group 2024](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-OpenGroup24) \] |


Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ tags:
---
# POS34-C. Do not call putenv() with a pointer to an automatic variable as the argument

The POSIX function `putenv()` is used to set environment variable values. The `putenv()` function does not create a copy of the string supplied to it as an argument; rather, it inserts a pointer to the string into the environment array. If a pointer to a buffer of automatic storage duration is supplied as an argument to `putenv()` , the memory allocated for that buffer may be overwritten when the containing function returns and stack memory is recycled. This behavior is noted in the Open Group Base Specifications, Issue 6 \[ [Open Group 2004](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-OpenGroup04) \]:
The POSIX function `putenv()` is used to set environment variable values. The `putenv()` function does not create a copy of the string supplied to it as an argument; rather, it inserts a pointer to the string into the environment array. If a pointer to a buffer of automatic storage duration is supplied as an argument to `putenv()` , the memory allocated for that buffer may be overwritten when the containing function returns and stack memory is recycled. This behavior is noted in the Open Group Base Specifications, Issue 8 \[ [Open Group 2024](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-OpenGroup24) \]:

> A potential error is to call `putenv()` with an automatic variable as the argument, then return from the calling function while `string` is still part of the environment.

Expand Down Expand Up @@ -54,7 +54,7 @@ int func(const char *var) {
```
::

According to the \[ [Open Group 2004](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-OpenGroup04) \] entry for `putenv()` :
According to the \[ [Open Group 2024](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-OpenGroup24) \] entry for `putenv()` :

> ...the string pointed to by *string* shall become part of the environment, so altering the string shall change the environment.

Expand Down Expand Up @@ -86,9 +86,9 @@ int func(const char *var) {
```
::

The POSIX `setenv()` function is preferred over this function \[ [Open Group 2004](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-OpenGroup04) \]. In particular, using `putenv()` will necessarily leak memory if called multiple times for the same environment variable, due to restrictions on when you can safely free the old value. According to the \[ [Open Group 2004](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-OpenGroup04) \] entry for `putenv()` :
The POSIX `setenv()` function is preferred over this function \[ [Open Group 2024](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-OpenGroup24) \]. In particular, using `putenv()` will necessarily leak memory if called multiple times for the same environment variable, due to restrictions on when you can safely free the old value. According to the \[ [Open Group 2024](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-OpenGroup24) \] entry for `putenv()` :

> Although the space used by *string* is no longer used once a new string which defines *name* is passed to *putenv* (), if any thread in the application has used [*getenv* ()](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getenv.html) to retrieve a pointer to this variable, it should not be freed by calling [*free* ()](https://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html) . If the changed environment variable is one known by the system (such as the locale environment variables) the application should never free the buffer used by earlier calls to *putenv* () for the same variable.
> Although the space used by *string* is no longer used once a new string which defines *name* is passed to *putenv* (), if any thread in the application has used [*getenv* ()](https://pubs.opengroup.org/onlinepubs/9799919799/functions/getenv.html) to retrieve a pointer to this variable, it should not be freed by calling [*free* ()](https://pubs.opengroup.org/onlinepubs/9799919799/functions/free.html) . If the changed environment variable is one known by the system (such as the locale environment variables) the application should never free the buffer used by earlier calls to *putenv* () for the same variable.

## Compliant Solution ( `setenv()` )

Expand Down Expand Up @@ -164,6 +164,6 @@ CWE-391 = Union( ERR33-C, POS34-C, list) where list =
| --- | --- |
| \[ [Dowd 2006](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-Dowd06) \] | Chapter 10, "UNIX Processes" |
| \[ [ISO/IEC 9899:2024](https://www.securecoding.cert.org/confluence/display/seccode/AA.+Bibliography#AABibliography-ISOIEC9899-2024) \] | Section 6.2.4, "Storage Durations of Objects" Section 7.24.3, "Memory Management Functions" |
| \[ [Open Group 2004](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-OpenGroup04) \] | [`putenv()`](http://www.opengroup.org/onlinepubs/009695399/functions/putenv.html) [`setenv()`](http://www.opengroup.org/onlinepubs/009695399/functions/setenv.html) |
| \[ [Open Group 2024](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-OpenGroup24) \] | [`putenv()`](https://pubs.opengroup.org/onlinepubs/9799919799/functions/putenv.html) [`setenv()`](https://pubs.opengroup.org/onlinepubs/9799919799/functions/setenv.html) |


Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ CWE-764 is about semaphores, or objects capable of being locked multiple times.
| --- | --- |
| \[ [Dowd 2006](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-Dowd06) \] | Chapter 9, "UNIX 1: Privileges and Files" |
| \[ [ISO/IEC 9899:2024](https://www.securecoding.cert.org/confluence/display/seccode/AA.+Bibliography#AABibliography-ISOIEC9899-2024) \] | Section 7.23, "Input/output `&lt;stdio.h&gt;` " |
| \[ [Open Group 2004](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-OpenGroup04) \] | [lstat()](http://www.opengroup.org/onlinepubs/000095399/functions/lstat.html) [fstat()](http://www.opengroup.org/onlinepubs/009695399/functions/fstat.html) [open()](http://www.opengroup.org/onlinepubs/009695399/functions/open.html) |
| \[ [Open Group 2024](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-OpenGroup24) \] | [lstat()](https://pubs.opengroup.org/onlinepubs/9799919799/functions/fstatat.html) [fstat()](https://pubs.opengroup.org/onlinepubs/9799919799/functions/fstat.html) [open()](https://pubs.opengroup.org/onlinepubs/9799919799/functions/open.html) |
| \[ [Seacord 2013](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-Seacord2013) \] | Chapter 8, "File I/O" |


Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ tags:

In case of set-user-ID and set-group-ID programs, when the effective user ID and group ID are different from those of the real user, it is important to drop not only the user-level privileges but also the group privileges. While doing so, the order of revocation must be correct.

POSIX defines `setgid()` to have the following behavior \[ [Open Group 2004](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-OpenGroup04) \]:
POSIX defines `setgid()` to have the following behavior \[ [Open Group 2024](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-OpenGroup24) \]:

> If the process has appropriate privileges, `setgid()` shall set the real group ID, effective group ID, and the saved set-group-ID of the calling process to `gid` .
>
Expand Down Expand Up @@ -196,7 +196,7 @@ CWE-696 = Union( POS36-C, list) where list =
| --- | --- |
| \[ [Chen 2002](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-Chen02) \] | "Setuid Demystified" |
| \[ [Dowd 2006](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-Dowd06) \] | Chapter 9, "UNIX I: Privileges and Files" |
| \[ [Open Group 2004](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-OpenGroup04) \] | [`setuid()`](http://www.opengroup.org/onlinepubs/009695399/functions/setuid.html) [`setgid()`](http://www.opengroup.org/onlinepubs/009695399/functions/setgid.html) |
| \[ [Open Group 2024](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-OpenGroup24) \] | [`setuid()`](https://pubs.opengroup.org/onlinepubs/9799919799/functions/setuid.html) [`setgid()`](https://pubs.opengroup.org/onlinepubs/9799919799/functions/setgid.html) |
| \[ [Tsafrir 2008](/sei-cert-c-coding-standard/back-matter/aa-bibliography#AA.Bibliography-Tsafrir08) \] | "The Murky Issue of Changing Process Identity: Revising 'Setuid Demystified'" |


Loading