`

C库需要注意的函数

阅读更多
 

Table of C Library Functions

 The table below explains the necessary security considerations when using various C library functions. Each function is classified in one of the following categories.

UNRESTRICTED
This is the default for functions
USE WITH CAUTION
Allowed for use, but special care is needed when using these functions
AVOID
Use should be avoided as these functions are difficult to use securely
UNSAFE
These functions cannot be used securely so they should not to be used under any circumstances
 A
access
ascftime
asprintf
 B
bcopy
 C
catopen
cftime
chdir
chmod
chroot
chown
copylist
creat
 D
dbm_open
dlopen
dbminit
drand48
dup
dup2
 E
erand48
execl
execlp
execv
execve
execvp
 F
fattach
fchmod
fchmodat
fchown
fdopen
fopen
fprintf
freopen
fscanf
fstat
fstatat
ftw
fwprintf
 G
getenv
getlogin
getpass
gets
 J
jrand48
 K
kvm_open
 L
lchown
lrand48
lstat
 M
memcpy
mkdir
mkdirat
mknod
mknodat
mkstemp
mktemp
mrand48
 N
nftw
nlist
nrand48
 O
open
 P
p2open
popen
printf
 R
rand
rand_r
random
 S
scanf
snprintf
sprintf
srand
srand48
sscanf
stat
strcadd
strcat
strccpy
strcpy
streadd
strecpy
strlcat
strlcpy
strncat
strncpy
strtrns
swprintf
syslog
system
 T
tempnam
tmpfile
tmpnam
tmpnam_r
truncate
 U
umask
utmpname
utmpxname
 V
vfprintf
vfscanf
vfwprintf
vprintf
vscanf
vsnprintf
vsprintf
vsscanf
vswprintf
vsyslog
vwprintf
 W
wprintf

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)
getline(buf, bufsize, stdin) New in Solaris 11

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 no 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.
Note
 When opening a file, consider if the file descriptor should be kept open across an exec() call.   In Solaris 11, you can specify O_CLOEXEC in the open flags to atomically mark the file descriptor to be closed by exec system calls.  In older releases, you will need to use fcntl() with the FD_CLOEXEC flag, which allows a race condition in multithreaded programs, if another thread forks and execs between the open() and fcntl() calls.

dup

int dup(int fildes)
int dup2(int fildes, int fildes2)
Category
USE WITH CAUTION
Note
 dup() and dup2() both return file descriptors with the FD_CLOEXEC cleared so that they may leak when a program calls exec(). Older code made fcntl() calls shortly after these functions returned to set that flag, but in multi-threaded 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. The F_DUPFD_CLOEXEC & F_DUP2FD_CLOEXEC calls to fcntl (available in Solaris 11 and later releases) combine the duplication & flag setting into an atomic operation so there is no race.
Alternative
fcntl(fildes, F_DUPFD_CLOEXEC, 0)
fcntl(fildes, F_DUP2FD_CLOEXEC, fildes2)

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)
int fstatat(int fildes, const char *path, struct stat *buf, int flag)
Category
USE WITH CAUTION
Note
None of these functions is suitable to check for the existence or absence of a file. lstat()/stat()/fstatat() 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, &statbuf);

 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 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)
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()).
 Solaris 11 has added the POSIX 2008 *at() versions of the system calls that operate on files (openat(), linkat(), mkdirat(), mkfifoat(), readlinkat(), symlinkat(), etc.) which take the file descriptor of a directory as the first argument, to use as the working directory for relative paths, to avoid the race condition when one thread calls chdir() while another is calling open(), unlink(), etc.

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().
Alternative
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)
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()
 asprintf() New in Solaris 11

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 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)
Category
USE WITH CAUTION
Note
Be careful about the path used. These functions 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() to create a file, mkdtemp() to create a directory.

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.
分享到:
评论

相关推荐

    信捷 TouchWin C函数功能块用户手册.zip

    因此在介绍中只使用了一些简单易懂的C函数知识,主要目的是让客户找到了解这个功能,知道一些基本的书写规则,了解在使用过程中的一些注意事项。信捷人机界面软件TouchWin支持C语言的多数函数库,详细的函数使用请...

    c语言函数库 标准 使用

    很好的c语言资料,适合大部分朋友使用,有很多以前没有注意到的函数

    getchar函数是C语言标准库.pdf

    getchar函数的功能 getchar函数读取到用户输入的字符后,将该字符...需要注意的是,getchar函数每次只能读取一个字符,如果需要读取多个字符,需要多次调用getchar函数。如果需要读取整行输入,可以考虑使用fgets函数。

    lua调用c函数库的demo

    lua调用c函数库的demo 其中实现了对一个 数组的管理。 注意lua参数与c函数的对应, 如:b=lua_dllb.getarray(a,1) static int getarray(lua_State* L) { NumArray * a=(NumArray*)lua_touserdata(L,1); //对应lua...

    Java JNI调用C语言写的清屏的动态链接库

    用c语言写了一个清屏的函数,然后生成动态链接库,再通过jni在java里调用清屏函数。请注意代码中的函数JNIEXPORT void JNICALL Java_Test_cls(JNIEnv *env, jobject obj),函数名字的Test是指使用该函数的Java类的...

    strcmp在C语言中是什么意思:深入理解字符串比较函数

    内容涵盖strcmp函数的基本用法、工作原理、注意事项、示例代码、安全性、性能、多字节字符集处理、面试题、国际化处理、社区资源、标准库、函数指针使用、排序算法结合、错误处理和性能优化等高级特性。 **适用人群...

    C语言中输入函数(scanf()、fgets()和gets())的区别详解

    大家都知道在C语言中,有三种主要的输入函数:scanf(),fgets()以及gets()。他们的使用方法及注意事项如下: 1.scanf() 它是一种格式化的输入方式,可一次性按照规定的格式输入多个数据域。 scanf函数是一个标准...

    MATLAB_C++数学函数库在测量程序开发中的应用.pdf

    比较了MATLAB几种应用程序接口方法,详细介绍了在VisualC++6.0中调用MATLAB C++数学函数库的步骤,通过示例说明了利用该法进行测量程序设计的优越性及应注意的问题。

    用于查找给定的项目在给定文本文件中的存在性的C函数(含头文件、静态库、动态库和说明文档)

    - 本函数以C语言写就,并以标准的C格式导出;所用IDE为Microsoft Visual Studio 2019,编译器遵循C17标准; - 请注意,目标文本文件的一行被视为一个项目,即以`'\n'`分隔项目,若您的目标文本文件非此格式,烦请稍...

    c语言基于stdarg.h的可变参数函数的用法

    C语言编程中有时会遇到一些参数个数可变的函数,本文详细讲解了可变参数函数的实现原理,分享给大家 在开始学习C语言的函数的时候,我们就知道函数的参数个数应该是...这个用法需要引用一些宏,这些宏定义在C标准库“std

    STM32F4 SysTick定时器配置延时函数,库函数 精准毫秒级延时

    使用STM32F4的SysTick定时器配置延时函数,使用时注意根据自己板子的晶振修改stm32f4xx.h中的HSE_VALUE宏定义和system_stm32f4xx.c中的PLL_M宏定义

    API之网络函数---整理网络函数及功能

    GetFileVersionInfoSize 针对包含了版本资源的一个文件,判断容纳文件版本信息需要一个多大的缓冲区 GetFullPathName 获取指定文件的完整路径名 GetLogicalDrives 判断系统中存在哪些逻辑驱动器字母 ...

    C语言编程注意事项.docx

    C语言编程注意事项 1. 每个程序中一定包含main()函数, 尽管C语言中对函数命名没有限制。 2. printf函数永远不会自动换行, 只能用\n来实现, 回车键进行的换行在编译中会出现错误信息。 3. 在vs2008等平台中编译、...

    linux下C++动态链接C++库示例

    注意其中使用函数返回基类指针的用法,因为Linux的动态链接库不能像MFC中那样直接导出类 一、介绍 如何使用dlopen API动态地加载C++函数和类,是Unix C++程序员经常碰到的问题。 事实上,情况偶尔有些复杂,需要...

    C#调用非托管动态库中的函数方法

    C#如何调用一个非托管动态库中的函数呢,比如用VC6写的动态库,总之C#调用动态库的过程是比Java调用DLL动态库方便快捷多了,下面举例说明这个过程。 1、创建一个非托管动态库 代码如下: 代码如下:  //这一句是...

    C++中使用标准库中的函数来进行大小写字母的转换

     c 大小写字母转换 示例中,我们使用了toupper()和tolower()函数来分别将字符 'a' 转换为大写和小写。你可以用这些函数来处理...注意:这些函数只会对字母字符进行大小写转换,对于非字母字符,它们不会产生任何影响。

    教你用C语言写一个鼠标信息检测工具 包含easyx图形库

    这段代码是一个使用C语言中的graphics.h库和conio.h库实现的基本图形窗口操作示例。...需要注意的是,这段代码需要在支持graphics.h库的编译环境中运行。如果编译环境不支持该库,代码可能无法编译通过或运行。

    2011年3月全国计算机等级考试二级C语言上机题库

    注意:源程序存放在考生文件夹下的BLANK1.C中。 不得增行或删行,也不得更改程序的结构! #include double f1(double x) { return x*x; } double f2(double x, double y) { return x*y; } /**********found******...

    C240X系列DSP定点数学函数库的应用 (2005年)

    本文介绍了该数学函数库的使用方法和要注意的问题,并在相同硬件条件下进行了执行定点函数和浮点函数的对比实验,结果表明合理使用定点数学函数可以显著提升C语言DSP程序的执行效率,对定点DSP应用系统的高级语言...

    python3中datetime库,time库以及pandas中的时间函数区别与详解

    1介绍datetime库之前 我们先比较... 需要注意的是在该模块中的大多数函数是调用了所在平台C library的同名函数, 所以要特别注意有些函数是平台相关的,可能会在不同的平台有不同的效果。另外一点是,由于是基于Unix Ti

Global site tag (gtag.js) - Google Analytics