gets
char *gets(char *s)
- Category
- UNSAFE
- Note
- This function does not check for bounds while storing the input. This function can't be used securely.
- Alternative
- fgets(buf, sizeof (buf), stdin)
cftime
int cftime(char *s, char *format, const time_t *clock)
int ascftime(char *s, const char *format, const struct tm *timeptr)
- Category
- UNSAFE
- Note
- These routines do on bounds checking on the output buffer and may import user-data through the environment variable CFTIME.
- Alternative
- strftime(buf, sizeof (buf), fmt, &tm)
strcat
char *strcat(char *s1, const char *s2)
char *strcpy(char *s1, const char *s2)
- Category
- AVOID
- Note
- It is not possible to limit these functions to a maximum buffer size. Although one can calculate the amount of space needed before calling strcat or strcpy, the use of these functions will always force reviewers to follow the logic, and prevent automated scanning of source code for vulnerabilities.
- Alternative
- strlcat(dst, src, dstsize)
strlcpy(dst, src, dstsize)
strncat
char *strncat(char *s1, const char *s2, size_t n)
char *strncpy(char *s1, const char *s2, size_t n)
- Category
- USE WITH CAUTION
- Note
- strncpy() is not guaranteed to null-terminate the destination buffer. strncat() is hard to use as it requires the proper size of the destination buffer to be calculated.
- Note
- The fact that strncpy() does not null- terminate on insufficient space, together with the side effect that it will add NUL bytes if there is space left makes it a useful function for updating structures that reside on disk, for example wtmpx, which are often generated with write(fd, w, sizeof (*w));
- Alternative
- strlcpy(dst, src, dstsize)
strlcat(dst, src, dstsize)
strlcpy
size_t strlcpy(char *dst, const char *src, size_t dstsize)
size_t strlcat(char *dst, const char *src, size_t dstsize)
- Category
- UNRESTRICTED
- Note
- Preferred alternative to strcpy/strcat functions. Available in Solaris 8 and later. Should be used with constant and not computed size arguments to facilitate code review.
open
int open(const char *path, int oflag, /* mode_t mode */...)
int creat(const char *path, mode_t mode)
- Category
- USE WITH CAUTION
- Note
- When opening for reading from a privileged program, make sure that you open the file as the user by dropping privileges or setting the effective uid to the real uid. Under no circumstances should programs implement their own access control based on file ownership and modes. Similarly, when creating files, do not open() and then chown() the file.
- Note
- When opening for writing, the program can be tricked into opening the wrong file by following symbolic or hard links. To avoid this problem, either use the O_NOFOLLOW and O_NOLINKS flags, or use O_CREAT|O_EXCL to ensure that a new file is created instead of opening an existing file.
fopen
FILE *fopen(const char *path, const char *mode)
FILE *freopen(const char *path, const char *mode, FILE *stream)
- Category
- USE WITH CAUTION
- Note
- It's not possible to safely create files using fopen(). However, once a pathname is verified to exist, e.g., after mkstemp(), it can be used to open those pathnames. In other cases, a safe invocation of open() followed by fdopen() should be used.
- Alternative
- open() followed by fdopen(), e.g.:
FILE *fp;
int fd;
fd = open(path, O_CREAT|O_EXCL|O_WRONLY, 0600);
if (fd < 0) {
...
}
fp = fdopen(fd, "w");
fdopen
FILE *fdopen(int filedes, const char *mode)
- Category
- UNRESTRICTED
- Note
- Alternative for fopen()
access
int access(const char *path, in mode)
- Category
- AVOID
- Note
- This function is useless because the information it provides is outdated by the time you get to use it. Using access() followed by open() has a race condition that can't be solved.
- Alternative
- open() the file with the permissions of the intended user.
lstat
int lstat(const char *path, struct stat *buf)
int stat(const char *path, struct stat *buf)
- Category
- USE WITH CAUTION
- Note
- Neither of these functions is suitable to check for the existence or absence of a file. lstat()/stat() followed by open() has an inherent race condition that can't be solved.
- Alternative
; - If the purpose is to create the file if it doesn't exist, use
open(file, O_CREAT|O_EXCL, mode).
If the purpose is to read the file, open it for reading. If the purpose is to make sure the file attributes are correct before reading from it, use
fd = open(file, O_RDONLY);
fstat(fd, &stat);
If the pathname can't be trusted, add O_NONBLOCK to the open-flags. This prevents the application from hanging upon opening a device.
chmod
int chmod(const char *path, mode_t mode)
int chown(const char *path, uid_t owner, gid_t group)
int lchown(const char *path, uid_t owner, gid_t group)
- Category
- AVOID
- Note
- These functions operate on pathnames and are prone to race conditions. Normally, programs shouldn't need to call chown/chmod but honor the current uid (switch back to it before opening files.) and umask. Note that chmod() always follows symbolic links.
- Alternative
- If a file's attributes need to be changed, the best way to do this is to safely open the file and use fchown/fchmod on the resulting file descriptor.
fchmod
int fchmod(int filedes, mode_t mode)
int fchown(int filedes, uid_t owner, gid_t group)
- Category
- UNRESTRICTED
- Note
- Preferred alternative to chmod and chown.
fstat
int fstat(int filedes, struct stat *buf)
- Category
- UNRESTRICTED
- Note
- Useful for checking that the file you've just opened is the file you expected to open.
bcopy
void bcopy(const void *s1, void *s2, size_t n)
void *memcpy(void *s1, const void *s2, size_t n)
- Category
- USE WITH CAUTION
- Note
- Should not be used for copying strings, even though the length may be known. Use strlcpy() in those cases instead.
catopen
nl_catd catopen(const char *name, int oflag)
- Category
- USE WITH CAUTION
- Note
- Libraries and programs should not call catopen() on user supplied pathnames. User supplied message catalogues can be leveraged to break privileged code easily.
chdir
int chdir(const char *path)
- Category
- USE WITH CAUTION
- Note
- This function is open to pathname race conditions. Do not use in multi-threaded programs.
- Alternative
- To avoid the race condition, use fchdir() after the directory has been open()-ed and the properties have been checked using fstat()).
chroot
int chroot(const char *path)
- Category
- USE WITH CAUTION
- Note
- chroot'ed environments offer little protection; programs can easily escape. Make sure you run no privileged programs in a chroot()'ed environment and that you chdir() to a point below the new root after the chroot().
copylist
char *copylist(const char *filenm, off_t *szptr)
DBM *dbm_open(const char *file, int open_flags, mode_t file_mode)
int dbminit(char *file)
- Category
- USE WITH CAUTION
- Note
- These functions open files and should only be used to open known-safe pathnames.
dlopen
void *dlopen(const char *pathname, int mode)
- Category
- USE WITH CAUTION
- Note
- Parameters passed to dlopen should only be unqualified pathnames which are then found using the runtime linker's path, or full pathnames not in any way derived from user input (including from argv[0] !!!) There is no way to safely open a user-supplied shared object; the object's _init() function is executed before dlopen() returns.
drand48
double drand48(void)
double erand48(unsigned short xi[3])
long lrand48(void)long mrand48(void)
long jrand48(unsigned short xi[3])
long nrand48(unsigned short xi[3])
void srand48(long seedval)
int rand(void)
int rand_r(unsigned int *seed)
void srand(unsigned int seed)
long random(void)
- Category
- AVOID
- Note
- These are weak random number generators; they are not useful for increasing security. If you need random numbers for security, it's better to use /dev/urandom, which is available starting with Solaris 9.
execvp
int execvp(const char *file, const char *argv[])
int execlp(const char *file, const char *arg0, ..., const char *argn, NULL)
- Category
- AVOID
- Note
- These functions are too dangerous to use in libraries or privileged commands and daemons because they find the executable by searching the directories in the PATH environment variable, which is under the complete control of the user. They should be avoided for most other programs.
- Alternative
- Carefully use one of the exec* functions defined below.
execl
int execl(const char *path, const char *arg0, ..., const char *argn, NULL)
int execv(const char *path, char *const argv[])
int execve(const char *path, char *const argv[], char *const envp[])
- Category
- USE WITH CAUTION
- Note
- Make sure that the environment is sanitized and unneeded file descriptors are closed before executing a new program.
fattach
int fattach(int filedes, const char *path)
- Category
- USE WITH CAUTION
- Note
- Check the file descriptor after open (using fstat()), not the pathname before the open.
sprintf
int sprintf(char *s, const char *fmt, ...)
int vsprintf(char *s, const char *fmt, va_list ap)
- Category
- AVOID
- Note
- sprintf() and vsprintf() are typical buffer overflow causes. If, for whatever reason, you must use these functions, make sure that the fmt argument can't be user-controlled and that you can trust the parameters not to overflow the destination buffer.
- Alternative
- snprintf()/vsnprintf()
printf
int printf(const char *format, ...)
int vprintf(const char *format, va_list ap)
int fprintf(FILE *stream, const char *format, ...)
int vfprintf(FILE *stream, const char *format, va_list ap)
int snprintf(char *s, size_t n, const char *format, ...)
int vsnprintf(char *s, size_t n, const char *format, va_list ap)
int wprintf(const wchar_t *format, ...)
int vwprintf(const wchar_t format, va_list arg)
int fwprintf(FILE *stream, const wchar_t *format, ...)
int vfwprintf(FILE *stream, const wchar_t *format, va_list arg)
int swprintf(wchar_t *s, size_t n, const wchar_t *format, ...)
int vswprintf(wchar_t *s, size_t n, const wchar_t *format, va_list arg)
int asprintf(char **ret, const char *format, ...)
- Category
- USE WITH CAUTION
- Note
- At risk from user-specified format strings. If the format string comes from a message catalog, verify your NLSPATH manipulations and catopen()/catget() uses. (The C library tries to be safe by ignoring NLSPATH settings for set-uid and set-gid applications.)
- Note
- snprintf() and vsnprintf() return the number of characters that would have been written to the buffer if it were large enough. You can't use this value in constructs like:
p += snprintf(p, lenp, "...");
since p might point beyond p+lenp afterwards.
syslog
void syslog(int priority, const char *message, ...)
void vsyslog(int priority, const char *message, va_list ap)
- Category
- USE WITH CAUTION
- Note
- At risk from user-specified format strings. Verify your NLSPATH manipulations and catopen()/catget() uses.
scanf
int scanf(const char *format, ...)
int vscanf(const char *format, va_list arg)
int fscanf(FILE *stream, const char *format, ...)
int vfscanf(FILE *stream, const char *format, va_list arg)
int sscanf(const char *s, const char *format, ...)
int vsscanf(const char *s, const char *format, va_list arg)
- Category
- USE WITH CAUTION
- Note
- When scanning strings, make sure the format specified includes maximum buffer lengths, thus use
scanf("%10s", p);
to limit scanf() to reading 10 characters at most. Note that the corresponding buffer must be at least eleven bytes to allow space for the terminating NUL character.
ftw
int ftw(const char *path, int (*fn)(), int depth)
int nftw(const char *path, int (*fn)(), int depth, int flags)
- Category
- USE WITH CAUTION
- Note
- ftw follows symbolic links and crosses mount points.
- Alternative
- use nftw with the appropriate flags set (a combination of FTW_PHYS and FTW_MOUNT).
getenv
char *getenv(const char *name)
- Category
- USE WITH CAUTION
- Note
- The environment is completely user-specified. When possible, use of getenv() should be avoided in libraries. Strings returned by getenv() can be up to NCARGS bytes long (that's currently 1MB for 32-bit environments.) Pathnames derived from environment variables should not be trusted. They should not be used as input for any of the *open() functions (including catopen() and dlopen()).
getlogin
char *getlogin(void)
- Category
- AVOID
- Note
- The value returned by getlogin() is not reliable; it is a mere hint as to the user name.
getpass
char *getpass(const char *prompt)
- Category
- AVOID
- Note
- Only the first 8 bytes of input are used. Avoid using it in new code.
- Alternative
- getpassphrase().
kvm_open
kvm_t *kvm_open(char *namelist, char *corefile, char *swapfile, int flag, char *errstr)
int nlist(const char *filename, struct nlist *nl)
- Category
- AVOID
- Note
- Write a proper kstat or other interface if you need information from the kernel. If you accept a user-specified namelist argument, make sure you revoke privileges before using it. If you don't, a specifically constructed namelist can be used to read random parts of the kernel, revealing possibly sensitive data.
mkdir
int mkdir(const char *path, mode_t mode)
int mknod(const char *path, mode_t mode, dev_t dev)
- Category
- USE WITH CAUTION
- Note
- Be careful about the path used. mkdir() and mknod() will not follow symlinks for the last component, so they are relatively safe.
mkstemp
int mkstemp(char *template)
- Category
- UNRESTRICTED
- Note
- Safe temporary file creation function.
mktemp
char *mktemp(char *template)
- Category
- AVOID
- Note
- Generates temporary filename, but the use of the generated pathname is not guaranteed safe since there is a race condition between the checks in mktemp() and the subsequent open() by the application.
- Alternative
- Use mkstemp().
popen
FILE *popen(const char *command, const char *mode)
int p2open(const char *cmd, FILE *fp[2])
int system(const char *string)
- Category
- AVOID
- Note
- These three library calls always involve the shell which involves PATH, IFS, other environment variables and interpretation of special characters.
strccpy
char *strccpy(char *output, const char *input)
char *strcadd(char *output, const char *input)
char *streadd(char *output, const char *input)
char *strecpy(char *output, const char *input, const char *exceptions)
char *strtrns(const char *string, const char *old, const char *new, char *result)
- Category
- USE WITH CAUTION
- Note
- Similar problems as with strcpy(). See the manual pages on proper use.
tempnam
char *tempnam(const char *dir, const char *pfx)
char *tmpnam(char *s)
char *tmpnam_r(char *s)
- Category
- AVOID
- Note
- These functions are not suitable for generating unpredictable filenames. There is a race condition between the generation of the filename and its use in, e.g., open()
- Alternative
- mkstemp()
tmpfile
FILE *tmpfile(void)
- Category
- USE WITH CAUTION
- Note
- Uses mkstemp() since Solaris 2.6 or thereabouts, so is safe to use. However: since this function changes the umask, it is not multi-thread safe.
truncate
int truncate(const char *path, off_t length)
- Category
- AVOID
- Note
- This function is prone to pathname race conditions.
- Alternative
- Use ftruncate() after a safe open().
umask
mode_t umask(mode_t cmask)
- Category
- USE WITH CAUTION
- Note
- Shouldn't be used in libraries or applications; the user knows best and his umask should be used. Also not multi-thread safe.
utmpname
int utmpname(const char *file)
int utmpxname(const char *file)
- Category
- AVOID
- Note
- Use the default utmp and utmpx files.