Main Content

CERT C: Rule MSC30-C

Do not use the rand() function for generating pseudorandom numbers

Description

Rule Definition

Do not use the rand() function for generating pseudorandom numbers.1

Polyspace Implementation

The rule checker checks for Use of rand() for Generating Pseudorandom Number.

Examples

expand all

Issue

This issue occurs when you use the function rand for generating pseudorandom numbers.

Risk

The function rand is cryptographically weak. That is, the numbers generated by rand can be predictable. Do not use pseudorandom numbers generated from rand for security purposes. When a predictable random value controls the execution flow, your program is vulnerable to attacks.

Fix

Use more cryptographically sound pseudorandom number generators (PRNG), such as CryptGenRandom (Windows), OpenSSL/RAND_bytes(Linux/UNIX), or random (POSIX).

Example - Random Loop Numbers
#include <stdio.h>
#include <stdlib.h>

volatile int rd = 1;
int main(int argc, char *argv[])
{   
	int j, r, nloops;
	struct random_data buf;
	int i = 0;
	
	nloops = rand(); //Noncompliant
	
	for (j = 0; j < nloops; j++) {
		i = rand(); //Noncompliant
		printf("random_r: %ld\n", (long)i);
	}
	return 0;
}

This example uses rand to generate random numbers nloops and i. The predictability of these variables makes these function vulnerable to attacks.

Correction — Use Stronger PRNG

One possible correction is to replace the vulnerable PRNG with a stronger random number generator. For instance, this code uses the PRNG random() from POSIX library. random is a much stronger PRNG because it can be seeded by a different number every time it is called.

  
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define TIME_UTC 1
volatile int rd = 1;
int randomWrapper(){
	struct timespec ts;
  if (timespec_get(&ts, TIME_UTC) == 0) {
    /* Handle error */
  }
  srandom(ts.tv_nsec ^ ts.tv_sec);  /* Seed the PRNG */
	return random();
}
int main(int argc, char *argv[])
{   
    int j, r, nloops;
    struct random_data buf;
    int i = 0;
    
    nloops = randomWrapper();
    
    for (j = 0; j < nloops; j++) {
		i = randomWrapper();
        printf("random_r: %ld\n", (long)i);
    }
    return 0;
}

Check Information

Group: Rule 48. Miscellaneous (MSC)

Version History

Introduced in R2019a


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.