Re: [bug report] nfsd: Protect session creation and client confirm using client_lock

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 2021-09-08 at 21:32 +0000, Chuck Lever III wrote:
> 
> > On Sep 8, 2021, at 5:26 PM, Bruce Fields <bfields@xxxxxxxxxxxx> wrote:
> > 
> > On Tue, Sep 07, 2021 at 03:00:23PM +0000, Chuck Lever III wrote:
> > > We have IPV6_SCOPE_ID_LEN as a maximum size of the scope ID,
> > > and it's not a big value. As long as boundary checking is made
> > > to be sufficient, then a stack residency for the device name
> > > should be safe.
> > 
> > Something like this?  (Or are you making a patch?
> 
> I thought Jeff was going to handle it? More below.
> 

No, sorry... I was just suggesting a potential fix. I'd probably rather
you guys fix it since you're better positioned to test this at the
moment.

> 
> > I'm not even sure how to test.)
> > are
> > --b.
> > 
> > diff --git a/net/sunrpc/addr.c b/net/sunrpc/addr.c
> > index 6e4dbd577a39..d435bffc6199 100644
> > --- a/net/sunrpc/addr.c
> > +++ b/net/sunrpc/addr.c
> > @@ -162,8 +162,10 @@ static int rpc_parse_scope_id(struct net *net, const char *buf,
> > 			      const size_t buflen, const char *delim,
> > 			      struct sockaddr_in6 *sin6)
> > {
> > -	char *p;
> > +	char p[IPV6_SCOPE_ID_LEN + 1];
> > 	size_t len;
> > +	u32 scope_id = 0;
> > +	struct net_device *dev;
> > 
> > 	if ((buf + buflen) == delim)
> > 		return 1;
> > @@ -175,29 +177,23 @@ static int rpc_parse_scope_id(struct net *net, const char *buf,
> > 		return 0;
> > 
> > 	len = (buf + buflen) - delim - 1;
> > -	p = kmemdup_nul(delim + 1, len, GFP_KERNEL);
> > -	if (p) {
> > -		u32 scope_id = 0;
> > -		struct net_device *dev;
> > -
> > -		dev = dev_get_by_name(net, p);
> > -		if (dev != NULL) {
> > -			scope_id = dev->ifindex;
> > -			dev_put(dev);
> > -		} else {
> > -			if (kstrtou32(p, 10, &scope_id) != 0) {
> > -				kfree(p);
> > -				return 0;
> > -			}
> > -		}
> > -
> > -		kfree(p);
> > -
> > -		sin6->sin6_scope_id = scope_id;
> > -		return 1;
> > +	if (len > IPV6_SCOPE_ID_LEN)
> > +		return 0;
> > +
> > +	memcpy(p, delim + 1, len);
> > +	p[len] = 0;
> 
> If I recall correctly, Linus prefers us to use the str*()
> functions instead of raw memcpy() in cases like this.
> 

I hadn't heard that. If you already know the length to be copied, then
strcpy and the like tend to be less efficient since they continually
have to check for null terminators as they walk the source string.

> 
> > +
> > +	dev = dev_get_by_name(net, p);
> > +	if (dev != NULL) {
> > +		scope_id = dev->ifindex;
> > +		dev_put(dev);
> > +	} else {
> > +		if (kstrtou32(p, 10, &scope_id) != 0)
> > +			return 0;
> > 	}
> > 
> > -	return 0;
> > +	sin6->sin6_scope_id = scope_id;
> > +	return 1;
> > }
> > 
> > static size_t rpc_pton6(struct net *net, const char *buf, const size_t buflen,
> 
> --
> Chuck Lever
> 
> 
> 

-- 
Jeff Layton <jlayton@xxxxxxxxxx>




[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux