From: Greg Kroah-Hartman Date: Fri, 20 Mar 2026 09:00:05 +0000 (+0100) Subject: 5.15-stable patches X-Git-Tag: v6.1.167~96 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d7cc7b2fa5ae12d204d5397f9f1c3c98193a5cb5;p=thirdparty%2Fkernel%2Fstable-queue.git 5.15-stable patches added patches: bluetooth-l2cap-fix-type-confusion-in-l2cap_ecred_reconf_rsp.patch bluetooth-l2cap-validate-l2cap_info_rsp-payload-length-before-access.patch net-macb-fix-use-after-free-access-to-ptp-clock.patch nfc-nxp-nci-allow-gpios-to-sleep.patch nvdimm-bus-fix-potential-use-after-free-in-asynchronous-initialization.patch sunrpc-fix-cache_request-leak-in-cache_release.patch --- diff --git a/queue-5.15/bluetooth-l2cap-fix-type-confusion-in-l2cap_ecred_reconf_rsp.patch b/queue-5.15/bluetooth-l2cap-fix-type-confusion-in-l2cap_ecred_reconf_rsp.patch new file mode 100644 index 0000000000..0943ac7792 --- /dev/null +++ b/queue-5.15/bluetooth-l2cap-fix-type-confusion-in-l2cap_ecred_reconf_rsp.patch @@ -0,0 +1,59 @@ +From 15145675690cab2de1056e7ed68e59cbd0452529 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Lukas=20Johannes=20M=C3=B6ller?= + +Date: Tue, 10 Mar 2026 21:59:46 +0000 +Subject: Bluetooth: L2CAP: Fix type confusion in l2cap_ecred_reconf_rsp() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Lukas Johannes Möller + +commit 15145675690cab2de1056e7ed68e59cbd0452529 upstream. + +l2cap_ecred_reconf_rsp() casts the incoming data to struct +l2cap_ecred_conn_rsp (the ECRED *connection* response, 8 bytes with +result at offset 6) instead of struct l2cap_ecred_reconf_rsp (2 bytes +with result at offset 0). + +This causes two problems: + + - The sizeof(*rsp) length check requires 8 bytes instead of the + correct 2, so valid L2CAP_ECRED_RECONF_RSP packets are rejected + with -EPROTO. + + - rsp->result reads from offset 6 instead of offset 0, returning + wrong data when the packet is large enough to pass the check. + +Fix by using the correct type. Also pass the already byte-swapped +result variable to BT_DBG instead of the raw __le16 field. + +Fixes: 15f02b910562 ("Bluetooth: L2CAP: Add initial code for Enhanced Credit Based Mode") +Cc: stable@vger.kernel.org +Signed-off-by: Lukas Johannes Möller +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Greg Kroah-Hartman +--- + net/bluetooth/l2cap_core.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/bluetooth/l2cap_core.c ++++ b/net/bluetooth/l2cap_core.c +@@ -6397,7 +6397,7 @@ static inline int l2cap_ecred_reconf_rsp + u8 *data) + { + struct l2cap_chan *chan, *tmp; +- struct l2cap_ecred_conn_rsp *rsp = (void *) data; ++ struct l2cap_ecred_reconf_rsp *rsp = (void *)data; + u16 result; + + if (cmd_len < sizeof(*rsp)) +@@ -6405,7 +6405,7 @@ static inline int l2cap_ecred_reconf_rsp + + result = __le16_to_cpu(rsp->result); + +- BT_DBG("result 0x%4.4x", rsp->result); ++ BT_DBG("result 0x%4.4x", result); + + if (!result) + return 0; diff --git a/queue-5.15/bluetooth-l2cap-validate-l2cap_info_rsp-payload-length-before-access.patch b/queue-5.15/bluetooth-l2cap-validate-l2cap_info_rsp-payload-length-before-access.patch new file mode 100644 index 0000000000..233e1e3feb --- /dev/null +++ b/queue-5.15/bluetooth-l2cap-validate-l2cap_info_rsp-payload-length-before-access.patch @@ -0,0 +1,63 @@ +From dd815e6e3918dc75a49aaabac36e4f024d675101 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Lukas=20Johannes=20M=C3=B6ller?= + +Date: Tue, 10 Mar 2026 21:59:47 +0000 +Subject: Bluetooth: L2CAP: Validate L2CAP_INFO_RSP payload length before access +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Lukas Johannes Möller + +commit dd815e6e3918dc75a49aaabac36e4f024d675101 upstream. + +l2cap_information_rsp() checks that cmd_len covers the fixed +l2cap_info_rsp header (type + result, 4 bytes) but then reads +rsp->data without verifying that the payload is present: + + - L2CAP_IT_FEAT_MASK calls get_unaligned_le32(rsp->data), which reads + 4 bytes past the header (needs cmd_len >= 8). + + - L2CAP_IT_FIXED_CHAN reads rsp->data[0], 1 byte past the header + (needs cmd_len >= 5). + +A truncated L2CAP_INFO_RSP with result == L2CAP_IR_SUCCESS triggers an +out-of-bounds read of adjacent skb data. + +Guard each data access with the required payload length check. If the +payload is too short, skip the read and let the state machine complete +with safe defaults (feat_mask and remote_fixed_chan remain zero from +kzalloc), so the info timer cleanup and l2cap_conn_start() still run +and the connection is not stalled. + +Fixes: 4e8402a3f884 ("[Bluetooth] Retrieve L2CAP features mask on connection setup") +Cc: stable@vger.kernel.org +Signed-off-by: Lukas Johannes Möller +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Greg Kroah-Hartman +--- + net/bluetooth/l2cap_core.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/net/bluetooth/l2cap_core.c ++++ b/net/bluetooth/l2cap_core.c +@@ -4837,7 +4837,8 @@ static inline int l2cap_information_rsp( + + switch (type) { + case L2CAP_IT_FEAT_MASK: +- conn->feat_mask = get_unaligned_le32(rsp->data); ++ if (cmd_len >= sizeof(*rsp) + sizeof(u32)) ++ conn->feat_mask = get_unaligned_le32(rsp->data); + + if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) { + struct l2cap_info_req req; +@@ -4856,7 +4857,8 @@ static inline int l2cap_information_rsp( + break; + + case L2CAP_IT_FIXED_CHAN: +- conn->remote_fixed_chan = rsp->data[0]; ++ if (cmd_len >= sizeof(*rsp) + sizeof(rsp->data[0])) ++ conn->remote_fixed_chan = rsp->data[0]; + conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE; + conn->info_ident = 0; + diff --git a/queue-5.15/net-macb-fix-use-after-free-access-to-ptp-clock.patch b/queue-5.15/net-macb-fix-use-after-free-access-to-ptp-clock.patch new file mode 100644 index 0000000000..ecda43f69c --- /dev/null +++ b/queue-5.15/net-macb-fix-use-after-free-access-to-ptp-clock.patch @@ -0,0 +1,128 @@ +From 8da13e6d63c1a97f7302d342c89c4a56a55c7015 Mon Sep 17 00:00:00 2001 +From: Fedor Pchelkin +Date: Mon, 16 Mar 2026 13:38:24 +0300 +Subject: net: macb: fix use-after-free access to PTP clock + +From: Fedor Pchelkin + +commit 8da13e6d63c1a97f7302d342c89c4a56a55c7015 upstream. + +PTP clock is registered on every opening of the interface and destroyed on +every closing. However it may be accessed via get_ts_info ethtool call +which is possible while the interface is just present in the kernel. + +BUG: KASAN: use-after-free in ptp_clock_index+0x47/0x50 drivers/ptp/ptp_clock.c:426 +Read of size 4 at addr ffff8880194345cc by task syz.0.6/948 + +CPU: 1 PID: 948 Comm: syz.0.6 Not tainted 6.1.164+ #109 +Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.16.1-0-g3208b098f51a-prebuilt.qemu.org 04/01/2014 +Call Trace: + + __dump_stack lib/dump_stack.c:88 [inline] + dump_stack_lvl+0x8d/0xba lib/dump_stack.c:106 + print_address_description mm/kasan/report.c:316 [inline] + print_report+0x17f/0x496 mm/kasan/report.c:420 + kasan_report+0xd9/0x180 mm/kasan/report.c:524 + ptp_clock_index+0x47/0x50 drivers/ptp/ptp_clock.c:426 + gem_get_ts_info+0x138/0x1e0 drivers/net/ethernet/cadence/macb_main.c:3349 + macb_get_ts_info+0x68/0xb0 drivers/net/ethernet/cadence/macb_main.c:3371 + __ethtool_get_ts_info+0x17c/0x260 net/ethtool/common.c:558 + ethtool_get_ts_info net/ethtool/ioctl.c:2367 [inline] + __dev_ethtool net/ethtool/ioctl.c:3017 [inline] + dev_ethtool+0x2b05/0x6290 net/ethtool/ioctl.c:3095 + dev_ioctl+0x637/0x1070 net/core/dev_ioctl.c:510 + sock_do_ioctl+0x20d/0x2c0 net/socket.c:1215 + sock_ioctl+0x577/0x6d0 net/socket.c:1320 + vfs_ioctl fs/ioctl.c:51 [inline] + __do_sys_ioctl fs/ioctl.c:870 [inline] + __se_sys_ioctl fs/ioctl.c:856 [inline] + __x64_sys_ioctl+0x18c/0x210 fs/ioctl.c:856 + do_syscall_x64 arch/x86/entry/common.c:46 [inline] + do_syscall_64+0x35/0x80 arch/x86/entry/common.c:76 + entry_SYSCALL_64_after_hwframe+0x6e/0xd8 + + +Allocated by task 457: + kmalloc include/linux/slab.h:563 [inline] + kzalloc include/linux/slab.h:699 [inline] + ptp_clock_register+0x144/0x10e0 drivers/ptp/ptp_clock.c:235 + gem_ptp_init+0x46f/0x930 drivers/net/ethernet/cadence/macb_ptp.c:375 + macb_open+0x901/0xd10 drivers/net/ethernet/cadence/macb_main.c:2920 + __dev_open+0x2ce/0x500 net/core/dev.c:1501 + __dev_change_flags+0x56a/0x740 net/core/dev.c:8651 + dev_change_flags+0x92/0x170 net/core/dev.c:8722 + do_setlink+0xaf8/0x3a80 net/core/rtnetlink.c:2833 + __rtnl_newlink+0xbf4/0x1940 net/core/rtnetlink.c:3608 + rtnl_newlink+0x63/0xa0 net/core/rtnetlink.c:3655 + rtnetlink_rcv_msg+0x3c6/0xed0 net/core/rtnetlink.c:6150 + netlink_rcv_skb+0x15d/0x430 net/netlink/af_netlink.c:2511 + netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline] + netlink_unicast+0x6d7/0xa30 net/netlink/af_netlink.c:1344 + netlink_sendmsg+0x97e/0xeb0 net/netlink/af_netlink.c:1872 + sock_sendmsg_nosec net/socket.c:718 [inline] + __sock_sendmsg+0x14b/0x180 net/socket.c:730 + __sys_sendto+0x320/0x3b0 net/socket.c:2152 + __do_sys_sendto net/socket.c:2164 [inline] + __se_sys_sendto net/socket.c:2160 [inline] + __x64_sys_sendto+0xdc/0x1b0 net/socket.c:2160 + do_syscall_x64 arch/x86/entry/common.c:46 [inline] + do_syscall_64+0x35/0x80 arch/x86/entry/common.c:76 + entry_SYSCALL_64_after_hwframe+0x6e/0xd8 + +Freed by task 938: + kasan_slab_free include/linux/kasan.h:177 [inline] + slab_free_hook mm/slub.c:1729 [inline] + slab_free_freelist_hook mm/slub.c:1755 [inline] + slab_free mm/slub.c:3687 [inline] + __kmem_cache_free+0xbc/0x320 mm/slub.c:3700 + device_release+0xa0/0x240 drivers/base/core.c:2507 + kobject_cleanup lib/kobject.c:681 [inline] + kobject_release lib/kobject.c:712 [inline] + kref_put include/linux/kref.h:65 [inline] + kobject_put+0x1cd/0x350 lib/kobject.c:729 + put_device+0x1b/0x30 drivers/base/core.c:3805 + ptp_clock_unregister+0x171/0x270 drivers/ptp/ptp_clock.c:391 + gem_ptp_remove+0x4e/0x1f0 drivers/net/ethernet/cadence/macb_ptp.c:404 + macb_close+0x1c8/0x270 drivers/net/ethernet/cadence/macb_main.c:2966 + __dev_close_many+0x1b9/0x310 net/core/dev.c:1585 + __dev_close net/core/dev.c:1597 [inline] + __dev_change_flags+0x2bb/0x740 net/core/dev.c:8649 + dev_change_flags+0x92/0x170 net/core/dev.c:8722 + dev_ifsioc+0x151/0xe00 net/core/dev_ioctl.c:326 + dev_ioctl+0x33e/0x1070 net/core/dev_ioctl.c:572 + sock_do_ioctl+0x20d/0x2c0 net/socket.c:1215 + sock_ioctl+0x577/0x6d0 net/socket.c:1320 + vfs_ioctl fs/ioctl.c:51 [inline] + __do_sys_ioctl fs/ioctl.c:870 [inline] + __se_sys_ioctl fs/ioctl.c:856 [inline] + __x64_sys_ioctl+0x18c/0x210 fs/ioctl.c:856 + do_syscall_x64 arch/x86/entry/common.c:46 [inline] + do_syscall_64+0x35/0x80 arch/x86/entry/common.c:76 + entry_SYSCALL_64_after_hwframe+0x6e/0xd8 + +Set the PTP clock pointer to NULL after unregistering. + +Fixes: c2594d804d5c ("macb: Common code to enable ptp support for MACB/GEM") +Cc: stable@vger.kernel.org +Signed-off-by: Fedor Pchelkin +Link: https://patch.msgid.link/20260316103826.74506-1-pchelkin@ispras.ru +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/cadence/macb_ptp.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/cadence/macb_ptp.c ++++ b/drivers/net/ethernet/cadence/macb_ptp.c +@@ -395,8 +395,10 @@ void gem_ptp_remove(struct net_device *n + { + struct macb *bp = netdev_priv(ndev); + +- if (bp->ptp_clock) ++ if (bp->ptp_clock) { + ptp_clock_unregister(bp->ptp_clock); ++ bp->ptp_clock = NULL; ++ } + + gem_ptp_clear_timer(bp); + diff --git a/queue-5.15/nfc-nxp-nci-allow-gpios-to-sleep.patch b/queue-5.15/nfc-nxp-nci-allow-gpios-to-sleep.patch new file mode 100644 index 0000000000..a129ecc39a --- /dev/null +++ b/queue-5.15/nfc-nxp-nci-allow-gpios-to-sleep.patch @@ -0,0 +1,41 @@ +From 55dc632ab2ac2889b15995a9eef56c753d48ebc7 Mon Sep 17 00:00:00 2001 +From: Ian Ray +Date: Tue, 17 Mar 2026 10:53:36 +0200 +Subject: NFC: nxp-nci: allow GPIOs to sleep + +From: Ian Ray + +commit 55dc632ab2ac2889b15995a9eef56c753d48ebc7 upstream. + +Allow the firmware and enable GPIOs to sleep. + +This fixes a `WARN_ON' and allows the driver to operate GPIOs which are +connected to I2C GPIO expanders. + +-- >8 -- +kernel: WARNING: CPU: 3 PID: 2636 at drivers/gpio/gpiolib.c:3880 gpiod_set_value+0x88/0x98 +-- >8 -- + +Fixes: 43201767b44c ("NFC: nxp-nci: Convert to use GPIO descriptor") +Cc: stable@vger.kernel.org +Signed-off-by: Ian Ray +Link: https://patch.msgid.link/20260317085337.146545-1-ian.ray@gehealthcare.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nfc/nxp-nci/i2c.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/nfc/nxp-nci/i2c.c ++++ b/drivers/nfc/nxp-nci/i2c.c +@@ -47,8 +47,8 @@ static int nxp_nci_i2c_set_mode(void *ph + { + struct nxp_nci_i2c_phy *phy = (struct nxp_nci_i2c_phy *) phy_id; + +- gpiod_set_value(phy->gpiod_fw, (mode == NXP_NCI_MODE_FW) ? 1 : 0); +- gpiod_set_value(phy->gpiod_en, (mode != NXP_NCI_MODE_COLD) ? 1 : 0); ++ gpiod_set_value_cansleep(phy->gpiod_fw, (mode == NXP_NCI_MODE_FW) ? 1 : 0); ++ gpiod_set_value_cansleep(phy->gpiod_en, (mode != NXP_NCI_MODE_COLD) ? 1 : 0); + usleep_range(10000, 15000); + + if (mode == NXP_NCI_MODE_COLD) diff --git a/queue-5.15/nvdimm-bus-fix-potential-use-after-free-in-asynchronous-initialization.patch b/queue-5.15/nvdimm-bus-fix-potential-use-after-free-in-asynchronous-initialization.patch new file mode 100644 index 0000000000..dccd0741e9 --- /dev/null +++ b/queue-5.15/nvdimm-bus-fix-potential-use-after-free-in-asynchronous-initialization.patch @@ -0,0 +1,55 @@ +From a8aec14230322ed8f1e8042b6d656c1631d41163 Mon Sep 17 00:00:00 2001 +From: Ira Weiny +Date: Fri, 6 Mar 2026 12:33:05 -0600 +Subject: nvdimm/bus: Fix potential use after free in asynchronous initialization + +From: Ira Weiny + +commit a8aec14230322ed8f1e8042b6d656c1631d41163 upstream. + +Dingisoul with KASAN reports a use after free if device_add() fails in +nd_async_device_register(). + +Commit b6eae0f61db2 ("libnvdimm: Hold reference on parent while +scheduling async init") correctly added a reference on the parent device +to be held until asynchronous initialization was complete. However, if +device_add() results in an allocation failure the ref count of the +device drops to 0 prior to the parent pointer being accessed. Thus +resulting in use after free. + +The bug bot AI correctly identified the fix. Save a reference to the +parent pointer to be used to drop the parent reference regardless of the +outcome of device_add(). + +Reported-by: Dingisoul +Closes: http://lore.kernel.org/8855544b-be9e-4153-aa55-0bc328b13733@gmail.com +Fixes: b6eae0f61db2 ("libnvdimm: Hold reference on parent while scheduling async init") +Cc: stable@vger.kernel.org +Reviewed-by: Dave Jiang +Link: https://patch.msgid.link/20260306-fix-uaf-async-init-v1-1-a28fd7526723@intel.com +Signed-off-by: Ira Weiny +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvdimm/bus.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/nvdimm/bus.c ++++ b/drivers/nvdimm/bus.c +@@ -492,14 +492,15 @@ EXPORT_SYMBOL_GPL(nd_synchronize); + static void nd_async_device_register(void *d, async_cookie_t cookie) + { + struct device *dev = d; ++ struct device *parent = dev->parent; + + if (device_add(dev) != 0) { + dev_err(dev, "%s: failed\n", __func__); + put_device(dev); + } + put_device(dev); +- if (dev->parent) +- put_device(dev->parent); ++ if (parent) ++ put_device(parent); + } + + static void nd_async_device_unregister(void *d, async_cookie_t cookie) diff --git a/queue-5.15/series b/queue-5.15/series index dadc340770..5ad824cfe3 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -194,3 +194,9 @@ bpf-forget-ranges-when-refining-tnum-after-jset.patch l2tp-do-not-use-sock_hold-in-pppol2tp_session_get_sock.patch io_uring-io-wq-check-io_wq_bit_exit-inside-work-run-loop.patch driver-iio-add-missing-checks-on-iio_info-s-callback-access.patch +sunrpc-fix-cache_request-leak-in-cache_release.patch +nvdimm-bus-fix-potential-use-after-free-in-asynchronous-initialization.patch +nfc-nxp-nci-allow-gpios-to-sleep.patch +net-macb-fix-use-after-free-access-to-ptp-clock.patch +bluetooth-l2cap-fix-type-confusion-in-l2cap_ecred_reconf_rsp.patch +bluetooth-l2cap-validate-l2cap_info_rsp-payload-length-before-access.patch diff --git a/queue-5.15/sunrpc-fix-cache_request-leak-in-cache_release.patch b/queue-5.15/sunrpc-fix-cache_request-leak-in-cache_release.patch new file mode 100644 index 0000000000..c5006d4e2c --- /dev/null +++ b/queue-5.15/sunrpc-fix-cache_request-leak-in-cache_release.patch @@ -0,0 +1,86 @@ +From 17ad31b3a43b72aec3a3d83605891e1397d0d065 Mon Sep 17 00:00:00 2001 +From: Jeff Layton +Date: Mon, 23 Feb 2026 12:09:58 -0500 +Subject: sunrpc: fix cache_request leak in cache_release + +From: Jeff Layton + +commit 17ad31b3a43b72aec3a3d83605891e1397d0d065 upstream. + +When a reader's file descriptor is closed while in the middle of reading +a cache_request (rp->offset != 0), cache_release() decrements the +request's readers count but never checks whether it should free the +request. + +In cache_read(), when readers drops to 0 and CACHE_PENDING is clear, the +cache_request is removed from the queue and freed along with its buffer +and cache_head reference. cache_release() lacks this cleanup. + +The only other path that frees requests with readers == 0 is +cache_dequeue(), but it runs only when CACHE_PENDING transitions from +set to clear. If that transition already happened while readers was +still non-zero, cache_dequeue() will have skipped the request, and no +subsequent call will clean it up. + +Add the same cleanup logic from cache_read() to cache_release(): after +decrementing readers, check if it reached 0 with CACHE_PENDING clear, +and if so, dequeue and free the cache_request. + +Reported-by: NeilBrown +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Cc: stable@kernel.org +Signed-off-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + net/sunrpc/cache.c | 26 +++++++++++++++++++++----- + 1 file changed, 21 insertions(+), 5 deletions(-) + +--- a/net/sunrpc/cache.c ++++ b/net/sunrpc/cache.c +@@ -1037,14 +1037,25 @@ static int cache_release(struct inode *i + struct cache_reader *rp = filp->private_data; + + if (rp) { ++ struct cache_request *rq = NULL; ++ + spin_lock(&queue_lock); + if (rp->offset) { + struct cache_queue *cq; +- for (cq= &rp->q; &cq->list != &cd->queue; +- cq = list_entry(cq->list.next, struct cache_queue, list)) ++ for (cq = &rp->q; &cq->list != &cd->queue; ++ cq = list_entry(cq->list.next, ++ struct cache_queue, list)) + if (!cq->reader) { +- container_of(cq, struct cache_request, q) +- ->readers--; ++ struct cache_request *cr = ++ container_of(cq, ++ struct cache_request, q); ++ cr->readers--; ++ if (cr->readers == 0 && ++ !test_bit(CACHE_PENDING, ++ &cr->item->flags)) { ++ list_del(&cr->q.list); ++ rq = cr; ++ } + break; + } + rp->offset = 0; +@@ -1052,9 +1063,14 @@ static int cache_release(struct inode *i + list_del(&rp->q.list); + spin_unlock(&queue_lock); + ++ if (rq) { ++ cache_put(rq->item, cd); ++ kfree(rq->buf); ++ kfree(rq); ++ } ++ + filp->private_data = NULL; + kfree(rp); +- + } + if (filp->f_mode & FMODE_WRITE) { + atomic_dec(&cd->writers);