Re: [PATCH rdma-next 1/2] IB/mlx5: Protect against prefetch of invalid MR

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

 



On Tue, Feb 05, 2019 at 08:17:43AM +0200, Leon Romanovsky wrote:
> > .. so if we are now relying on the work queue flush to make this
> > correct, I think the mlx5_ib_prefetch_mr_work could be written a bit
> > more clearly:
> >
> >         if (WARN_ON(!ib_device_try_get(&w->dev->ib_dev)))
> > 	     goto out;
> >
> >         mlx5_ib_prefetch_sg_list(w->dev, w->pf_flags, w->sg_list,
> >                                  w->num_sge);
> >         ib_device_put(&w->dev->ib_dev);
> >  out:
> >
> > As it is no longer acceptable for work to be executed on an
> > unregistered ib device, this means that the MR's were not flushed
> > before all the clients exited, which should not be possible.
> 
> Why should we do ib_device get/put? We are already operating on such
> device and it should be "with us" all the time we are executing
> mlx5_ib_prefetch_sg_list().

Indeed, that should all be deleted too and replaced with a comment.

> > >  	INIT_WORK(&work->work, mlx5_ib_prefetch_mr_work);
> > > -	schedule_work(&work->work);
> > > -	return 0;
> > > +
> > > +	srcu_key = srcu_read_lock(&dev->mr_srcu);
> > > +	for (i = 0; i < num_sge; ++i) {
> >
> > 'num_sge' is read directly from userspace and it is a u32, but 'i'
> > here is an 'int', so userspace can trigger and infinite loop in the
> > kernel. I noticed this type mistake in other similar places here as
> > well.
> >
> > Using 'int' for a for loop variable is almost always the wrong thing
> > to do in some subtle way like this..
> 
> It is true for 32bit systems where "int" is 32 bits length. Those
> systems are under radar for us anyway.

'int' is always 32 bit

> > > +		struct mlx5_core_mkey *mmkey;
> > > +		struct mlx5_ib_mr *mr;
> > > +
> > > +		mmkey = __mlx5_mr_lookup(dev->mdev,
> > > +					 mlx5_base_mkey(sg_list[i].lkey));
> > > +		if (!mmkey || mmkey->key != sg_list[i].lkey) {
> > > +			valid_req = false;
> > > +			break;
> > > +		}
> > > +
> > > +		if (mmkey->type != MLX5_MKEY_MR) {
> > > +			valid_req = false;
> > > +			break;
> > > +		}
> > > +
> > > +		mr = container_of(mmkey, struct mlx5_ib_mr, mmkey);
> > > +
> > > +		if (mr->ibmr.pd != pd) {
> > > +			valid_req = false;
> > > +			break;
> > > +		}
> > > +
> > > +		if (!mr->live) {
> > > +			valid_req = false;
> > > +			break;
> > > +		}
> > > +
> > > +		atomic_inc(&mr->num_pending_prefetch);
> > > +	}
> >
> > This would be nicer in a function 'incr_num_pending_prefetch' or some
> > such
> 
> Maybe, I'm not fun of one-time called functions.

It is useful if it fixes error unwind control flow messes..

Jason




[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux