14 Aug, 2019

1 commit

  • If you use lseek or similar (e.g. pread) to access a location in a
    seq_file file that is within a record, rather than at a record boundary,
    then the first read will return the remainder of the record, and the
    second read will return the whole of that same record (instead of the
    next record). When seeking to a record boundary, the next record is
    correctly returned.

    This bug was introduced by a recent patch (identified below). Before
    that patch, seq_read() would increment m->index when the last of the
    buffer was returned (m->count == 0). After that patch, we rely on
    ->next to increment m->index after filling the buffer - but there was
    one place where that didn't happen.

    Link: https://lkml.kernel.org/lkml/877e7xl029.fsf@notabene.neil.brown.name/
    Fixes: 1f4aace60b0e ("fs/seq_file.c: simplify seq_file iteration code and interface")
    Signed-off-by: NeilBrown
    Reported-by: Sergei Turchanov
    Tested-by: Sergei Turchanov
    Cc: Alexander Viro
    Cc: Markus Elfring
    Cc: [4.19+]
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    NeilBrown
     

04 Jul, 2019

1 commit

  • I'm exposing some information about NFS clients in pseudofiles. I
    expect to eventually have simple tools to help read those pseudofiles.

    But it's also helpful if the raw files are human-readable to the extent
    possible. It aids debugging and makes them usable on systems that don't
    have the latest nfs-utils.

    A minor challenge there is opaque client-generated protocol objects like
    state owners and client identifiers. Some clients generate those to
    include handy information in plain ascii. But they may also include
    arbitrary byte sequences.

    I think the simplest approach is to limit to isprint(c) && isascii(c)
    and escape everything else.

    That means you can just cat the file and get something that looks OK.
    Also, I'm trying to keep these files legal YAML, which requires them to
    UTF-8, and this is a simple way to guarantee that.

    Acked-by: Kees Cook
    Signed-off-by: J. Bruce Fields

    J. Bruce Fields
     

09 Apr, 2019

1 commit

  • In preparation to enabling -Wimplicit-fallthrough, mark switch cases
    where we are expecting to fall through.

    This patch fixes the following warnings:

    fs/affs/affs.h:124:38: warning: this statement may fall through [-Wimplicit-fallthrough=]
    fs/configfs/dir.c:1692:11: warning: this statement may fall through [-Wimplicit-fallthrough=]
    fs/configfs/dir.c:1694:7: warning: this statement may fall through [-Wimplicit-fallthrough=]
    fs/ceph/file.c:249:3: warning: this statement may fall through [-Wimplicit-fallthrough=]
    fs/ext4/hash.c:233:15: warning: this statement may fall through [-Wimplicit-fallthrough=]
    fs/ext4/hash.c:246:15: warning: this statement may fall through [-Wimplicit-fallthrough=]
    fs/ext2/inode.c:1237:7: warning: this statement may fall through [-Wimplicit-fallthrough=]
    fs/ext2/inode.c:1244:7: warning: this statement may fall through [-Wimplicit-fallthrough=]
    fs/ext4/indirect.c:1182:6: warning: this statement may fall through [-Wimplicit-fallthrough=]
    fs/ext4/indirect.c:1188:6: warning: this statement may fall through [-Wimplicit-fallthrough=]
    fs/ext4/indirect.c:1432:6: warning: this statement may fall through [-Wimplicit-fallthrough=]
    fs/ext4/indirect.c:1440:6: warning: this statement may fall through [-Wimplicit-fallthrough=]
    fs/f2fs/node.c:618:8: warning: this statement may fall through [-Wimplicit-fallthrough=]
    fs/f2fs/node.c:620:8: warning: this statement may fall through [-Wimplicit-fallthrough=]
    fs/btrfs/ref-verify.c:522:15: warning: this statement may fall through [-Wimplicit-fallthrough=]
    fs/gfs2/bmap.c:711:7: warning: this statement may fall through [-Wimplicit-fallthrough=]
    fs/gfs2/bmap.c:722:7: warning: this statement may fall through [-Wimplicit-fallthrough=]
    fs/jffs2/fs.c:339:6: warning: this statement may fall through [-Wimplicit-fallthrough=]
    fs/nfsd/nfs4proc.c:429:12: warning: this statement may fall through [-Wimplicit-fallthrough=]
    fs/ufs/util.h:62:6: warning: this statement may fall through [-Wimplicit-fallthrough=]
    fs/ufs/util.h:43:6: warning: this statement may fall through [-Wimplicit-fallthrough=]
    fs/fcntl.c:770:7: warning: this statement may fall through [-Wimplicit-fallthrough=]
    fs/seq_file.c:319:10: warning: this statement may fall through [-Wimplicit-fallthrough=]
    fs/libfs.c:148:11: warning: this statement may fall through [-Wimplicit-fallthrough=]
    fs/libfs.c:150:7: warning: this statement may fall through [-Wimplicit-fallthrough=]
    fs/signalfd.c:178:7: warning: this statement may fall through [-Wimplicit-fallthrough=]
    fs/locks.c:1473:16: warning: this statement may fall through [-Wimplicit-fallthrough=]

    Warning level 3 was used: -Wimplicit-fallthrough=3

    This patch is part of the ongoing efforts to enabling
    -Wimplicit-fallthrough.

    Reviewed-by: Kees Cook
    Signed-off-by: Gustavo A. R. Silva

    Gustavo A. R. Silva
     

18 Aug, 2018

1 commit

  • The documentation for seq_file suggests that it is necessary to be able
    to move the iterator to a given offset, however that is not the case.
    If the iterator is stored in the private data and is stable from one
    read() syscall to the next, it is only necessary to support first/next
    interactions. Implementing this in a client is a little clumsy.

    - if ->start() is given a pos of zero, it should go to start of
    sequence.

    - if ->start() is given the name pos that was given to the most recent
    next() or start(), it should restore the iterator to state just
    before that last call

    - if ->start is given another number, it should set the iterator one
    beyond the start just before the last ->start or ->next call.

    Also, the documentation says that the implementation can interpret the
    pos however it likes (other than zero meaning start), but seq_file
    increments the pos sometimes which does impose on the implementation.

    This patch simplifies the interface for first/next iteration and
    simplifies the code, while maintaining complete backward compatability.
    Now:

    - if ->start() is given a pos of zero, it should return an iterator
    placed at the start of the sequence

    - if ->start() is given a non-zero pos, it should return the iterator
    in the same state it was after the last ->start or ->next.

    This is particularly useful for interators which walk the multiple
    chains in a hash table, e.g. using rhashtable_walk*. See
    fs/gfs2/glock.c and drivers/staging/lustre/lustre/llite/vvp_dev.c

    A large part of achieving this is to *always* call ->next after ->show
    has successfully stored all of an entry in the buffer. Never just
    increment the index instead. Also:

    - always pass &m->index to ->start() and ->next(), never a temp
    variable

    - don't clear ->from when ->count is zero, as ->from is dead when
    ->count is zero.

    Some ->next functions do not increment *pos when they return NULL. To
    maintain compatability with this, we still need to increment m->index in
    one place, if ->next didn't increment it. Note that such ->next
    functions are buggy and should be fixed. A simple demonstration is

    dd if=/proc/swaps bs=1000 skip=1

    Choose any block size larger than the size of /proc/swaps. This will
    always show the whole last line of /proc/swaps.

    This patch doesn't work around buggy next() functions for this case.

    [neilb@suse.com: ensure ->from is valid]
    Link: http://lkml.kernel.org/r/87601ryb8a.fsf@notabene.neil.brown.name
    Signed-off-by: NeilBrown
    Acked-by: Jonathan Corbet [docs]
    Tested-by: Jann Horn
    Cc: Alexander Viro
    Cc: Kees Cook
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    NeilBrown
     

26 May, 2018

1 commit

  • The 4.17-rc /proc/meminfo and /proc//smaps look ugly: single-digit
    numbers (commonly 0) are misaligned.

    Remove seq_put_decimal_ull_width()'s leftover optimization for single
    digits: it's wrong now that num_to_str() takes care of the width.

    Link: http://lkml.kernel.org/r/alpine.LSU.2.11.1805241554210.1326@eggly.anvils
    Fixes: d1be35cb6f96 ("proc: add seq_put_decimal_ull_width to speed up /proc/pid/smaps")
    Signed-off-by: Hugh Dickins
    Cc: Andrei Vagin
    Cc: Alexey Dobriyan
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Hugh Dickins
     

12 Apr, 2018

6 commits

  • All it takes to open a file and read 1 byte from it.

    seq_file will be allocated along with any private allocations, and more
    importantly seq file buffer which is 1 page by default.

    Link: http://lkml.kernel.org/r/20180310085252.GB17121@avx2
    Signed-off-by: Alexey Dobriyan
    Reviewed-by: Andrew Morton
    Acked-by: Michal Hocko
    Cc: Al Viro
    Cc: Glauber Costa
    Cc: Vladimir Davydov
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Alexey Dobriyan
     
  • For fine-grained debugging and usercopy protection.

    Link: http://lkml.kernel.org/r/20180310085027.GA17121@avx2
    Signed-off-by: Alexey Dobriyan
    Reviewed-by: Andrew Morton
    Cc: Al Viro
    Cc: Glauber Costa
    Cc: Vladimir Davydov
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Alexey Dobriyan
     
  • A delimiter is a string which is printed before a number. A
    syngle-symbol delimiters can be printed by set_putc() and this works
    faster than printing by set_puts().

    == test_proc.c

    int main(int argc, char **argv)
    {
    int n, i, fd;
    char buf[16384];

    n = atoi(argv[1]);
    for (i = 0; i < n; i++) {
    fd = open(argv[2], O_RDONLY);
    if (fd < 0)
    return 1;
    if (read(fd, buf, sizeof(buf))
    Cc: Alexey Dobriyan
    Cc: KAMEZAWA Hiroyuki
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Andrei Vagin
     
  • seq_put_decimal_ull_w(m, str, val, width) prints a decimal number with a
    specified minimal field width.

    It is equivalent of seq_printf(m, "%s%*d", str, width, val), but it
    works much faster.

    == test_smaps.py
    num = 0
    with open("/proc/1/smaps") as f:
    for x in xrange(10000):
    data = f.read()
    f.seek(0, 0)
    ==

    == Before patch ==
    $ time python test_smaps.py
    real 0m4.593s
    user 0m0.398s
    sys 0m4.158s

    == After patch ==
    $ time python test_smaps.py
    real 0m3.828s
    user 0m0.413s
    sys 0m3.408s

    $ perf -g record python test_smaps.py
    == Before patch ==
    - 79.01% 3.36% python [kernel.kallsyms] [k] show_smap.isra.33
    - 75.65% show_smap.isra.33
    + 48.85% seq_printf
    + 15.75% __walk_page_range
    + 9.70% show_map_vma.isra.23
    0.61% seq_puts

    == After patch ==
    - 75.51% 4.62% python [kernel.kallsyms] [k] show_smap.isra.33
    - 70.88% show_smap.isra.33
    + 24.82% seq_put_decimal_ull_w
    + 19.78% __walk_page_range
    + 12.74% seq_printf
    + 11.08% show_map_vma.isra.23
    + 1.68% seq_puts

    [akpm@linux-foundation.org: fix drivers/of/unittest.c build]
    Link: http://lkml.kernel.org/r/20180212074931.7227-1-avagin@openvz.org
    Signed-off-by: Andrei Vagin
    Cc: Alexey Dobriyan
    Cc: KAMEZAWA Hiroyuki
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Andrei Vagin
     
  • seq_printf() is slow and it can be replaced by memset() in this case.

    == test.py
    num = 0
    with open("/proc/1/maps") as f:
    while num < 10000 :
    data = f.read()
    f.seek(0, 0)
    num = num + 1
    ==

    == Before patch ==
    $ time python test.py
    real 0m0.986s
    user 0m0.279s
    sys 0m0.707s

    == After patch ==
    $ time python test.py
    real 0m0.932s
    user 0m0.261s
    sys 0m0.669s

    $ perf record -g python test.py
    == Before patch ==
    - 47.35% 3.38% python [kernel.kallsyms] [k] show_map_vma.isra.23
    - 43.97% show_map_vma.isra.23
    + 20.84% seq_path
    - 15.73% show_vma_header_prefix
    + 6.96% seq_pad
    + 2.94% __GI___libc_read

    == After patch ==
    - 44.01% 0.34% python [kernel.kallsyms] [k] show_pid_map
    - 43.67% show_pid_map
    - 42.91% show_map_vma.isra.23
    + 21.55% seq_path
    - 15.68% show_vma_header_prefix
    + 2.08% seq_pad
    0.55% seq_putc

    Link: http://lkml.kernel.org/r/20180112185812.7710-2-avagin@openvz.org
    Signed-off-by: Andrei Vagin
    Cc: Alexey Dobriyan
    Cc: KAMEZAWA Hiroyuki
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Andrei Vagin
     
  • seq_put_hex_ll() prints a number in hexadecimal notation and works
    faster than seq_printf().

    == test.py
    num = 0
    with open("/proc/1/maps") as f:
    while num < 10000 :
    data = f.read()
    f.seek(0, 0)
    num = num + 1
    ==

    == Before patch ==
    $ time python test.py

    real 0m1.561s
    user 0m0.257s
    sys 0m1.302s

    == After patch ==
    $ time python test.py

    real 0m0.986s
    user 0m0.279s
    sys 0m0.707s

    $ perf -g record python test.py:

    == Before patch ==
    - 67.42% 2.82% python [kernel.kallsyms] [k] show_map_vma.isra.22
    - 64.60% show_map_vma.isra.22
    - 44.98% seq_printf
    - seq_vprintf
    - vsnprintf
    + 14.85% number
    + 12.22% format_decode
    5.56% memcpy_erms
    + 15.06% seq_path
    + 4.42% seq_pad
    + 2.45% __GI___libc_read

    == After patch ==
    - 47.35% 3.38% python [kernel.kallsyms] [k] show_map_vma.isra.23
    - 43.97% show_map_vma.isra.23
    + 20.84% seq_path
    - 15.73% show_vma_header_prefix
    10.55% seq_put_hex_ll
    + 2.65% seq_put_decimal_ull
    0.95% seq_putc
    + 6.96% seq_pad
    + 2.94% __GI___libc_read

    [avagin@openvz.org: use unsigned int instead of int where it is suitable]
    Link: http://lkml.kernel.org/r/20180214025619.4005-1-avagin@openvz.org
    [avagin@openvz.org: v2]
    Link: http://lkml.kernel.org/r/20180117082050.25406-1-avagin@openvz.org
    Link: http://lkml.kernel.org/r/20180112185812.7710-1-avagin@openvz.org
    Signed-off-by: Andrei Vagin
    Cc: Alexey Dobriyan
    Cc: KAMEZAWA Hiroyuki
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Andrei Vagin
     

20 Jan, 2018

1 commit

  • When resetting iterator on a zero offset we need to discard any data
    already in the buffer (count), and private state of the iterator (version).

    For example this bug results in first line being repeated in /proc/mounts
    if doing a zero size read before a non-zero size read.

    Reported-by: Rich Felker
    Signed-off-by: Miklos Szeredi
    Fixes: e522751d605d ("seq_file: reset iterator to first record for zero offset")
    Cc: # v4.10
    Signed-off-by: Al Viro

    Miklos Szeredi
     

02 Nov, 2017

1 commit

  • Many source files in the tree are missing licensing information, which
    makes it harder for compliance tools to determine the correct license.

    By default all files without license information are under the default
    license of the kernel, which is GPL version 2.

    Update the files which contain no license information with the 'GPL-2.0'
    SPDX license identifier. The SPDX identifier is a legally binding
    shorthand, which can be used instead of the full boiler plate text.

    This patch is based on work done by Thomas Gleixner and Kate Stewart and
    Philippe Ombredanne.

    How this work was done:

    Patches were generated and checked against linux-4.14-rc6 for a subset of
    the use cases:
    - file had no licensing information it it.
    - file was a */uapi/* one with no licensing information in it,
    - file was a */uapi/* one with existing licensing information,

    Further patches will be generated in subsequent months to fix up cases
    where non-standard license headers were used, and references to license
    had to be inferred by heuristics based on keywords.

    The analysis to determine which SPDX License Identifier to be applied to
    a file was done in a spreadsheet of side by side results from of the
    output of two independent scanners (ScanCode & Windriver) producing SPDX
    tag:value files created by Philippe Ombredanne. Philippe prepared the
    base worksheet, and did an initial spot review of a few 1000 files.

    The 4.13 kernel was the starting point of the analysis with 60,537 files
    assessed. Kate Stewart did a file by file comparison of the scanner
    results in the spreadsheet to determine which SPDX license identifier(s)
    to be applied to the file. She confirmed any determination that was not
    immediately clear with lawyers working with the Linux Foundation.

    Criteria used to select files for SPDX license identifier tagging was:
    - Files considered eligible had to be source code files.
    - Make and config files were included as candidates if they contained >5
    lines of source
    - File already had some variant of a license header in it (even if
    Reviewed-by: Philippe Ombredanne
    Reviewed-by: Thomas Gleixner
    Signed-off-by: Greg Kroah-Hartman

    Greg Kroah-Hartman
     

09 May, 2017

1 commit

  • Patch series "kvmalloc", v5.

    There are many open coded kmalloc with vmalloc fallback instances in the
    tree. Most of them are not careful enough or simply do not care about
    the underlying semantic of the kmalloc/page allocator which means that
    a) some vmalloc fallbacks are basically unreachable because the kmalloc
    part will keep retrying until it succeeds b) the page allocator can
    invoke a really disruptive steps like the OOM killer to move forward
    which doesn't sound appropriate when we consider that the vmalloc
    fallback is available.

    As it can be seen implementing kvmalloc requires quite an intimate
    knowledge if the page allocator and the memory reclaim internals which
    strongly suggests that a helper should be implemented in the memory
    subsystem proper.

    Most callers, I could find, have been converted to use the helper
    instead. This is patch 6. There are some more relying on __GFP_REPEAT
    in the networking stack which I have converted as well and Eric Dumazet
    was not opposed [2] to convert them as well.

    [1] http://lkml.kernel.org/r/20170130094940.13546-1-mhocko@kernel.org
    [2] http://lkml.kernel.org/r/1485273626.16328.301.camel@edumazet-glaptop3.roam.corp.google.com

    This patch (of 9):

    Using kmalloc with the vmalloc fallback for larger allocations is a
    common pattern in the kernel code. Yet we do not have any common helper
    for that and so users have invented their own helpers. Some of them are
    really creative when doing so. Let's just add kv[mz]alloc and make sure
    it is implemented properly. This implementation makes sure to not make
    a large memory pressure for > PAGE_SZE requests (__GFP_NORETRY) and also
    to not warn about allocation failures. This also rules out the OOM
    killer as the vmalloc is a more approapriate fallback than a disruptive
    user visible action.

    This patch also changes some existing users and removes helpers which
    are specific for them. In some cases this is not possible (e.g.
    ext4_kvmalloc, libcfs_kvzalloc) because those seems to be broken and
    require GFP_NO{FS,IO} context which is not vmalloc compatible in general
    (note that the page table allocation is GFP_KERNEL). Those need to be
    fixed separately.

    While we are at it, document that __vmalloc{_node} about unsupported gfp
    mask because there seems to be a lot of confusion out there.
    kvmalloc_node will warn about GFP_KERNEL incompatible (which are not
    superset) flags to catch new abusers. Existing ones would have to die
    slowly.

    [sfr@canb.auug.org.au: f2fs fixup]
    Link: http://lkml.kernel.org/r/20170320163735.332e64b7@canb.auug.org.au
    Link: http://lkml.kernel.org/r/20170306103032.2540-2-mhocko@kernel.org
    Signed-off-by: Michal Hocko
    Signed-off-by: Stephen Rothwell
    Reviewed-by: Andreas Dilger [ext4 part]
    Acked-by: Vlastimil Babka
    Cc: John Hubbard
    Cc: David Miller
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Michal Hocko
     

25 Dec, 2016

1 commit


23 Dec, 2016

1 commit

  • If kernfs file is empty on a first read, successive read operations
    using the same file descriptor will return no data, even when data is
    available. Default kernfs 'seq_next' implementation advances iterator
    position even when next object is not there. Kernfs 'seq_start' for
    following requests will not return iterator as position is already on
    the second object.

    This defect doesn't allow to monitor badblocks sysfs files from MD raid.
    They are initially empty but if data appears at some stage, userspace is
    not able to read it.

    Signed-off-by: Tomasz Majchrzak
    Signed-off-by: Miklos Szeredi
    Signed-off-by: Al Viro

    Tomasz Majchrzak
     

08 Oct, 2016

1 commit

  • Allow some seq_puts removals by taking a string instead of a single
    char.

    [akpm@linux-foundation.org: update vmstat_show(), per Joe]
    Link: http://lkml.kernel.org/r/667e1cf3d436de91a5698170a1e98d882905e956.1470704995.git.joe@perches.com
    Signed-off-by: Joe Perches
    Cc: Joe Perches
    Cc: Andi Kleen
    Cc: Al Viro
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Joe Perches
     

27 Aug, 2016

1 commit

  • seq_read() is a nasty piece of work, not to mention buggy.

    It has (I think) an old bug which allows unprivileged userspace to read
    beyond the end of m->buf.

    I was getting these:

    BUG: KASAN: slab-out-of-bounds in seq_read+0xcd2/0x1480 at addr ffff880116889880
    Read of size 2713 by task trinity-c2/1329
    CPU: 2 PID: 1329 Comm: trinity-c2 Not tainted 4.8.0-rc1+ #96
    Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.9.3-0-ge2fc41e-prebuilt.qemu-project.org 04/01/2014
    Call Trace:
    kasan_object_err+0x1c/0x80
    kasan_report_error+0x2cb/0x7e0
    kasan_report+0x4e/0x80
    check_memory_region+0x13e/0x1a0
    kasan_check_read+0x11/0x20
    seq_read+0xcd2/0x1480
    proc_reg_read+0x10b/0x260
    do_loop_readv_writev.part.5+0x140/0x2c0
    do_readv_writev+0x589/0x860
    vfs_readv+0x7b/0xd0
    do_readv+0xd8/0x2c0
    SyS_readv+0xb/0x10
    do_syscall_64+0x1b3/0x4b0
    entry_SYSCALL64_slow_path+0x25/0x25
    Object at ffff880116889100, in cache kmalloc-4096 size: 4096
    Allocated:
    PID = 1329
    save_stack_trace+0x26/0x80
    save_stack+0x46/0xd0
    kasan_kmalloc+0xad/0xe0
    __kmalloc+0x1aa/0x4a0
    seq_buf_alloc+0x35/0x40
    seq_read+0x7d8/0x1480
    proc_reg_read+0x10b/0x260
    do_loop_readv_writev.part.5+0x140/0x2c0
    do_readv_writev+0x589/0x860
    vfs_readv+0x7b/0xd0
    do_readv+0xd8/0x2c0
    SyS_readv+0xb/0x10
    do_syscall_64+0x1b3/0x4b0
    return_from_SYSCALL_64+0x0/0x6a
    Freed:
    PID = 0
    (stack is not available)
    Memory state around the buggy address:
    ffff88011688a000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    ffff88011688a080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    >ffff88011688a100: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
    ^
    ffff88011688a180: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
    ffff88011688a200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
    ==================================================================
    Disabling lock debugging due to kernel taint

    This seems to be the same thing that Dave Jones was seeing here:

    https://lkml.org/lkml/2016/8/12/334

    There are multiple issues here:

    1) If we enter the function with a non-empty buffer, there is an attempt
    to flush it. But it was not clearing m->from after doing so, which
    means that if we try to do this flush twice in a row without any call
    to traverse() in between, we are going to be reading from the wrong
    place -- the splat above, fixed by this patch.

    2) If there's a short write to userspace because of page faults, the
    buffer may already contain multiple lines (i.e. pos has advanced by
    more than 1), but we don't save the progress that was made so the
    next call will output what we've already returned previously. Since
    that is a much less serious issue (and I have a headache after
    staring at seq_read() for the past 8 hours), I'll leave that for now.

    Link: http://lkml.kernel.org/r/1471447270-32093-1-git-send-email-vegard.nossum@oracle.com
    Signed-off-by: Vegard Nossum
    Reported-by: Dave Jones
    Cc: Al Viro
    Cc:
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Vegard Nossum
     

15 Apr, 2016

1 commit

  • A lot of seqfile users seem to be using things like %pK that uses the
    credentials of the current process, but that is actually completely
    wrong for filesystem interfaces.

    The unix semantics for permission checking files is to check permissions
    at _open_ time, not at read or write time, and that is not just a small
    detail: passing off stdin/stdout/stderr to a suid application and making
    the actual IO happen in privileged context is a classic exploit
    technique.

    So if we want to be able to look at permissions at read time, we need to
    use the file open credentials, not the current ones. Normal file
    accesses can just use "f_cred" (or any of the helper functions that do
    that, like file_ns_capable()), but the seqfile interfaces do not have
    any such options.

    It turns out that seq_file _does_ save away the user_ns information of
    the file, though. Since user_ns is just part of the full credential
    information, replace that special case with saving off the cred pointer
    instead, and suddenly seq_file has all the permission information it
    needs.

    Signed-off-by: Linus Torvalds

    Linus Torvalds
     

07 Nov, 2015

3 commits

  • Since 5cec38ac866b ("fs, seq_file: fallback to vmalloc instead of oom kill
    processes") seq_buf_alloc() avoids calling the oom killer for PAGE_SIZE or
    smaller allocations; but larger allocations can use the oom killer via
    vmalloc(). Thus reads of small files can return ENOMEM, but larger files
    use the oom killer to avoid ENOMEM.

    The effect of this bug is that reads from /proc and other virtual
    filesystems can return ENOMEM instead of the preferred behavior - oom
    killing something (possibly the calling process). I don't know of anyone
    except Google who has noticed the issue.

    I suspect the fix is more needed in smaller systems where there isn't any
    reclaimable memory. But these seem like the kinds of systems which
    probably don't use the oom killer for production situations.

    Memory overcommit requires use of the oom killer to select a victim
    regardless of file size.

    Enable oom killer for small seq_buf_alloc() allocations.

    Fixes: 5cec38ac866b ("fs, seq_file: fallback to vmalloc instead of oom kill processes")
    Signed-off-by: David Rientjes
    Signed-off-by: Greg Thelen
    Acked-by: Eric Dumazet
    Cc:
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Greg Thelen
     
  • strint_escape_str() escapes input string by given criteria. In case of
    seq_escape() the criteria is to convert some characters to their octal
    representation.

    Signed-off-by: Andy Shevchenko
    Cc: Alexander Viro
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Andy Shevchenko
     
  • This improves code readability.

    Signed-off-by: Andy Shevchenko
    Cc: Alexander Viro
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Andy Shevchenko
     

12 Sep, 2015

1 commit

  • The seq_ function return values were frequently misused.

    See: commit 1f33c41c03da ("seq_file: Rename seq_overflow() to
    seq_has_overflowed() and make public")

    All uses of these return values have been removed, so convert the
    return types to void.

    Miscellanea:

    o Move seq_put_decimal_ and seq_escape prototypes closer the
    other seq_vprintf prototypes
    o Reorder seq_putc and seq_puts to return early on overflow
    o Add argument names to seq_vprintf and seq_printf
    o Update the seq_escape kernel-doc
    o Convert a couple of leading spaces to tabs in seq_escape

    Signed-off-by: Joe Perches
    Cc: Al Viro
    Cc: Steven Rostedt
    Cc: Mark Brown
    Cc: Stephen Rothwell
    Cc: Joerg Roedel
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Joe Perches
     

11 Sep, 2015

1 commit

  • This introduces a new helper and switches current users to use it. All
    patches are compiled tested. kmemleak is tested via its own test suite.

    This patch (of 6):

    The new seq_hex_dump() is a complete analogue of print_hex_dump().

    We have few users of this functionality already. It allows to reduce their
    codebase.

    Signed-off-by: Andy Shevchenko
    Cc: Alexander Viro
    Cc: Joe Perches
    Cc: Tadeusz Struk
    Cc: Helge Deller
    Cc: Ingo Tuchscherer
    Cc: Catalin Marinas
    Cc: Vladimir Kondratiev
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Andy Shevchenko
     

05 Jul, 2015

1 commit

  • Pull more vfs updates from Al Viro:
    "Assorted VFS fixes and related cleanups (IMO the most interesting in
    that part are f_path-related things and Eric's descriptor-related
    stuff). UFS regression fixes (it got broken last cycle). 9P fixes.
    fs-cache series, DAX patches, Jan's file_remove_suid() work"

    [ I'd say this is much more than "fixes and related cleanups". The
    file_table locking rule change by Eric Dumazet is a rather big and
    fundamental update even if the patch isn't huge. - Linus ]

    * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (49 commits)
    9p: cope with bogus responses from server in p9_client_{read,write}
    p9_client_write(): avoid double p9_free_req()
    9p: forgetting to cancel request on interrupted zero-copy RPC
    dax: bdev_direct_access() may sleep
    block: Add support for DAX reads/writes to block devices
    dax: Use copy_from_iter_nocache
    dax: Add block size note to documentation
    fs/file.c: __fget() and dup2() atomicity rules
    fs/file.c: don't acquire files->file_lock in fd_install()
    fs:super:get_anon_bdev: fix race condition could cause dev exceed its upper limitation
    vfs: avoid creation of inode number 0 in get_next_ino
    namei: make set_root_rcu() return void
    make simple_positive() public
    ufs: use dir_pages instead of ufs_dir_pages()
    pagemap.h: move dir_pages() over there
    remove the pointless include of lglock.h
    fs: cleanup slight list_entry abuse
    xfs: Correctly lock inode when removing suid and file capabilities
    fs: Call security_ops->inode_killpriv on truncate
    fs: Provide function telling whether file_remove_privs() will do anything
    ...

    Linus Torvalds
     

02 Jul, 2015

1 commit

  • Merge third patchbomb from Andrew Morton:

    - the rest of MM

    - scripts/gdb updates

    - ipc/ updates

    - lib/ updates

    - MAINTAINERS updates

    - various other misc things

    * emailed patches from Andrew Morton : (67 commits)
    genalloc: rename of_get_named_gen_pool() to of_gen_pool_get()
    genalloc: rename dev_get_gen_pool() to gen_pool_get()
    x86: opt into HAVE_COPY_THREAD_TLS, for both 32-bit and 64-bit
    MAINTAINERS: add zpool
    MAINTAINERS: BCACHE: Kent Overstreet has changed email address
    MAINTAINERS: move Jens Osterkamp to CREDITS
    MAINTAINERS: remove unused nbd.h pattern
    MAINTAINERS: update brcm gpio filename pattern
    MAINTAINERS: update brcm dts pattern
    MAINTAINERS: update sound soc intel patterns
    MAINTAINERS: remove website for paride
    MAINTAINERS: update Emulex ocrdma email addresses
    bcache: use kvfree() in various places
    libcxgbi: use kvfree() in cxgbi_free_big_mem()
    target: use kvfree() in session alloc and free
    IB/ehca: use kvfree() in ipz_queue_{cd}tor()
    drm/nouveau/gem: use kvfree() in u_free()
    drm: use kvfree() in drm_free_large()
    cxgb4: use kvfree() in t4_free_mem()
    cxgb3: use kvfree() in cxgb_free_mem()
    ...

    Linus Torvalds
     

01 Jul, 2015

2 commits

  • seq_open() stores its struct seq_file in file->private_data, thus it must
    not be modified by user of seq_file.

    Link: http://lkml.kernel.org/r/cover.1433193673.git.ydroneaud@opteya.com
    Signed-off-by: Yann Droneaud
    Cc: Al Viro
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Yann Droneaud
     
  • Since patch described below, from v2.6.15-rc1, seq_open() could use a
    struct seq_file already allocated by the caller if the pointer to the
    structure is stored in file->private_data before calling the function.

    Commit 1abe77b0fc4b485927f1f798ae81a752677e1d05
    Author: Al Viro
    Date: Mon Nov 7 17:15:34 2005 -0500

    [PATCH] allow callers of seq_open do allocation themselves

    Allow caller of seq_open() to kmalloc() seq_file + whatever else they
    want and set ->private_data to it. seq_open() will then abstain from
    doing allocation itself.

    As there's no more use for such feature, as it could be easily replaced by
    calls to seq_open_private() (see commit 39699037a5c9 ("[FS] seq_file:
    Introduce the seq_open_private()")) and seq_release_private() (see
    v2.6.0-test3), support for this uncommon feature can be removed from
    seq_open().

    Link: http://lkml.kernel.org/r/cover.1433193673.git.ydroneaud@opteya.com
    Signed-off-by: Yann Droneaud
    Cc: Al Viro
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Yann Droneaud
     

24 Jun, 2015

1 commit


03 Jun, 2015

1 commit

  • Now that we're guaranteed to have a meaningful root dentry, we can just
    export seq_dentry() and use it in btrfs_show_options(). The subvolume ID
    is easy to get and can also be useful, so put that in there, too.

    Reviewed-by: David Sterba
    Signed-off-by: Omar Sandoval
    Signed-off-by: Chris Mason

    Omar Sandoval
     

14 Feb, 2015

1 commit

  • Now that all bitmap formatting usages have been converted to
    '%*pb[l]', the separate formatting functions are unnecessary. The
    following functions are removed.

    * bitmap_scn[list]printf()
    * cpumask_scnprintf(), cpulist_scnprintf()
    * [__]nodemask_scnprintf(), [__]nodelist_scnprintf()
    * seq_bitmap[_list](), seq_cpumask[_list](), seq_nodemask[_list]()
    * seq_buf_bitmask()

    Signed-off-by: Tejun Heo
    Cc: Rusty Russell
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Tejun Heo
     

14 Dec, 2014

1 commit

  • Since commit 058504edd026 ("fs/seq_file: fallback to vmalloc allocation"),
    seq_buf_alloc() falls back to vmalloc() when the kmalloc() for contiguous
    memory fails. This was done to address order-4 slab allocations for
    reading /proc/stat on large machines and noticed because
    PAGE_ALLOC_COSTLY_ORDER < 4, so there is no infinite loop in the page
    allocator when allocating new slab for such high-order allocations.

    Contiguous memory isn't necessary for caller of seq_buf_alloc(), however.
    Other GFP_KERNEL high-order allocations that are
    Cc: Heiko Carstens
    Cc: Christoph Hellwig
    Cc: Al Viro
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    David Rientjes
     

30 Oct, 2014

1 commit

  • The return values of seq_printf/puts/putc are frequently misused.

    Start down a path to remove all the return value uses of these
    functions.

    Move the seq_overflow() to a global inlined function called
    seq_has_overflowed() that can be used by the users of seq_file() calls.

    Update the documentation to not show return types for seq_printf
    et al. Add a description of seq_has_overflowed().

    Link: http://lkml.kernel.org/p/848ac7e3d1c31cddf638a8526fa3c59fa6fdeb8a.1412031505.git.joe@perches.com

    Cc: Al Viro
    Signed-off-by: Joe Perches
    [ Reworked the original patch from Joe ]
    Signed-off-by: Steven Rostedt

    Joe Perches
     

04 Jul, 2014

1 commit

  • There are a couple of seq_files which use the single_open() interface.
    This interface requires that the whole output must fit into a single
    buffer.

    E.g. for /proc/stat allocation failures have been observed because an
    order-4 memory allocation failed due to memory fragmentation. In such
    situations reading /proc/stat is not possible anymore.

    Therefore change the seq_file code to fallback to vmalloc allocations
    which will usually result in a couple of order-0 allocations and hence
    also work if memory is fragmented.

    For reference a call trace where reading from /proc/stat failed:

    sadc: page allocation failure: order:4, mode:0x1040d0
    CPU: 1 PID: 192063 Comm: sadc Not tainted 3.10.0-123.el7.s390x #1
    [...]
    Call Trace:
    show_stack+0x6c/0xe8
    warn_alloc_failed+0xd6/0x138
    __alloc_pages_nodemask+0x9da/0xb68
    __get_free_pages+0x2e/0x58
    kmalloc_order_trace+0x44/0xc0
    stat_open+0x5a/0xd8
    proc_reg_open+0x8a/0x140
    do_dentry_open+0x1bc/0x2c8
    finish_open+0x46/0x60
    do_last+0x382/0x10d0
    path_openat+0xc8/0x4f8
    do_filp_open+0x46/0xa8
    do_sys_open+0x114/0x1f0
    sysc_tracego+0x14/0x1a

    Signed-off-by: Heiko Carstens
    Tested-by: David Rientjes
    Cc: Ian Kent
    Cc: Hendrik Brueckner
    Cc: Thorsten Diehl
    Cc: Andrea Righi
    Cc: Christoph Hellwig
    Cc: Al Viro
    Cc: Stefan Bader
    Cc:
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Heiko Carstens
     

19 Nov, 2013

1 commit


15 Nov, 2013

1 commit

  • There are several users who want to know bytes written by seq_*() for
    alignment purpose. Currently they are using %n format for knowing it
    because seq_*() returns 0 on success.

    This patch introduces seq_setwidth() and seq_pad() for allowing them to
    align without using %n format.

    Signed-off-by: Tetsuo Handa
    Signed-off-by: Kees Cook
    Cc: Joe Perches
    Cc: David Miller
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Tetsuo Handa
     

25 Oct, 2013

1 commit

  • This issue was first pointed out by Jiaxing Wang several months ago, but no
    further comments:
    https://lkml.org/lkml/2013/6/29/41

    As we know pread() does not change f_pos, so after pread(), file->f_pos
    and m->read_pos become different. And seq_lseek() does not update file->f_pos
    if offset equals to m->read_pos, so after pread() and seq_lseek()(lseek to
    m->read_pos), then a subsequent read may read from a wrong position, the
    following program produces the problem:

    char str1[32] = { 0 };
    char str2[32] = { 0 };
    int poffset = 10;
    int count = 20;

    /*open any seq file*/
    int fd = open("/proc/modules", O_RDONLY);

    pread(fd, str1, count, poffset);
    printf("pread:%s\n", str1);

    /*seek to where m->read_pos is*/
    lseek(fd, poffset+count, SEEK_SET);

    /*supposed to read from poffset+count, but this read from position 0*/
    read(fd, str2, count);
    printf("read:%s\n", str2);

    out put:
    pread:
    ck_netbios_ns 12665
    read:
    nf_conntrack_netbios

    /proc/modules:
    nf_conntrack_netbios_ns 12665 0 - Live 0xffffffffa038b000
    nf_conntrack_broadcast 12589 1 nf_conntrack_netbios_ns, Live 0xffffffffa0386000

    So we always update file->f_pos to offset in seq_lseek() to fix this issue.

    Signed-off-by: Jiaxing Wang
    Signed-off-by: Gu Zheng
    Signed-off-by: Al Viro

    Gu Zheng
     

08 Jul, 2013

1 commit

  • When we convert the file_lock_list to a set of percpu lists, we'll need
    a way to iterate over them in order to output /proc/locks info. Add
    some seq_list_*_percpu helpers to handle that.

    Signed-off-by: Jeff Layton
    Acked-by: J. Bruce Fields
    Signed-off-by: Al Viro

    Jeff Layton
     

10 Apr, 2013

1 commit

  • Same as single_open(), but preallocates the buffer of given size.
    Doesn't make any sense for sizes up to PAGE_SIZE and doesn't make
    sense if output of show() exceeds PAGE_SIZE only rarely - seq_read()
    will take care of growing the buffer and redoing show(). If you
    _know_ that it will be large, it might make more sense to look into
    saner iterator, rather than go with single-shot one. If that's
    impossible, single_open_size() might be for you.

    Again, don't use that without a good reason; occasionally that's really
    the best way to go, but very often there are better solutions.

    Signed-off-by: Al Viro

    Al Viro
     

04 Mar, 2013

1 commit

  • Pull more VFS bits from Al Viro:
    "Unfortunately, it looks like xattr series will have to wait until the
    next cycle ;-/

    This pile contains 9p cleanups and fixes (races in v9fs_fid_add()
    etc), fixup for nommu breakage in shmem.c, several cleanups and a bit
    more file_inode() work"

    * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
    constify path_get/path_put and fs_struct.c stuff
    fix nommu breakage in shmem.c
    cache the value of file_inode() in struct file
    9p: if v9fs_fid_lookup() gets to asking server, it'd better have hashed dentry
    9p: make sure ->lookup() adds fid to the right dentry
    9p: untangle ->lookup() a bit
    9p: double iput() in ->lookup() if d_materialise_unique() fails
    9p: v9fs_fid_add() can't fail now
    v9fs: get rid of v9fs_dentry
    9p: turn fid->dlist into hlist
    9p: don't bother with private lock in ->d_fsdata; dentry->d_lock will do just fine
    more file_inode() open-coded instances
    selinux: opened file can't have NULL or negative ->f_path.dentry

    (In the meantime, the hlist traversal macros have changed, so this
    required a semantic conflict fixup for the newly hlistified fid->dlist)

    Linus Torvalds