我首先调用 close(1),然后使用 open() 系统调用打开一个文件。
open() 是否有可能返回 1,因为它将使用最低的空闲文件描述符?
我读过 open() 在这里使用最低的免费文件描述符。
我首先调用 close(1),然后使用 open() 系统调用打开一个文件。
open() 是否有可能返回 1,因为它将使用最低的空闲文件描述符?
我读过 open() 在这里使用最低的免费文件描述符。
Linux中所谓的“标准流”就是stdin、stdout、stderr。但它们必须被称为“标准”是有原因的。有非标准流吗?内核是否从根本上区别对待这些非标准流?
我对操作系统感兴趣。所以我正在阅读 xv6 书以了解操作系统。这是我关于这个主题的第一本书。我读了一句我听不懂。
在内部,xv6 内核使用文件描述符作为每个进程表的索引,因此每个进程都有一个从零开始的文件描述符的私有空间。
我认为文件描述符代表可以写入或读取的数据流。这与进程表有何关联?文件描述符表不是代表其打开文件资源的进程内存的一部分吗?
提前致谢!
我有一个C
程序来演示capability leak
关于 set-uid 的攻击。
// cap_leak.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
void main()
{
int fd; char *v[2];
/* Assume that /etc/zzz is an important system file, and it is owned by root with permission 0644. Before running this program, you should create the file /etc/zzz first. */
fd = open("/etc/zzz", O_RDWR | O_APPEND);
// Print out the file descriptor value
printf("fd is %d\n", fd);
if (fd == -1)
{
printf("Cannot open /etc/zzz\n");
exit(0);
}
// Permanently disable the privilege by making the
// effective uid the same as the real uid
setuid(getuid());
printf("Real user id is %d\n", getuid());
printf("Effective user id is %d\n", geteuid());
// Execute /bin/sh
v[0] = "/bin/sh"; v[1] = 0;
execve(v[0], v, 0);
}
最初,cat /etc/zzz
给出:
this is a very important file
现在我编译这个程序:
gcc -o cap_leak cap_leak.c
将所有者更改为 root 并打开 setuid 位:
sudo chown root cap_root
sudo chmod 4755 cap_root
现在,当我从普通用户运行程序时,我得到一个 shell 提示:
fd is 3
Real user id is 1000
Effective user id is 1000
$whoami
$seed
$echo bbbbbb >&3
$cat /etc/zzz
$this is a very important file
bbbbbb
最后一次写入fd = 3
ie/etc/zzz
是成功的,尽管在打开文件后setuid()
调用了该函数,该函数基本上将真实、有效和保存的 uid 设置为原始 uid。我的问题是,为什么最后一次写入是成功的,即使它是在之后执行的,setuid()
并且在这种情况下为了防止能力泄漏,应该把setuid()
它放在哪里,为什么?
我正在玩弄文件描述符以更好地理解它们,但我无法理解以下内容。
$ grep "..." 3>&1 1>/dev/null
1
12
13
123
321
3
上面没有在 shell 中显示任何匹配项,这显然是因为我正在重定向到 /dev/null。我不明白的是为什么3>&1
不让它让我仍然看到输出,因为我在 fd 3 中制作了它的副本。
我错过了什么?
我试图找出为什么我的长时间运行的应用程序有时会破坏最大打开文件描述符限制 ( ulimit -n
) 的原因。我想定期记录应用程序打开了多少文件描述符,以便我可以看到峰值发生的时间。
我知道这lsof
包括一堆被排除在外的项目/proc/$PID/fd
......这些项目与打开文件描述符限制相关吗?即我应该从lsof
还是从记录信息/proc/$PID/fd
?
有时您需要卸载文件系统或分离循环设备,但这是busy
因为打开的文件描述符,可能是因为smb
服务器进程。
要强制卸载,您可以终止有问题的进程(或 try kill -SIGTERM
),但这会关闭smb
连接(即使它打开的某些文件不需要关闭)。
这里使用gdb
to call描述了一种强制进程关闭给定文件描述符的 hacky 方法close(fd)
。然而,这似乎很危险。如果关闭的描述符被回收了怎么办?该进程可能使用旧的存储描述符,但没有意识到它现在指的是完全不同的文件。
我有一个想法,但不知道它有什么样的缺陷:使用gdb
,打开/dev/null
方式O_WRONLY
(编辑:建议O_PATH
作为更好的选择的评论),然后dup2
关闭有问题的文件描述符并将其描述符重用于/dev/null
. 这样,对文件描述符的任何读取或写入都将失败。
像这样:
sudo gdb -p 234532
(gdb) set $dummy_fd = open("/dev/null", 0x200000) // O_PATH
(gdb) p dup2($dummy_fd, offending_fd)
(gdb) p close($dummy_fd)
(gdb) detach
(gdb) quit
会出什么问题?
在“测试文件描述符是否有效”问题中,寻求测试文件描述符是否打开的测试。
答案都集中在测试文件描述符是否打开用于输出,但如何测试文件描述符是否打开用于输入?
这出现在评论线程中,以回答另一个问题,其中答案说,释义,
if [ -n "$1" ]; then
# read input from file "$1" (we're assuming it exists)
elif [ ! -t 0 ]; then
# read input from standard input (from pipe or redirection)
else
# no input given (we don't want to read from the terminal)
fi
问题[ ! -t 0 ]
在于,-t
如果文件描述符打开并与终端相关联,则测试为真。如果测试为假,那么描述符要么关闭,要么与终端无关(即我们正在从管道或重定向中读取)。因此,测试并[ ! -t 0 ]
不能保证文件描述符甚至是有效的。
如何确定它是否有效(这样read
就不会抱怨)或它是否已关闭?
我一直java.io.IOException: Too many open files
在运行 Kafka 实例并使用一个具有 1000 个分区的主题,因此我开始调查我的 ec2 vm 中的文件描述符限制。我无法理解 Centos 7 机器上打开文件的确切限制是什么,因为以下所有命令都会产生不同的结果。命令是:
ulimit -a
: 打开文件 1024lsof | wc -l
: 298280cat /proc/sys/fs/file-max
: 758881(与 一致/proc/sys/fs/file-nr
)如果实际限制是最后一个命令产生的限制,那么我远低于它(lsof | wc -l
:298280)。但如果是这种情况,ulimit
命令的输出对我来说很不清楚,因为我远远高于 1024 个打开的文件。
根据官方文档,在 Centos 中检查文件描述符的最佳方法是/proc/sys/fs/file-max
文件,但是这些命令之间是否存在所有这些看似“不一致”的地方?