Message ID | 20220923202822.2667581-7-keescook@chromium.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | slab: Introduce kmalloc_size_roundup() | expand |
>-----Original Message----- >From: Kees Cook <keescook@chromium.org> >Sent: Friday, September 23, 2022 4:28 PM >To: Vlastimil Babka <vbabka@suse.cz> >Cc: Kees Cook <keescook@chromium.org>; Brandeburg, Jesse ><jesse.brandeburg@intel.com>; Nguyen, Anthony L ><anthony.l.nguyen@intel.com>; David S. Miller <davem@davemloft.net>; >Eric Dumazet <edumazet@google.com>; Jakub Kicinski <kuba@kernel.org>; >Paolo Abeni <pabeni@redhat.com>; intel-wired-lan@lists.osuosl.org; >netdev@vger.kernel.org; Ruhl, Michael J <michael.j.ruhl@intel.com>; >Hyeonggon Yoo <42.hyeyoo@gmail.com>; Christoph Lameter ><cl@linux.com>; Pekka Enberg <penberg@kernel.org>; David Rientjes ><rientjes@google.com>; Joonsoo Kim <iamjoonsoo.kim@lge.com>; Andrew >Morton <akpm@linux-foundation.org>; Greg Kroah-Hartman ><gregkh@linuxfoundation.org>; Nick Desaulniers ><ndesaulniers@google.com>; Alex Elder <elder@kernel.org>; Josef Bacik ><josef@toxicpanda.com>; David Sterba <dsterba@suse.com>; Sumit Semwal ><sumit.semwal@linaro.org>; Christian König <christian.koenig@amd.com>; >Daniel Micay <danielmicay@gmail.com>; Yonghong Song <yhs@fb.com>; >Marco Elver <elver@google.com>; Miguel Ojeda <ojeda@kernel.org>; linux- >kernel@vger.kernel.org; linux-mm@kvack.org; linux-btrfs@vger.kernel.org; >linux-media@vger.kernel.org; dri-devel@lists.freedesktop.org; linaro-mm- >sig@lists.linaro.org; linux-fsdevel@vger.kernel.org; dev@openvswitch.org; >x86@kernel.org; llvm@lists.linux.dev; linux-hardening@vger.kernel.org >Subject: [PATCH v2 06/16] igb: Proactively round up to kmalloc bucket size > >In preparation for removing the "silently change allocation size" >users of ksize(), explicitly round up all q_vector allocations so that >allocations can be correctly compared to ksize(). > >Additionally fix potential use-after-free in the case of new allocation >failure: only free memory if the replacement allocation succeeds. > >Cc: Jesse Brandeburg <jesse.brandeburg@intel.com> >Cc: Tony Nguyen <anthony.l.nguyen@intel.com> >Cc: "David S. Miller" <davem@davemloft.net> >Cc: Eric Dumazet <edumazet@google.com> >Cc: Jakub Kicinski <kuba@kernel.org> >Cc: Paolo Abeni <pabeni@redhat.com> >Cc: intel-wired-lan@lists.osuosl.org >Cc: netdev@vger.kernel.org >Signed-off-by: Kees Cook <keescook@chromium.org> >--- > drivers/net/ethernet/intel/igb/igb_main.c | 5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) > >diff --git a/drivers/net/ethernet/intel/igb/igb_main.c >b/drivers/net/ethernet/intel/igb/igb_main.c >index 2796e81d2726..eb51e531c096 100644 >--- a/drivers/net/ethernet/intel/igb/igb_main.c >+++ b/drivers/net/ethernet/intel/igb/igb_main.c >@@ -1195,15 +1195,16 @@ static int igb_alloc_q_vector(struct igb_adapter >*adapter, > return -ENOMEM; > > ring_count = txr_count + rxr_count; >- size = struct_size(q_vector, ring, ring_count); >+ size = kmalloc_size_roundup(struct_size(q_vector, ring, ring_count)); This looks good to me... > /* allocate q_vector and rings */ > q_vector = adapter->q_vector[v_idx]; > if (!q_vector) { > q_vector = kzalloc(size, GFP_KERNEL); > } else if (size > ksize(q_vector)) { >- kfree_rcu(q_vector, rcu); > q_vector = kzalloc(size, GFP_KERNEL); >+ if (q_vector) >+ kfree_rcu(q_vector, rcu); Even though this is in the ksize part, this seems like an unrelated change? Should this be in a different patch? Also, the kfree_rcu will free q_vector after the RCU grace period? Is that what you want to do? How does rcu distinguish between the original q_vector, and the newly kzalloced one? Thanks, Mike > } else { > memset(q_vector, 0, size); > } >-- >2.34.1
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 2796e81d2726..eb51e531c096 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -1195,15 +1195,16 @@ static int igb_alloc_q_vector(struct igb_adapter *adapter, return -ENOMEM; ring_count = txr_count + rxr_count; - size = struct_size(q_vector, ring, ring_count); + size = kmalloc_size_roundup(struct_size(q_vector, ring, ring_count)); /* allocate q_vector and rings */ q_vector = adapter->q_vector[v_idx]; if (!q_vector) { q_vector = kzalloc(size, GFP_KERNEL); } else if (size > ksize(q_vector)) { - kfree_rcu(q_vector, rcu); q_vector = kzalloc(size, GFP_KERNEL); + if (q_vector) + kfree_rcu(q_vector, rcu); } else { memset(q_vector, 0, size); }
In preparation for removing the "silently change allocation size" users of ksize(), explicitly round up all q_vector allocations so that allocations can be correctly compared to ksize(). Additionally fix potential use-after-free in the case of new allocation failure: only free memory if the replacement allocation succeeds. Cc: Jesse Brandeburg <jesse.brandeburg@intel.com> Cc: Tony Nguyen <anthony.l.nguyen@intel.com> Cc: "David S. Miller" <davem@davemloft.net> Cc: Eric Dumazet <edumazet@google.com> Cc: Jakub Kicinski <kuba@kernel.org> Cc: Paolo Abeni <pabeni@redhat.com> Cc: intel-wired-lan@lists.osuosl.org Cc: netdev@vger.kernel.org Signed-off-by: Kees Cook <keescook@chromium.org> --- drivers/net/ethernet/intel/igb/igb_main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)