コメントは、proc_fd_linkをご覧ください。これは良い考えです。コードがどのようにそこに到達できるかに問題がある場合は、systemtapで自分自身を助けることができます。ここでは魔法のスクリプトさ:/ FDの下からファイルを開くとき
probe kernel.function("proc_fd_link") {
print_backtrace();
}
がそれを実行できます:
我々が見るproc_pid_get_linkで
0xffffffffbb2cad70 : proc_fd_link+0x0/0xd0 [kernel]
0xffffffffbb2c4c3b : proc_pid_get_link+0x6b/0x90 [kernel] (inexact)
0xffffffffbb36341a : security_inode_follow_link+0x4a/0x70 [kernel] (inexact)
0xffffffffbb25bf13 : trailing_symlink+0x1e3/0x220 [kernel] (inexact)
0xffffffffbb25f559 : path_openat+0xe9/0x1380 [kernel] (inexact)
0xffffffffbb261af1 : do_filp_open+0x91/0x100 [kernel] (inexact)
0xffffffffbb26fd8f : __alloc_fd+0x3f/0x170 [kernel] (inexact)
0xffffffffbb24f280 : do_sys_open+0x130/0x220 [kernel] (inexact)
0xffffffffbb24f38e : sys_open+0x1e/0x20 [kernel] (inexact)
0xffffffffbb003c57 : do_syscall_64+0x67/0x160 [kernel] (inexact)
0xffffffffbb8039e1 : return_from_SYSCALL_64+0x0/0x6a [kernel] (inexact)
:
/* Are we allowed to snoop on the tasks file descriptors? */
if (!proc_fd_access_allowed(inode))
goto out;
/* permission checks */
static int proc_fd_access_allowed(struct inode *inode)
{
struct task_struct *task;
int allowed = 0;
/* Allow access to a task's file descriptors if it is us or we
* may use ptrace attach to the process and find out that
* information.
*/
task = get_proc_task(inode);
if (task) {
allowed = ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS);
put_task_struct(task);
}
return allowed;
}
aaaand
明らかに、あなたはptraceで接続しているのと同じパーマです。
最後に、ソケットを開くのが失敗するのはなぜですか? straceはENXIOが返されることを示します。 。ENXIOのFS/* cは明らかに迅速にgit grepを:
static int no_open(struct inode *inode, struct file *file)
{
return -ENXIO;
}
コードがno_openを使用して終わるかチェックは読者の練習として残しています。また、ソースコードを変更せずにprintfのようなデバッグにsystemtapを使うこともできます。また、関数からの「戻り」に配置してエラーコードを報告することもできます。
興味深い質問です。 [proc_fd_link](http://elixir.free-electrons.com/linux/v4.12.1/source/fs/proc/fd.c#L138)で魔法が起こったようですが、これは '/ proc /自己/ fd/NUM'はへのリンクです。これは、オープンファイルテーブルから 'struct path *'(dentry、基本的に)をコピーするだけです。これは、dentryのinodeを開くための機能を実装するための元の 'struct path'を作成したものに任せます。この場合、[open_fifo](http://elixir.free-electrons.com/linux/v4.12.1/source/fs /pipe.c#L883)を 'fs/pipe.c'から削除します。 TIL:Linuxにはすべてのパイプが存在する "pipefs"があります。 –