| | | | |
---|
access() | int access(const char *path, in mode) | AVOID | The information this function provides is outdated by the time you receive it. Using theaccess() function followed by theopen() function causes a race condition that cannot be solved. | Open the file with the permissions of the intended user. |
bcopy() | void bcopy(const void *s1, void *s2, size_t n) void *memcpy(void *s1, const void *s2, size_t n) | USE WITH CAUTION | Should not be used for copying strings, even though the length is known. Instead, use thestrlcpy() function. | NA |
catopen() | nl_catd catopen(const char *name, int oflag) | USE WITH CAUTION | Libraries and programs should not call thecatopen() function on user-supplied pathnames. User-supplied message catalogues can be leveraged to break privileged code easily. | NA |
cftime() | int cftime(char *s, char *format, const time_t *clock) int ascftime(char *s, const char *format, const struct tm *timeptr) | UNSAFE | These functions do not check for bounds on the output buffer and might import the user data through theCFTIME environment variable. | strftime(buf, sizeof (buf), fmt, &tm) |
chdir() | int chdir(const char *path) | USE WITH CAUTION | Prone to pathname race conditions. Do not use in multithreaded programs. | To avoid the race condition, use thefchdir() function after the directory has been opened and the properties have been checked using thefstat() function). Oracle Solaris 11 has added the POSIX 2008*at() versions of the system calls that operate on files such asopenat(),linkat(),mkdirat(),mkfifoat(),readlinkat(), andsymlinkat(). These calls take the file descriptor of a directory as the first argument to use as the working directory for relative paths. These methods avoid the race condition when one thread callschdir() while another is callingopen(),unlink() and the like. |
chmod() | int chmod(const char *path, mode_t mode) int fchmodat(int fd, const char *path, mode_t mode, int flag) int chown(const char *path, uid_t owner, gid_t group) int lchown(const char *path, uid_t owner, gid_t group) | AVOID | These functions operate on pathnames and are prone to race conditions. Normally, programs need not callchown() orchmod(), but honor the currentUID (switch back to it before opening files) and umask. Note thatchmod() always follows symbolic links. | If the attributes of a file must be changed, open the file safely and use thefchown() or thefchmod() functions on the resulting file descriptor. |
chroot() | int chroot(const char *path) | USE WITH CAUTION | After thechroot() function is called, the environment in which it is called offers little protection. Programs can easily escape. Do not run privileged programs in such a environment and that you change the directory to a point below the new root after thechroot() function. | Run in a non-global zone. |
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) | USE WITH CAUTION | Used to open files and should only be used to open pathnames known to be safe. | NA |
dlopen() | void *dlopen(const char *pathname, int mode) | USE WITH CAUTION | Parameters passed to thedlopen() function 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 run beforedlopen() returns. | NA |
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) | AVOID | To generate random numbers for security or cryptography, use thegetrandom() function. | NA |
dup() | int dup(int fildes) int dup2(int fildes, int fildes2) | USE WITH CAUTION | Both thedup() and thedup2() functions return file descriptors with theFD_CLOEXEC cleared and therefore they might leak when a program callsexec(). Older code madefcntl() calls shortly after these functions returned to set that flag. But in multithreaded code (including programs that only run one thread themselves but may be linked with libraries that run additional threads), that leaves a window open for a race with another thread. TheF_DUPFD_CLOEXEC andF_DUP2FD_CLOEXE calls to fcntl (available in Oracle Solaris 11 and later releases) combine the duplication and flag setting into an atomic operation so there is no race. | fcntl(fildes, F_DUPFD_CLOEXEC, 0) fcntl(fildes, F_DUP2FD_CLOEXEC, fildes2) |
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[]) | USE WITH CAUTION | Make sure that the environment is sanitized and non-essential file descriptors are closed before running a new program. | NA |
execvp() | int execvp(const char *file, const char *argv[]) int execlp(const char *file, const char *arg0, ..., const char *argn, NULL) | AVOID | Too dangerous to use in libraries or privileged commands and daemons because they find the executable by searching the directories in thePATH environment variable, which is under the complete control of the user. They should be avoided for most other programs. | Use theexecl(),execv(), orexecve() functions. |
fattach() | int fattach(int filedes, const char *path) | USE WITH CAUTION | Check the file descriptor after theopen() function (usingfstat()), and not the pathname before theopen() function. | NA |
fchmod() | int fchmod(int filedes, mode_t mode) int fchown(int filedes, uid_t owner, gid_t group) | UNRESTRICTED | Preferred alternative tochmod() andchown() functions. | NA |
fdopen() | FILE *fdopen(int filedes, const char *mode) | UNRESTRICTED | Alternative forfopen() | NA |
fopen() | FILE *fopen(const char *path, const char *mode) FILE *freopen(const char *path, const char *mode, FILE *stream) | USE WITH CAUTION | It is not possible to safely create files by usingfopen(). However, once a pathname is verified to exist, that is, after calling themkstemp() function, it can be used to open those pathnames. In other cases, a safe invocation ofopen() followed byfdopen() should be used. | Useopen() followed byfdopen(), For example: FILE *fp; int fd;fd = open(path,O_CREAT|O_EXCL|O_WRONLY,0600); if (fd < 0){...... }fp = fdopen(fd, "w"); |
fstat() | int fstat(int filedes, struct stat *buf) | UNRESTRICTED | Useful to check whether the file that is opened is the file you expected to open. | NA |
ftw() | int ftw(const char *path, int (*fn)(), int depth) int nftw(const char *path, int (*fn)(), int depth, int flags) | USE WITH CAUTION | Follows symbolic links and crosses mount points. | Use nftw with the appropriate flags set (a combination ofFTW_PHYS andFTW_MOUNT). |
getenv() | char *getenv(const char *name) | USE WITH CAUTION | The environment is completely user-specified. If possible, avoid the use ofgetenv() in libraries. Strings returned bygetenv() can be up toNCARGS bytes long (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 (includingcatopen() anddlopen()). | NA |
getlogin() | char *getlogin(void) | AVOID | The value returned bygetlogin() is not reliable. It is only a hint for the user name. | NA |
getpass() | char *getpass(const char *prompt) | AVOID | Only the first 8 bytes of input are used. Avoid using it in new code. | Use thegetpassphrase() function. |
gets() | char *gets(char *s) | UNSAFE | This function does not check for bounds when storing the input. This function cannot be used securely. | Usefgets(buf, sizeof (buf), stdin) ORgetline(buf, bufsize, stdin). Thegetline(buf, bufsize, stdin) function is new in Oracle Solaris 11. |
kvm_open() | kvm_t *kvm_open(char *namelist, char *corefile, char *swapfile, int flag, char *errstr) int nlist(const char *filename, struct nlist *nl) | AVOID | 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. Otherwise, a specifically constructed namelist can be used to read random parts of the kernel, revealing possibly sensitive data. | NA |
lstat() | int lstat(const char *path, struct stat *buf) int stat(const char *path, struct stat *buf) int fstatat(int fildes, const char *path, struct stat *buf, int flag) | USE WITH CAUTION | Do not use these functions to check for the existence or absence of a file. Thelstat(),stat(), orfstatat() functions followed byopen() have an inherent race condition. | If the purpose is to create the file that does not 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, &statbuf); If the pathname can't be trusted, addO_NONBLOCK to the open flags. This prevents the application from freezing upon opening a device. |
mkdir() | int mkdir(const char *path, mode_t mode) int mkdirat(int fd, const char *path, mode_t mode) int mknod(const char *path, mode_t mode, dev_t dev) int mknodat(int fd, const char *path, mode_t mode, dev_t dev) | USE WITH CAUTION | Be careful about the path used. These functions will not follow symbolic links for the last component and hence they are relatively safe. | NA |
mkstemp() | int mkstemp(char *template) | UNRESTRICTED | Safe temporary file creation function. | NA |
mktemp() | char *mktemp(char *template) | AVOID | Generates a temporary filename but the use of the generated pathname is not guaranteed safe because there is a race condition between the checks inmktemp() and the subsequent call toopen() by the application. | Usemkstemp() to create a file andmkdtemp() to create a directory. |
open() | int open(const char *path, int oflag, /* mode_t mode */...) int creat(const char *path, mode_t mode) | USE WITH CAUTION | When opening for reading from a privileged program, make sure that you open the file as a user by dropping privileges or setting the effectiveUID to the realUID. 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 usechown() on the file. 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 theO_NOFOLLOW andO_NOLINKS flags, or useO_CREAT|O_EXCL to ensure that a new file is created instead of opening an existing file. When opening a file, consider whether the file descriptor should be kept open across anexec() call. In Oracle Solaris 11, you can specifyO_CLOEXEC in the open flags to atomically mark the file descriptor to be closed by exec system calls. In older releases, you must use thefcntl() function with theFD_CLOEXEC flag, which allows a race condition in multithreaded programs, if another thread forks and runs between theopen() andfcntl() calls. | NA |
popen() | FILE *popen(const char *command, const char *mode) int p2open(const char *cmd, FILE *fp[2]) int system(const char *string) | AVOID | These three library calls always involve the shell which involves PATH, IFS, other environment variables and interpretation of special characters. ReferCERT C Coding Recommendation ENV04-C for more details. | Useposix_spawn() to run other programs,with waitpid() orpipe() as necessary. |
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, ...) | USE WITH CAUTION | At risk from user-specified format strings. If the format string comes from a message catalog, verify yourNLSPATH manipulations andcatopen() orcatget() uses. The C library tries to be safe by ignoringNLSPATH settings for setuid and setgid applications. | Thesnprintf() andvsnprintf() functions return the number of characters that would have been written to the buffer if it were large enough. You cannot use this value in constructs like,p += snprintf(p, lenp, "...") because p might point beyond p+lenp afterwards. |
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) | USE WITH CAUTION | When scanning strings, make sure the format specified includes maximum buffer lengths. Usescanf("%10s", p) to limitscanf() to read 10 characters at most. Note that the corresponding buffer must be at least eleven bytes to allow space for the terminatingNULL character. | NA |
sprintf() | int sprintf(char *s, const char *fmt, ...) int vsprintf(char *s, const char *fmt, va_list ap) | AVOID | Typically cause buffer overflow. If you must use these functions, make sure that the fmt argument cannot be user-controlled and that you can trust the parameters not to overflow the destination buffer. | Usesnprintf(),vsnprintf() orasprintf(). Theasprintf() function is new in Oracle Solaris 11. |
strcat() | char *strcat(char *s1, const char *s2) char *strcpy(char *s1, const char *s2) | AVOID | It is not possible to limit these functions to a maximum buffer size. However, you can calculate the amount of space required before calling strcat or strcpy. Use of these functions always forces reviewers to follow the logic, and prevent automated scanning of source code for vulnerabilities. | strlcat(dst, src, dstsize) strlcpy(dst, src, dstsize) |
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) | USE WITH CAUTION | Similar problems as withstrcpy(). See the strcpy and strccpy man pages for proper use. | NA |
strlcpy() | size_t strlcpy(char *dst, const char *src, size_t dstsize) size_t strlcat(char *dst, const char *src, size_t dstsize) | UNRESTRICTED | Preferred alternative to thestrcpy() and thestrcat() functions. Available in Solaris 8 and later. Should be used with constant and not computed size arguments to facilitate code review. | NA |
strncat() | char *strncat(char *s1, const char *s2, size_t n) char *strncpy(char *s1, const char *s2, size_t n) | USE WITH CAUTION | Thestrncpy() function is not guaranteed to null-terminate the destination buffer. Thestrncat() function is hard to use as it requires the proper size of the destination buffer to be calculated. The fact that thestrncpy() function does not null- terminate on insufficient space, together with the side effect that it will addNULL bytes if there is space left, makes it a useful function for updating structures that reside on disk. For example, the wtmpx files, are often generated with write (fd, w, sizeof (*w)); | strlcpy(dst, src, dstsize) strlcat(dst, src, dstsize) |
syslog() | void syslog(int priority, const char *message, ...) void vsyslog(int priority, const char *message, va_list ap) | USE WITH CAUTION | At risk from user-specified format strings. Verify yourNLSPATH manipulations andcatopen() orcatget() uses. | NA |
tempnam() | char *tempnam(const char *dir, const char *pfx) char *tmpnam(char *s) char *tmpnam_r(char *s) | AVOID | These functions are not suitable for generating unpredictable filenames. There is a race condition between the generation of the filename and its use, for example,open(). | mkstem() |
tmpfile() | FILE *tmpfile(void) | USE WITH CAUTION | Usesmkstemp(), so it is safe to use. However, because this function changes the umask, it is not multithread safe. | NA |
truncate() | int truncate(const char *path, off_t length) | AVOID | This function is prone to pathname race conditions. | Useftruncate() after a safeopen(). |
umask() | mode_t umask(mode_t cmask) | USE WITH CAUTION | Should not be used in libraries or applications; the user's umask should be used. Also it is not multithread safe. | NA |
utmpname() | int utmpname(const char *file) int utmpxname(const char *file) | AVOID | Use the defaultutmp andutmpx files. | NA |
wordexp() | int wordexp(const char *restrict words, wordexp_t *restrict pwordexp, int flags) | USE WITH CAUTION | wordexp() passes the input string to a shell for expansion. Input provided by untrusted sources may attempt to use shell injection attacks to run additional commands. | If only wildcard expansion is required, use theglob() function. |