Received: by 2002:a25:ad19:0:0:0:0:0 with SMTP id y25csp4136872ybi; Mon, 29 Jul 2019 20:04:08 -0700 (PDT) X-Google-Smtp-Source: APXvYqzvaNmxvLkcDZXokKb7WBigrIQ5p2aD52I3lofyNWbyFFCgOqC2SV7cO8kjPBbhhzJ3lfM2 X-Received: by 2002:a17:90a:8c92:: with SMTP id b18mr112856487pjo.97.1564455848793; Mon, 29 Jul 2019 20:04:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1564455848; cv=none; d=google.com; s=arc-20160816; b=ICVyodi6HrzBlVrz7ektQcacwI1du7VZ+Oyce/lAQyJmNVeWW71kuu1h1Y4X9DoVZs 1YKjotdi4IVWzmLwk+ELkUv0SKJbWnRv3654D/O14axgJkkuTGBBD9BtvMYVlYD+aIKY VOA7zVUAMIx1RIuclT05oDLB+StPSRMQNvRNRf4ivw+6KImt3AylBBV175FRxN5WgU+t eOri+vMpVuG83eVhUOtn2LN7UETiIMFsqiNuEcSmHjWoDI7wdt4ExNUqTuHUJAL/ngeZ dndqOlJ5oeakl3NtDGLCo6QrPGThSXwJvLaQEN3WBiAmQsehrOi0/4k0CgxvD7Zi30eH m3hg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date; bh=JYL1NiJizGTx7NS91Xl3cEy5xY0fGPGznf+NOvXEmiQ=; b=GEu4EYZ1gJz/5P+lxe/x3yQA3VOsorZK7sv5v0gx1L7T0x/BDTCkSzyx+KBQJcBZQv 163s1k2JGJQq/uVERvVmZ2otA22luxYRzgh18+3s+805osFJ0vHHe7s7PITzQFQFUpIe QoNBy7Gasabqa9H8t6QTtrmV1upeAcHayshymmv9ULrRHJT4BNwjuKMRLH7AHjcZt6dG LowH3KJKtYpl7nS4Z56zsB9wyjjn6wNrS1x1HsNy2yHKrFx/Xl4xV8UH2ri5hi2cAtCY JmfMQZd9AGjA/VJcWIXn9fMO1RkBrM+27g2sfJ4NR4tb6q5u2KQD5Ev9WyfDJa3t23eM OuVg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-nfs-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-nfs-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 65si29593792pfg.241.2019.07.29.20.03.42; Mon, 29 Jul 2019 20:04:08 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-nfs-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-nfs-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-nfs-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388917AbfG2Vvz (ORCPT + 99 others); Mon, 29 Jul 2019 17:51:55 -0400 Received: from fieldses.org ([173.255.197.46]:40680 "EHLO fieldses.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388897AbfG2Vvz (ORCPT ); Mon, 29 Jul 2019 17:51:55 -0400 Received: by fieldses.org (Postfix, from userid 2815) id BBD6DABE; Mon, 29 Jul 2019 17:51:54 -0400 (EDT) Date: Mon, 29 Jul 2019 17:51:54 -0400 From: "J. Bruce Fields" To: Dave Wysochanski Cc: neilb@suse.com, linux-nfs@vger.kernel.org Subject: Re: [RFC PATCH] SUNRPC: Track writers of the 'channel' file to improve cache_listeners_exist Message-ID: <20190729215154.GI20723@fieldses.org> References: <20190725185421.GA15073@fieldses.org> <1564180381-9916-1-git-send-email-dwysocha@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1564180381-9916-1-git-send-email-dwysocha@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org On Fri, Jul 26, 2019 at 06:33:01PM -0400, Dave Wysochanski wrote: > The sunrpc cache interface is susceptible to being fooled by a rogue > process just reading a 'channel' file. If this happens the kernel > may think a valid daemon exists to service the cache when it does not. > For example, the following may fool the kernel: > cat /proc/net/rpc/auth.unix.gid/channel > > Change the tracking of readers to writers when considering whether a > listener exists as all valid daemon processes either open a channel > file O_RDWR or O_WRONLY. While this does not prevent a rogue process > from "stealing" a message from the kernel, it does at least improve > the kernels perception of whether a valid process servicing the cache > exists. > > Signed-off-by: Dave Wysochanski > --- > include/linux/sunrpc/cache.h | 6 +++--- > net/sunrpc/cache.c | 12 ++++++++---- > 2 files changed, 11 insertions(+), 7 deletions(-) > > diff --git a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h > index c7f38e8..f7d086b 100644 > --- a/include/linux/sunrpc/cache.h > +++ b/include/linux/sunrpc/cache.h > @@ -107,9 +107,9 @@ struct cache_detail { > /* fields for communication over channel */ > struct list_head queue; > > - atomic_t readers; /* how many time is /chennel open */ > - time_t last_close; /* if no readers, when did last close */ > - time_t last_warn; /* when we last warned about no readers */ > + atomic_t writers; /* how many time is /channel open */ > + time_t last_close; /* if no writers, when did last close */ > + time_t last_warn; /* when we last warned about no writers */ > > union { > struct proc_dir_entry *procfs; > diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c > index 6f1528f..a6a6190 100644 > --- a/net/sunrpc/cache.c > +++ b/net/sunrpc/cache.c > @@ -373,7 +373,7 @@ void sunrpc_init_cache_detail(struct cache_detail *cd) > spin_lock(&cache_list_lock); > cd->nextcheck = 0; > cd->entries = 0; > - atomic_set(&cd->readers, 0); > + atomic_set(&cd->writers, 0); > cd->last_close = 0; > cd->last_warn = -1; > list_add(&cd->others, &cache_list); > @@ -1029,11 +1029,13 @@ static int cache_open(struct inode *inode, struct file *filp, > } > rp->offset = 0; > rp->q.reader = 1; > - atomic_inc(&cd->readers); > + > spin_lock(&queue_lock); > list_add(&rp->q.list, &cd->queue); > spin_unlock(&queue_lock); > } > + if (filp->f_mode & FMODE_WRITE) > + atomic_inc(&cd->writers); This patch would be even simpler if we just modified the condition of the preceding if clause: - if (filp->f_mode & FMODE_READ) { + if (filp->f_mode & FMODE_WRITE) { and then we could drop the following chunk completely. Is there any reason not to do that? Or if the resulting behavior isn't right for write-only openers, we could make the condition ((filp->f_mode & FMODE_READ) && (filp->f_mode & FMODE_WRITE)). --b. > filp->private_data = rp; > return 0; > } > @@ -1062,8 +1064,10 @@ static int cache_release(struct inode *inode, struct file *filp, > filp->private_data = NULL; > kfree(rp); > > + } > + if (filp->f_mode & FMODE_WRITE) { > + atomic_dec(&cd->writers); > cd->last_close = seconds_since_boot(); > - atomic_dec(&cd->readers); > } > module_put(cd->owner); > return 0; > @@ -1171,7 +1175,7 @@ static void warn_no_listener(struct cache_detail *detail) > > static bool cache_listeners_exist(struct cache_detail *detail) > { > - if (atomic_read(&detail->readers)) > + if (atomic_read(&detail->writers)) > return true; > if (detail->last_close == 0) > /* This cache was never opened */ > -- > 1.8.3.1