Linux cryptographic layer development
 help / color / mirror / Atom feed
* [PATCH] lib/crypto/mpi: Fix heap OOB write in mpi_powm() when res aliases input
@ 2026-11-02  6:42 Maholi Tumanggor
  2026-11-02  6:49 ` sashiko-bot
  2026-11-02  9:25 ` [PATCH v2] " Maholi Tumanggor
  0 siblings, 2 replies; 5+ messages in thread
From: Maholi Tumanggor @ 2026-11-02  6:42 UTC (permalink / raw)
  To: linux-crypto; +Cc: herbert, davem, Maholi Tumanggor

When mpi_powm() is called with res->alloced < size and res->d aliases
base->d or exp->d, assign_rp is set to 1 and a new buffer is allocated
for rp. However the final write-back block unconditionally writes the
result into res->d (the original undersized buffer) instead of rp,
causing a heap out-of-bounds write and a subsequent use-after-free when
mpi_assign_limb_space() frees and re-assigns the corrupted buffer.

Fix by skipping the copy into res->d when assign_rp is set, keeping
the result in rp so that mpi_assign_limb_space() can correctly transfer
ownership.

Signed-off-by: Maholi Tumanggor <maholitumanggor@gmail.com>
---
 lib/crypto/mpi/mpi-pow.c | 30 ++++++++++++++++--------------
 1 file changed, 16 insertions(+), 14 deletions(-)

diff --git a/lib/crypto/mpi/mpi-pow.c b/lib/crypto/mpi/mpi-pow.c
index 9e695a3bd..06038ac8f 100644
--- a/lib/crypto/mpi/mpi-pow.c
+++ b/lib/crypto/mpi/mpi-pow.c
@@ -187,14 +187,14 @@ int mpi_powm(MPI res, MPI base, MPI exp, MPI mod)
 					if (!tspace) {
 						tsize = 2 * rsize;
 						tspace =
-						    mpi_alloc_limb_space(tsize);
+							mpi_alloc_limb_space(tsize);
 						if (!tspace)
 							goto enomem;
 					} else if (tsize < (2 * rsize)) {
 						mpi_free_limb_space(tspace);
 						tsize = 2 * rsize;
 						tspace =
-						    mpi_alloc_limb_space(tsize);
+							mpi_alloc_limb_space(tsize);
 						if (!tspace)
 							goto enomem;
 					}
@@ -204,7 +204,7 @@ int mpi_powm(MPI res, MPI base, MPI exp, MPI mod)
 				xsize = 2 * rsize;
 				if (xsize > msize) {
 					mpihelp_divrem(xp + msize, 0, xp, xsize,
-						       mp, msize);
+							   mp, msize);
 					xsize = msize;
 				}
 
@@ -216,21 +216,21 @@ int mpi_powm(MPI res, MPI base, MPI exp, MPI mod)
 					if (bsize < KARATSUBA_THRESHOLD) {
 						mpi_limb_t tmp;
 						if (mpihelp_mul
-						    (xp, rp, rsize, bp, bsize,
-						     &tmp) < 0)
+							(xp, rp, rsize, bp, bsize,
+							 &tmp) < 0)
 							goto enomem;
 					} else {
 						if (mpihelp_mul_karatsuba_case
-						    (xp, rp, rsize, bp, bsize,
-						     &karactx) < 0)
+							(xp, rp, rsize, bp, bsize,
+							 &karactx) < 0)
 							goto enomem;
 					}
 
 					xsize = rsize + bsize;
 					if (xsize > msize) {
 						mpihelp_divrem(xp + msize, 0,
-							       xp, xsize, mp,
-							       msize);
+								   xp, xsize, mp,
+								   msize);
 						xsize = msize;
 					}
 
@@ -256,14 +256,16 @@ int mpi_powm(MPI res, MPI base, MPI exp, MPI mod)
 		 * might be, see above).
 		 */
 		if (mod_shift_cnt) {
-			carry_limb =
-			    mpihelp_lshift(res->d, rp, rsize, mod_shift_cnt);
+			mpi_ptr_t dst = assign_rp ? rp : res->d;
+
+			carry_limb = mpihelp_lshift(dst, rp, rsize, mod_shift_cnt);
+			if (!assign_rp)
 			rp = res->d;
 			if (carry_limb) {
-				rp[rsize] = carry_limb;
-				rsize++;
+			rp[rsize] = carry_limb;
+			rsize++;
 			}
-		} else {
+		} else if (!assign_rp) {
 			MPN_COPY(res->d, rp, rsize);
 			rp = res->d;
 		}
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-11-02 18:12 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-02  6:42 [PATCH] lib/crypto/mpi: Fix heap OOB write in mpi_powm() when res aliases input Maholi Tumanggor
2026-11-02  6:49 ` sashiko-bot
2026-11-02  9:25 ` [PATCH v2] " Maholi Tumanggor
2026-11-02 13:03   ` sashiko-bot
2026-11-02 18:12   ` Eric Biggers

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox