红联Linux门户
Linux帮助

linux的一点小bug

发布时间:2008-01-09 00:50:56来源:红联作者:MONND
作者:梦婷轩
这也许不算是linux的漏洞吧,应该算是它的一点点不足之处了。至少我是不晓得它有什么威胁到系统安全的利用价值。 呵呵,可能是我才疏学浅。

大致情况是这样的,那天我们操作系统课安排上机。实验主题是让我们熟悉linux下的系统调用,尝试用fork()函数创建一个子进程。

我是刚接触linux不久,很多概念还不清晰。至于fork()函数调用了以后,系统到底做了些什么都不是很清楚。于是自己在电脑上一步一步尝试。

老师告诉我说,fork()执行以后,父进程和子进程共享代码段。但我还是不理解子进程运行的时候,到底是从头开始执行呢,还是从fork()开始执行。fork这个单词的字面意思是分叉,按这个逻辑来应该是从fork()这个语句开始执行,上面的语句应该是不执行的。于是,我写了下面这段代码检验我的推测:

#include
#include
#include

int main(void)
...{
int pid;

printf("1");
pid = fork();
printf("0 ");

return 0;
}

然后输入gcc main.c -o main进行编译,在执行"./main"运行,结果出来的是:

10
10

这输出了两个10,那不就是指printf(1)执行了2两次了?难道前面的代码会被运行吗?

不过同时我也发现我的程序有个失误,我的本意一个是让1单独占一行,却忘了加转义字符'\n'。于是重新打开main.c在1后面添加了回车。按上面的逻辑来,这回应该输出:

1
0
1
0

于是再编译,再运行。但结果出来的却是:

1
0
0

前后两段代码仅仅只差了一个回车。却有不同的效果。问题就出在这个回车上,我又写了另一段测试代码:

#include
#include
#include

int main(void)
...{
int pid;

printf("1\n");
printf("2");
pid = fork();
printf("0 ");

return 0;
}

运行结果是:

1
20
20

加了回车它就不会显示,把上面的代码作一下修改,1后面没有回车,2后面加回车。输出结果是:

12
0
0

我猜测可能是输出回车的同时,系统还会清理一下标准输入的缓存区。我们知道C语言里标准输出是stdout,那用fflush(stdout)来主动清空一下缓存,看看效果,来验证我的猜想。代码:

#include
#include
#include

int main(void)
...{
int pid;

printf("1");
fflush(stdout);
pid = fork();
printf("0 ");

return 0;
}

输出结果是:

10
0

看来是对了,问题就是没有情况缓冲区,子进程把父进程的输出缓冲内容一起copy过来了。

我换了几个系统试了一下,发现在Redhat, fedora这些系统里都有这个问题。不小的其他版本的linux也没有这个问题。

按上面的说法,我们在终端里每运行一个程序,它应该都有系统输出的一个拷贝(如果没有清空的话)。也不小的这个问题也没有什么利用价值,也许这个问题已经很早就有人发现了,大概是高手们觉得这个不算是漏洞,没有修复的必要吧。
文章评论

共有 1 条评论

  1. niutao0602 于 2008-01-09 11:06:56发表:

    这不是bug.
    fork()出来的子进程是对父进程的一个完全copy,也包括父进程打开的文件(其中就包括stdout文件)。在终端里运行一个程序系统确实是fork出一个子进程去执行该程序,但该子进程会完全脱离父进程。参考:
    http://groups.google.com/group/linuxerfamily/browse_thread/thread/1d11df6d807e4620#5d628f3345a40ebd
    http://www.linuxdiyf.com/blog/?87680/action_viewspace_itemid_2247.html