summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pagano <mpagano@gentoo.org>2020-10-17 06:16:51 -0400
committerMike Pagano <mpagano@gentoo.org>2020-10-17 06:16:51 -0400
commitba05e5e05bb7b8cec17f15325584fd90ac6bef38 (patch)
treee36fb6e9dbeb9ae29628fe7b6d05677f9334af30
parentLinux patch 4.14.201 (diff)
downloadlinux-patches-4.14-212.tar.gz
linux-patches-4.14-212.tar.bz2
linux-patches-4.14-212.zip
Linux patch 4.14.2024.14-212
Signed-off-by: Mike Pagano <mpagano@gentoo.org>
-rw-r--r--0000_README4
-rw-r--r--1201_linux-4.14.202.patch692
2 files changed, 696 insertions, 0 deletions
diff --git a/0000_README b/0000_README
index 9cff2cfc..a6503727 100644
--- a/0000_README
+++ b/0000_README
@@ -847,6 +847,10 @@ Patch: 1200_linux-4.14.201.patch
From: https://www.kernel.org
Desc: Linux 4.14.201
+Patch: 1201_linux-4.14.202.patch
+From: https://www.kernel.org
+Desc: Linux 4.14.202
+
Patch: 1500_XATTR_USER_PREFIX.patch
From: https://bugs.gentoo.org/show_bug.cgi?id=470644
Desc: Support for namespace user.pax.* on tmpfs.
diff --git a/1201_linux-4.14.202.patch b/1201_linux-4.14.202.patch
new file mode 100644
index 00000000..730e54b2
--- /dev/null
+++ b/1201_linux-4.14.202.patch
@@ -0,0 +1,692 @@
+diff --git a/Makefile b/Makefile
+index e3e2d7fa72325..0284c231bdead 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 4
+ PATCHLEVEL = 14
+-SUBLEVEL = 201
++SUBLEVEL = 202
+ EXTRAVERSION =
+ NAME = Petit Gorille
+
+diff --git a/drivers/crypto/bcm/cipher.c b/drivers/crypto/bcm/cipher.c
+index 279e907590e98..af6119b3b6b72 100644
+--- a/drivers/crypto/bcm/cipher.c
++++ b/drivers/crypto/bcm/cipher.c
+@@ -2981,7 +2981,6 @@ static int aead_gcm_ccm_setkey(struct crypto_aead *cipher,
+
+ ctx->enckeylen = keylen;
+ ctx->authkeylen = 0;
+- memcpy(ctx->enckey, key, ctx->enckeylen);
+
+ switch (ctx->enckeylen) {
+ case AES_KEYSIZE_128:
+@@ -2997,6 +2996,8 @@ static int aead_gcm_ccm_setkey(struct crypto_aead *cipher,
+ goto badkey;
+ }
+
++ memcpy(ctx->enckey, key, ctx->enckeylen);
++
+ flow_log(" enckeylen:%u authkeylen:%u\n", ctx->enckeylen,
+ ctx->authkeylen);
+ flow_dump(" enc: ", ctx->enckey, ctx->enckeylen);
+@@ -3057,6 +3058,10 @@ static int aead_gcm_esp_setkey(struct crypto_aead *cipher,
+ struct iproc_ctx_s *ctx = crypto_aead_ctx(cipher);
+
+ flow_log("%s\n", __func__);
++
++ if (keylen < GCM_ESP_SALT_SIZE)
++ return -EINVAL;
++
+ ctx->salt_len = GCM_ESP_SALT_SIZE;
+ ctx->salt_offset = GCM_ESP_SALT_OFFSET;
+ memcpy(ctx->salt, key + keylen - GCM_ESP_SALT_SIZE, GCM_ESP_SALT_SIZE);
+@@ -3085,6 +3090,10 @@ static int rfc4543_gcm_esp_setkey(struct crypto_aead *cipher,
+ struct iproc_ctx_s *ctx = crypto_aead_ctx(cipher);
+
+ flow_log("%s\n", __func__);
++
++ if (keylen < GCM_ESP_SALT_SIZE)
++ return -EINVAL;
++
+ ctx->salt_len = GCM_ESP_SALT_SIZE;
+ ctx->salt_offset = GCM_ESP_SALT_OFFSET;
+ memcpy(ctx->salt, key + keylen - GCM_ESP_SALT_SIZE, GCM_ESP_SALT_SIZE);
+@@ -3114,6 +3123,10 @@ static int aead_ccm_esp_setkey(struct crypto_aead *cipher,
+ struct iproc_ctx_s *ctx = crypto_aead_ctx(cipher);
+
+ flow_log("%s\n", __func__);
++
++ if (keylen < CCM_ESP_SALT_SIZE)
++ return -EINVAL;
++
+ ctx->salt_len = CCM_ESP_SALT_SIZE;
+ ctx->salt_offset = CCM_ESP_SALT_OFFSET;
+ memcpy(ctx->salt, key + keylen - CCM_ESP_SALT_SIZE, CCM_ESP_SALT_SIZE);
+diff --git a/drivers/crypto/qat/qat_common/qat_algs.c b/drivers/crypto/qat/qat_common/qat_algs.c
+index baffae817259c..bb875245644fe 100644
+--- a/drivers/crypto/qat/qat_common/qat_algs.c
++++ b/drivers/crypto/qat/qat_common/qat_algs.c
+@@ -825,6 +825,11 @@ static int qat_alg_aead_dec(struct aead_request *areq)
+ struct icp_qat_fw_la_bulk_req *msg;
+ int digst_size = crypto_aead_authsize(aead_tfm);
+ int ret, ctr = 0;
++ u32 cipher_len;
++
++ cipher_len = areq->cryptlen - digst_size;
++ if (cipher_len % AES_BLOCK_SIZE != 0)
++ return -EINVAL;
+
+ ret = qat_alg_sgl_to_bufl(ctx->inst, areq->src, areq->dst, qat_req);
+ if (unlikely(ret))
+@@ -839,7 +844,7 @@ static int qat_alg_aead_dec(struct aead_request *areq)
+ qat_req->req.comn_mid.src_data_addr = qat_req->buf.blp;
+ qat_req->req.comn_mid.dest_data_addr = qat_req->buf.bloutp;
+ cipher_param = (void *)&qat_req->req.serv_specif_rqpars;
+- cipher_param->cipher_length = areq->cryptlen - digst_size;
++ cipher_param->cipher_length = cipher_len;
+ cipher_param->cipher_offset = areq->assoclen;
+ memcpy(cipher_param->u.cipher_IV_array, areq->iv, AES_BLOCK_SIZE);
+ auth_param = (void *)((uint8_t *)cipher_param + sizeof(*cipher_param));
+@@ -868,6 +873,9 @@ static int qat_alg_aead_enc(struct aead_request *areq)
+ uint8_t *iv = areq->iv;
+ int ret, ctr = 0;
+
++ if (areq->cryptlen % AES_BLOCK_SIZE != 0)
++ return -EINVAL;
++
+ ret = qat_alg_sgl_to_bufl(ctx->inst, areq->src, areq->dst, qat_req);
+ if (unlikely(ret))
+ return ret;
+diff --git a/drivers/media/usb/usbtv/usbtv-core.c b/drivers/media/usb/usbtv/usbtv-core.c
+index 50a61143898b5..bf0e3908cdc40 100644
+--- a/drivers/media/usb/usbtv/usbtv-core.c
++++ b/drivers/media/usb/usbtv/usbtv-core.c
+@@ -113,7 +113,8 @@ static int usbtv_probe(struct usb_interface *intf,
+
+ usbtv_audio_fail:
+ /* we must not free at this point */
+- usb_get_dev(usbtv->udev);
++ v4l2_device_get(&usbtv->v4l2_dev);
++ /* this will undo the v4l2_device_get() */
+ usbtv_video_free(usbtv);
+
+ usbtv_video_fail:
+diff --git a/drivers/net/ethernet/marvell/mvmdio.c b/drivers/net/ethernet/marvell/mvmdio.c
+index b6ff143c9cffe..024688c90aa96 100644
+--- a/drivers/net/ethernet/marvell/mvmdio.c
++++ b/drivers/net/ethernet/marvell/mvmdio.c
+@@ -319,15 +319,25 @@ static int orion_mdio_probe(struct platform_device *pdev)
+
+ init_waitqueue_head(&dev->smi_busy_wait);
+
+- for (i = 0; i < ARRAY_SIZE(dev->clk); i++) {
+- dev->clk[i] = of_clk_get(pdev->dev.of_node, i);
+- if (PTR_ERR(dev->clk[i]) == -EPROBE_DEFER) {
++ if (pdev->dev.of_node) {
++ for (i = 0; i < ARRAY_SIZE(dev->clk); i++) {
++ dev->clk[i] = of_clk_get(pdev->dev.of_node, i);
++ if (PTR_ERR(dev->clk[i]) == -EPROBE_DEFER) {
++ ret = -EPROBE_DEFER;
++ goto out_clk;
++ }
++ if (IS_ERR(dev->clk[i]))
++ break;
++ clk_prepare_enable(dev->clk[i]);
++ }
++ } else {
++ dev->clk[0] = clk_get(&pdev->dev, NULL);
++ if (PTR_ERR(dev->clk[0]) == -EPROBE_DEFER) {
+ ret = -EPROBE_DEFER;
+ goto out_clk;
+ }
+- if (IS_ERR(dev->clk[i]))
+- break;
+- clk_prepare_enable(dev->clk[i]);
++ if (!IS_ERR(dev->clk[0]))
++ clk_prepare_enable(dev->clk[0]);
+ }
+
+ dev->err_interrupt = platform_get_irq(pdev, 0);
+diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c
+index 1800eb3ae0176..cdf86284dd047 100644
+--- a/drivers/staging/comedi/drivers/vmk80xx.c
++++ b/drivers/staging/comedi/drivers/vmk80xx.c
+@@ -676,6 +676,9 @@ static int vmk80xx_find_usb_endpoints(struct comedi_device *dev)
+ if (!devpriv->ep_rx || !devpriv->ep_tx)
+ return -ENODEV;
+
++ if (!usb_endpoint_maxp(devpriv->ep_rx) || !usb_endpoint_maxp(devpriv->ep_tx))
++ return -EINVAL;
++
+ return 0;
+ }
+
+diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
+index 3e2d3a96b559e..8ed84338a626a 100644
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -1032,6 +1032,11 @@ static const struct usb_device_id id_table_combined[] = {
+ /* U-Blox devices */
+ { USB_DEVICE(UBLOX_VID, UBLOX_C099F9P_ZED_PID) },
+ { USB_DEVICE(UBLOX_VID, UBLOX_C099F9P_ODIN_PID) },
++ /* FreeCalypso USB adapters */
++ { USB_DEVICE(FTDI_VID, FTDI_FALCONIA_JTAG_BUF_PID),
++ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
++ { USB_DEVICE(FTDI_VID, FTDI_FALCONIA_JTAG_UNBUF_PID),
++ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+ { } /* Terminating entry */
+ };
+
+diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
+index b5ca17a5967a0..3d47c6d72256e 100644
+--- a/drivers/usb/serial/ftdi_sio_ids.h
++++ b/drivers/usb/serial/ftdi_sio_ids.h
+@@ -39,6 +39,13 @@
+
+ #define FTDI_LUMEL_PD12_PID 0x6002
+
++/*
++ * Custom USB adapters made by Falconia Partners LLC
++ * for FreeCalypso project, ID codes allocated to Falconia by FTDI.
++ */
++#define FTDI_FALCONIA_JTAG_BUF_PID 0x7150
++#define FTDI_FALCONIA_JTAG_UNBUF_PID 0x7151
++
+ /* Sienna Serial Interface by Secyourit GmbH */
+ #define FTDI_SIENNA_PID 0x8348
+
+diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
+index c2f1e49ea5062..3fc14b3774643 100644
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -531,6 +531,7 @@ static void option_instat_callback(struct urb *urb);
+ /* Cellient products */
+ #define CELLIENT_VENDOR_ID 0x2692
+ #define CELLIENT_PRODUCT_MEN200 0x9005
++#define CELLIENT_PRODUCT_MPL200 0x9025
+
+ /* Hyundai Petatel Inc. products */
+ #define PETATEL_VENDOR_ID 0x1ff4
+@@ -1189,6 +1190,8 @@ static const struct usb_device_id option_ids[] = {
+ .driver_info = NCTRL(2) | RSVD(3) },
+ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1053, 0xff), /* Telit FN980 (ECM) */
+ .driver_info = NCTRL(0) | RSVD(1) },
++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1054, 0xff), /* Telit FT980-KS */
++ .driver_info = NCTRL(2) | RSVD(3) },
+ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910),
+ .driver_info = NCTRL(0) | RSVD(1) | RSVD(3) },
+ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM),
+@@ -1985,6 +1988,8 @@ static const struct usb_device_id option_ids[] = {
+ { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_4COM2, 0xff, 0x02, 0x01) },
+ { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_4COM2, 0xff, 0x00, 0x00) },
+ { USB_DEVICE(CELLIENT_VENDOR_ID, CELLIENT_PRODUCT_MEN200) },
++ { USB_DEVICE(CELLIENT_VENDOR_ID, CELLIENT_PRODUCT_MPL200),
++ .driver_info = RSVD(1) | RSVD(4) },
+ { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T_600A) },
+ { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T_600E) },
+ { USB_DEVICE_AND_INTERFACE_INFO(TPLINK_VENDOR_ID, TPLINK_PRODUCT_LTE, 0xff, 0x00, 0x00) }, /* TP-Link LTE Module */
+diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
+index 5051b1dad09ee..7fb62dd77317b 100644
+--- a/drivers/usb/serial/pl2303.c
++++ b/drivers/usb/serial/pl2303.c
+@@ -97,6 +97,7 @@ static const struct usb_device_id id_table[] = {
+ { USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) },
+ { USB_DEVICE(HP_VENDOR_ID, HP_LD220TA_PRODUCT_ID) },
+ { USB_DEVICE(HP_VENDOR_ID, HP_LD381_PRODUCT_ID) },
++ { USB_DEVICE(HP_VENDOR_ID, HP_LD381GC_PRODUCT_ID) },
+ { USB_DEVICE(HP_VENDOR_ID, HP_LD960_PRODUCT_ID) },
+ { USB_DEVICE(HP_VENDOR_ID, HP_LD960TA_PRODUCT_ID) },
+ { USB_DEVICE(HP_VENDOR_ID, HP_LCM220_PRODUCT_ID) },
+diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h
+index f0a9eeb6272de..c01b31a2a5d29 100644
+--- a/drivers/usb/serial/pl2303.h
++++ b/drivers/usb/serial/pl2303.h
+@@ -126,6 +126,7 @@
+
+ /* Hewlett-Packard POS Pole Displays */
+ #define HP_VENDOR_ID 0x03f0
++#define HP_LD381GC_PRODUCT_ID 0x0183
+ #define HP_LM920_PRODUCT_ID 0x026b
+ #define HP_TD620_PRODUCT_ID 0x0956
+ #define HP_LD960_PRODUCT_ID 0x0b39
+diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
+index 683496322aa8b..4b0fed69e0330 100644
+--- a/fs/reiserfs/inode.c
++++ b/fs/reiserfs/inode.c
+@@ -1552,11 +1552,7 @@ void reiserfs_read_locked_inode(struct inode *inode,
+ * set version 1, version 2 could be used too, because stat data
+ * key is the same in both versions
+ */
+- key.version = KEY_FORMAT_3_5;
+- key.on_disk_key.k_dir_id = dirino;
+- key.on_disk_key.k_objectid = inode->i_ino;
+- key.on_disk_key.k_offset = 0;
+- key.on_disk_key.k_type = 0;
++ _make_cpu_key(&key, KEY_FORMAT_3_5, dirino, inode->i_ino, 0, 0, 3);
+
+ /* look for the object's stat data */
+ retval = search_item(inode->i_sb, &key, &path_to_sd);
+diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
+index 28f6daf371d3d..57a7b9a164a23 100644
+--- a/fs/reiserfs/xattr.c
++++ b/fs/reiserfs/xattr.c
+@@ -665,6 +665,13 @@ reiserfs_xattr_get(struct inode *inode, const char *name, void *buffer,
+ if (get_inode_sd_version(inode) == STAT_DATA_V1)
+ return -EOPNOTSUPP;
+
++ /*
++ * priv_root needn't be initialized during mount so allow initial
++ * lookups to succeed.
++ */
++ if (!REISERFS_SB(inode->i_sb)->priv_root)
++ return 0;
++
+ dentry = xattr_lookup(inode, name, XATTR_REPLACE);
+ if (IS_ERR(dentry)) {
+ err = PTR_ERR(dentry);
+diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
+index 6cd4d5b48239f..f80356a98081b 100644
+--- a/include/net/bluetooth/hci_core.h
++++ b/include/net/bluetooth/hci_core.h
+@@ -1252,16 +1252,34 @@ static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status)
+ conn->security_cfm_cb(conn, status);
+ }
+
+-static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status,
+- __u8 encrypt)
++static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status)
+ {
+ struct hci_cb *cb;
++ __u8 encrypt;
++
++ if (conn->state == BT_CONFIG) {
++ if (!status)
++ conn->state = BT_CONNECTED;
+
+- if (conn->sec_level == BT_SECURITY_SDP)
+- conn->sec_level = BT_SECURITY_LOW;
++ hci_connect_cfm(conn, status);
++ hci_conn_drop(conn);
++ return;
++ }
+
+- if (conn->pending_sec_level > conn->sec_level)
+- conn->sec_level = conn->pending_sec_level;
++ if (!test_bit(HCI_CONN_ENCRYPT, &conn->flags))
++ encrypt = 0x00;
++ else if (test_bit(HCI_CONN_AES_CCM, &conn->flags))
++ encrypt = 0x02;
++ else
++ encrypt = 0x01;
++
++ if (!status) {
++ if (conn->sec_level == BT_SECURITY_SDP)
++ conn->sec_level = BT_SECURITY_LOW;
++
++ if (conn->pending_sec_level > conn->sec_level)
++ conn->sec_level = conn->pending_sec_level;
++ }
+
+ mutex_lock(&hci_cb_list_lock);
+ list_for_each_entry(cb, &hci_cb_list, list) {
+diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
+index 0697fd4130877..21dbd38f724d4 100644
+--- a/include/net/bluetooth/l2cap.h
++++ b/include/net/bluetooth/l2cap.h
+@@ -619,6 +619,8 @@ struct l2cap_ops {
+ struct sk_buff *(*alloc_skb) (struct l2cap_chan *chan,
+ unsigned long hdr_len,
+ unsigned long len, int nb);
++ int (*filter) (struct l2cap_chan * chan,
++ struct sk_buff *skb);
+ };
+
+ struct l2cap_conn {
+diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c
+index aad994edd3bb7..cd20c35daa6c7 100644
+--- a/net/bluetooth/a2mp.c
++++ b/net/bluetooth/a2mp.c
+@@ -233,6 +233,9 @@ static int a2mp_discover_rsp(struct amp_mgr *mgr, struct sk_buff *skb,
+ struct a2mp_info_req req;
+
+ found = true;
++
++ memset(&req, 0, sizeof(req));
++
+ req.id = cl->id;
+ a2mp_send(mgr, A2MP_GETINFO_REQ, __next_ident(mgr),
+ sizeof(req), &req);
+@@ -312,6 +315,8 @@ static int a2mp_getinfo_req(struct amp_mgr *mgr, struct sk_buff *skb,
+ if (!hdev || hdev->dev_type != HCI_AMP) {
+ struct a2mp_info_rsp rsp;
+
++ memset(&rsp, 0, sizeof(rsp));
++
+ rsp.id = req->id;
+ rsp.status = A2MP_STATUS_INVALID_CTRL_ID;
+
+@@ -355,6 +360,8 @@ static int a2mp_getinfo_rsp(struct amp_mgr *mgr, struct sk_buff *skb,
+ if (!ctrl)
+ return -ENOMEM;
+
++ memset(&req, 0, sizeof(req));
++
+ req.id = rsp->id;
+ a2mp_send(mgr, A2MP_GETAMPASSOC_REQ, __next_ident(mgr), sizeof(req),
+ &req);
+@@ -383,6 +390,8 @@ static int a2mp_getampassoc_req(struct amp_mgr *mgr, struct sk_buff *skb,
+ struct a2mp_amp_assoc_rsp rsp;
+ rsp.id = req->id;
+
++ memset(&rsp, 0, sizeof(rsp));
++
+ if (tmp) {
+ rsp.status = A2MP_STATUS_COLLISION_OCCURED;
+ amp_mgr_put(tmp);
+@@ -471,7 +480,6 @@ static int a2mp_createphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb,
+ struct a2mp_cmd *hdr)
+ {
+ struct a2mp_physlink_req *req = (void *) skb->data;
+-
+ struct a2mp_physlink_rsp rsp;
+ struct hci_dev *hdev;
+ struct hci_conn *hcon;
+@@ -482,6 +490,8 @@ static int a2mp_createphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb,
+
+ BT_DBG("local_id %d, remote_id %d", req->local_id, req->remote_id);
+
++ memset(&rsp, 0, sizeof(rsp));
++
+ rsp.local_id = req->remote_id;
+ rsp.remote_id = req->local_id;
+
+@@ -560,6 +570,8 @@ static int a2mp_discphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb,
+
+ BT_DBG("local_id %d remote_id %d", req->local_id, req->remote_id);
+
++ memset(&rsp, 0, sizeof(rsp));
++
+ rsp.local_id = req->remote_id;
+ rsp.remote_id = req->local_id;
+ rsp.status = A2MP_STATUS_SUCCESS;
+@@ -682,6 +694,8 @@ static int a2mp_chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
+ if (err) {
+ struct a2mp_cmd_rej rej;
+
++ memset(&rej, 0, sizeof(rej));
++
+ rej.reason = cpu_to_le16(0);
+ hdr = (void *) skb->data;
+
+@@ -905,6 +919,8 @@ void a2mp_send_getinfo_rsp(struct hci_dev *hdev)
+
+ BT_DBG("%s mgr %p", hdev->name, mgr);
+
++ memset(&rsp, 0, sizeof(rsp));
++
+ rsp.id = hdev->id;
+ rsp.status = A2MP_STATUS_INVALID_CTRL_ID;
+
+@@ -1002,6 +1018,8 @@ void a2mp_send_create_phy_link_rsp(struct hci_dev *hdev, u8 status)
+ if (!mgr)
+ return;
+
++ memset(&rsp, 0, sizeof(rsp));
++
+ hs_hcon = hci_conn_hash_lookup_state(hdev, AMP_LINK, BT_CONNECT);
+ if (!hs_hcon) {
+ rsp.status = A2MP_STATUS_UNABLE_START_LINK_CREATION;
+@@ -1034,6 +1052,8 @@ void a2mp_discover_amp(struct l2cap_chan *chan)
+
+ mgr->bredr_chan = chan;
+
++ memset(&req, 0, sizeof(req));
++
+ req.mtu = cpu_to_le16(L2CAP_A2MP_DEFAULT_MTU);
+ req.ext_feat = 0;
+ a2mp_send(mgr, A2MP_DISCOVER_REQ, 1, sizeof(req), &req);
+diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
+index 1d085eed72d0c..e3cd81ce2a7bb 100644
+--- a/net/bluetooth/hci_conn.c
++++ b/net/bluetooth/hci_conn.c
+@@ -1163,6 +1163,23 @@ int hci_conn_check_link_mode(struct hci_conn *conn)
+ return 0;
+ }
+
++ /* AES encryption is required for Level 4:
++ *
++ * BLUETOOTH CORE SPECIFICATION Version 5.2 | Vol 3, Part C
++ * page 1319:
++ *
++ * 128-bit equivalent strength for link and encryption keys
++ * required using FIPS approved algorithms (E0 not allowed,
++ * SAFER+ not allowed, and P-192 not allowed; encryption key
++ * not shortened)
++ */
++ if (conn->sec_level == BT_SECURITY_FIPS &&
++ !test_bit(HCI_CONN_AES_CCM, &conn->flags)) {
++ bt_dev_err(conn->hdev,
++ "Invalid security: Missing AES-CCM usage");
++ return 0;
++ }
++
+ if (hci_conn_ssp_enabled(conn) &&
+ !test_bit(HCI_CONN_ENCRYPT, &conn->flags))
+ return 0;
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 587b674bbcd64..ba12bf8de8267 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -1133,6 +1133,9 @@ static void store_pending_adv_report(struct hci_dev *hdev, bdaddr_t *bdaddr,
+ {
+ struct discovery_state *d = &hdev->discovery;
+
++ if (len > HCI_MAX_AD_LENGTH)
++ return;
++
+ bacpy(&d->last_adv_addr, bdaddr);
+ d->last_adv_addr_type = bdaddr_type;
+ d->last_adv_rssi = rssi;
+@@ -2490,7 +2493,7 @@ static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+ &cp);
+ } else {
+ clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
+- hci_encrypt_cfm(conn, ev->status, 0x00);
++ hci_encrypt_cfm(conn, ev->status);
+ }
+ }
+
+@@ -2576,22 +2579,7 @@ static void read_enc_key_size_complete(struct hci_dev *hdev, u8 status,
+ conn->enc_key_size = rp->key_size;
+ }
+
+- if (conn->state == BT_CONFIG) {
+- conn->state = BT_CONNECTED;
+- hci_connect_cfm(conn, 0);
+- hci_conn_drop(conn);
+- } else {
+- u8 encrypt;
+-
+- if (!test_bit(HCI_CONN_ENCRYPT, &conn->flags))
+- encrypt = 0x00;
+- else if (test_bit(HCI_CONN_AES_CCM, &conn->flags))
+- encrypt = 0x02;
+- else
+- encrypt = 0x01;
+-
+- hci_encrypt_cfm(conn, 0, encrypt);
+- }
++ hci_encrypt_cfm(conn, 0);
+
+ unlock:
+ hci_dev_unlock(hdev);
+@@ -2638,27 +2626,23 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
+
+ clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
+
++ /* Check link security requirements are met */
++ if (!hci_conn_check_link_mode(conn))
++ ev->status = HCI_ERROR_AUTH_FAILURE;
++
+ if (ev->status && conn->state == BT_CONNECTED) {
+ if (ev->status == HCI_ERROR_PIN_OR_KEY_MISSING)
+ set_bit(HCI_CONN_AUTH_FAILURE, &conn->flags);
+
++ /* Notify upper layers so they can cleanup before
++ * disconnecting.
++ */
++ hci_encrypt_cfm(conn, ev->status);
+ hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
+ hci_conn_drop(conn);
+ goto unlock;
+ }
+
+- /* In Secure Connections Only mode, do not allow any connections
+- * that are not encrypted with AES-CCM using a P-256 authenticated
+- * combination key.
+- */
+- if (hci_dev_test_flag(hdev, HCI_SC_ONLY) &&
+- (!test_bit(HCI_CONN_AES_CCM, &conn->flags) ||
+- conn->key_type != HCI_LK_AUTH_COMBINATION_P256)) {
+- hci_connect_cfm(conn, HCI_ERROR_AUTH_FAILURE);
+- hci_conn_drop(conn);
+- goto unlock;
+- }
+-
+ /* Try reading the encryption key size for encrypted ACL links */
+ if (!ev->status && ev->encrypt && conn->type == ACL_LINK) {
+ struct hci_cp_read_enc_key_size cp;
+@@ -2688,14 +2672,7 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
+ }
+
+ notify:
+- if (conn->state == BT_CONFIG) {
+- if (!ev->status)
+- conn->state = BT_CONNECTED;
+-
+- hci_connect_cfm(conn, ev->status);
+- hci_conn_drop(conn);
+- } else
+- hci_encrypt_cfm(conn, ev->status, ev->encrypt);
++ hci_encrypt_cfm(conn, ev->status);
+
+ unlock:
+ hci_dev_unlock(hdev);
+@@ -4779,6 +4756,11 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
+ return;
+ }
+
++ if (len > HCI_MAX_AD_LENGTH) {
++ pr_err_ratelimited("legacy adv larger than 31 bytes");
++ return;
++ }
++
+ /* Find the end of the data in case the report contains padded zero
+ * bytes at the end causing an invalid length value.
+ *
+@@ -4839,7 +4821,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
+ */
+ conn = check_pending_le_conn(hdev, bdaddr, bdaddr_type, type,
+ direct_addr);
+- if (conn && type == LE_ADV_IND) {
++ if (conn && type == LE_ADV_IND && len <= HCI_MAX_AD_LENGTH) {
+ /* Store report for later inclusion by
+ * mgmt_device_connected
+ */
+@@ -4964,10 +4946,14 @@ static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
+ struct hci_ev_le_advertising_info *ev = ptr;
+ s8 rssi;
+
+- rssi = ev->data[ev->length];
+- process_adv_report(hdev, ev->evt_type, &ev->bdaddr,
+- ev->bdaddr_type, NULL, 0, rssi,
+- ev->data, ev->length);
++ if (ev->length <= HCI_MAX_AD_LENGTH) {
++ rssi = ev->data[ev->length];
++ process_adv_report(hdev, ev->evt_type, &ev->bdaddr,
++ ev->bdaddr_type, NULL, 0, rssi,
++ ev->data, ev->length);
++ } else {
++ bt_dev_err(hdev, "Dropping invalid advertising data");
++ }
+
+ ptr += sizeof(*ev) + ev->length + 1;
+ }
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index c301b9debea7c..df8cc639c46d5 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -6683,9 +6683,10 @@ static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
+ goto drop;
+ }
+
+- if ((chan->mode == L2CAP_MODE_ERTM ||
+- chan->mode == L2CAP_MODE_STREAMING) && sk_filter(chan->data, skb))
+- goto drop;
++ if (chan->ops->filter) {
++ if (chan->ops->filter(chan, skb))
++ goto drop;
++ }
+
+ if (!control->sframe) {
+ int err;
+diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
+index 511a1da6ca971..7ff82f97e42cc 100644
+--- a/net/bluetooth/l2cap_sock.c
++++ b/net/bluetooth/l2cap_sock.c
+@@ -1477,6 +1477,19 @@ static void l2cap_sock_suspend_cb(struct l2cap_chan *chan)
+ sk->sk_state_change(sk);
+ }
+
++static int l2cap_sock_filter(struct l2cap_chan *chan, struct sk_buff *skb)
++{
++ struct sock *sk = chan->data;
++
++ switch (chan->mode) {
++ case L2CAP_MODE_ERTM:
++ case L2CAP_MODE_STREAMING:
++ return sk_filter(sk, skb);
++ }
++
++ return 0;
++}
++
+ static const struct l2cap_ops l2cap_chan_ops = {
+ .name = "L2CAP Socket Interface",
+ .new_connection = l2cap_sock_new_connection_cb,
+@@ -1491,6 +1504,7 @@ static const struct l2cap_ops l2cap_chan_ops = {
+ .set_shutdown = l2cap_sock_set_shutdown_cb,
+ .get_sndtimeo = l2cap_sock_get_sndtimeo_cb,
+ .alloc_skb = l2cap_sock_alloc_skb_cb,
++ .filter = l2cap_sock_filter,
+ };
+
+ static void l2cap_sock_destruct(struct sock *sk)
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index ba24f613c0fc1..bca1408f815ff 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -635,7 +635,8 @@ static u32 get_supported_settings(struct hci_dev *hdev)
+
+ if (lmp_ssp_capable(hdev)) {
+ settings |= MGMT_SETTING_SSP;
+- settings |= MGMT_SETTING_HS;
++ if (IS_ENABLED(CONFIG_BT_HS))
++ settings |= MGMT_SETTING_HS;
+ }
+
+ if (lmp_sc_capable(hdev))
+@@ -1645,6 +1646,10 @@ static int set_hs(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
+
+ BT_DBG("request for %s", hdev->name);
+
++ if (!IS_ENABLED(CONFIG_BT_HS))
++ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_HS,
++ MGMT_STATUS_NOT_SUPPORTED);
++
+ status = mgmt_bredr_support(hdev);
+ if (status)
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_HS, status);