SV.USAGERULES.PROCESS_VARIANTS
Exposure to privilege escalation in process
Some process-creation system calls provide exposure to local privilege escalation. These calls are prone to attacks that allow execution of malicious code with the privileges of the host process. The SV.USAGERULES.PROCESS_VARIANTS checker flags the following system calls:
- CreateProcess
- CreateProcessAsUser
- CreateProcessWithLogon
- ShellExecute
- ShellExecuteEx
- WinExec
- system
- _wsystem
- _*exec*
- _*spawn*
Vulnerability and risk
If a process-creation system call doesn't contain the full path of the .exe executable properly before calling the process-creation API, it creates an opportunity for attack. A search path vulnerability can allow local users to gain privileges using a malicious .exe file.
Mitigation and prevention
To prevent exposure, use fork (not vfork), execve, and pipes to control process execution completely.
Vulnerable code example 1
In this example, Klocwork flags the use of the function execlp in line 4. This system call provides possible exposure to local privilege escalation through a malicious .exe file.
#include <process.h>
void foo() {
_execlp("li", "li", "-al", 0);
_wexeclp((wchar_t *)"li", (wchar_t *)"li", (wchar_t *)"-al", 0);
}
Fixed code example 1
In the fixed code, the function execlp has been replaced by execve, which controls process execution, eliminating the possibility of privilege escalation.
#include <process.h>
void foo() {
execve("li", "li", "-al", 0);
}
Vulnerable code example 2
In this example, Klocwork reports the SV.USAGERULES.PROCESS_VARIANTS error on line 13. System function call commands are executed by the host environment shell without any checks, providing exposure to local privilege escalation.
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(int argc, char *argv[]) {
int fd;
if ((fd = open(argv[1], 0)) == -1) {
error("can't open %s", argv[1]);
return -1;
}
if (argc == 2) {/* execute command */
if (system("/bin/sh/", "sh", "-c", argv[1], (char*) 0)) { /* SV.USAGERULES.PROCESS_VARIANTS reported here */
/* some code */
} else {
error("can't execute %s", argv[1]);
}
}
}
Fixed code example 2
In the fixed example, the system function has once again been replaced by execve, which controls process execution and eliminates the possibility of privilege escalation.
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(int argc, char *argv[]) {
int fd;
if ((fd = open(argv[1], 0)) == -1) {
error("can't open %s", argv[1]);
return -1;
}
if (argc == 2) {/* execute command */
if (execve ("/bin/sh/", "sh", "-c", argv[1], (char*) 0)) { * / SV.USAGERULES.PROCESS_VARIANTS not reported */
/* some code */
} else {
error("can't execute %s", argv[1]);
}
}
}
External guidance
Security training
Application security training materials provided by Secure Code Warrior.