netdev.vger.kernel.org archive mirror
 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).