{"id":2231519,"url":"http://patchwork.ozlabs.org/api/patches/2231519/?format=json","web_url":"http://patchwork.ozlabs.org/project/ubuntu-kernel/patch/11541ce7c7ded1473206c24068ca1748a402d079.1777576834.git.massimiliano.pellizzer@canonical.com/","project":{"id":15,"url":"http://patchwork.ozlabs.org/api/projects/15/?format=json","name":"Ubuntu Kernel","link_name":"ubuntu-kernel","list_id":"kernel-team.lists.ubuntu.com","list_email":"kernel-team@lists.ubuntu.com","web_url":null,"scm_url":null,"webscm_url":null,"list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<11541ce7c7ded1473206c24068ca1748a402d079.1777576834.git.massimiliano.pellizzer@canonical.com>","list_archive_url":null,"date":"2026-04-30T19:28:12","name":"[SRU,N,v2,1/9] crypto: scatterwalk - Backport memcpy_sglist()","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"266d620b7279ff5e1e47661d3a51607748336840","submitter":{"id":89057,"url":"http://patchwork.ozlabs.org/api/people/89057/?format=json","name":"Massimiliano Pellizzer","email":"massimiliano.pellizzer@canonical.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/ubuntu-kernel/patch/11541ce7c7ded1473206c24068ca1748a402d079.1777576834.git.massimiliano.pellizzer@canonical.com/mbox/","series":[{"id":502367,"url":"http://patchwork.ozlabs.org/api/series/502367/?format=json","web_url":"http://patchwork.ozlabs.org/project/ubuntu-kernel/list/?series=502367","date":"2026-04-30T19:28:11","name":"CVE-2026-31431","version":2,"mbox":"http://patchwork.ozlabs.org/series/502367/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2231519/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2231519/checks/","tags":{},"related":[],"headers":{"Return-Path":"<kernel-team-bounces@lists.ubuntu.com>","X-Original-To":"incoming@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (4096-bit key;\n unprotected) header.d=canonical.com header.i=@canonical.com\n header.a=rsa-sha256 header.s=20251003 header.b=M4vgmYno;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com\n (client-ip=185.125.189.65; helo=lists.ubuntu.com;\n envelope-from=kernel-team-bounces@lists.ubuntu.com;\n receiver=patchwork.ozlabs.org)"],"Received":["from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g644C5c1hz1yJr\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 01 May 2026 05:29:31 +1000 (AEST)","from localhost ([127.0.0.1] helo=lists.ubuntu.com)\n\tby lists.ubuntu.com with esmtp (Exim 4.86_2)\n\t(envelope-from <kernel-team-bounces@lists.ubuntu.com>)\n\tid 1wIX4g-00023b-Ka; Thu, 30 Apr 2026 19:29:26 +0000","from smtp-relay-internal-0.internal ([10.131.114.225]\n helo=smtp-relay-internal-0.canonical.com)\n by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)\n (Exim 4.86_2) (envelope-from <massimiliano.pellizzer@canonical.com>)\n id 1wIX4c-0001qD-RH\n for kernel-team@lists.ubuntu.com; Thu, 30 Apr 2026 19:29:22 +0000","from mail-wr1-f69.google.com (mail-wr1-f69.google.com\n [209.85.221.69])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest\n SHA256)\n (No client certificate requested)\n by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id A11173FE9F\n for <kernel-team@lists.ubuntu.com>; Thu, 30 Apr 2026 19:29:22 +0000 (UTC)","by mail-wr1-f69.google.com with SMTP id\n ffacd0b85a97d-43d789cebcfso1535403f8f.1\n for <kernel-team@lists.ubuntu.com>; Thu, 30 Apr 2026 12:29:22 -0700 (PDT)","from tuxedo-infinitybook (net-93-71-66-38.cust.vodafonedsl.it.\n [93.71.66.38]) by smtp.gmail.com with ESMTPSA id\n ffacd0b85a97d-448e74324a5sm8133217f8f.12.2026.04.30.12.29.20\n for <kernel-team@lists.ubuntu.com>\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Thu, 30 Apr 2026 12:29:21 -0700 (PDT)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com;\n s=20251003; t=1777577362;\n bh=YT1IKhJ7ePW075BzLDso9syq/DX6Rqg0Ay07VGxUA0E=;\n h=From:To:Subject:Date:Message-ID:In-Reply-To:References:\n MIME-Version;\n b=M4vgmYnoPVTBhEDnb91sXNlODpFdnARO1tGio4jiYV+Fusd9iB7dPp7qnCKsyBmQb\n AeZL7XwVaS6Rw3sWwu7EZXqjevrJUKtTKYwA4CsrOvzt0AMUGl/rkkRONm5LO/dC5y\n uCTaWFNZB3OFV5taKazq7+HysJnhHKA0AJ+u/5wu5k9foM2W6W5x/Qyw8XTZO2+ohI\n plGHaxejsRYzrSiTUj/oGQx90VzEWzDzmsUz5ohLphjzScqHKrTLfcKMSEDjHORZiE\n LcA/Wyvc2hxQO/SnBhKjT8wWZa2SeWifA0PFuLhLZE7UaToQMMAKH2M9B96hxGPmj7\n j5CpfUEJ9/SSyoVkDMIfoc7fhlfYVWHrR29qsoatBoFK8D5iWm4+oWVgFnkZImfLa0\n x2zqBLJ7lwxpFHZVkbjL5uVj+kom1cb9YmXnSYK7LwB5NC01K9T2xuJDeYkAvojwo9\n S+nhxUGdefCQQtVV/8of4vMqqaSCzn227qBJBisxzHGqJi66Q0ukmRW+1J0RCK/H3s\n sj8dsxwHeq9fX4BN+XA3nvOn6OjlyiwV/Cf/VqBVB7YgOn/dNAv/LOnhL1HrYDsHrS\n Eg+mqIyNCAtn7crXu97fj9NwKI//lCeI7IXYZPa0aB9rwEOKYvjC7mAcbU0sfnGPHF\n MgGMIw5YsFH81Go3xW3wQj2U=","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1777577362; x=1778182162;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to\n :cc:subject:date:message-id:reply-to;\n bh=YT1IKhJ7ePW075BzLDso9syq/DX6Rqg0Ay07VGxUA0E=;\n b=NrF/QWnP203jhzbp2iQSUoN7ok2QL8QJkB7B275+P5fD+w60+diAtUbqX6B46v0dLU\n IWbCG3SZ6kZJBHundWJ+rPV31VXvxKGsCpkyBtAWM8d6ud1fDrV0Fv7ip8IbudMi/+7I\n /A/Mq8HeuY+vsPKxGxQ/YoxJ7kKlfQfkpPlmr64ueOG3AdnK1hKO1qFmPuVTRgxEbZYg\n ydVcN3IC9lPhUjmkzAeHy7mXmUkXc0QzNESIrfo7Pi0kmlZxdtBBmv8YnOdcnS56lARy\n 9gpGz9jtrfzKKRnZaUWL6i+P0uijRhEnrRNhzvJnmPpcnlgjy9/1AajClBAo3EhBrNUG\n aPkg==","X-Gm-Message-State":"AOJu0YyC6725B1ayg6aDU+6RTz0c5R2wZE4LGIg6rexCA/wp6DQbld60\n 0J/bd0BLEdi8zaXJmXKtOF56DzeMcvxYdkvUmZyiXDsCTqiwqAmHtpbBRRQp6Eq8oDwROFtG+BO\n mkcFHVIWtLed12GwRqCJUY5dUjYgaYmcWdKe9pbeBinz2ixZr7e5ideIqv9oedjgS0n+aJwVSqX\n 8peLAupD7wS9djcA==","X-Gm-Gg":"AeBDiesdyh72RSVRlCzaUVQ0F4Aj3kVKUtOl0tNZaKcGkWQrpcbPU6gUIZtZwqVJT1I\n z+bm3WQ63dftaUuuzi85xqF70MUw3kTU5DYrIWKak2YkeFvHQZ6yxUzuv9zHRpjPyiUUs9qBhva\n wEdAZlhLFfKqjrAvug8hDEImonWegiQnOkXyDLaJV1oVSF4k+IyC+Cy7R+Bl+Bedv99px4rDU9f\n kQ/EG07dzjAIY2kWXYsfKqtYI62hin0J+mDpDOaKQ0QwfXDPlF/9dnYszhY3ffFvMLvgBnzjRwh\n CjDq5pyXwF6sWuvmoYCWx6/L7x0n/5JS4ca+402xjbKO8loLOLdtfclmXFMAvKGXfTD8ZSolXut\n FkrFSz6MUOxUBiW5hsT0I0Sv50UOP1eueMwmuiGDfMEFIE4u3RsDCTZbPKiKoq/HfGNrt7lfCxY\n A037rQIN4JSkhOTed590zNZ4Nm4BXYK34B2umNdd90+NVzRFvPKVpmlCDRd2g0GLeZYs8XawvfT\n KZYi9TuY7xWew==","X-Received":["by 2002:a05:600c:3e8e:b0:48a:5339:a46 with SMTP id\n 5b1f17b1804b1-48a86069e04mr55808555e9.9.1777577361826;\n Thu, 30 Apr 2026 12:29:21 -0700 (PDT)","by 2002:a05:600c:3e8e:b0:48a:5339:a46 with SMTP id\n 5b1f17b1804b1-48a86069e04mr55808345e9.9.1777577361411;\n Thu, 30 Apr 2026 12:29:21 -0700 (PDT)"],"From":"Massimiliano Pellizzer <massimiliano.pellizzer@canonical.com>","To":"kernel-team@lists.ubuntu.com","Subject":"[SRU][N][PATCH v2 1/9] crypto: scatterwalk - Backport memcpy_sglist()","Date":"Thu, 30 Apr 2026 21:28:12 +0200","Message-ID":"\n <11541ce7c7ded1473206c24068ca1748a402d079.1777576834.git.massimiliano.pellizzer@canonical.com>","X-Mailer":"git-send-email 2.53.0","In-Reply-To":"<cover.1777576834.git.massimiliano.pellizzer@canonical.com>","References":"\n <177757626672.818044.11792928639290212185@tuxedo-infinitybook.public>\n <cover.1777576834.git.massimiliano.pellizzer@canonical.com>","MIME-Version":"1.0","X-BeenThere":"kernel-team@lists.ubuntu.com","X-Mailman-Version":"2.1.20","Precedence":"list","List-Id":"Kernel team discussions <kernel-team.lists.ubuntu.com>","List-Unsubscribe":"<https://lists.ubuntu.com/mailman/options/kernel-team>,\n <mailto:kernel-team-request@lists.ubuntu.com?subject=unsubscribe>","List-Archive":"<https://lists.ubuntu.com/archives/kernel-team>","List-Post":"<mailto:kernel-team@lists.ubuntu.com>","List-Help":"<mailto:kernel-team-request@lists.ubuntu.com?subject=help>","List-Subscribe":"<https://lists.ubuntu.com/mailman/listinfo/kernel-team>,\n <mailto:kernel-team-request@lists.ubuntu.com?subject=subscribe>","Content-Type":"text/plain; charset=\"utf-8\"","Content-Transfer-Encoding":"base64","Errors-To":"kernel-team-bounces@lists.ubuntu.com","Sender":"\"kernel-team\" <kernel-team-bounces@lists.ubuntu.com>"},"content":"From: Eric Biggers <ebiggers@kernel.org>\n\nThis backports the current implementation of memcpy_sglist() from\nupstream commit 4dffc9bbffb9ccfcda730d899c97c553599e7ca8.\n\nThis function was rewritten twice.  The earlier implementations had many\nprerequisite commits, while the latest implementation is standalone.\nIt's much easier to just backport the latest code directly.\n\nSigned-off-by: Eric Biggers <ebiggers@kernel.org>\nSigned-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>\n(cherry picked from commit 41c3aa511e6ede871d0f5d9288969f4b7ab10f94 linux-6.12.y)\nCVE-2026-31431\nSigned-off-by: Massimiliano Pellizzer <massimiliano.pellizzer@canonical.com>\n---\n crypto/scatterwalk.c         | 94 ++++++++++++++++++++++++++++++++++++\n include/crypto/scatterwalk.h | 31 ++++++++++++\n 2 files changed, 125 insertions(+)","diff":"diff --git a/crypto/scatterwalk.c b/crypto/scatterwalk.c\nindex 16f6ba896fb6..9f0b27005166 100644\n--- a/crypto/scatterwalk.c\n+++ b/crypto/scatterwalk.c\n@@ -69,6 +69,100 @@ void scatterwalk_map_and_copy(void *buf, struct scatterlist *sg,\n }\n EXPORT_SYMBOL_GPL(scatterwalk_map_and_copy);\n \n+/**\n+ * memcpy_sglist() - Copy data from one scatterlist to another\n+ * @dst: The destination scatterlist.  Can be NULL if @nbytes == 0.\n+ * @src: The source scatterlist.  Can be NULL if @nbytes == 0.\n+ * @nbytes: Number of bytes to copy\n+ *\n+ * The scatterlists can describe exactly the same memory, in which case this\n+ * function is a no-op.  No other overlaps are supported.\n+ *\n+ * Context: Any context\n+ */\n+void memcpy_sglist(struct scatterlist *dst, struct scatterlist *src,\n+\t\t   unsigned int nbytes)\n+{\n+\tunsigned int src_offset, dst_offset;\n+\n+\tif (unlikely(nbytes == 0)) /* in case src and/or dst is NULL */\n+\t\treturn;\n+\n+\tsrc_offset = src->offset;\n+\tdst_offset = dst->offset;\n+\tfor (;;) {\n+\t\t/* Compute the length to copy this step. */\n+\t\tunsigned int len = min3(src->offset + src->length - src_offset,\n+\t\t\t\t\tdst->offset + dst->length - dst_offset,\n+\t\t\t\t\tnbytes);\n+\t\tstruct page *src_page = sg_page(src);\n+\t\tstruct page *dst_page = sg_page(dst);\n+\t\tconst void *src_virt;\n+\t\tvoid *dst_virt;\n+\n+\t\tif (IS_ENABLED(CONFIG_HIGHMEM)) {\n+\t\t\t/* HIGHMEM: we may have to actually map the pages. */\n+\t\t\tconst unsigned int src_oip = offset_in_page(src_offset);\n+\t\t\tconst unsigned int dst_oip = offset_in_page(dst_offset);\n+\t\t\tconst unsigned int limit = PAGE_SIZE;\n+\n+\t\t\t/* Further limit len to not cross a page boundary. */\n+\t\t\tlen = min3(len, limit - src_oip, limit - dst_oip);\n+\n+\t\t\t/* Compute the source and destination pages. */\n+\t\t\tsrc_page += src_offset / PAGE_SIZE;\n+\t\t\tdst_page += dst_offset / PAGE_SIZE;\n+\n+\t\t\tif (src_page != dst_page) {\n+\t\t\t\t/* Copy between different pages. */\n+\t\t\t\tmemcpy_page(dst_page, dst_oip,\n+\t\t\t\t\t    src_page, src_oip, len);\n+\t\t\t\tflush_dcache_page(dst_page);\n+\t\t\t} else if (src_oip != dst_oip) {\n+\t\t\t\t/* Copy between different parts of same page. */\n+\t\t\t\tdst_virt = kmap_local_page(dst_page);\n+\t\t\t\tmemcpy(dst_virt + dst_oip, dst_virt + src_oip,\n+\t\t\t\t       len);\n+\t\t\t\tkunmap_local(dst_virt);\n+\t\t\t\tflush_dcache_page(dst_page);\n+\t\t\t} /* Else, it's the same memory.  No action needed. */\n+\t\t} else {\n+\t\t\t/*\n+\t\t\t * !HIGHMEM: no mapping needed.  Just work in the linear\n+\t\t\t * buffer of each sg entry.  Note that we can cross page\n+\t\t\t * boundaries, as they are not significant in this case.\n+\t\t\t */\n+\t\t\tsrc_virt = page_address(src_page) + src_offset;\n+\t\t\tdst_virt = page_address(dst_page) + dst_offset;\n+\t\t\tif (src_virt != dst_virt) {\n+\t\t\t\tmemcpy(dst_virt, src_virt, len);\n+\t\t\t\tif (ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE)\n+\t\t\t\t\t__scatterwalk_flush_dcache_pages(\n+\t\t\t\t\t\tdst_page, dst_offset, len);\n+\t\t\t} /* Else, it's the same memory.  No action needed. */\n+\t\t}\n+\t\tnbytes -= len;\n+\t\tif (nbytes == 0) /* No more to copy? */\n+\t\t\tbreak;\n+\n+\t\t/*\n+\t\t * There's more to copy.  Advance the offsets by the length\n+\t\t * copied this step, and advance the sg entries as needed.\n+\t\t */\n+\t\tsrc_offset += len;\n+\t\tif (src_offset >= src->offset + src->length) {\n+\t\t\tsrc = sg_next(src);\n+\t\t\tsrc_offset = src->offset;\n+\t\t}\n+\t\tdst_offset += len;\n+\t\tif (dst_offset >= dst->offset + dst->length) {\n+\t\t\tdst = sg_next(dst);\n+\t\t\tdst_offset = dst->offset;\n+\t\t}\n+\t}\n+}\n+EXPORT_SYMBOL_GPL(memcpy_sglist);\n+\n struct scatterlist *scatterwalk_ffwd(struct scatterlist dst[2],\n \t\t\t\t     struct scatterlist *src,\n \t\t\t\t     unsigned int len)\ndiff --git a/include/crypto/scatterwalk.h b/include/crypto/scatterwalk.h\nindex 32fc4473175b..7e7942950c07 100644\n--- a/include/crypto/scatterwalk.h\n+++ b/include/crypto/scatterwalk.h\n@@ -83,6 +83,34 @@ static inline void scatterwalk_pagedone(struct scatter_walk *walk, int out,\n \t\tscatterwalk_start(walk, sg_next(walk->sg));\n }\n \n+/*\n+ * Flush the dcache of any pages that overlap the region\n+ * [offset, offset + nbytes) relative to base_page.\n+ *\n+ * This should be called only when ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE, to ensure\n+ * that all relevant code (including the call to sg_page() in the caller, if\n+ * applicable) gets fully optimized out when !ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE.\n+ */\n+static inline void __scatterwalk_flush_dcache_pages(struct page *base_page,\n+\t\t\t\t\t\t    unsigned int offset,\n+\t\t\t\t\t\t    unsigned int nbytes)\n+{\n+\tunsigned int num_pages;\n+\n+\tbase_page += offset / PAGE_SIZE;\n+\toffset %= PAGE_SIZE;\n+\n+\t/*\n+\t * This is an overflow-safe version of\n+\t * num_pages = DIV_ROUND_UP(offset + nbytes, PAGE_SIZE).\n+\t */\n+\tnum_pages = nbytes / PAGE_SIZE;\n+\tnum_pages += DIV_ROUND_UP(offset + (nbytes % PAGE_SIZE), PAGE_SIZE);\n+\n+\tfor (unsigned int i = 0; i < num_pages; i++)\n+\t\tflush_dcache_page(base_page + i);\n+}\n+\n static inline void scatterwalk_done(struct scatter_walk *walk, int out,\n \t\t\t\t    int more)\n {\n@@ -94,6 +122,9 @@ static inline void scatterwalk_done(struct scatter_walk *walk, int out,\n void scatterwalk_copychunks(void *buf, struct scatter_walk *walk,\n \t\t\t    size_t nbytes, int out);\n \n+void memcpy_sglist(struct scatterlist *dst, struct scatterlist *src,\n+\t\t   unsigned int nbytes);\n+\n void scatterwalk_map_and_copy(void *buf, struct scatterlist *sg,\n \t\t\t      unsigned int start, unsigned int nbytes, int out);\n \n","prefixes":["SRU","N","v2","1/9"]}