linux /dev/null 中有数据

前段时间有个同事问我说,他 cat /dev/null有数据。这个颠覆大家认知的问题最终却是个小问题。

我们来看/dev/null的操作函数:

static const struct memdev {
	const char *name;
	umode_t mode;
	const struct file_operations *fops;
	struct backing_dev_info *dev_info;
} devlist[] = {
	 [1] = { "mem", 0, &mem_fops, &directly_mappable_cdev_bdi },
#ifdef CONFIG_DEVKMEM
	 [2] = { "kmem", 0, &kmem_fops, &directly_mappable_cdev_bdi },
#endif
	 [3] = { "null", 0666, &null_fops, NULL },-------------操作/dev/null的ops
#ifdef CONFIG_DEVPORT
	 [4] = { "port", 0, &port_fops, NULL },
#endif
	 [5] = { "zero", 0666, &zero_fops, &zero_bdi },
	 [7] = { "full", 0666, &full_fops, NULL },
	 [8] = { "random", 0666, &random_fops, NULL },
	 [9] = { "urandom", 0666, &urandom_fops, NULL },
#ifdef CONFIG_PRINTK
	[11] = { "kmsg", 0644, &kmsg_fops, NULL },
#endif
#ifdef CONFIG_CRASH_DUMP
	[12] = { "oldmem", 0, &oldmem_fops, NULL },
#endif
};

static const struct file_operations null_fops = {
    .llseek     = null_lseek,
    .read       = read_null,
    .write      = write_null,
    .aio_read   = aio_read_null,
    .aio_write  = aio_write_null,
    .splice_write   = splice_write_null,
};

  很显然,我们应该看read_null和write_null的实现,

static ssize_t read_null(struct file *file, char __user *buf,
			 size_t count, loff_t *ppos)
{
	return 0;
}

static ssize_t write_null(struct file *file, const char __user *buf,
			  size_t count, loff_t *ppos)
{
	return count;
}

  很显然,不应该有任何内容存在才对,因为往/dev/null里面写的时候,直接return count,读的时候,啥都不返回,那为什么会有数据呢?

再仔细一看,这个/dev/null有点蹊跷:

[root@centos7 stap_all]# ls -alrt /dev/null
rw-r-r-. 1 root root 1, 3 7月   6 09:35 /dev/null

  而正常的/dev/null的权限是:

[root@localhost ~]# ls -alrt /dev/null
crw-rw-rw- 1 root root 1, 3 Aug  1 17:51 /dev/null

 一开始想不明白,然后我手贱删除/dev/null再touch /dev/null,却复现了这个问题。

[root@centos7 ~]# rm /dev/null && touch /dev/null
rm:是否删除字符特殊文件 "/dev/null"?y
[root@centos7 ~]# ls -alrt /dev/null
-rw-r--r--. 1 root root 157 8月   7 20:00 /dev/null

  然后再cat一下:

[root@centos7 ~]# cat /dev/null
--2018-08-07 20:00:50--  http://10.47.242.88:3220/getdevid_type
正在连接 10.47.242.88:3220... 失败:没有到主机的路由。
。

  好吧,其实就是因为某个进程做了跟我类似的动作导致的。

接下来,使用audit来抓这个进程就ok了。

水平有限,如果有错误,请帮忙提醒我。如果您觉得本文对您有帮助,可以点击下面的 推荐 支持一下我。版权所有,需要转发请带上本文源地址,博客一直在更新,欢迎 关注 。
原文地址:https://www.cnblogs.com/10087622blog/p/9358648.html