All of lore.kernel.org
 help / color / mirror / Atom feed
From: John Fastabend <john.r.fastabend@intel.com>
To: Al Viro <viro@ZenIV.linux.org.uk>
Cc: netdev@vger.kernel.org, David Miller <davem@davemloft.net>,
	Neil Horman <nhorman@tuxdriver.com>,
	linux-kernel@vger.kernel.org
Subject: Re: [flame^Wreview] net: netprio_cgroup: rework update socket logic
Date: Sun, 12 Aug 2012 22:55:17 -0700	[thread overview]
Message-ID: <502896C5.7080303@intel.com> (raw)
In-Reply-To: <20120813015348.GZ23464@ZenIV.linux.org.uk>

On 8/12/2012 6:53 PM, Al Viro wrote:
> 	Ladies and gentlemen, who the devil had reviewed that little gem?
>
> commit 406a3c638ce8b17d9704052c07955490f732c2b8
> Author: John Fastabend <john.r.fastabend@intel.com>
> Date:   Fri Jul 20 10:39:25 2012 +0000
>
> is a bleeding bogosity that doesn't pass even the most cursory
> inspection.  It iterates through descriptor tables of a bunch
> of processes, doing this:
>                          file = fcheck_files(files, fd);
>                          if (!file)
>                                  continue;
>
>                          path = d_path(&file->f_path, tmp, PAGE_SIZE);
>                          rv = sscanf(path, "socket:[%lu]", &s);
>                          if (rv <= 0)
>                                  continue;
>
>                          sock = sock_from_file(file, &err);
>                          if (!err)
>                                  sock_update_netprioidx(sock->sk, p);
> Note the charming use of sscanf() for pattern-matching.  's' (inode
> number of socket) is completely unused afterwards; what happens here
> is a very badly written attempt to skip non-sockets.  Why, will
> sock_from_file() blow up on non-sockets?  And isn't there some less
> obnoxious way to check that the file is a sockfs one?  Let's see:
> struct socket *sock_from_file(struct file *file, int *err)
> {
>          if (file->f_op == &socket_file_ops)
>                  return file->private_data;      /* set in sock_map_fd */
>
>          *err = -ENOTSOCK;
>          return NULL;
> }
> ... and the first line is exactly that - a check that we are on sockfs.
> _Far_ less expensive one, at that, so it's not even that we are avoiding
> a costly test.  In other words, all masturbation with d_path() is absolutely
> pointless.
>
> Furthermore, it's racy; had been even more so before the delayed fput series
> went in, but even now it's not safe.  fcheck_files() does *NOT* guarantee
> that file is not getting closed right now.  rcu_read_lock() prevents only
> freeing and potential reuse of struct file we'd got; it might go all the
> way through final fput() just as we look at it.  So file->f_path is not
> protected by anything.  Worse yet, neither is struct socket itself - we
> might be going through sock_release() at the same time, so sock->sk might
> very well be NULL, leaving us a oops even after we dump d_path() idiocy.
>
> To make it even funnier, there's such thing as SCM_RIGHTS datagrams and
> descriptor passing.  In other words, it's *not* going to catch all sockets
> that would be caught by the earlier variant.
>

OK clearly I screwed it up thanks for reviewing Al. How about this.

                 fdt = files_fdtable(files);
                 for (fd = 0; fd < fdt->max_fds; fd++) {
                         struct socket *sock;
                         int err = 0;

                         sock = sockfd_lookup(fd, &err);
                         if (!sock) {
                                 lock_sock(sock->sk);
                                 sock_update_netprioidx(sock->sk, p);
                                 release_sock(sock->sk);
                                 sockfd_put(sock);
                         }
                 }

sockfd_lookup will call fget() and also test file->f_op. testing this
now.

  parent reply	other threads:[~2012-08-13  5:55 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-08-13  1:53 [flame^Wreview] net: netprio_cgroup: rework update socket logic Al Viro
2012-08-13  2:30 ` Al Viro
2012-08-13  5:55 ` John Fastabend [this message]
2012-08-13  6:23   ` John Fastabend
2012-08-13 12:18     ` Al Viro
2012-08-13 16:58       ` John Fastabend
2012-08-13 17:01         ` Al Viro
2012-08-13 17:31           ` John Fastabend
2012-08-13  9:08   ` Joe Perches
2012-08-13 11:22   ` Neil Horman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=502896C5.7080303@intel.com \
    --to=john.r.fastabend@intel.com \
    --cc=davem@davemloft.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=nhorman@tuxdriver.com \
    --cc=viro@ZenIV.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.