linux mktemp 不可重入 问题

问题起源:

lighttpd 在接收到上传数据(PUT/POST),会生成大小为1M的很多临时文件。

线上最近有很多上传请求,lighttpd 经常报警,说上传的临时文件丢失,


分析

起初怀疑是被其它程序删除,后来勇哥提到,会不会是我们生成临时文件的方法有问题,生成了重名的临时文件?

查了lighttpd 的实现,使用的是mktemp函数:



http://linux.die.net/man/3/mktemp


If the call was successful, the last six bytes of template will have been modified in such a way that the resulting name is unique (does not exist already). If the call was unsuccessful, template is made an empty string.

Never use mktemp(). Some implementations follow 4.3BSD and replace XXXXXX by the current process ID and a single letter, so that at most 26 different names can be returned.



The tempnam() function is re-entrant while mktemp() isn't
不可重入,可能两个进程产生同一个文件名


实验:


a.c

#include<stdio.h>

int main(){

   int i = 0;

   for (i=0; i< 1024*1024*8; i++){

       char s[200] = "/tmp/XXXXXX";                                                                                                                         

       mktemp(s);

       printf("%s\n", s);

   }

}~  



ning@ning-baidu ~/idning/langtest/c/mktemp$ cc a.c
/tmp/ccXoEO8Z.o: In function `main':
a.c:(.text+0x63): warning: the use of `mktemp' is dangerous, better use `mkstemp' or `mkdtemp'
ning@ning-baidu ~/idning/langtest/c/mktemp$ ./a.out > /tmp/x
^C
ning@ning-baidu ~/idning/langtest/c/mktemp$ cat /tmp/x | sort | uniq -c | sort -nr | head
     2 /tmp/ywysSJ
     2 /tmp/YbfzNb
     2 /tmp/wzJUMa
     2 /tmp/WwwcEJ
     2 /tmp/wV6oJe
     2 /tmp/wjsmMR
     2 /tmp/WIefPG
     2 /tmp/wbOxzX
     2 /tmp/UPUz9A
     2 /tmp/uGJcIG


可以看出确实有重名文件生成。

lighttpd源码中使用了:
#define mkstemp(x) open(mktemp(x), O_RDWR)


解决

建议去掉该#define,直接使用可重入的 mkstemp ,它会返回:
fd = __open (tmpl,
              (flags & ~O_ACCMODE)
              | O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);    
打开的文件


Warning: Between the time the pathname is constructed and the file is created another process might have created a file with the same name using mktemp , leading to a possible security hole. The implementation generates names which can hardly be predicted, but when opening the file you should use the O_EXCL flag. Using mkstemp is a safe way to avoid this problem.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值