1. 20 1月, 2016 1 次提交
    • W
      pipe: limit the per-user amount of pages allocated in pipes · 759c0114
      Willy Tarreau 提交于
      On no-so-small systems, it is possible for a single process to cause an
      OOM condition by filling large pipes with data that are never read. A
      typical process filling 4000 pipes with 1 MB of data will use 4 GB of
      memory. On small systems it may be tricky to set the pipe max size to
      prevent this from happening.
      
      This patch makes it possible to enforce a per-user soft limit above
      which new pipes will be limited to a single page, effectively limiting
      them to 4 kB each, as well as a hard limit above which no new pipes may
      be created for this user. This has the effect of protecting the system
      against memory abuse without hurting other users, and still allowing
      pipes to work correctly though with less data at once.
      
      The limit are controlled by two new sysctls : pipe-user-pages-soft, and
      pipe-user-pages-hard. Both may be disabled by setting them to zero. The
      default soft limit allows the default number of FDs per process (1024)
      to create pipes of the default size (64kB), thus reaching a limit of 64MB
      before starting to create only smaller pipes. With 256 processes limited
      to 1024 FDs each, this results in 1024*64kB + (256*1024 - 1024) * 4kB =
      1084 MB of memory allocated for a user. The hard limit is disabled by
      default to avoid breaking existing applications that make intensive use
      of pipes (eg: for splicing).
      
      Reported-by: socketpair@gmail.com
      Reported-by: NTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
      Mitigates: CVE-2013-4312 (Linux 2.0+)
      Suggested-by: NLinus Torvalds <torvalds@linux-foundation.org>
      Signed-off-by: NWilly Tarreau <w@1wt.eu>
      Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
      759c0114
  2. 11 11月, 2015 2 次提交
    • E
      fs/pipe.c: return error code rather than 0 in pipe_write() · 6ae08069
      Eric Biggers 提交于
      pipe_write() would return 0 if it failed to merge the beginning of the
      data to write with the last, partially filled pipe buffer.  It should
      return an error code instead.  Userspace programs could be confused by
      write() returning 0 when called with a nonzero 'count'.
      
      The EFAULT error case was a regression from f0d1bec9 ("new helper:
      copy_page_from_iter()"), while the ops->confirm() error case was a much
      older bug.
      
      Test program:
      
      	#include <assert.h>
      	#include <errno.h>
      	#include <unistd.h>
      
      	int main(void)
      	{
      		int fd[2];
      		char data[1] = {0};
      
      		assert(0 == pipe(fd));
      		assert(1 == write(fd[1], data, 1));
      
      		/* prior to this patch, write() returned 0 here  */
      		assert(-1 == write(fd[1], NULL, 1));
      		assert(errno == EFAULT);
      	}
      
      Cc: stable@vger.kernel.org # at least v3.15+
      Signed-off-by: NEric Biggers <ebiggers3@gmail.com>
      Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
      6ae08069
    • E
      fs/pipe.c: preserve alloc_file() error code · e9bb1f9b
      Eric Biggers 提交于
      If sys_pipe() was unable to allocate a 'struct file', it always failed
      with ENFILE, which means "The number of simultaneously open files in the
      system would exceed a system-imposed limit." However, alloc_file()
      actually returns an ERR_PTR value and might fail with other error codes.
      Currently, in addition to ENFILE, it can fail with ENOMEM, potentially
      when there are few open files in the system.  Update sys_pipe() to
      preserve this error code.
      
      In a prior submission of a similar patch (1) some concern was raised
      about introducing a new error code for sys_pipe().  However, for most
      system calls, programs cannot assume that new error codes will never be
      introduced.  In addition, ENOMEM was, in fact, already a possible error
      code for sys_pipe(), in the case where the file descriptor table could
      not be expanded due to insufficient memory.
      
      	(1) http://comments.gmane.org/gmane.linux.kernel/1357942Signed-off-by: NEric Biggers <ebiggers3@gmail.com>
      Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
      e9bb1f9b
  3. 16 4月, 2015 1 次提交
  4. 12 4月, 2015 1 次提交
  5. 26 3月, 2015 1 次提交
  6. 07 5月, 2014 3 次提交
  7. 02 4月, 2014 2 次提交
  8. 24 1月, 2014 1 次提交
  9. 03 12月, 2013 1 次提交
    • L
      vfs: fix subtle use-after-free of pipe_inode_info · b0d8d229
      Linus Torvalds 提交于
      The pipe code was trying (and failing) to be very careful about freeing
      the pipe info only after the last access, with a pattern like:
      
              spin_lock(&inode->i_lock);
              if (!--pipe->files) {
                      inode->i_pipe = NULL;
                      kill = 1;
              }
              spin_unlock(&inode->i_lock);
              __pipe_unlock(pipe);
              if (kill)
                      free_pipe_info(pipe);
      
      where the final freeing is done last.
      
      HOWEVER.  The above is actually broken, because while the freeing is
      done at the end, if we have two racing processes releasing the pipe
      inode info, the one that *doesn't* free it will decrement the ->files
      count, and unlock the inode i_lock, but then still use the
      "pipe_inode_info" afterwards when it does the "__pipe_unlock(pipe)".
      
      This is *very* hard to trigger in practice, since the race window is
      very small, and adding debug options seems to just hide it by slowing
      things down.
      
      Simon originally reported this way back in July as an Oops in
      kmem_cache_allocate due to a single bit corruption (due to the final
      "spin_unlock(pipe->mutex.wait_lock)" incrementing a field in a different
      allocation that had re-used the free'd pipe-info), it's taken this long
      to figure out.
      
      Since the 'pipe->files' accesses aren't even protected by the pipe lock
      (we very much use the inode lock for that), the simple solution is to
      just drop the pipe lock early.  And since there were two users of this
      pattern, create a helper function for it.
      
      Introduced commit ba5bb147 ("pipe: take allocation and freeing of
      pipe_inode_info out of ->i_mutex").
      Reported-by: NSimon Kirby <sim@hostway.ca>
      Reported-by: NIan Applegate <ia@cloudflare.com>
      Acked-by: NAl Viro <viro@zeniv.linux.org.uk>
      Cc: stable@kernel.org   # v3.10+
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      b0d8d229
  10. 08 5月, 2013 1 次提交
  11. 10 4月, 2013 11 次提交
  12. 12 3月, 2013 1 次提交
    • A
      vfs: fix pipe counter breakage · a930d879
      Al Viro 提交于
      If you open a pipe for neither read nor write, the pipe code will not
      add any usage counters to the pipe, causing the 'struct pipe_inode_info"
      to be potentially released early.
      
      That doesn't normally matter, since you cannot actually use the pipe,
      but the pipe release code - particularly fasync handling - still expects
      the actual pipe infrastructure to all be there.  And rather than adding
      NULL pointer checks, let's just disallow this case, the same way we
      already do for the named pipe ("fifo") case.
      
      This is ancient going back to pre-2.4 days, and until trinity, nobody
      naver noticed.
      Reported-by: NDave Jones <davej@redhat.com>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      a930d879
  13. 23 2月, 2013 2 次提交
  14. 27 9月, 2012 1 次提交
  15. 30 7月, 2012 1 次提交
  16. 24 7月, 2012 1 次提交
  17. 02 6月, 2012 1 次提交
    • J
      fs: introduce inode operation ->update_time · c3b2da31
      Josef Bacik 提交于
      Btrfs has to make sure we have space to allocate new blocks in order to modify
      the inode, so updating time can fail.  We've gotten around this by having our
      own file_update_time but this is kind of a pain, and Christoph has indicated he
      would like to make xfs do something different with atime updates.  So introduce
      ->update_time, where we will deal with i_version an a/m/c time updates and
      indicate which changes need to be made.  The normal version just does what it
      has always done, updates the time and marks the inode dirty, and then
      filesystems can choose to do something different.
      
      I've gone through all of the users of file_update_time and made them check for
      errors with the exception of the fault code since it's complicated and I wasn't
      quite sure what to do there, also Jan is going to be pushing the file time
      updates into page_mkwrite for those who have it so that should satisfy btrfs and
      make it not a big deal to check the file_update_time() return code in the
      generic fault path. Thanks,
      Signed-off-by: NJosef Bacik <josef@redhat.com>
      c3b2da31
  18. 01 6月, 2012 1 次提交
  19. 31 5月, 2012 1 次提交
    • W
      pipe: return -ENOIOCTLCMD instead of -EINVAL on unknown ioctl command · 46ce341b
      Will Deacon 提交于
      As described in commit 07d106d0 ("vfs: fix up ENOIOCTLCMD error
      handling"), drivers should return -ENOIOCTLCMD if they receive an ioctl
      command which they don't understand. Doing so will result in -ENOTTY
      being returned to userspace, which matches the behaviour of the compat
      layer if it fails to translate an ioctl command.
      
      This patch fixes the pipe ioctl to return -ENOIOCTLCMD instead of
      -EINVAL when passed an unknown ioctl command.
      
      Cc: Al Viro <viro@zeniv.linux.org.uk>
      Cc: Andrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
      46ce341b
  20. 30 4月, 2012 1 次提交
    • L
      pipes: add a "packetized pipe" mode for writing · 9883035a
      Linus Torvalds 提交于
      The actual internal pipe implementation is already really about
      individual packets (called "pipe buffers"), and this simply exposes that
      as a special packetized mode.
      
      When we are in the packetized mode (marked by O_DIRECT as suggested by
      Alan Cox), a write() on a pipe will not merge the new data with previous
      writes, so each write will get a pipe buffer of its own.  The pipe
      buffer is then marked with the PIPE_BUF_FLAG_PACKET flag, which in turn
      will tell the reader side to break the read at that boundary (and throw
      away any partial packet contents that do not fit in the read buffer).
      
      End result: as long as you do writes less than PIPE_BUF in size (so that
      the pipe doesn't have to split them up), you can now treat the pipe as a
      packet interface, where each read() system call will read one packet at
      a time.  You can just use a sufficiently big read buffer (PIPE_BUF is
      sufficient, since bigger than that doesn't guarantee atomicity anyway),
      and the return value of the read() will naturally give you the size of
      the packet.
      
      NOTE! We do not support zero-sized packets, and zero-sized reads and
      writes to a pipe continue to be no-ops.  Also note that big packets will
      currently be split at write time, but that the size at which that
      happens is not really specified (except that it's bigger than PIPE_BUF).
      Currently that limit is the system page size, but we might want to
      explicitly support bigger packets some day.
      
      The main user for this is going to be the autofs packet interface,
      allowing us to stop having to care so deeply about exact packet sizes
      (which have had bugs with 32/64-bit compatibility modes).  But user
      space can create packetized pipes with "pipe2(fd, O_DIRECT)", which will
      fail with an EINVAL on kernels that do not support this interface.
      Tested-by: NMichael Tokarev <mjt@tls.msk.ru>
      Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
      Cc: David Miller <davem@davemloft.net>
      Cc: Ian Kent <raven@themaw.net>
      Cc: Thomas Meyer <thomas@m3y3r.de>
      Cc: stable@kernel.org  # needed for systemd/autofs interaction fix
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      9883035a
  21. 24 3月, 2012 1 次提交
  22. 20 3月, 2012 1 次提交
  23. 13 1月, 2012 1 次提交
    • S
      pipe: fail cleanly when root tries F_SETPIPE_SZ with big size · 2ccd4f4d
      Sasha Levin 提交于
      When a user with the CAP_SYS_RESOURCE cap tries to F_SETPIPE_SZ a pipe
      with size bigger than kmalloc() can alloc it spits out an ugly warning:
      
        ------------[ cut here ]------------
        WARNING: at mm/page_alloc.c:2095 __alloc_pages_nodemask+0x5d3/0x7a0()
        Pid: 733, comm: a.out Not tainted 3.2.0-rc1+ #4
        Call Trace:
           warn_slowpath_common+0x75/0xb0
           warn_slowpath_null+0x15/0x20
           __alloc_pages_nodemask+0x5d3/0x7a0
           __get_free_pages+0x12/0x50
           __kmalloc+0x12b/0x150
           pipe_set_size+0x75/0x120
           pipe_fcntl+0xf8/0x140
           do_fcntl+0x2d4/0x410
           sys_fcntl+0x66/0xa0
           system_call_fastpath+0x16/0x1b
        ---[ end trace 432f702e6db7b5ee ]---
      
      Instead, make kcalloc() handle the overflow case and fail quietly.
      
      [akpm@linux-foundation.org: switch to sizeof(*bufs) for 80-column niceness]
      Signed-off-by: NSasha Levin <levinsasha928@gmail.com>
      Cc: Alexander Viro <viro@zeniv.linux.org.uk>
      Acked-by: NPekka Enberg <penberg@kernel.org>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      2ccd4f4d
  24. 04 1月, 2012 1 次提交
  25. 01 11月, 2011 1 次提交