tech-kern archive

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

Re: kmem API to allocate arrays



On 29.07.2017 16:19, Taylor R Campbell wrote:
> It's stupid that we have to litter drivers with
> 
> 	if (SIZE_MAX/sizeof(struct xyz_cookie) < iocmd->ncookies) {
> 		error = EINVAL;
> 		goto out;
> 	}
> 	cookies = kmem_alloc(iocmd->ncookies*sizeof(struct xyz_cookie),
> 	    KM_SLEEP);
> 	...
> 
> and as you can tell from some recent commits, it hasn't been done
> everywhere.  It's been a consistent source of problems in the past.
> 
> This multiplication overflow check, which is all that most drivers do,
> also doesn't limit the amount of wired kmem that userland can request,
> and there's no way for kmem to say `sorry, I can't satisfy this
> request: it's too large' other than to panic or wedge.
> 
> In userland we now have reallocarr(3).  I propose that we add
> something to the kernel, but I'm not immediately sure what it should
> look like because kernel is a little different.  Solaris/illumos
> doesn't seem to have anything we could obviously parrot, from a
> cursory examination.
> 
> We could add something like
> 
> 	void	*kmem_allocarray(size_t n, size_t size, int flags);
> 	void	kmem_freearray(size_t n, size_t size);
> 
> That wouldn't address bounding the amount of wired kmem userland can
> request.  Perhaps that's OK: perhaps it's enough to have drivers put
> limits on the number of (say) array elements at the call site,
> although then there's not as much advantage to having a new API.
> Instead, we could make it
> 
> 	void	*kmem_allocarray(size_t n, size_t size, size_t maxn,
> 		    int flags);
> or
> 	void	*kmem_allocarray(size_t n, size_t size, size_t maxbytes,
> 		    int flags);
> 
> It's not clear that the call site is exactly the right place to
> compute a bound on the number of bytes a user can allocate.  On the
> other hand, if it's not clear up front what the bound is, then that
> makes a foot-oriented panic gun, or an instawedge, if the kernel can
> decides at run-time how many bytes is more than it can possibly ever
> satisfy, which is not so great either.  If you specify up front in the
> source, at least you can say by examination of the source whether it
> has a chance of working or not on some particular platform.  And maybe
> we can make it easier to write an expression for `no more than 10% of
> the machine's current RAM' or something.
> 
> Either way, kmem_allocarray would have to have the option of returning
> NULL, unlike kmem_alloc(..., KM_SLEEP), which is a nontrivial change
> to the contract now that chuq@ recently dove in deep to make sure it
> never returns NULL.
> 
> Thoughts?
> 

I think we should go for kmem_reallocarr(). It has been designed for
overflows like realocarray(3) with an option to be capable to resize a
table fron 1 to N elements and back from N to 0 including freeing.

Attachment: signature.asc
Description: OpenPGP digital signature



Home | Main Index | Thread Index | Old Index