Main Content

Unsafe standard function

Function unsafe for security-related purposes

Description

This defect occurs when you use standard functions that are unsafe and must not be used for security-related programming. Functions can be unsafe for many reasons. Some functions are unsafe because they are nonreentrant. Other functions change behavior depending on the target or platform, making some implementations unsafe.

Risk

Some unsafe functions are not reentrant, meaning that the contents of the function are not locked during a call. So, an attacker can change the values midstream.

getlogin specifically can be unsafe depending on the implementation. Some implementations of getlogin return only the first eight characters of a log-in name. An attacker can use a different login with the same first eight characters to gain entry and manipulate the program.

Fix

Avoid unsafe functions for security-related purposes. If you cannot avoid unsafe functions, use a safer version of the function instead. For getlogin, use getlogin_r.

Examples

expand all

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
#include <string.h>
#include <stdlib.h>


volatile int rd = 1;

int login_name_check(char *user)
{
    int r = -2;
    char *name = getlogin();
    if (name != NULL)
    {
        if (strcmp(name, user) == 0)
        {
            r = 0;
        }
        else
            r = -1;
    }

    return r;
}

This example uses getlogin to compare the user name of the current user to the given user name. However, getlogin can return something other than the current user name because a parallel process can change the string.

Correction — Use getlogin_r

One possible correction is to use getlogin_r instead of getlogin. getlogin_r is reentrant, so you can trust the result.

#define _POSIX_C_SOURCE 199506L // use of getlogin_r
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
#include <string.h>
#include <stdlib.h>


volatile int rd = 1;

enum {  NAME_MAX_SIZE=64  };

int login_name_check(char *user)
{
    int r;
    char name[NAME_MAX_SIZE];
    
    if (getlogin_r(name, sizeof(name)) == 0) 
    {
        if ((strlen(user) < sizeof(name)) && 
                     (strncmp(name, user, strlen(user)) == 0))
        {
            r = 0;
        }
        else
            r = -1;
    }
    else
        r = -2;
    return r;
}

Result Information

Group: Security
Language: C | C++
Default: Off
Command-Line Syntax: UNSAFE_STD_FUNC
Impact: Medium

Version History

Introduced in R2015b