Where does the Linux kernel code implement open ("/ proc / self / fd / NUM")?

I always assumed that execution is open(/proc/self/fd/NUM, flags)equivalent dup(NUM), but apparently it is not! For example, if you are a dupfile descriptor, set the new fd to non-blocking, this also affects the original file descriptor (since the non-blocking state is a property of the file description, and two file descriptors point to the same file description). However, if you open it /proc/self/fd/NUM, then you seem to get a new independent file description, and you can set the non-blocking state of your old and new fds yourself. You can even use this to get two file descriptions that link to the same anonymous channel, which is otherwise impossible ( example ). On the other hand, if you can dupfd socket,open("/proc/self/fd/NUM", flags) Failure if NUM refers to a socket.

Now I would like to see how it works for other types of special file, and answer questions such as “what kind of access control is performed when the file is opened again this way?”, So I tried to find code on Linux that really implements this path but when I started reading fs/proc/fd.c, I quickly got lost in the maze of winding structures of operations, all different.

So my question is: can someone explain the code path and then do it open("/proc/self/fd/NUM", flags)? For concreteness, let me say what NUMrelates to the pipe, and we are talking about the latest release of the kernel.

+4
source share
1 answer

proc_fd_link, . , , systemtap. script:

probe kernel.function("proc_fd_link") {
    print_backtrace();
}

fd/:

 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)

proc_pid_get_link :

/* Are we allowed to snoop on the tasks file descriptors? */
if (!proc_fd_access_allowed(inode))
        goto out;

aaaand

/* permission checks */
static int proc_fd_access_allowed(struct inode *inode)
{
        struct task_struct *task;
        int allowed = 0;
        /* Allow access to a task 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;
}

, , ptrace.

, ? strace , ENXIO. git grep ENXIO fs/*. C :

static int no_open(struct inode *inode, struct file *file)
{
        return -ENXIO;
}

, no_open, . , systemtap printf, . "" .

+3

Source: https://habr.com/ru/post/1681308/


All Articles