lkml.org 
[lkml]   [2022]   [Jun]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    Subject[PATCH v2 2/2] procfs: Add 'path' to /proc/<pid>/fdinfo/
    From
    In order to identify the type of memory a process has pinned through
    its open fds, add the file path to fdinfo output. This allows
    identifying memory types based on common prefixes:
    e.g. "/memfd...", "/dmabuf...", "/dev/ashmem...".

    To be cautious, only expose the paths for anonymous inodes, and this
    also avoids printing path names with strange characters.

    Access to /proc/<pid>/fdinfo is governed by PTRACE_MODE_READ_FSCREDS
    the same as /proc/<pid>/maps which also exposes the file path of
    mappings; so the security permissions for accessing path is consistent
    with that of /proc/<pid>/maps.

    Signed-off-by: Kalesh Singh <kaleshsingh@google.com>
    ---

    Changes in v2:
    - Only add path field for files with anon inodes.

    Changes from rfc:
    - Split adding 'size' and 'path' into a separate patches, per Christian
    - Fix indentation (use tabs) in documentaion, per Randy

    Documentation/filesystems/proc.rst | 10 ++++++++++
    fs/libfs.c | 9 +++++++++
    fs/proc/fd.c | 13 +++++++++++--
    include/linux/fs.h | 1 +
    4 files changed, 31 insertions(+), 2 deletions(-)

    diff --git a/Documentation/filesystems/proc.rst b/Documentation/filesystems/proc.rst
    index 779c05528e87..ca23a9af4845 100644
    --- a/Documentation/filesystems/proc.rst
    +++ b/Documentation/filesystems/proc.rst
    @@ -1907,6 +1907,9 @@ All locks associated with a file descriptor are shown in its fdinfo too::

    lock: 1: FLOCK ADVISORY WRITE 359 00:13:11691 0 EOF

    +Files with anonymous inodes have an additional 'path' field which represents
    +the anonymous file path.
    +
    The files such as eventfd, fsnotify, signalfd, epoll among the regular pos/flags
    pair provide additional information particular to the objects they represent.

    @@ -1920,6 +1923,7 @@ Eventfd files
    mnt_id: 9
    ino: 63107
    size: 0
    + path: anon_inode:[eventfd]
    eventfd-count: 5a

    where 'eventfd-count' is hex value of a counter.
    @@ -1934,6 +1938,7 @@ Signalfd files
    mnt_id: 9
    ino: 63107
    size: 0
    + path: anon_inode:[signalfd]
    sigmask: 0000000000000200

    where 'sigmask' is hex value of the signal mask associated
    @@ -1949,6 +1954,7 @@ Epoll files
    mnt_id: 9
    ino: 63107
    size: 0
    + path: anon_inode:[eventpoll]
    tfd: 5 events: 1d data: ffffffffffffffff pos:0 ino:61af sdev:7

    where 'tfd' is a target file descriptor number in decimal form,
    @@ -1968,6 +1974,7 @@ For inotify files the format is the following::
    mnt_id: 9
    ino: 63107
    size: 0
    + path: anon_inode:inotify
    inotify wd:3 ino:9e7e sdev:800013 mask:800afce ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:7e9e0000640d1b6d

    where 'wd' is a watch descriptor in decimal form, i.e. a target file
    @@ -1992,6 +1999,7 @@ For fanotify files the format is::
    mnt_id: 9
    ino: 63107
    size: 0
    + path: anon_inode:[fanotify]
    fanotify flags:10 event-flags:0
    fanotify mnt_id:12 mflags:40 mask:38 ignored_mask:40000003
    fanotify ino:4f969 sdev:800013 mflags:0 mask:3b ignored_mask:40000000 fhandle-bytes:8 fhandle-type:1 f_handle:69f90400c275b5b4
    @@ -2018,6 +2026,7 @@ Timerfd files
    mnt_id: 9
    ino: 63107
    size: 0
    + path: anon_inode:[timerfd]
    clockid: 0
    ticks: 0
    settime flags: 01
    @@ -2042,6 +2051,7 @@ DMA Buffer files
    mnt_id: 9
    ino: 63107
    size: 32768
    + path: /dmabuf:
    count: 2
    exp_name: system-heap

    diff --git a/fs/libfs.c b/fs/libfs.c
    index 31b0ddf01c31..6911749b4da7 100644
    --- a/fs/libfs.c
    +++ b/fs/libfs.c
    @@ -1217,6 +1217,15 @@ void kfree_link(void *p)
    }
    EXPORT_SYMBOL(kfree_link);

    +static const struct address_space_operations anon_aops = {
    + .dirty_folio = noop_dirty_folio,
    +};
    +
    +bool is_anon_inode(struct inode *inode)
    +{
    + return inode->i_mapping->a_ops == &anon_aops;
    +}
    +
    struct inode *alloc_anon_inode(struct super_block *s)
    {
    static const struct address_space_operations anon_aops = {
    diff --git a/fs/proc/fd.c b/fs/proc/fd.c
    index 464bc3f55759..5bac79a2fa51 100644
    --- a/fs/proc/fd.c
    +++ b/fs/proc/fd.c
    @@ -23,6 +23,7 @@ static int seq_show(struct seq_file *m, void *v)
    struct files_struct *files = NULL;
    int f_flags = 0, ret = -ENOENT;
    struct file *file = NULL;
    + struct inode *inode = NULL;
    struct task_struct *task;

    task = get_proc_task(m->private);
    @@ -54,11 +55,19 @@ static int seq_show(struct seq_file *m, void *v)
    if (ret)
    return ret;

    + inode = file_inode(file);
    +
    seq_printf(m, "pos:\t%lli\n", (long long)file->f_pos);
    seq_printf(m, "flags:\t0%o\n", f_flags);
    seq_printf(m, "mnt_id:\t%i\n", real_mount(file->f_path.mnt)->mnt_id);
    - seq_printf(m, "ino:\t%lu\n", file_inode(file)->i_ino);
    - seq_printf(m, "size:\t%lli\n", (long long)file_inode(file)->i_size);
    + seq_printf(m, "ino:\t%lu\n", inode->i_ino);
    + seq_printf(m, "size:\t%lli\n", (long long)inode->i_size);
    +
    + if (is_anon_inode(inode)) {
    + seq_puts(m, "path:\t");
    + seq_file_path(m, file, "\n");
    + seq_putc(m, '\n');
    + }

    /* show_fd_locks() never deferences files so a stale value is safe */
    show_fd_locks(m, file, files);
    diff --git a/include/linux/fs.h b/include/linux/fs.h
    index 9ad5e3520fae..73449e620b66 100644
    --- a/include/linux/fs.h
    +++ b/include/linux/fs.h
    @@ -3111,6 +3111,7 @@ extern void page_put_link(void *);
    extern int page_symlink(struct inode *inode, const char *symname, int len);
    extern const struct inode_operations page_symlink_inode_operations;
    extern void kfree_link(void *);
    +extern bool is_anon_inode(struct inode *inode);
    void generic_fillattr(struct user_namespace *, struct inode *, struct kstat *);
    void generic_fill_statx_attr(struct inode *inode, struct kstat *stat);
    extern int vfs_getattr_nosec(const struct path *, struct kstat *, u32, unsigned int);
    --
    2.37.0.rc0.161.g10f37bed90-goog
    \
     
     \ /
      Last update: 2022-09-17 16:25    [W:3.776 / U:0.044 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site