--- /dev/null
+From ytcoode@gmail.com Thu Jun 16 15:08:23 2022
+From: Yuntao Wang <ytcoode@gmail.com>
+Date: Tue, 14 Jun 2022 22:26:22 +0800
+Subject: bpf: Fix incorrect memory charge cost calculation in stack_map_alloc()
+To: gregkh@linuxfoundation.org
+Cc: daniel@iogearbox.net, linux-kernel@vger.kernel.org, pavel@denx.de, sashal@kernel.org, stable@vger.kernel.org, ytcoode@gmail.com, ast@kernel.org, andrii@kernel.org, kafai@fb.com, songliubraving@fb.com, yhs@fb.com, john.fastabend@gmail.com, kpsingh@kernel.org, bpf@vger.kernel.org
+Message-ID: <20220614142622.998611-1-ytcoode@gmail.com>
+
+From: Yuntao Wang <ytcoode@gmail.com>
+
+commit b45043192b3e481304062938a6561da2ceea46a6 upstream.
+
+This is a backport of the original upstream patch for 5.4/5.10.
+
+The original upstream patch has been applied to 5.4/5.10 branches, which
+simply removed the line:
+
+ cost += n_buckets * (value_size + sizeof(struct stack_map_bucket));
+
+This is correct for upstream branch but incorrect for 5.4/5.10 branches,
+as the 5.4/5.10 branches do not have the commit 370868107bf6 ("bpf:
+Eliminate rlimit-based memory accounting for stackmap maps"), so the
+bpf_map_charge_init() function has not been removed.
+
+Currently the bpf_map_charge_init() function in 5.4/5.10 branches takes a
+wrong memory charge cost, the
+
+ attr->max_entries * (sizeof(struct stack_map_bucket) + (u64)value_size))
+
+part is missing, let's fix it.
+
+Cc: <stable@vger.kernel.org> # 5.4.y
+Cc: <stable@vger.kernel.org> # 5.10.y
+Signed-off-by: Yuntao Wang <ytcoode@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/bpf/stackmap.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/kernel/bpf/stackmap.c
++++ b/kernel/bpf/stackmap.c
+@@ -117,7 +117,8 @@ static struct bpf_map *stack_map_alloc(u
+ return ERR_PTR(-E2BIG);
+
+ cost = n_buckets * sizeof(struct stack_map_bucket *) + sizeof(*smap);
+- err = bpf_map_charge_init(&mem, cost);
++ err = bpf_map_charge_init(&mem, cost + attr->max_entries *
++ (sizeof(struct stack_map_bucket) + (u64)value_size));
+ if (err)
+ return ERR_PTR(err);
+
--- /dev/null
+From f2e19b36593caed4c977c2f55aeba7408aeb2132 Mon Sep 17 00:00:00 2001
+From: Martin Faltesek <mfaltesek@google.com>
+Date: Mon, 6 Jun 2022 21:57:29 -0500
+Subject: nfc: st21nfca: fix incorrect sizing calculations in EVT_TRANSACTION
+
+From: Martin Faltesek <mfaltesek@google.com>
+
+commit f2e19b36593caed4c977c2f55aeba7408aeb2132 upstream.
+
+The transaction buffer is allocated by using the size of the packet buf,
+and subtracting two which seem intended to remove the two tags which are
+not present in the target structure. This calculation leads to under
+counting memory because of differences between the packet contents and the
+target structure. The aid_len field is a u8 in the packet, but a u32 in
+the structure, resulting in at least 3 bytes always being under counted.
+Further, the aid data is a variable length field in the packet, but fixed
+in the structure, so if this field is less than the max, the difference is
+added to the under counting.
+
+The last validation check for transaction->params_len is also incorrect
+since it employs the same accounting error.
+
+To fix, perform validation checks progressively to safely reach the
+next field, to determine the size of both buffers and verify both tags.
+Once all validation checks pass, allocate the buffer and copy the data.
+This eliminates freeing memory on the error path, as those checks are
+moved ahead of memory allocation.
+
+Fixes: 26fc6c7f02cb ("NFC: st21nfca: Add HCI transaction event support")
+Fixes: 4fbcc1a4cb20 ("nfc: st21nfca: Fix potential buffer overflows in EVT_TRANSACTION")
+Cc: stable@vger.kernel.org
+Signed-off-by: Martin Faltesek <mfaltesek@google.com>
+Reviewed-by: Guenter Roeck <groeck@chromium.org>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nfc/st21nfca/se.c | 63 ++++++++++++++++++++++------------------------
+ 1 file changed, 31 insertions(+), 32 deletions(-)
+
+--- a/drivers/nfc/st21nfca/se.c
++++ b/drivers/nfc/st21nfca/se.c
+@@ -304,6 +304,8 @@ int st21nfca_connectivity_event_received
+ int r = 0;
+ struct device *dev = &hdev->ndev->dev;
+ struct nfc_evt_transaction *transaction;
++ u32 aid_len;
++ u8 params_len;
+
+ pr_debug("connectivity gate event: %x\n", event);
+
+@@ -312,51 +314,48 @@ int st21nfca_connectivity_event_received
+ r = nfc_se_connectivity(hdev->ndev, host);
+ break;
+ case ST21NFCA_EVT_TRANSACTION:
+- /*
+- * According to specification etsi 102 622
++ /* According to specification etsi 102 622
+ * 11.2.2.4 EVT_TRANSACTION Table 52
+ * Description Tag Length
+ * AID 81 5 to 16
+ * PARAMETERS 82 0 to 255
++ *
++ * The key differences are aid storage length is variably sized
++ * in the packet, but fixed in nfc_evt_transaction, and that the aid_len
++ * is u8 in the packet, but u32 in the structure, and the tags in
++ * the packet are not included in nfc_evt_transaction.
++ *
++ * size in bytes: 1 1 5-16 1 1 0-255
++ * offset: 0 1 2 aid_len + 2 aid_len + 3 aid_len + 4
++ * member name: aid_tag(M) aid_len aid params_tag(M) params_len params
++ * example: 0x81 5-16 X 0x82 0-255 X
+ */
+- if (skb->len < NFC_MIN_AID_LENGTH + 2 ||
+- skb->data[0] != NFC_EVT_TRANSACTION_AID_TAG)
++ if (skb->len < 2 || skb->data[0] != NFC_EVT_TRANSACTION_AID_TAG)
+ return -EPROTO;
+
+- transaction = (struct nfc_evt_transaction *)devm_kzalloc(dev,
+- skb->len - 2, GFP_KERNEL);
+- if (!transaction)
+- return -ENOMEM;
++ aid_len = skb->data[1];
++
++ if (skb->len < aid_len + 4 || aid_len > sizeof(transaction->aid))
++ return -EPROTO;
+
+- transaction->aid_len = skb->data[1];
++ params_len = skb->data[aid_len + 3];
+
+- /* Checking if the length of the AID is valid */
+- if (transaction->aid_len > sizeof(transaction->aid)) {
+- devm_kfree(dev, transaction);
+- return -EINVAL;
+- }
+-
+- memcpy(transaction->aid, &skb->data[2],
+- transaction->aid_len);
+-
+- /* Check next byte is PARAMETERS tag (82) */
+- if (skb->data[transaction->aid_len + 2] !=
+- NFC_EVT_TRANSACTION_PARAMS_TAG) {
+- devm_kfree(dev, transaction);
++ /* Verify PARAMETERS tag is (82), and final check that there is enough
++ * space in the packet to read everything.
++ */
++ if ((skb->data[aid_len + 2] != NFC_EVT_TRANSACTION_PARAMS_TAG) ||
++ (skb->len < aid_len + 4 + params_len))
+ return -EPROTO;
+- }
+
+- transaction->params_len = skb->data[transaction->aid_len + 3];
++ transaction = devm_kzalloc(dev, sizeof(*transaction) + params_len, GFP_KERNEL);
++ if (!transaction)
++ return -ENOMEM;
+
+- /* Total size is allocated (skb->len - 2) minus fixed array members */
+- if (transaction->params_len > ((skb->len - 2) -
+- sizeof(struct nfc_evt_transaction))) {
+- devm_kfree(dev, transaction);
+- return -EINVAL;
+- }
++ transaction->aid_len = aid_len;
++ transaction->params_len = params_len;
+
+- memcpy(transaction->params, skb->data +
+- transaction->aid_len + 4, transaction->params_len);
++ memcpy(transaction->aid, &skb->data[2], aid_len);
++ memcpy(transaction->params, &skb->data[aid_len + 4], params_len);
+
+ r = nfc_se_transaction(hdev->ndev, host, transaction);
+ break;