Support needed to continue Smatch work
Subsystems (26)
I have been doing Smatch static analysis work at Linaro under a larger umbrella project to do with Linux kernel quality but unfortunately that project has ended so I will be wrapping up at the end of the year unless we can raise new support.
Smatch is an important tool for kernel development so hopefully there are enough companies willing to support it financially and I will be able to continue. In fact, there potentially is an opportunity to expand if companies with other large C projects and want static analysis. This isn't something we have explored very deeply but reach out if you want to have that discussion. Please contact Bill Fletcher <[email protected]> for any inquiries, either about supporting Smatch in the Linux kernel or about other static analysis projects.
Background: I am the author of the Smatch static checker.
https://github.com/error27/smatch
In the kernel we use a number of different static analysis tools with different features and goals. What makes Smatch unique is the flow analysis. Flow analysis is basically the logic of saying that if X is true that must mean Y is true. Smatch is the only Open Source static checker with this level of flow analysis and the only one that does analysis across function boundaries. Being Open Source is important because it lets you write project specific checks. There are a number of commercial static analysis tools that exist as well, however, for parsing kernel code nothing else is at the same level.
This is borne out in the numbers. I have been working on Smatch since 2010, first at Oracle and now at Linaro. Over that period I have been the number 12 bug fixer with 5568 patches and the number 2 bug reporter with 2587 bug reports and almost all those fixes are driven by Smatch. Smatch is included in several subsystem CI tools, such as Media and Wireless and many maintainers use Smatch as well.
I like to say that static analysis is not just a product, it is an on-going process. I regularly review CVEs to consider how these bugs could have been caught earlier with static analysis. Also the kernel is constantly changing and adding new APIs. Without continuous updates then a static checker will eventually bit rot.
An important part of what I do is review static checker warnings and filter out the false positives. People complain about false positives but in some ways, with static analysis the false positive ratio is a knob you can adjust where you can either have very few false positives and miss bugs or you can have more false positives and catch more bugs. Since the kernel is very important I prefer to have more false positives and then manually review them. This lets us catch as many bugs as possible without annoying the developers.
Especially for cross function bugs, you need a human to figure out who the correct developer is to handle an issue. I've also found that adding a bit of explanation to each bug report helps developers know how to handle them faster.
To be honest, the work with Smatch will need to continue either way because it's really important but it would be great if I could be a part of that. I still have a lot of plans for changes and improvements that should be made. I'm hoping there are several companies who could support this project by paying a proportion of my salary. This is something that Linaro has done before with other shared cost projects.
I'll post again closer to the end of the year to let people know what's happening next.
I need to post an update on the current situation with Smatch.
First of all, I want to start by thanking Brad Spengler from grsecurity who reached out to me on this, offered some funding, and has been trying to push the Smatch work forward. It really means a lot to me.
Unfortunately, we haven't been able to raise enough support to continue my Smatch work. I have still been filtering zero day bot warnings and I am a bit worried that people have the impression that I'm reviewing static checker warnings when I am not.
The situation isn't great. The zero day bot can't do cross function analsysis and it only looks at checks with a low false positive rate. We're missing out on a bunch of bugs. I'm going to add some of the those missed warnings to this thread so people have a better picture of what we're missing. There are some buffer overflows in there. A bunch of off by one bugs. A missing error code in fork(). And random other minor things as well.
https://lore.kernel.org/all/[email protected]/
I am still trying to figure out a way to restart Smatch checking. The funding model would be that several companies would support this project by paying a proportion of my salary. Part of that goes to reporting bugs like the ones above and part of that goes to developing Smatch and writing new checks. Please, contact
Bill Fletcher <[email protected]> if you would like to support this work.
regards,
dan carpenter
[bug report] net: ethtool: Introduce per-PHY DUMP operations
[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Maxime Chevallier,
Commit 172265b44cd3 ("net: ethtool: Introduce per-PHY DUMP operations") from May 2, 2025 (linux-next), leads to the following Smatch static checker warning:
net/ethtool/netlink.c:714 ethnl_perphy_start() error: buffer overflow 'ethnl_default_requests' 52 <= 255 user_rl='0-255' uncapped
net/ethtool/netlink.c
700 static int ethnl_perphy_start(struct netlink_callback *cb)
701 {
702 struct ethnl_perphy_dump_ctx *phy_ctx = ethnl_perphy_dump_context(cb);
703 const struct genl_dumpit_info *info = genl_dumpit_info(cb);
704 struct ethnl_dump_ctx *ctx = &phy_ctx->ethnl_ctx;
705 struct ethnl_reply_data *reply_data;
706 const struct ethnl_request_ops *ops;
707 struct ethnl_req_info *req_info;
708 struct genlmsghdr *ghdr;
709 int ret;
710
711 BUILD_BUG_ON(sizeof(*ctx) > sizeof(cb->ctx));
712
713 ghdr = nlmsg_data(cb->nlh);--> 714 ops = ethnl_default_requests[ghdr->cmd];
Smatch thinks nlmsg_data() is untrusted data, so it could be out of bounds. It's a u8, but there are only 52 elements in the ethnl_default_requests[] array.
715 if (WARN_ONCE(!ops, "cmd %u has no ethnl_request_ops\n", ghdr->cmd))
716 return -EOPNOTSUPP;
717 req_info = kzalloc(ops->req_info_size, GFP_KERNEL);
718 if (!req_info)
719 return -ENOMEM;
720 reply_data = kmalloc(ops->reply_data_size, GFP_KERNEL);
721 if (!reply_data) {
722 ret = -ENOMEM;
723 goto free_req_info;
724 }
725
726 /* Unlike per-dev dump, don't ignore dev. The dump handler
727 * will notice it and dump PHYs from given dev. We only keep track of
728 * the dev's ifindex, .dumpit() will grab and release the netdev itself.
729 */
730 ret = ethnl_default_parse(req_info, &info->info, ops, false);
731 if (ret < 0)
732 goto free_reply_data;
733 if (req_info->dev) {
734 phy_ctx->ifindex = req_info->dev->ifindex;
735 netdev_put(req_info->dev, &req_info->dev_tracker);
736 req_info->dev = NULL;
737 }
738
739 ctx->ops = ops;
740 ctx->req_info = req_info;
741 ctx->reply_data = reply_data;
742 ctx->pos_ifindex = 0;
743
744 return 0;
745
746 free_reply_data:
747 kfree(reply_data);
748 free_req_info:
749 kfree(req_info);
750
751 return ret;
752 }regards,
dan carpenter
Re: [bug report] net: ethtool: Introduce per-PHY DUMP operations
Hi Dan,
Quoted 27 lines · Dan Carpenter
[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]Hello Maxime Chevallier,
Commit
172265b44cd3("net: ethtool: Introduce per-PHY DUMP operations") from May 2, 2025 (linux-next), leads to the following Smatch static checker warning:net/ethtool/netlink.c:714 ethnl_perphy_start() error: buffer overflow 'ethnl_default_requests' 52 <= 255 user_rl='0-255' uncapped
net/ethtool/netlink.c700 static int ethnl_perphy_start(struct netlink_callback *cb) 701 { 702 struct ethnl_perphy_dump_ctx *phy_ctx = ethnl_perphy_dump_context(cb); 703 const struct genl_dumpit_info *info = genl_dumpit_info(cb); 704 struct ethnl_dump_ctx *ctx = &phy_ctx->ethnl_ctx; 705 struct ethnl_reply_data *reply_data; 706 const struct ethnl_request_ops *ops; 707 struct ethnl_req_info *req_info; 708 struct genlmsghdr *ghdr; 709 int ret; 710 711 BUILD_BUG_ON(sizeof(*ctx) > sizeof(cb->ctx)); 712 713 ghdr = nlmsg_data(cb->nlh);
Quoted 5 lines
--> 714 ops = ethnl_default_requests[ghdr->cmd];
Smatch thinks
nlmsg_data()is untrusted data, so it could be out of bounds. It's a u8, but there are only 52 elements in the ethnl_default_requests[] array.
I see, then we also have the same problem in ethnl_default_start().
I'd expect the genl part to validate cmd (I haven't checked yet), but we do have a WARN_ONCE just below for the case 'cmd' is wrong, so we could definitely add some more sanity checks before accessing ethnl_default_requests[].
I'll look further into that and send the relevant fixes :)
Thanks for the report,
Maxime
Re: [bug report] net: ethtool: Introduce per-PHY DUMP operations
Quoted 21 lines · Maxime Chevallier
Quoted 15 lines
net/ethtool/netlink.c700 static int ethnl_perphy_start(struct netlink_callback *cb) 701 { 702 struct ethnl_perphy_dump_ctx *phy_ctx = ethnl_perphy_dump_context(cb); 703 const struct genl_dumpit_info *info = genl_dumpit_info(cb); 704 struct ethnl_dump_ctx *ctx = &phy_ctx->ethnl_ctx; 705 struct ethnl_reply_data *reply_data; 706 const struct ethnl_request_ops *ops; 707 struct ethnl_req_info *req_info; 708 struct genlmsghdr *ghdr; 709 int ret; 710 711 BUILD_BUG_ON(sizeof(*ctx) > sizeof(cb->ctx)); 712 713 ghdr = nlmsg_data(cb->nlh);Quoted 5 lines
--> 714 ops = ethnl_default_requests[ghdr->cmd];
Smatch thinks
nlmsg_data()is untrusted data, so it could be out of bounds. It's a u8, but there are only 52 elements in the ethnl_default_requests[] array.
Quoted 6 lines
I see, then we also have the same problem in
ethnl_default_start().I'd expect the genl part to validate cmd (I haven't checked yet), but we do have a
WARN_ONCEjust below for the case 'cmd' is wrong, so we could definitely add some more sanity checks before accessing ethnl_default_requests[].
The WARN_ONCE() doesn't doesn't work as bounds checking since there is no guarantee that the array will be followed by NULL pointers. I didn't see a bounds check for this, but I'm not an expert.
netlink_rcv_skb() <- receives untrusted data nlh = nlmsg_hdr(skb); -> nfnetlink_rcv_msg() <- calls nc->call()
-> ip_set_dump()
-> netlink_dump_start()
-> __netlink_dump_start() <- calls control->start(cb);
-> genl_start() <- this is where the validation would be
when we call
genl_family_rcv_msg_attrs_parse()
-> ethnl_perphy_start()Also the WARN_ONCE() warns if we try to do a cmd which doesn't have a matching operation in ethnl_default_requests[]. Every time we check for missing commands it triggers a WARN_ONCE(). There are quite a few which don't have a handler so I'm surprised that syzbot doesn't trigger the warning and complain. Here is a list of commands without a handler:
ETHTOOL_MSG_USER_NONE,ETHTOOL_MSG_FEATURES_SET,ETHTOOL_MSG_CABLE_TEST_ACT,ETHTOOL_MSG_CABLE_TEST_TDR_ACT,ETHTOOL_MSG_TUNNEL_INFO_GET,ETHTOOL_MSG_MODULE_FW_FLASH_ACT,ETHTOOL_MSG_RSS_CREATE_ACT,ETHTOOL_MSG_RSS_DELETE_ACT,
regards,
dan carpenter
Re: [bug report] net: ethtool: Introduce per-PHY DUMP operations
Hi Dan,
Quoted 50 lines · Dan Carpenter
Quoted 21 lines · Maxime Chevallier
Quoted 15 lines
net/ethtool/netlink.c700 static int ethnl_perphy_start(struct netlink_callback *cb) 701 { 702 struct ethnl_perphy_dump_ctx *phy_ctx = ethnl_perphy_dump_context(cb); 703 const struct genl_dumpit_info *info = genl_dumpit_info(cb); 704 struct ethnl_dump_ctx *ctx = &phy_ctx->ethnl_ctx; 705 struct ethnl_reply_data *reply_data; 706 const struct ethnl_request_ops *ops; 707 struct ethnl_req_info *req_info; 708 struct genlmsghdr *ghdr; 709 int ret; 710 711 BUILD_BUG_ON(sizeof(*ctx) > sizeof(cb->ctx)); 712 713 ghdr = nlmsg_data(cb->nlh);Quoted 5 lines
--> 714 ops = ethnl_default_requests[ghdr->cmd];
Smatch thinks
nlmsg_data()is untrusted data, so it could be out of bounds. It's a u8, but there are only 52 elements in the ethnl_default_requests[] array.Quoted 6 lines
I see, then we also have the same problem in
ethnl_default_start().I'd expect the genl part to validate cmd (I haven't checked yet), but we do have a
WARN_ONCEjust below for the case 'cmd' is wrong, so we could definitely add some more sanity checks before accessing ethnl_default_requests[].The
WARN_ONCE()doesn't doesn't work as bounds checking since there is no guarantee that the array will be followed by NULL pointers. I didn't see a bounds check for this, but I'm not an expert.
netlink_rcv_skb()<- receives untrusted data nlh =nlmsg_hdr(skb); ->nfnetlink_rcv_msg()<- callsnc->call()
->ip_set_dump()-> netlink_dump_start() -> __netlink_dump_start() <- calls control->start(cb); -> genl_start() <- this is where the validation would be when we call genl_family_rcv_msg_attrs_parse() -> ethnl_perphy_start()Also the
WARN_ONCE()warns if we try to do a cmd which doesn't have a matching operation in ethnl_default_requests[]. Every time we check for missing commands it triggers aWARN_ONCE(). There are quite a few which don't have a handler so I'm surprised that syzbot doesn't trigger the warning and complain. Here is a list of commands without a handler:
Quoted 8 lines
ETHTOOL_MSG_USER_NONE,ETHTOOL_MSG_FEATURES_SET,ETHTOOL_MSG_CABLE_TEST_ACT,ETHTOOL_MSG_CABLE_TEST_TDR_ACT,ETHTOOL_MSG_TUNNEL_INFO_GET,ETHTOOL_MSG_MODULE_FW_FLASH_ACT,ETHTOOL_MSG_RSS_CREATE_ACT,ETHTOOL_MSG_RSS_DELETE_ACT,
While these commands don't have ethnl_request_ops handlers, they still have a genetlink handler, see the ethtool_genl_ops array [1]
The ethnl_request_ops are there to provide a framework for ethtool netlink commands, as most of them have roughly the same behaviour of needing to grab some info from the netdev/phy_device under rtnl, then populate a netlink message based on that outside rtnl.
It's expected that not all ethnl commands use that ethnl framework as some behave in a manner that don't fit the ethnl scaffholding. In the end, the "cmd" validation is done by the generic netlink infrastructure, that's why we don't see reports from fuzzing bots.
The WARN_ONCE we see in ethnl_default_start() and ethnl_perphy_start() is there in case a programmer tries to use the ethnl framework without having the ethnl ops populated.
[1] :
https://elixir.bootlin.com/linux/v6.18.6/source/net/ethtool/netlink.c#L1132
In reality, we should never end-up with an out of bounds cmd as the validation will occur higher-up, in the genetlink part.
However, I'm OK with adding a check, or a least a comment :)
Maxime
Re: [bug report] net: ethtool: Introduce per-PHY DUMP operations
Quoted 11 lines
Quoted 8 lines
ETHTOOL_MSG_USER_NONE,ETHTOOL_MSG_FEATURES_SET,ETHTOOL_MSG_CABLE_TEST_ACT,ETHTOOL_MSG_CABLE_TEST_TDR_ACT,ETHTOOL_MSG_TUNNEL_INFO_GET,ETHTOOL_MSG_MODULE_FW_FLASH_ACT,ETHTOOL_MSG_RSS_CREATE_ACT,ETHTOOL_MSG_RSS_DELETE_ACT,While these commands don't have
ethnl_request_opshandlers, they still have a genetlink handler, see theethtool_genl_opsarray [1]
At least for the *_ACT commands, they are not expected in the userspace->kernel space direction. They should only be sent by the kernel to user space, to indicate some action has been performed, or happened. I don't know the netlink code too well, but i assume there is something which will throw out such commands if sent to the kernel, without even looking at the parameters?
Andrew
Re: [bug report] net: ethtool: Introduce per-PHY DUMP operations
Quoted 12 lines · Andrew Lunn
Quoted 11 lines
Quoted 8 lines
ETHTOOL_MSG_USER_NONE,ETHTOOL_MSG_FEATURES_SET,ETHTOOL_MSG_CABLE_TEST_ACT,ETHTOOL_MSG_CABLE_TEST_TDR_ACT,ETHTOOL_MSG_TUNNEL_INFO_GET,ETHTOOL_MSG_MODULE_FW_FLASH_ACT,ETHTOOL_MSG_RSS_CREATE_ACT,ETHTOOL_MSG_RSS_DELETE_ACT,While these commands don't have
ethnl_request_opshandlers, they still have a genetlink handler, see theethtool_genl_opsarray [1]
Quoted 6 lines
At least for the
*_ACTcommands, they are not expected in theuserspace->kernelspace direction. They should only be sent by the kernel to user space, to indicate some action has been performed, or happened. I don't know the netlink code too well, but i assume there is something which will throw out such commands if sent to the kernel, without even looking at the parameters?
Ah. Got it. Thanks!
regards,
dan carpenter
[bug report] net: wwan: Add Qualcomm BAM-DMUX WWAN network driver
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Stephan Gerhold,
Commit 21a0ffd9b38c ("net: wwan: Add Qualcomm BAM-DMUX WWAN network driver") from Nov 27, 2021 (linux-next), leads to the following Smatch static checker warning:
drivers/net/wwan/qcom_bam_dmux.c:505 bam_dmux_cmd_data() error: buffer overflow 'dmux->netdevs' 8 <= 255 user_rl='0-255' uncapped
drivers/net/wwan/qcom_bam_dmux.c
500 static void bam_dmux_cmd_data(struct bam_dmux_skb_dma *skb_dma)
501 {
502 struct bam_dmux *dmux = skb_dma->dmux;
503 struct sk_buff *skb = skb_dma->skb;
504 struct bam_dmux_hdr *hdr = (struct bam_dmux_hdr *)skb->data;
--> 505 struct net_device *netdev = dmux->netdevs[hdr->ch];
^^^^^^^Smatch thinks skb->data is untrusted. This is the rx path.
506
507 if (!netdev || !netif_running(netdev)) {
508 dev_warn(dmux->dev, "Data for inactive channel %u\n", hdr->ch);
509 return;
510 }
511 regards,
dan carpenter
Re: [bug report] net: wwan: Add Qualcomm BAM-DMUX WWAN network driver
Hi Dan,
Quoted 13 lines · Dan Carpenter
[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]Hello Stephan Gerhold,
Commit
21a0ffd9b38c("net: wwan: Add Qualcomm BAM-DMUX WWAN network driver") from Nov 27, 2021 (linux-next), leads to the following Smatch static checker warning:drivers/net/wwan/qcom_bam_dmux.c:505 bam_dmux_cmd_data() error: buffer overflow 'dmux->netdevs' 8 <= 255 user_rl='0-255' uncapped
drivers/net/wwan/qcom_bam_dmux.c
Quoted 9 lines
500 static void bam_dmux_cmd_data(struct bam_dmux_skb_dma *skb_dma) 501 { 502 struct bam_dmux *dmux = skb_dma->dmux; 503 struct sk_buff *skb = skb_dma->skb; 504 struct bam_dmux_hdr *hdr = (struct bam_dmux_hdr *)skb->data; --> 505 struct net_device *netdev = dmux->netdevs[hdr->ch]; ^^^^^^^Smatch thinks
skb->datais untrusted. This is the rx path.
Thanks a lot for the report!
I believe this is not a problem in practice, since there is an existing check for this in bam_dmux_rx_callback() (which is the only function that calls bam_dmux_cmd_data()):
if (hdr->ch >= BAM_DMUX_NUM_CH) {
dev_dbg(dmux->dev, "Unsupported channel: %u\n", hdr->ch);
goto out;
}
switch (hdr->cmd) {
case BAM_DMUX_CMD_DATA:
bam_dmux_cmd_data(skb_dma);
break;Is that something Smatch should be able to detect?
Thanks,
Stephan
Re: [bug report] net: wwan: Add Qualcomm BAM-DMUX WWAN network driver
Quoted 42 lines · Stephan Gerhold
Hi Dan,
Quoted 13 lines · Dan Carpenter
[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]Hello Stephan Gerhold,
Commit
21a0ffd9b38c("net: wwan: Add Qualcomm BAM-DMUX WWAN network driver") from Nov 27, 2021 (linux-next), leads to the following Smatch static checker warning:drivers/net/wwan/qcom_bam_dmux.c:505 bam_dmux_cmd_data() error: buffer overflow 'dmux->netdevs' 8 <= 255 user_rl='0-255' uncapped
drivers/net/wwan/qcom_bam_dmux.cQuoted 9 lines
500 static void bam_dmux_cmd_data(struct bam_dmux_skb_dma *skb_dma) 501 { 502 struct bam_dmux *dmux = skb_dma->dmux; 503 struct sk_buff *skb = skb_dma->skb; 504 struct bam_dmux_hdr *hdr = (struct bam_dmux_hdr *)skb->data; --> 505 struct net_device *netdev = dmux->netdevs[hdr->ch]; ^^^^^^^Smatch thinks
skb->datais untrusted. This is the rx path.Thanks a lot for the report!
I believe this is not a problem in practice, since there is an existing check for this in
bam_dmux_rx_callback()(which is the only function that callsbam_dmux_cmd_data()):if (hdr->ch >= BAM_DMUX_NUM_CH) { dev_dbg(dmux->dev, "Unsupported channel: %u\n", hdr->ch); goto out; } switch (hdr->cmd) { case BAM_DMUX_CMD_DATA: bam_dmux_cmd_data(skb_dma); break;
Quoted 2 lines
Is that something Smatch should be able to detect?
Ah, you are right. Thanks.
The problem is that skb->data is a buffer of u8 data. Smatch does cross function analysis, but it treats a buffer like that as opaque data.
Btw, I see that this code is actually from five years ago so I don't know why it's showing up as a warning now. :/ Sorry about that.
regards,
dan carpenter
[bug report] iommu/amd: Introduce gDomID-to-hDomID Mapping and handle parent domain invalidation
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Suravee Suthikulpanit,
Commit 757d2b1fdf5b ("iommu/amd: Introduce gDomID-to-hDomID Mapping and handle parent domain invalidation") from Jan 15, 2026 (linux-next), leads to the following Smatch static checker warning:
drivers/iommu/amd/nested.c:161 amd_iommu_alloc_domain_nested() warn: 'gdom_info->hdom_id' unsigned <= 0
drivers/iommu/amd/nested.c
148 /* Check if gDomID exist */
149 if (refcount_inc_not_zero(&gdom_info->users)) {
150 ndom->gdom_info = gdom_info;
151 xa_unlock(&aviommu->gdomid_array);
152
153 pr_debug("%s: Found gdom_id=%#x, hdom_id=%#x\n",
154 __func__, ndom->gdom_id, gdom_info->hdom_id);
155
156 return &ndom->domain;
157 }
158
159 /* The gDomID does not exist. We allocate new hdom_id */
160 gdom_info->hdom_id = amd_iommu_pdom_id_alloc();--> 161 if (gdom_info->hdom_id <= 0) {
gdom_info->hdom_id is unsigned. amd_iommu_pdom_id_alloc() can't return zero. It either returns negatives or 1-65535.
162 __xa_cmpxchg(&aviommu->gdomid_array,
163 ndom->gdom_id, gdom_info, NULL, GFP_ATOMIC);
164 xa_unlock(&aviommu->gdomid_array);
165 ret = -ENOSPC;
166 goto out_err_gdom_info;
167 }
168
169 ndom->gdom_info = gdom_info;regards,
dan carpenter
[bug report] drm/amdkfd: add debug set and clear address watch points operation
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Jonathan Kim,
Commit e0f85f4690d0 ("drm/amdkfd: add debug set and clear address watch points operation") from May 6, 2022 (linux-next), leads to the following Smatch static checker warning:
drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_debug.c:448 kfd_dbg_trap_clear_dev_address_watch() error: buffer overflow 'pdd->watch_points' 4 <= u32max user_rl='0-3,2147483648-u32max' uncapped
drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_debug.c
433 int kfd_dbg_trap_clear_dev_address_watch(struct kfd_process_device *pdd,
434 uint32_t watch_id)
435 {
436 int r;
437
438 if (!kfd_dbg_owns_dev_watch_id(pdd, watch_id))kfd_dbg_owns_dev_watch_id() doesn't check for negative values so if watch_id is larger than INT_MAX it leads to a buffer overflow. (Negative shifts are undefined).
439 return -EINVAL;
440
441 if (!pdd->dev->kfd->shared_resources.enable_mes) {
442 r = debug_lock_and_unmap(pdd->dev->dqm);
443 if (r)
444 return r;
445 }
446
447 amdgpu_gfx_off_ctrl(pdd->dev->adev, false);
--> 448 pdd->watch_points[watch_id] = pdd->dev->kfd2kgd->clear_address_watch(
449 pdd->dev->adev,
450 watch_id);
451 amdgpu_gfx_off_ctrl(pdd->dev->adev, true);
452
453 if (!pdd->dev->kfd->shared_resources.enable_mes)
454 r = debug_map_and_unlock(pdd->dev->dqm);
455 else
456 r = kfd_dbg_set_mes_debug_mode(pdd, true);
457
458 kfd_dbg_clear_dev_watch_id(pdd, watch_id);
459
460 return r;
461 }regards,
dan carpenter
PATCH 1/1 mtd: spi-nor: hisi-sfc: fix refcounting bug in hisi_spi_nor_register_all()
In reply to Dan CarpenterThis was converted to a _scoped() loop but this of_node_put() was accidentally left behind which is a double free.
--- drivers/mtd/spi-nor/controllers/hisi-sfc.c | 1 - 1 file changed, 1 deletion(-)
drivers/mtd/spi-nor/controllers/hisi-sfc.c +0 -1
@@ -403,7 +403,6 @@ static int hisi_spi_nor_register_all(struct hifmc_host *host)if (host->num_chip ==HIFMC_MAX_CHIP_NUM ) {dev_warn (dev,"Flash device number exceeds the maximum chipselect number\n" ); -of_node_put (np);break ; } }
Signature · 1 line
2.51.0
Re: [PATCH next] mtd: spi-nor: hisi-sfc: fix refcounting bug in hisi_spi_nor_register_all()
Quoted 5 lines · Dan Carpenter
This was converted to a
_scoped()loop but thisof_node_put()was accidentally left behind which is a double free.Fixes aa8cb72c2018 ("mtd: spi-nor: hisi-sfc: Simplify with scoped for each OF child loop")Signed-off-by Dan Carpenter <[email protected]>
Miquel, since you took the original patch through the NAND tree, can you please take this one too?
[...]
Signature · 2 lines
Regards, Pratyush Yadav
Miquel Raynal
maintainerRe: [PATCH next] mtd: spi-nor: hisi-sfc: fix refcounting bug in hisi_spi_nor_register_all()
Hello,
Quoted 5 lines · Pratyush Yadav
Quoted 3 lines · Dan Carpenter
This was converted to a
_scoped()loop but thisof_node_put()was accidentally left behind which is a double free.
Quoted 7 lines
Quoted 2 lines
Fixes aa8cb72c2018 ("mtd: spi-nor: hisi-sfc: Simplify with scoped for each OF child loop")Signed-off-by Dan Carpenter <[email protected]>Reviewed-by Pratyush Yadav <[email protected]>Miquel, since you took the original patch through the NAND tree, can you please take this one too?
Yes I will, thanks!
Miquèl
Re: [PATCH next] mtd: spi-nor: hisi-sfc: fix refcounting bug in hisi_spi_nor_register_all()
In reply to Dan CarpenterQuoted 4 lines · Dan Carpenter
This was converted to a
_scoped()loop but thisof_node_put()was accidentally left behind which is a double free.
Applied to nand/next, thanks!
[1/1] mtd: spi-nor: hisi-sfc: fix refcounting bug in hisi_spi_nor_register_all()
commit: 6c7860aa28b81b7e909b8d2072ed76fa22db6eda
Patche(s) should be available on mtd/linux.git and will be part of the next PR (provided that no robot complains by then).
Kind regards,
Miquèl
[bug report] media: synopsys: add driver for the designware mipi csi-2 receiver
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Michael Riesch,
Commit 355a11004066 ("media: synopsys: add driver for the designware mipi csi-2 receiver") from Jan 20, 2026 (linux-next), leads to the following Smatch static checker warning:
drivers/media/platform/synopsys/dw-mipi-csi2rx.c:307 dw_mipi_csi2rx_enum_mbus_code() warn: array off by one? 'csi2->formats[code->index]'
drivers/media/platform/synopsys/dw-mipi-csi2rx.c
286 static int
287 dw_mipi_csi2rx_enum_mbus_code(struct v4l2_subdev *sd,
288 struct v4l2_subdev_state *sd_state,
289 struct v4l2_subdev_mbus_code_enum *code)
290 {
291 struct dw_mipi_csi2rx_device *csi2 = to_csi2(sd);
292
293 switch (code->pad) {
294 case DW_MIPI_CSI2RX_PAD_SRC:
295 if (code->index)
296 return -EINVAL;
297
298 code->code =
299 v4l2_subdev_state_get_format(sd_state,
300 DW_MIPI_CSI2RX_PAD_SINK)->code;
301
302 return 0;
303 case DW_MIPI_CSI2RX_PAD_SINK:
304 if (code->index > csi2->formats_num)This should be >=.
305 return -EINVAL;
306
--> 307 code->code = csi2->formats[code->index].code;
308 return 0;
309 default:
310 return -EINVAL;
311 }
312 }regards,
dan carpenter
[bug report] crush: remove forcefeed functionality
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Ceph Maintainers,
Commit 41ebcc0907c5 ("crush: remove forcefeed functionality") from May 7, 2012 (linux-next), leads to the following Smatch static checker warning:
net/ceph/crush/mapper.c:1015 crush_do_rule() warn: iterator 'j' not incremented
net/ceph/crush/mapper.c
897 int crush_do_rule(const struct crush_map *map,
898 int ruleno, int x, int *result, int result_max,
899 const __u32 *weight, int weight_max,
900 void *cwin, const struct crush_choose_arg *choose_args)
901 {
902 int result_len;
903 struct crush_work *cw = cwin;
904 int *a = cwin + map->working_size;
905 int *b = a + result_max;
906 int *c = b + result_max;
907 int *w = a;
908 int *o = b;
909 int recurse_to_leaf;
910 int wsize = 0;
911 int osize;
912 const struct crush_rule *rule;
913 __u32 step;
914 int i, j;
915 int numrep;
916 int out_size;
917 /*
918 * the original choose_total_tries value was off by one (it
919 * counted "retries" and not "tries"). add one.
920 */
921 int choose_tries = map->choose_total_tries + 1;
922 int choose_leaf_tries = 0;
923 /*
924 * the local tries values were counted as "retries", though,
925 * and need no adjustment
926 */
927 int choose_local_retries = map->choose_local_tries;
928 int choose_local_fallback_retries = map->choose_local_fallback_tries;
929
930 int vary_r = map->chooseleaf_vary_r;
931 int stable = map->chooseleaf_stable;
932
933 if ((__u32)ruleno >= map->max_rules) {
934 dprintk(" bad ruleno %d\n", ruleno);
935 return 0;
936 }
937
938 rule = map->rules[ruleno];
939 result_len = 0;
940
941 for (step = 0; step < rule->len; step++) {
942 int firstn = 0;
943 const struct crush_rule_step *curstep = &rule->steps[step];
944
945 switch (curstep->op) {
946 case CRUSH_RULE_TAKE:
947 if ((curstep->arg1 >= 0 &&
948 curstep->arg1 < map->max_devices) ||
949 (-1-curstep->arg1 >= 0 &&
950 -1-curstep->arg1 < map->max_buckets &&
951 map->buckets[-1-curstep->arg1])) {
952 w[0] = curstep->arg1;
953 wsize = 1;
954 } else {
955 dprintk(" bad take value %d\n", curstep->arg1);
956 }
957 break;
958
959 case CRUSH_RULE_SET_CHOOSE_TRIES:
960 if (curstep->arg1 > 0)
961 choose_tries = curstep->arg1;
962 break;
963
964 case CRUSH_RULE_SET_CHOOSELEAF_TRIES:
965 if (curstep->arg1 > 0)
966 choose_leaf_tries = curstep->arg1;
967 break;
968
969 case CRUSH_RULE_SET_CHOOSE_LOCAL_TRIES:
970 if (curstep->arg1 >= 0)
971 choose_local_retries = curstep->arg1;
972 break;
973
974 case CRUSH_RULE_SET_CHOOSE_LOCAL_FALLBACK_TRIES:
975 if (curstep->arg1 >= 0)
976 choose_local_fallback_retries = curstep->arg1;
977 break;
978
979 case CRUSH_RULE_SET_CHOOSELEAF_VARY_R:
980 if (curstep->arg1 >= 0)
981 vary_r = curstep->arg1;
982 break;
983
984 case CRUSH_RULE_SET_CHOOSELEAF_STABLE:
985 if (curstep->arg1 >= 0)
986 stable = curstep->arg1;
987 break;
988
989 case CRUSH_RULE_CHOOSELEAF_FIRSTN:
990 case CRUSH_RULE_CHOOSE_FIRSTN:
991 firstn = 1;
992 fallthrough;
993 case CRUSH_RULE_CHOOSELEAF_INDEP:
994 case CRUSH_RULE_CHOOSE_INDEP:
995 if (wsize == 0)
996 break;
997
998 recurse_to_leaf =
999 curstep->op ==
1000 CRUSH_RULE_CHOOSELEAF_FIRSTN ||
1001 curstep->op ==
1002 CRUSH_RULE_CHOOSELEAF_INDEP;
1003
1004 /* reset output */
1005 osize = 0;
1006
1007 for (i = 0; i < wsize; i++) {
1008 int bno;
1009 numrep = curstep->arg1;
1010 if (numrep <= 0) {
1011 numrep += result_max;
1012 if (numrep <= 0)
1013 continue;
1014 }
--> 1015 j = 0;
^^^^^
1016 /* make sure bucket id is valid */
1017 bno = -1 - w[i];
1018 if (bno < 0 || bno >= map->max_buckets) {
1019 /* w[i] is probably CRUSH_ITEM_NONE */
1020 dprintk(" bad w[i] %d\n", w[i]);
1021 continue;
1022 }
1023 if (firstn) {
1024 int recurse_tries;
1025 if (choose_leaf_tries)
1026 recurse_tries =
1027 choose_leaf_tries;
1028 else if (map->chooseleaf_descend_once)
1029 recurse_tries = 1;
1030 else
1031 recurse_tries = choose_tries;
1032 osize += crush_choose_firstn(
1033 map,
1034 cw,
1035 map->buckets[bno],
1036 weight, weight_max,
1037 x, numrep,
1038 curstep->arg2,
1039 o+osize, j,
1040 result_max-osize,
1041 choose_tries,
1042 recurse_tries,
1043 choose_local_retries,
1044 choose_local_fallback_retries,
1045 recurse_to_leaf,
1046 vary_r,
1047 stable,
1048 c+osize,
1049 0,
1050 choose_args);
1051 } else {
1052 out_size = ((numrep < (result_max-osize)) ?
1053 numrep : (result_max-osize));
1054 crush_choose_indep(
1055 map,
1056 cw,
1057 map->buckets[bno],
1058 weight, weight_max,
1059 x, out_size, numrep,
1060 curstep->arg2,
1061 o+osize, j,
1062 choose_tries,
1063 choose_leaf_tries ?
1064 choose_leaf_tries : 1,
1065 recurse_to_leaf,
1066 c+osize,
1067 0,
1068 choose_args);
1069 osize += out_size;
1070 }There used to be a j++ around here but it was deleted.
1071 }
1072
1073 if (recurse_to_leaf)
1074 /* copy final _leaf_ values to output set */
1075 memcpy(o, c, osize*sizeof(*o));
1076
1077 /* swap o and w arrays */
1078 swap(o, w);
1079 wsize = osize;
1080 break;
1081
1082
1083 case CRUSH_RULE_EMIT:
1084 for (i = 0; i < wsize && result_len < result_max; i++) {
1085 result[result_len] = w[i];
1086 result_len++;
1087 }
1088 wsize = 0;
1089 break;
1090
1091 default:
1092 dprintk(" unknown op %d at step %d\n",
1093 curstep->op, step);
1094 break;
1095 }
1096 }
1097
1098 return result_len;
1099 }regards,
dan carpenter
Re: [bug report] crush: remove forcefeed functionality
Quoted 11 lines · Dan Carpenter
[ Smatch checking is paused while we raise funding. #SadFace
https://urldefense.proofpoint.com/v2/url?u=https-3A__lore.kernel.org_all_aTaiGSbWZ9DJaGo7-40stanley.mountain_&d=DwIBAg&c=BSDicqBQBDjDI9RkVyTcHQ&r=q5bIm4AXMzc8NJu1_RGmnQ2fMWKq4Y4RAkElvUgSs00&m=EbbQA8mLawUrIpoBP1JgkEbj9ykB2zMAgU-BpxccK9crlqQp8eHphKm2eDfswppo&s=4dnJgIrt1z5jJRZwXTmcMBeS0RZ5lg-CZ04H1P9fcrE&e= -dan ]Hello Ceph Maintainers,
Commit
41ebcc0907c5("crush: remove forcefeed functionality") from May 7, 2012 (linux-next), leads to the following Smatch static checker warning:net/ceph/crush/mapper.c:1015 crush_do_rule() warn: iterator 'j' not incremented
Yeah, it looks like an issue.
Quoted 114 lines
net/ceph/crush/mapper.c897 int crush_do_rule(const struct crush_map *map, 898 int ruleno, int x, int *result, int result_max, 899 const __u32 *weight, int weight_max, 900 void *cwin, const struct crush_choose_arg *choose_args) 901 { 902 int result_len; 903 struct crush_work *cw = cwin; 904 int *a = cwin + map->working_size; 905 int *b = a + result_max; 906 int *c = b + result_max; 907 int *w = a; 908 int *o = b; 909 int recurse_to_leaf; 910 int wsize = 0; 911 int osize; 912 const struct crush_rule *rule; 913 __u32 step; 914 int i, j; 915 int numrep; 916 int out_size; 917 /* 918 * the original choose_total_tries value was off by one (it 919 * counted "retries" and not "tries"). add one. 920 */ 921 int choose_tries = map->choose_total_tries + 1; 922 int choose_leaf_tries = 0; 923 /* 924 * the local tries values were counted as "retries", though, 925 * and need no adjustment 926 */ 927 int choose_local_retries = map->choose_local_tries; 928 int choose_local_fallback_retries = map->choose_local_fallback_tries; 929 930 int vary_r = map->chooseleaf_vary_r; 931 int stable = map->chooseleaf_stable; 932 933 if ((__u32)ruleno >= map->max_rules) { 934 dprintk(" bad ruleno %d\n", ruleno); 935 return 0; 936 } 937 938 rule = map->rules[ruleno]; 939 result_len = 0; 940 941 for (step = 0; step < rule->len; step++) { 942 int firstn = 0; 943 const struct crush_rule_step *curstep = &rule->steps[step]; 944 945 switch (curstep->op) { 946 case CRUSH_RULE_TAKE: 947 if ((curstep->arg1 >= 0 && 948 curstep->arg1 < map->max_devices) || 949 (-1-curstep->arg1 >= 0 && 950 -1-curstep->arg1 < map->max_buckets && 951 map->buckets[-1-curstep->arg1])) { 952 w[0] = curstep->arg1; 953 wsize = 1; 954 } else { 955 dprintk(" bad take value %d\n", curstep->arg1); 956 } 957 break; 958 959 case CRUSH_RULE_SET_CHOOSE_TRIES: 960 if (curstep->arg1 > 0) 961 choose_tries = curstep->arg1; 962 break; 963 964 case CRUSH_RULE_SET_CHOOSELEAF_TRIES: 965 if (curstep->arg1 > 0) 966 choose_leaf_tries = curstep->arg1; 967 break; 968 969 case CRUSH_RULE_SET_CHOOSE_LOCAL_TRIES: 970 if (curstep->arg1 >= 0) 971 choose_local_retries = curstep->arg1; 972 break; 973 974 case CRUSH_RULE_SET_CHOOSE_LOCAL_FALLBACK_TRIES: 975 if (curstep->arg1 >= 0) 976 choose_local_fallback_retries = curstep->arg1; 977 break; 978 979 case CRUSH_RULE_SET_CHOOSELEAF_VARY_R: 980 if (curstep->arg1 >= 0) 981 vary_r = curstep->arg1; 982 break; 983 984 case CRUSH_RULE_SET_CHOOSELEAF_STABLE: 985 if (curstep->arg1 >= 0) 986 stable = curstep->arg1; 987 break; 988 989 case CRUSH_RULE_CHOOSELEAF_FIRSTN: 990 case CRUSH_RULE_CHOOSE_FIRSTN: 991 firstn = 1; 992 fallthrough; 993 case CRUSH_RULE_CHOOSELEAF_INDEP: 994 case CRUSH_RULE_CHOOSE_INDEP: 995 if (wsize == 0) 996 break; 997 998 recurse_to_leaf = 999 curstep->op == 1000 CRUSH_RULE_CHOOSELEAF_FIRSTN || 1001 curstep->op == 1002 CRUSH_RULE_CHOOSELEAF_INDEP; 1003 1004 /* reset output */ 1005 osize = 0; 1006 1007 for (i = 0; i < wsize; i++) { 1008 int bno;
Quoted 8 lines
1009 numrep = curstep->arg1;
1010 if (numrep <= 0) {
1011 numrep += result_max;
1012 if (numrep <= 0)
1013 continue;
1014 }
--> 1015 j = 0;
^^^^^It looks like intentional initialization of variable. But let me spend some time to better understand the crush_choose_firstn() and crush_choose_indep() logic and the history of this function modifications in commits.
Thanks,
Slava.
Quoted 91 lines
1016 /* make sure bucket id is valid */ 1017 bno = -1 - w[i]; 1018 if (bno < 0 || bno >= map->max_buckets) { 1019 /* w[i] is probably CRUSH_ITEM_NONE */ 1020 dprintk(" bad w[i] %d\n", w[i]); 1021 continue; 1022 } 1023 if (firstn) { 1024 int recurse_tries; 1025 if (choose_leaf_tries) 1026 recurse_tries = 1027 choose_leaf_tries; 1028 else if (map->chooseleaf_descend_once) 1029 recurse_tries = 1; 1030 else 1031 recurse_tries = choose_tries; 1032 osize += crush_choose_firstn( 1033 map, 1034 cw, 1035 map->buckets[bno], 1036 weight, weight_max, 1037 x, numrep, 1038 curstep->arg2, 1039 o+osize, j, 1040 result_max-osize, 1041 choose_tries, 1042 recurse_tries, 1043 choose_local_retries, 1044 choose_local_fallback_retries, 1045 recurse_to_leaf, 1046 vary_r, 1047 stable, 1048 c+osize, 1049 0, 1050 choose_args); 1051 } else { 1052 out_size = ((numrep < (result_max-osize)) ? 1053 numrep : (result_max-osize)); 1054 crush_choose_indep( 1055 map, 1056 cw, 1057 map->buckets[bno], 1058 weight, weight_max, 1059 x, out_size, numrep, 1060 curstep->arg2, 1061 o+osize, j, 1062 choose_tries, 1063 choose_leaf_tries ? 1064 choose_leaf_tries : 1, 1065 recurse_to_leaf, 1066 c+osize, 1067 0, 1068 choose_args); 1069 osize += out_size; 1070 }There used to be a j++ around here but it was deleted.
1071 } 1072 1073 if (recurse_to_leaf) 1074 /* copy final _leaf_ values to output set */ 1075 memcpy(o, c, osize*sizeof(*o)); 1076 1077 /* swap o and w arrays */ 1078 swap(o, w); 1079 wsize = osize; 1080 break; 1081 1082 1083 case CRUSH_RULE_EMIT: 1084 for (i = 0; i < wsize && result_len < result_max; i++) { 1085 result[result_len] = w[i]; 1086 result_len++; 1087 } 1088 wsize = 0; 1089 break; 1090 1091 default: 1092 dprintk(" unknown op %d at step %d\n", 1093 curstep->op, step); 1094 break; 1095 } 1096 } 1097 1098 return result_len; 1099 }regards,
dan carpenter
[bug report] net: ethernet: ti: am65-cpsw: enable bc/mc storm prevention support
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Grygorii Strashko,
Commit 5ec836be11b3 ("net: ethernet: ti: am65-cpsw: enable bc/mc storm prevention support") from Apr 12, 2022 (linux-next), leads to the following Smatch static checker warning:
drivers/net/ethernet/ti/am65-cpsw-qos.c:1126 am65_cpsw_qos_configure_clsflower() warn: iterator 'i' not incremented
drivers/net/ethernet/ti/am65-cpsw-qos.c
1118 static int am65_cpsw_qos_configure_clsflower(struct am65_cpsw_port *port,
1119 struct flow_cls_offload *cls)
1120 {
1121 struct flow_rule *rule = flow_cls_offload_flow_rule(cls);
1122 struct netlink_ext_ack *extack = cls->common.extack;
1123 const struct flow_action_entry *act;
1124 int i, ret;
1125 --> 1126 flow_action_for_each(i, act, &rule->action) {
This loop only iterates one time. Is that intentional? We could use "act = flow_action_first_entry_geti(&rule->action);" if we just want the first entry.
1127 switch (act->id) {
1128 case FLOW_ACTION_POLICE:
1129 ret = am65_cpsw_qos_clsflower_policer_validate(&rule->action, act, extack);
1130 if (ret)
1131 return ret;
1132
1133 return am65_cpsw_qos_clsflower_add_policer(port, extack, cls,
1134 act->police.rate_pkt_ps);
1135 default:
1136 NL_SET_ERR_MSG_MOD(extack,
1137 "Action not supported");
1138 return -EOPNOTSUPP;
1139 }
1140 }
1141 return -EOPNOTSUPP;
1142 }regards,
dan carpenter
[bug report] phy: qcom: qmp-usbc: Add QCS615 USB/DP PHY config and DP mode support
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Xiangxu Yin,
Commit 81791c45c8e0 ("phy: qcom: qmp-usbc: Add QCS615 USB/DP PHY config and DP mode support") from Dec 15, 2025 (linux-next), leads to the following Smatch static checker warning:
drivers/phy/qualcomm/phy-qcom-qmp-usbc.c:803 qmp_v2_configure_dp_swing() index hardmax out of bounds '(*cfg->swing_tbl)[v_level]' size=4 max='4' rl='0-4'
drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
777 static int qmp_v2_configure_dp_swing(struct qmp_usbc *qmp)
778 {
779 const struct qmp_phy_cfg *cfg = qmp->cfg;
780 const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts;
781 void __iomem *tx = qmp->dp_tx;
782 void __iomem *tx2 = qmp->dp_tx2;
783 unsigned int v_level = 0, p_level = 0;
784 u8 voltage_swing_cfg, pre_emphasis_cfg;
785 int i;
786
787 if (dp_opts->lanes > 4) {
788 dev_err(qmp->dev, "Invalid lane_num(%d)\n", dp_opts->lanes);
789 return -EINVAL;
790 }
791
792 for (i = 0; i < dp_opts->lanes; i++) {
793 v_level = max(v_level, dp_opts->voltage[i]);
794 p_level = max(p_level, dp_opts->pre[i]);
795 }
796
797 if (v_level > 4 || p_level > 4) {These should be >= 4 instead of >.
798 dev_err(qmp->dev, "Invalid v(%d) | p(%d) level)\n",
799 v_level, p_level);
800 return -EINVAL;
801 }
802
--> 803 voltage_swing_cfg = (*cfg->swing_tbl)[v_level][p_level];
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^This is a 4x4 array.
804 pre_emphasis_cfg = (*cfg->pre_emphasis_tbl)[v_level][p_level];
805
806 voltage_swing_cfg |= DP_PHY_TXn_TX_DRV_LVL_MUX_EN;
807 pre_emphasis_cfg |= DP_PHY_TXn_TX_EMP_POST1_LVL_MUX_EN;
808
809 if (voltage_swing_cfg == 0xff && pre_emphasis_cfg == 0xff)
810 return -EINVAL;
811
812 writel(voltage_swing_cfg, tx + QSERDES_V2_TX_TX_DRV_LVL);
813 writel(pre_emphasis_cfg, tx + QSERDES_V2_TX_TX_EMP_POST1_LVL);
814 writel(voltage_swing_cfg, tx2 + QSERDES_V2_TX_TX_DRV_LVL);
815 writel(pre_emphasis_cfg, tx2 + QSERDES_V2_TX_TX_EMP_POST1_LVL);
816
817 return 0;
818 }regards,
dan carpenter
Re: [bug report] phy: qcom: qmp-usbc: Add QCS615 USB/DP PHY config and DP mode support
Quoted 37 lines · Dan Carpenter
[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]Hello Xiangxu Yin,
Commit
81791c45c8e0("phy: qcom: qmp-usbc: Add QCS615 USB/DP PHY config and DP mode support") from Dec 15, 2025 (linux-next), leads to the following Smatch static checker warning:drivers/phy/qualcomm/phy-qcom-qmp-usbc.c:803 qmp_v2_configure_dp_swing() index hardmax out of bounds '(*cfg->swing_tbl)[v_level]' size=4 max='4' rl='0-4'
drivers/phy/qualcomm/phy-qcom-qmp-usbc.c777 static int qmp_v2_configure_dp_swing(struct qmp_usbc *qmp) 778 { 779 const struct qmp_phy_cfg *cfg = qmp->cfg; 780 const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts; 781 void __iomem *tx = qmp->dp_tx; 782 void __iomem *tx2 = qmp->dp_tx2; 783 unsigned int v_level = 0, p_level = 0; 784 u8 voltage_swing_cfg, pre_emphasis_cfg; 785 int i; 786 787 if (dp_opts->lanes > 4) { 788 dev_err(qmp->dev, "Invalid lane_num(%d)\n", dp_opts->lanes); 789 return -EINVAL; 790 } 791 792 for (i = 0; i < dp_opts->lanes; i++) { 793 v_level = max(v_level, dp_opts->voltage[i]); 794 p_level = max(p_level, dp_opts->pre[i]); 795 } 796 797 if (v_level > 4 || p_level > 4) {These should be >= 4 instead of >.
Quoted 8 lines
798 dev_err(qmp->dev, "Invalid v(%d) | p(%d) level)\n", 799 v_level, p_level); 800 return -EINVAL; 801 } 802 --> 803 voltage_swing_cfg = (*cfg->swing_tbl)[v_level][p_level]; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^This is a 4x4 array.
Thanks Dan for the report
Xiangxu, are you planning to send a patch to address that?
Konrad
Re: [bug report] phy: qcom: qmp-usbc: Add QCS615 USB/DP PHY config and DP mode support
Quoted 46 lines · Konrad Dybcio
Quoted 37 lines · Dan Carpenter
[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]Hello Xiangxu Yin,
Commit
81791c45c8e0("phy: qcom: qmp-usbc: Add QCS615 USB/DP PHY config and DP mode support") from Dec 15, 2025 (linux-next), leads to the following Smatch static checker warning:drivers/phy/qualcomm/phy-qcom-qmp-usbc.c:803 qmp_v2_configure_dp_swing() index hardmax out of bounds '(*cfg->swing_tbl)[v_level]' size=4 max='4' rl='0-4'
drivers/phy/qualcomm/phy-qcom-qmp-usbc.c777 static int qmp_v2_configure_dp_swing(struct qmp_usbc *qmp) 778 { 779 const struct qmp_phy_cfg *cfg = qmp->cfg; 780 const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts; 781 void __iomem *tx = qmp->dp_tx; 782 void __iomem *tx2 = qmp->dp_tx2; 783 unsigned int v_level = 0, p_level = 0; 784 u8 voltage_swing_cfg, pre_emphasis_cfg; 785 int i; 786 787 if (dp_opts->lanes > 4) { 788 dev_err(qmp->dev, "Invalid lane_num(%d)\n", dp_opts->lanes); 789 return -EINVAL; 790 } 791 792 for (i = 0; i < dp_opts->lanes; i++) { 793 v_level = max(v_level, dp_opts->voltage[i]); 794 p_level = max(p_level, dp_opts->pre[i]); 795 } 796 797 if (v_level > 4 || p_level > 4) {These should be >= 4 instead of >.
Quoted 8 lines
798 dev_err(qmp->dev, "Invalid v(%d) | p(%d) level)\n", 799 v_level, p_level); 800 return -EINVAL; 801 } 802 --> 803 voltage_swing_cfg = (*cfg->swing_tbl)[v_level][p_level]; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^This is a 4x4 array.
Quoted 5 lines
Thanks Dan for the report
Xiangxu, are you planning to send a patch to address that?
Konrad
Thanks for the notice, Dan & Konrad.
I just got back from a long leave and will submit the relevant patches as soon as possible.
[bug report] drm/amd/display: add DC changes for DCN351
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Hamza Mahfooz,
Commit 2728e9c7c842 ("drm/amd/display: add DC changes for DCN351") from Feb 23, 2024 (linux-next), leads to the following Smatch static checker warning:
drivers/gpu/drm/amd/amdgpu/../display/dc/resource/dcn351/dcn351_resource.c:1284 dcn35_stream_encoder_create() index hardmax out of bounds 'stream_enc_regs[eng_id]' size=5 max='5' rl='s32min-5' drivers/gpu/drm/amd/amdgpu/../display/dc/resource/dcn36/dcn36_resource.c:1285 dcn35_stream_encoder_create() index hardmax out of bounds 'stream_enc_regs[eng_id]' size=5 max='5' rl='s32min-5' drivers/gpu/drm/amd/amdgpu/../display/dc/resource/dcn321/dcn321_resource.c:1222 dcn321_stream_encoder_create() index hardmax out of bounds 'stream_enc_regs[eng_id]' size=5 max='5' rl='s32min-5' drivers/gpu/drm/amd/amdgpu/../display/dc/resource/dcn315/dcn315_resource.c:1252 dcn315_stream_encoder_create() index hardmax out of bounds 'stream_enc_regs[eng_id]' size=5 max='5' rl='s32min-5' drivers/gpu/drm/amd/amdgpu/../display/dc/resource/dcn35/dcn35_resource.c:1304 dcn35_stream_encoder_create() index hardmax out of bounds 'stream_enc_regs[eng_id]' size=5 max='5' rl='s32min-5' drivers/gpu/drm/amd/amdgpu/../display/dc/resource/dcn32/dcn32_resource.c:1241 dcn32_stream_encoder_create() index hardmax out of bounds 'stream_enc_regs[eng_id]' size=5 max='5' rl='s32min-5' drivers/gpu/drm/amd/amdgpu/../display/dc/resource/dcn316/dcn316_resource.c:1245 dcn316_stream_encoder_create() index hardmax out of bounds 'stream_enc_regs[eng_id]' size=5 max='5' rl='s32min-5'
drivers/gpu/drm/amd/amdgpu/../display/dc/resource/dcn351/dcn351_resource.c
1246 static struct stream_encoder *dcn35_stream_encoder_create(
1247 enum engine_id eng_id,
1248 struct dc_context *ctx)
1249 {
1250 struct dcn10_stream_encoder *enc1;
1251 struct vpg *vpg;
1252 struct afmt *afmt;
1253 int vpg_inst;
1254 int afmt_inst;
1255
1256 /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */
1257 if (eng_id <= ENGINE_ID_DIGF) {ENGINE_ID_DIGF is 5. should <= be <?
Unrelated but, ugh, why is Smatch saying that "eng_id" can be negative? end_id is type signed long, but there are checks in the caller which prevent it from being negative.
1258 vpg_inst = eng_id;
1259 afmt_inst = eng_id;
1260 } else
1261 return NULL;
1262
1263 enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
1264 vpg = dcn31_vpg_create(ctx, vpg_inst);
1265 afmt = dcn31_afmt_create(ctx, afmt_inst);
1266
1267 if (!enc1 || !vpg || !afmt) {
1268 kfree(enc1);
1269 kfree(vpg);
1270 kfree(afmt);
1271 return NULL;
1272 }
1273
1274 #undef REG_STRUCT
1275 #define REG_STRUCT stream_enc_regs
1276 stream_enc_regs_init(0),
1277 stream_enc_regs_init(1),
1278 stream_enc_regs_init(2),
1279 stream_enc_regs_init(3),
1280 stream_enc_regs_init(4);
1281
1282 dcn35_dio_stream_encoder_construct(enc1, ctx, ctx->dc_bios,
1283 eng_id, vpg, afmt,
--> 1284 &stream_enc_regs[eng_id],
^^^^^^^^^^^^^^^^^^^^^^^This stream_enc_regs[] array has 5 elements so we are one element beyond the end of the array.
1285 &se_shift, &se_mask);
1286
1287 return &enc1->base;
1288 }regards,
dan carpenter
[bug report] media: rockchip: rkcif: add support for rk3568 vicap mipi capture
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Michael Riesch,
Commit 1f2353f5a1af ("media: rockchip: rkcif: add support for rk3568 vicap mipi capture") from Nov 14, 2025 (linux-next), leads to the following Smatch static checker warning:
drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.c:519 rkcif_mipi_id_get_reg() index hardmax out of bounds 'rkcif->match_data->mipi->regs_id[id]' size=4 max='4' rl='0-u32max'
drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.c:519 rkcif_mipi_id_get_reg() index hardmax out of bounds 'rkcif->match_data->mipi->regs_id[id][index]' size=11 max='11' rl='0-11'
drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.c
504 static inline unsigned int rkcif_mipi_id_get_reg(struct rkcif_stream *stream,
505 unsigned int index)
506 {
507 struct rkcif_device *rkcif = stream->rkcif;
508 unsigned int block, id, offset, reg;
509
510 block = stream->interface->index - RKCIF_MIPI_BASE;
511 id = stream->id;
512
513 if (WARN_ON_ONCE(block > RKCIF_MIPI_MAX - RKCIF_MIPI_BASE) ||
514 WARN_ON_ONCE(id > RKCIF_ID_MAX) ||
515 WARN_ON_ONCE(index > RKCIF_MIPI_ID_REGISTER_MAX))The id and index checks should be >=. Not sure about block but I assume it's off by one as well.
516 return RKCIF_REGISTER_NOTSUPPORTED;
517
518 offset = rkcif->match_data->mipi->blocks[block].offset;
--> 519 reg = rkcif->match_data->mipi->regs_id[id][index];
520 if (reg == RKCIF_REGISTER_NOTSUPPORTED)
521 return reg;
522
523 return offset + reg;
524 }regards,
dan carpenter
Re: [bug report] media: rockchip: rkcif: add support for rk3568 vicap mipi capture
Hi Dan,
Quoted 30 lines · Dan Carpenter
[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]Hello Michael Riesch,
Commit
1f2353f5a1af("media: rockchip: rkcif: add support for rk3568 vicap mipi capture") from Nov 14, 2025 (linux-next), leads to the following Smatch static checker warning:
drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.c:519rkcif_mipi_id_get_reg()index hardmax out of bounds 'rkcif->match_data->mipi->regs_id[id]' size=4 max='4' rl='0-u32max'
drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.c:519rkcif_mipi_id_get_reg()index hardmax out of bounds 'rkcif->match_data->mipi->regs_id[id][index]' size=11 max='11' rl='0-11'
drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.c504 static inline unsigned int rkcif_mipi_id_get_reg(struct rkcif_stream *stream, 505 unsigned int index) 506 { 507 struct rkcif_device *rkcif = stream->rkcif; 508 unsigned int block, id, offset, reg; 509 510 block = stream->interface->index - RKCIF_MIPI_BASE; 511 id = stream->id; 512 513 if (WARN_ON_ONCE(block > RKCIF_MIPI_MAX - RKCIF_MIPI_BASE) || 514 WARN_ON_ONCE(id > RKCIF_ID_MAX) || 515 WARN_ON_ONCE(index > RKCIF_MIPI_ID_REGISTER_MAX))
Quoted 2 lines
The id and index checks should be >=. Not sure about block but I assume it's off by one as well.
Thanks for the heads up. I started fixing this and then recalled some previous work on that issue.
I found that you submitted a patch that fixes exactly this, but this patch hasn't been applied for whatever reason.
Since I have some other fixes for the rkcif driver, I'll give your patch another spin in the scope of that series -- hope this is OK for you!
Best regards,
Michael
Quoted 13 lines
516 return RKCIF_REGISTER_NOTSUPPORTED; 517 518 offset = rkcif->match_data->mipi->blocks[block].offset; --> 519 reg = rkcif->match_data->mipi->regs_id[id][index]; 520 if (reg == RKCIF_REGISTER_NOTSUPPORTED) 521 return reg; 522 523 return offset + reg; 524 }regards,
dan carpenter
[bug report] drm/imagination: Add gpuid module parameter
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Alexandru Dadu,
Commit 3bf74137340a ("drm/imagination: Add gpuid module parameter") from Jan 13, 2026 (linux-next), leads to the following Smatch static checker warning:
drivers/gpu/drm/imagination/pvr_device.c:485 pvr_gpuid_decode_string()
warn: error code type promoted to positive: 'ret'
drivers/gpu/drm/imagination/pvr_device.c
475 int ret, idx = 0;
476 u16 user_bvnc_u16[4];
477 u8 dot_cnt = 0;
478
479 ret = strscpy(str_cpy, param_bvnc);
480
481 /*
482 * strscpy() should return at least a size 7 for the input to be valid.
483 * Returns -E2BIG for the case when the string is empty or too long.
484 */--> 485 if (ret < PVR_GPUID_STRING_MIN_LENGTH) {
PVR_GPUID_STRING_MIN_LENGTH is unsigned so -E2BIG is type promoted to positive and treated as success.
486 drm_info(drm_dev,
487 "Invalid size of the input GPU ID (BVNC): %s",
488 str_cpy);
489 return -EINVAL;
490 }
491
492 while (*param_bvnc) {
493 if (*param_bvnc == '.')
494 dot_cnt++;
495 param_bvnc++;
496 }regards,
dan carpenter
[bug report] ASoC: SOF: ipc4-control: Add support for generic bytes control
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Peter Ujfalusi,
Commit 2a28b5240f2b ("ASoC: SOF: ipc4-control: Add support for generic bytes control") from Dec 17, 2025 (linux-next), leads to the following Smatch static checker warning:
sound/soc/sof/ipc4-control.c:365 sof_ipc4_refresh_bytes_control() warn: missing error code here? '_dev_err()' failed. 'ret' = '0'
sound/soc/sof/ipc4-control.c
324 static int
325 sof_ipc4_refresh_bytes_control(struct snd_sof_control *scontrol, bool lock)
326 {
327 struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data;
328 struct snd_soc_component *scomp = scontrol->scomp;
329 struct sof_ipc4_control_msg_payload *msg_data;
330 struct sof_abi_hdr *data = cdata->data;
331 struct sof_ipc4_msg *msg = &cdata->msg;
332 size_t data_size;
333 int ret = 0;
334
335 if (!scontrol->comp_data_dirty)
336 return 0;
337
338 if (!pm_runtime_active(scomp->dev))
339 return 0;
340
341 data_size = scontrol->max_size - sizeof(*data);
342 if (data_size < sizeof(*msg_data))
343 data_size = sizeof(*msg_data);
344
345 msg_data = kzalloc(data_size, GFP_KERNEL);
346 if (!msg_data)
347 return -ENOMEM;
348
349 msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(data->type);
350
351 msg_data->id = cdata->index;
352 msg_data->num_elems = 0; /* ignored for bytes */
353
354 msg->data_ptr = msg_data;
355 msg->data_size = data_size;
356
357 scontrol->comp_data_dirty = false;
358 ret = sof_ipc4_set_get_kcontrol_data(scontrol, false, lock);
359 if (!ret) {
360 if (msg->data_size > scontrol->max_size - sizeof(*data)) {
361 dev_err(scomp->dev,
362 "%s: no space for data in %s (%zu, %zu)\n",
363 __func__, scontrol->name, msg->data_size,
364 scontrol->max_size - sizeof(*data));--> 365 goto out;
ret = -EINVAL;
366 }
367
368 data->size = msg->data_size;
369 scontrol->size = sizeof(*cdata) + sizeof(*data) + data->size;
370 memcpy(data->data, msg->data_ptr, data->size);
371 } else {
372 dev_err(scomp->dev, "Failed to read control data for %s\n",
373 scontrol->name);
374 scontrol->comp_data_dirty = true;
375 }
376
377 out:
378 msg->data_ptr = NULL;
379 msg->data_size = 0;
380
381 kfree(msg_data);
382
383 return ret;
384 }regards,
dan carpenter
[bug report] media: iris: gen1: Destroy internal buffers after FW releases
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Dikshita Agarwal,
Commit 1dabf00ee206 ("media: iris: gen1: Destroy internal buffers after FW releases") from Dec 29, 2025 (linux-next), leads to the following Smatch static checker warning:
drivers/media/platform/qcom/iris/iris_buffer.c:588 iris_release_internal_buffers()
error: dereferencing freed memory 'buffer' (line 585)
drivers/media/platform/qcom/iris/iris_buffer.c
572 static int iris_release_internal_buffers(struct iris_inst *inst,
573 enum iris_buffer_type buffer_type)
574 {
575 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
576 struct iris_buffers *buffers = &inst->buffers[buffer_type];
577 struct iris_buffer *buffer, *next;
578 int ret;
579
580 list_for_each_entry_safe(buffer, next, &buffers->list, list) {
581 if (buffer->attr & BUF_ATTR_PENDING_RELEASE)
582 continue;
583 if (!(buffer->attr & BUF_ATTR_QUEUED))
584 continue;
585 ret = hfi_ops->session_release_buf(inst, buffer);The commit adds a free of buffer to ->session_release_buf().
586 if (ret)
587 return ret;
--> 588 buffer->attr |= BUF_ATTR_PENDING_RELEASE;
^^^^^^^^^^^^Use after free.
589 }
590
591 return 0;
592 }regards,
dan carpenter
[bug report] cifs: Fix locking usage for tcon fields
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Shyam Prasad N,
Commit 91c866a6abb0 ("cifs: Fix locking usage for tcon fields") from Feb 1, 2026 (linux-next), leads to the following Smatch static checker warning:
fs/smb/client/smb2ops.c:3179 smb2_get_dfs_refer() error: dereferencing freed memory 'tcon' (line 3178)
fs/smb/client/smb2ops.c
3079 static int
3080 smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses,
3081 const char *search_name,
3082 struct dfs_info3_param **target_nodes,
3083 unsigned int *num_of_nodes,
3084 const struct nls_table *nls_codepage, int remap)
3085 {
3086 int rc;
3087 __le16 *utf16_path = NULL;
3088 int utf16_path_len = 0;
3089 struct cifs_tcon *tcon;
3090 struct fsctl_get_dfs_referral_req *dfs_req = NULL;
3091 struct get_dfs_referral_rsp *dfs_rsp = NULL;
3092 u32 dfs_req_size = 0, dfs_rsp_size = 0;
3093 int retry_once = 0;
3094
3095 cifs_dbg(FYI, "%s: path: %s\n", __func__, search_name);
3096
3097 /*
3098 * Try to use the IPC tcon, otherwise just use any
3099 */
3100 tcon = ses->tcon_ipc;
3101 if (tcon == NULL) {
3102 spin_lock(&cifs_tcp_ses_lock);
3103 tcon = list_first_entry_or_null(&ses->tcon_list,
3104 struct cifs_tcon,
3105 tcon_list);
3106 if (tcon) {
3107 spin_lock(&tcon->tc_lock);
3108 tcon->tc_count++;
3109 spin_unlock(&tcon->tc_lock);
3110 trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
3111 netfs_trace_tcon_ref_get_dfs_refer);
3112 }
3113 spin_unlock(&cifs_tcp_ses_lock);
3114 }
3115
3116 if (tcon == NULL) {
3117 cifs_dbg(VFS, "session %p has no tcon available for a dfs referral request\n",
3118 ses);
3119 rc = -ENOTCONN;
3120 goto out;
3121 }
3122
3123 utf16_path = cifs_strndup_to_utf16(search_name, PATH_MAX,
3124 &utf16_path_len,
3125 nls_codepage, remap);
3126 if (!utf16_path) {
3127 rc = -ENOMEM;
3128 goto out;
3129 }
3130
3131 dfs_req_size = sizeof(*dfs_req) + utf16_path_len;
3132 dfs_req = kzalloc(dfs_req_size, GFP_KERNEL);
3133 if (!dfs_req) {
3134 rc = -ENOMEM;
3135 goto out;
3136 }
3137
3138 /* Highest DFS referral version understood */
3139 dfs_req->MaxReferralLevel = DFS_VERSION;
3140
3141 /* Path to resolve in an UTF-16 null-terminated string */
3142 memcpy(dfs_req->RequestFileName, utf16_path, utf16_path_len);
3143
3144 for (;;) {
3145 rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID,
3146 FSCTL_DFS_GET_REFERRALS,
3147 (char *)dfs_req, dfs_req_size, CIFSMaxBufSize,
3148 (char **)&dfs_rsp, &dfs_rsp_size);
3149 if (fatal_signal_pending(current)) {
3150 rc = -EINTR;
3151 break;
3152 }
3153 if (!is_retryable_error(rc) || retry_once++)
3154 break;
3155 usleep_range(512, 2048);
3156 }
3157
3158 if (!rc && !dfs_rsp)
3159 rc = smb_EIO(smb_eio_trace_dfsref_no_rsp);
3160 if (rc) {
3161 if (!is_retryable_error(rc) && rc != -ENOENT && rc != -EOPNOTSUPP)
3162 cifs_tcon_dbg(FYI, "%s: ioctl error: rc=%d\n", __func__, rc);
3163 goto out;
3164 }
3165
3166 rc = parse_dfs_referrals(dfs_rsp, dfs_rsp_size,
3167 num_of_nodes, target_nodes,
3168 nls_codepage, remap, search_name,
3169 true /* is_unicode */);
3170 if (rc && rc != -ENOENT) {
3171 cifs_tcon_dbg(VFS, "%s: failed to parse DFS referral %s: %d\n",
3172 __func__, search_name, rc);
3173 }
3174
3175 out:
3176 if (tcon && !tcon->ipc) {
3177 /* ipc tcons are not refcounted */
3178 cifs_put_tcon(tcon, netfs_trace_tcon_ref_put_dfs_refer);
^^^^This free
--> 3179 trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
needs to happen after these dereferences.
3180 netfs_trace_tcon_ref_dec_dfs_refer);
3181 }
3182 kfree(utf16_path);
3183 kfree(dfs_req);
3184 kfree(dfs_rsp);
3185 return rc;
3186 }regards,
dan carpenter
[bug report] drm/xe: Avoid toggling schedule state to check LRC timestamp in TDR
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Matthew Brost,
Commit bb63e7257e63 ("drm/xe: Avoid toggling schedule state to check LRC timestamp in TDR") from Jan 9, 2026 (linux-next), leads to the following Smatch static checker warning:
drivers/gpu/drm/xe/xe_lrc.c:2450 xe_lrc_timestamp() error: uninitialized symbol 'new_ts'.
drivers/gpu/drm/xe/xe_lrc.c
2421 u64 xe_lrc_timestamp(struct xe_lrc *lrc)
2422 {
2423 u64 lrc_ts, reg_ts, new_ts;
2424 u32 engine_id;
2425
2426 lrc_ts = xe_lrc_ctx_timestamp(lrc);
2427 /* CTX_TIMESTAMP mmio read is invalid on VF, so return the LRC value */
2428 if (IS_SRIOV_VF(lrc_to_xe(lrc))) {
2429 new_ts = lrc_ts;
2430 goto done;
2431 }
2432
2433 if (lrc_ts == CONTEXT_ACTIVE) {
2434 engine_id = xe_lrc_engine_id(lrc);
2435 if (!get_ctx_timestamp(lrc, engine_id, ®_ts))
2436 new_ts = reg_ts;Imagine lrc_ts is active but get_ctx_timestamp() returns -1.
2437
2438 /* read lrc again to ensure context is still active */
2439 lrc_ts = xe_lrc_ctx_timestamp(lrc);
2440 }
2441
2442 /*
2443 * If context switched out, just use the lrc_ts. Note that this needs to
2444 * be a separate if condition.
2445 */
2446 if (lrc_ts != CONTEXT_ACTIVE)
2447 new_ts = lrc_ts;
2448
2449 done:--> 2450 return new_ts;
Then new_ts could be uninitialized.
2451 }
regards,
dan carpenter
[bug report] iio: dac: adding support for Microchip MCP47FEB02
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Ariana Lazar,
Commit bf394cc80369 ("iio: dac: adding support for Microchip MCP47FEB02") from Dec 16, 2025 (linux-next), leads to the following Smatch static checker warning:
drivers/iio/dac/mcp47feb02.c:732 mcp47feb02_init_scales_avail() warn: passing zero to 'dev_err_probe'
drivers/iio/dac/mcp47feb02.c
712 static int mcp47feb02_init_scales_avail(struct mcp47feb02_data *data, int vdd_mV,
713 int vref_mV, int vref1_mV)
714 {
715 struct device *dev = regmap_get_device(data->regmap);
716 int tmp_vref;
717
718 mcp47feb02_init_scale(data, MCP47FEB02_SCALE_VDD, vdd_mV, data->scale);
719
720 if (data->use_vref)
721 tmp_vref = vref_mV;
722 else
723 tmp_vref = MCP47FEB02_INTERNAL_BAND_GAP_mV;
724
725 mcp47feb02_init_scale(data, MCP47FEB02_SCALE_GAIN_X1, tmp_vref, data->scale);
726 mcp47feb02_init_scale(data, MCP47FEB02_SCALE_GAIN_X2, tmp_vref * 2, data->scale);
727
728 if (data->phys_channels >= 4) {
729 mcp47feb02_init_scale(data, MCP47FEB02_SCALE_VDD, vdd_mV, data->scale_1);
730
731 if (data->use_vref1 && vref1_mV <= 0)
--> 732 return dev_err_probe(dev, vref1_mV, "Invalid voltage for Vref1\n");
^^^^^^^^vref1_mV is not a valid error code. Return -EINVAL.
733
734 if (data->use_vref1)
735 tmp_vref = vref1_mV;
736 else
737 tmp_vref = MCP47FEB02_INTERNAL_BAND_GAP_mV;
738
739 mcp47feb02_init_scale(data, MCP47FEB02_SCALE_GAIN_X1,
740 tmp_vref, data->scale_1);
741 mcp47feb02_init_scale(data, MCP47FEB02_SCALE_GAIN_X2,
742 tmp_vref * 2, data->scale_1);
743 }
744
745 return 0;
746 }regards,
dan carpenter
Re: [bug report] iio: dac: adding support for Microchip MCP47FEB02
Quoted 11 lines · Dan Carpenter
[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]Hello Ariana Lazar,
Commit
bf394cc80369("iio: dac: adding support for Microchip MCP47FEB02") from Dec 16, 2025 (linux-next), leads to the following Smatch static checker warning:drivers/iio/dac/mcp47feb02.c:732 mcp47feb02_init_scales_avail() warn: passing zero to 'dev_err_probe'
Btw, why the bot mangles the patch, please?
Adding leading information (line number and some other markings) should not mangle the code (tab-based indentation).
Quoted 23 lines
drivers/iio/dac/mcp47feb02.c712 static int mcp47feb02_init_scales_avail(struct mcp47feb02_data *data, int vdd_mV, 713 int vref_mV, int vref1_mV) 714 { 715 struct device *dev = regmap_get_device(data->regmap); 716 int tmp_vref; 717 718 mcp47feb02_init_scale(data, MCP47FEB02_SCALE_VDD, vdd_mV, data->scale); 719 720 if (data->use_vref) 721 tmp_vref = vref_mV; 722 else 723 tmp_vref = MCP47FEB02_INTERNAL_BAND_GAP_mV; 724 725 mcp47feb02_init_scale(data, MCP47FEB02_SCALE_GAIN_X1, tmp_vref, data->scale); 726 mcp47feb02_init_scale(data, MCP47FEB02_SCALE_GAIN_X2, tmp_vref * 2, data->scale); 727 728 if (data->phys_channels >= 4) { 729 mcp47feb02_init_scale(data, MCP47FEB02_SCALE_VDD, vdd_mV, data->scale_1); 730 731 if (data->use_vref1 && vref1_mV <= 0) --> 732 return dev_err_probe(dev, vref1_mV, "Invalid voltage for Vref1\n"); ^^^^^^^^
Quoted 1 line
vref1_mVis not a valid error code.
Why not? When it's negative I believe the above statement is not true.
Quoted 1 line
Return
-EINVAL.
Probably true for the == 0 case.
With the above, this probably should be
Quoted 4 lines
734 if (data->use_vref1)
735 tmp_vref = vref1_mV;
736 else
737 tmp_vref = MCP47FEB02_INTERNAL_BAND_GAP_mV; if (data->use_vref1) {
if (vref1_mV < 0)
return dev_err_probe(dev, vref1_mV, "Can't get voltage for Vref1\n");
if (vref1_mV == 0)
return dev_err_probe(dev, -ERANGE, "Invalid voltage for Vref1\n");
// or -EINVAL?
tmp_vref = vref1_mV;
} else {
tmp_vref = MCP47FEB02_INTERNAL_BAND_GAP_mV;
}Quoted 8 lines
739 mcp47feb02_init_scale(data, MCP47FEB02_SCALE_GAIN_X1,
740 tmp_vref, data->scale_1);
741 mcp47feb02_init_scale(data, MCP47FEB02_SCALE_GAIN_X2,
742 tmp_vref * 2, data->scale_1);
743 }
744
745 return 0;
746 }Signature · 2 lines
With Best Regards, Andy Shevchenko
Re: [bug report] iio: dac: adding support for Microchip MCP47FEB02
Quoted 25 lines · Andy Shevchenko
Quoted 23 lines
drivers/iio/dac/mcp47feb02.c712 static int mcp47feb02_init_scales_avail(struct mcp47feb02_data *data, int vdd_mV, 713 int vref_mV, int vref1_mV) 714 { 715 struct device *dev = regmap_get_device(data->regmap); 716 int tmp_vref; 717 718 mcp47feb02_init_scale(data, MCP47FEB02_SCALE_VDD, vdd_mV, data->scale); 719 720 if (data->use_vref) 721 tmp_vref = vref_mV; 722 else 723 tmp_vref = MCP47FEB02_INTERNAL_BAND_GAP_mV; 724 725 mcp47feb02_init_scale(data, MCP47FEB02_SCALE_GAIN_X1, tmp_vref, data->scale); 726 mcp47feb02_init_scale(data, MCP47FEB02_SCALE_GAIN_X2, tmp_vref * 2, data->scale); 727 728 if (data->phys_channels >= 4) { 729 mcp47feb02_init_scale(data, MCP47FEB02_SCALE_VDD, vdd_mV, data->scale_1); 730 731 if (data->use_vref1 && vref1_mV <= 0) --> 732 return dev_err_probe(dev, vref1_mV, "Invalid voltage for Vref1\n"); ^^^^^^^^Quoted 1 line
vref1_mVis not a valid error code.
Quoted 2 lines
Why not? When it's negative I believe the above statement is not true.
I saw this as just sanity checking the input. vref1_mV is never actually negative. I don't know if devm_regulator_get_enable_read_voltage() can return less than one millivolt.
regards,
dan carpenter
Re: [bug report] iio: dac: adding support for Microchip MCP47FEB02
Quoted 26 lines · Dan Carpenter
Quoted 25 lines · Andy Shevchenko
Quoted 24 lines
drivers/iio/dac/mcp47feb02.c712 static int mcp47feb02_init_scales_avail(struct mcp47feb02_data *data, int vdd_mV, 713 int vref_mV, int vref1_mV) 714 { 715 struct device *dev = regmap_get_device(data->regmap); 716 int tmp_vref; 717 718 mcp47feb02_init_scale(data, MCP47FEB02_SCALE_VDD, vdd_mV, data->scale); 719 720 if (data->use_vref) 721 tmp_vref = vref_mV; 722 else 723 tmp_vref = MCP47FEB02_INTERNAL_BAND_GAP_mV; 724 725 mcp47feb02_init_scale(data, MCP47FEB02_SCALE_GAIN_X1, tmp_vref, data->scale); 726 mcp47feb02_init_scale(data, MCP47FEB02_SCALE_GAIN_X2, tmp_vref * 2, data->scale); 727 728 if (data->phys_channels >= 4) { 729 mcp47feb02_init_scale(data, MCP47FEB02_SCALE_VDD, vdd_mV, data->scale_1); 730 731 if (data->use_vref1 && vref1_mV <= 0) --> 732 return dev_err_probe(dev, vref1_mV, "Invalid voltage for Vref1\n"); ^^^^^^^^
vref1_mVis not a valid error code.
Quoted 5 lines
Quoted 1 line
Why not? When it's negative I believe the above statement is not true.
I saw this as just sanity checking the input.
vref1_mVis never actually negative. I don't know ifdevm_regulator_get_enable_read_voltage()can return less than one millivolt.
* In cases where the supply is not strictly required, callers can check for
* -ENODEV error and handle it accordingly.
*
* Returns: voltage in microvolts on success, or an negative error number on failure.
What did I miss?
Signature · 2 lines
With Best Regards, Andy Shevchenko
Re: [bug report] iio: dac: adding support for Microchip MCP47FEB02
Quoted 33 lines · Andy Shevchenko
Quoted 26 lines · Dan Carpenter
Quoted 25 lines · Andy Shevchenko
Quoted 24 lines
drivers/iio/dac/mcp47feb02.c712 static int mcp47feb02_init_scales_avail(struct mcp47feb02_data *data, int vdd_mV, 713 int vref_mV, int vref1_mV) 714 { 715 struct device *dev = regmap_get_device(data->regmap); 716 int tmp_vref; 717 718 mcp47feb02_init_scale(data, MCP47FEB02_SCALE_VDD, vdd_mV, data->scale); 719 720 if (data->use_vref) 721 tmp_vref = vref_mV; 722 else 723 tmp_vref = MCP47FEB02_INTERNAL_BAND_GAP_mV; 724 725 mcp47feb02_init_scale(data, MCP47FEB02_SCALE_GAIN_X1, tmp_vref, data->scale); 726 mcp47feb02_init_scale(data, MCP47FEB02_SCALE_GAIN_X2, tmp_vref * 2, data->scale); 727 728 if (data->phys_channels >= 4) { 729 mcp47feb02_init_scale(data, MCP47FEB02_SCALE_VDD, vdd_mV, data->scale_1); 730 731 if (data->use_vref1 && vref1_mV <= 0) --> 732 return dev_err_probe(dev, vref1_mV, "Invalid voltage for Vref1\n"); ^^^^^^^^
vref1_mVis not a valid error code.Quoted 5 lines
Quoted 1 line
Why not? When it's negative I believe the above statement is not true.
I saw this as just sanity checking the input.
vref1_mVis never actually negative. I don't know ifdevm_regulator_get_enable_read_voltage()can return less than one millivolt.
Quoted 7 lines
* In cases where the supply is not strictly required, callers can check for
*-ENODEVerror and handle it accordingly.
*
* Returns: voltage in microvolts on success, or an negative error number on failure.What did I miss?
drivers/iio/dac/mcp47feb02.c
1157 if (chip_features->have_ext_vref1) {
1158 ret = devm_regulator_get_enable_read_voltage(dev, "vref1");
1159 if (ret > 0) {
1160 vref1_mV = ret / MILLI;
Potentially, if ret is in the 1-999 range then vref1_mV could be zero, but it can't be negative.
1161 data->use_vref1 = true;
1162 } else {
1163 dev_dbg(dev, "using internal band gap as voltage reference 1.\n");
1164 dev_dbg(dev, "Vref1 is unavailable.\n");
1165 }
1166 }
1167
1168 ret = mcp47feb02_init_ctrl_regs(data);
1169 if (ret)
1170 return dev_err_probe(dev, ret, "Error initialising vref register\n");
1171
1172 ret = mcp47feb02_init_ch_scales(data, vdd_mV, vref_mV, vref1_mV);
^^^^^^^^ 1173 if (ret)
1174 return ret;
regards,
dan carpenter
Re: [bug report] iio: dac: adding support for Microchip MCP47FEB02
Quoted 42 lines · Dan Carpenter
Quoted 33 lines · Andy Shevchenko
Quoted 26 lines · Dan Carpenter
Quoted 25 lines · Andy Shevchenko
Quoted 24 lines
drivers/iio/dac/mcp47feb02.c712 static int mcp47feb02_init_scales_avail(struct mcp47feb02_data *data, int vdd_mV, 713 int vref_mV, int vref1_mV) 714 { 715 struct device *dev = regmap_get_device(data->regmap); 716 int tmp_vref; 717 718 mcp47feb02_init_scale(data, MCP47FEB02_SCALE_VDD, vdd_mV, data->scale); 719 720 if (data->use_vref) 721 tmp_vref = vref_mV; 722 else 723 tmp_vref = MCP47FEB02_INTERNAL_BAND_GAP_mV; 724 725 mcp47feb02_init_scale(data, MCP47FEB02_SCALE_GAIN_X1, tmp_vref, data->scale); 726 mcp47feb02_init_scale(data, MCP47FEB02_SCALE_GAIN_X2, tmp_vref * 2, data->scale); 727 728 if (data->phys_channels >= 4) { 729 mcp47feb02_init_scale(data, MCP47FEB02_SCALE_VDD, vdd_mV, data->scale_1); 730 731 if (data->use_vref1 && vref1_mV <= 0) --> 732 return dev_err_probe(dev, vref1_mV, "Invalid voltage for Vref1\n"); ^^^^^^^^
vref1_mVis not a valid error code.Quoted 5 lines
Quoted 1 line
Why not? When it's negative I believe the above statement is not true.
I saw this as just sanity checking the input.
vref1_mVis never actually negative. I don't know ifdevm_regulator_get_enable_read_voltage()can return less than one millivolt.Quoted 7 lines
* In cases where the supply is not strictly required, callers can check for
*-ENODEVerror and handle it accordingly.
*
* Returns: voltage in microvolts on success, or an negative error number on failure.What did I miss?
Quoted 8 lines
drivers/iio/dac/mcp47feb02.c
1157 if (chip_features->have_ext_vref1) {
1158 ret =devm_regulator_get_enable_read_voltage(dev, "vref1");
1159 if (ret > 0) {
1160vref1_mV= ret / MILLI;Potentially, if ret is in the 1-999 range then
vref1_mVcould be zero, but it can't be negative.
I see, thanks!
So, it means that the validation should be moved here on ret < 0 and ret < 1000 (if positive).
Quoted 4 lines
1161 data->use_vref1 = true;
1162 } else {
1163 dev_dbg(dev, "using internal band gap as voltage reference 1.\n");
1164 dev_dbg(dev, "Vref1 is unavailable.\n");But... ret < 0 is checked here.
Hence the only one left is the range [0..999].
Quoted 12 lines
1165 } 1166 } 1167 1168 ret = mcp47feb02_init_ctrl_regs(data); 1169 if (ret) 1170 return dev_err_probe(dev, ret, "Error initialising vref register\n"); 1171 1172 ret = mcp47feb02_init_ch_scales(data, vdd_mV, vref_mV, vref1_mV); ^^^^^^^^1173 if (ret)
1174 return ret;
Signature · 2 lines
With Best Regards, Andy Shevchenko
Re: [bug report] iio: dac: adding support for Microchip MCP47FEB02
Quoted 103 lines · Andy Shevchenko
EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
Quoted 66 lines · Dan Carpenter
Quoted 48 lines · Andy Shevchenko
Quoted 38 lines · Dan Carpenter
Quoted 36 lines · Andy Shevchenko
Quoted 35 lines
drivers/iio/dac/mcp47feb02.c
712 static int mcp47feb02_init_scales_avail(structmcp47feb02_data*data, intvdd_mV,
713 intvref_mV, intvref1_mV)
714 {
715 struct device *dev =regmap_get_device(data->regmap);
716 inttmp_vref;
717
718mcp47feb02_init_scale(data, MCP47FEB02_SCALE_VDD, vdd_mV, data->scale);
719
720 if (data->use_vref)
721tmp_vref=vref_mV;
722 else
723tmp_vref=MCP47FEB02_INTERNAL_BAND_GAP_mV;
724
725mcp47feb02_init_scale(data, MCP47FEB02_SCALE_GAIN_X1, tmp_vref, data->scale); 726mcp47feb02_init_scale(data, MCP47FEB02_SCALE_GAIN_X2, tmp_vref * 2, data->scale); 727
728 if (data->phys_channels>= 4) { 729mcp47feb02_init_scale(data, MCP47FEB02_SCALE_VDD, vdd_mV, data->scale_1);
730
731 if (data->use_vref1&&vref1_mV<=
0)
--> 732 returndev_err_probe(dev, vref1_mV, "Invalid voltage for Vref1\n");
^^^^^^^^vref1_mVis not a valid error code.Quoted 8 lines
Quoted 2 lines
Why not? When it's negative I believe the above statement is not true.
I saw this as just sanity checking the input.
vref1_mVis never
actually negative. I don't know ifdevm_regulator_get_enable_read_voltage()
can return less than one millivolt.Quoted 9 lines
* In cases where the supply is not strictly required, callers can check for
*-ENODEVerror and handle it accordingly.
*
* Returns: voltage in microvolts on success, or an negative error number on failure.What did I miss?
drivers/iio/dac/mcp47feb02.c
1157 if (chip_features->have_ext_vref1) { 1158 ret =devm_regulator_get_enable_read_voltage(dev, "vref1"); 1159 if (ret > 0) {
1160vref1_mV= ret / MILLI;Quoted 3 lines
Potentially, if ret is in the 1-999 range then
vref1_mVcould be zero,
but it can't be negative.I see, thanks!
So, it means that the validation should be moved here on ret < 0 and ret < 1000 (if positive).
Quoted 6 lines
1161
data->use_vref1= true; 1162 } else {
1163dev_dbg(dev, "using internal band gap as voltage reference 1.\n");
1164dev_dbg(dev, "Vref1 is unavailable.\n");But... ret < 0 is checked here.
Hence the only one left is the range [0..999].Quoted 13 lines
1165 }
1166 }
1167
1168 ret =mcp47feb02_init_ctrl_regs(data); 1169 if (ret)
1170 returndev_err_probe(dev, ret, "Error initialising vref register\n");
1171
1172 ret =mcp47feb02_init_ch_scales(data, vdd_mV, vref_mV, vref1_mV);
^^^^^^^^
Quoted 7 lines
Quoted 2 lines
1173 if (ret)
1174 return ret;--
With Best Regards,
Andy Shevchenko
Hello Dan and Andy,
Thank you for bringing to my attention this bug. I fixed it by storing voltages
in microvolts instead of millivolts in order to avoid the [1, 999] case.
I removed dividing by MILLI from the probe function and kept the computation of
the scale values only in init_scale function.
I will send a follow on patch.
Best regards,
Ariana
Jonathan Cameron
maintainerRe: [bug report] iio: dac: adding support for Microchip MCP47FEB02
Quoted 123 lines · On Tue, 10 Feb 2026 10:26:05 +0000 <[email protected]> wrote:
Quoted 103 lines · Andy Shevchenko
EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
Quoted 66 lines · Dan Carpenter
Quoted 48 lines · Andy Shevchenko
Quoted 38 lines · Dan Carpenter
Quoted 36 lines · Andy Shevchenko
Quoted 35 lines
drivers/iio/dac/mcp47feb02.c
712 static int mcp47feb02_init_scales_avail(structmcp47feb02_data*data, intvdd_mV,
713 intvref_mV, intvref1_mV)
714 {
715 struct device *dev =regmap_get_device(data->regmap);
716 inttmp_vref;
717
718mcp47feb02_init_scale(data, MCP47FEB02_SCALE_VDD, vdd_mV, data->scale);
719
720 if (data->use_vref)
721tmp_vref=vref_mV;
722 else
723tmp_vref=MCP47FEB02_INTERNAL_BAND_GAP_mV;
724
725mcp47feb02_init_scale(data, MCP47FEB02_SCALE_GAIN_X1, tmp_vref, data->scale); 726mcp47feb02_init_scale(data, MCP47FEB02_SCALE_GAIN_X2, tmp_vref * 2, data->scale); 727
728 if (data->phys_channels>= 4) { 729mcp47feb02_init_scale(data, MCP47FEB02_SCALE_VDD, vdd_mV, data->scale_1);
730
731 if (data->use_vref1&&vref1_mV<=
0)
--> 732 returndev_err_probe(dev, vref1_mV, "Invalid voltage for Vref1\n");
^^^^^^^^vref1_mVis not a valid error code.Quoted 8 lines
Quoted 2 lines
Why not? When it's negative I believe the above statement is not true.
I saw this as just sanity checking the input.
vref1_mVis never
actually negative. I don't know ifdevm_regulator_get_enable_read_voltage()
can return less than one millivolt.Quoted 9 lines
* In cases where the supply is not strictly required, callers can check for
*-ENODEVerror and handle it accordingly.
*
* Returns: voltage in microvolts on success, or an negative error number on failure.What did I miss?
drivers/iio/dac/mcp47feb02.c
1157 if (chip_features->have_ext_vref1) { 1158 ret =devm_regulator_get_enable_read_voltage(dev, "vref1"); 1159 if (ret > 0) {
1160vref1_mV= ret / MILLI;Quoted 3 lines
Potentially, if ret is in the 1-999 range then
vref1_mVcould be zero,
but it can't be negative.I see, thanks!
So, it means that the validation should be moved here on ret < 0 and ret < 1000 (if positive).
Quoted 6 lines
1161
data->use_vref1= true; 1162 } else {
1163dev_dbg(dev, "using internal band gap as voltage reference 1.\n");
1164dev_dbg(dev, "Vref1 is unavailable.\n");But... ret < 0 is checked here.
Hence the only one left is the range [0..999].Quoted 13 lines
1165 }
1166 }
1167
1168 ret =mcp47feb02_init_ctrl_regs(data); 1169 if (ret)
1170 returndev_err_probe(dev, ret, "Error initialising vref register\n");
1171
1172 ret =mcp47feb02_init_ch_scales(data, vdd_mV, vref_mV, vref1_mV);
^^^^^^^^Quoted 7 lines
Quoted 2 lines
1173 if (ret)
1174 return ret;--
With Best Regards,
Andy ShevchenkoHello Dan and Andy,
Thank you for bringing to my attention this bug. I fixed it by storing voltages
in microvolts instead of millivolts in order to avoid the [1, 999] case.
I removed dividing by MILLI from the probe function and kept the computation of
the scale values only ininit_scalefunction.
Quoted 1 line
I will send a follow on patch.
Hi Ariana,
Just a reminder that this one still seems to be outstanding. Maybe I missed a patch?
Thanks,
Jonathan
Quoted 4 lines
Best regards,
Ariana
Re: [bug report] iio: dac: adding support for Microchip MCP47FEB02
Quoted 13 lines
Just a reminder that this one still seems to be outstanding. Maybe I missed a patch?
Thanks,
Jonathan
Quoted 4 lines
Best regards,
Ariana
Hi Jonathan,
Given the latest reviews, I was wondering how do you prefer the next patch to be sent. At the moment I am working on the version with three modules in order to include both protocol families. If you prefer, I will firstly send a patch to fix these bugs for MCP47FEB02 and then I will send another one with the combined implementation.
Best regards,
Ariana
Jonathan Cameron
maintainerRe: [bug report] iio: dac: adding support for Microchip MCP47FEB02
Quoted 13 lines · On Mon, 2 Mar 2026 10:28:04 +0000 <[email protected]> wrote:
Quoted 12 lines
Just a reminder that this one still seems to be outstanding. Maybe I missed a patch?
Thanks,
Jonathan
Quoted 4 lines
Best regards,
Ariana
Quoted 7 lines
Hi Jonathan,
Given the latest reviews, I was wondering how do you prefer the next patch to be sent. At the moment I am working on the version with three modules in order to include both protocol families. If you prefer, I will firstly send a patch to fix these bugs for MCP47FEB02 and then I will send another one with the combined implementation.
That last option sounds like the right approach. The fix will need to go upstream first, then once that's available in upstream I can merge into the togreg branch and apply new stuff on top of it.
Thanks,
Jonathan
Quoted 3 lines
Best regards,
Ariana
[bug report] power: sequencing: qcom-wcn: add support for WCN39xx
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Dmitry Baryshkov,
Commit 0eb85f468ef5 ("power: sequencing: qcom-wcn: add support for WCN39xx") from Jan 6, 2026 (linux-next), leads to the following Smatch static checker warning:
drivers/power/sequencing/pwrseq-qcom-wcn.c:492 pwrseq_qcom_wcn_probe()
warn: passing zero to 'dev_err_probe'
drivers/power/sequencing/pwrseq-qcom-wcn.c
458 static int pwrseq_qcom_wcn_probe(struct platform_device *pdev)
459 {
460 struct device *dev = &pdev->dev;
461 struct pwrseq_qcom_wcn_ctx *ctx;
462 struct pwrseq_config config;
463 int i, ret;
464
465 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
466 if (!ctx)
467 return -ENOMEM;
468
469 ctx->of_node = dev->of_node;
470
471 ctx->pdata = device_get_match_data(dev);
472 if (!ctx->pdata)
473 return dev_err_probe(dev, -ENODEV,
474 "Failed to obtain platform data\n");
475
476 ctx->regs = devm_kcalloc(dev, ctx->pdata->num_vregs,
477 sizeof(*ctx->regs), GFP_KERNEL);
478 if (!ctx->regs)
479 return -ENOMEM;
480
481 for (i = 0; i < ctx->pdata->num_vregs; i++)
482 ctx->regs[i].supply = ctx->pdata->vregs[i];
483
484 ret = devm_regulator_bulk_get(dev, ctx->pdata->num_vregs, ctx->regs);
485 if (ret < 0)
486 return dev_err_probe(dev, ret,
487 "Failed to get all regulators\n");
488
489 if (ctx->pdata->has_vddio) {
490 ctx->vddio = devm_regulator_get(dev, "vddio");
491 if (IS_ERR(ctx->vddio))--> 492 return dev_err_probe(dev, ret, "Failed to get VDDIO\n");
s/ret/PTR_ERR(ctx->vddio)/
493 }
494
495 ctx->bt_gpio = devm_gpiod_get_optional(dev, "bt-enable", GPIOD_OUT_LOW);
496 if (IS_ERR(ctx->bt_gpio))
497 return dev_err_probe(dev, PTR_ERR(ctx->bt_gpio),
498 "Failed to get the Bluetooth enable GPIO\n");
499
500 /*regards,
dan carpenter
[bug report] io_uring: add task fork hook
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Jens Axboe,
Commit 4f08520591a2 ("io_uring: add task fork hook") from Jan 16, 2026 (linux-next), leads to the following Smatch static checker warning:
kernel/fork.c:2544 copy_process() warn: passing zero to 'ERR_PTR'
kernel/fork.c
2128 #ifdef CONFIG_IO_URING
2129 p->io_uring = NULL;
2130 retval = io_uring_fork(p);
The patch added this assignment.
2131 if (unlikely(retval))
2132 goto bad_fork_cleanup_delayacct;
2133 #endif
2134
2135 p->default_timer_slack_ns = current->timer_slack_ns;
2136
2137 #ifdef CONFIG_PSI
2138 p->psi_flags = 0;
2139 #endif
2140
2141 task_io_accounting_init(&p->ioac);
2142 acct_clear_integrals(p);
2143
2144 posix_cputimers_init(&p->posix_cputimers);
2145 tick_dep_init_task(p);
2146
2147 p->io_context = NULL;
2148 audit_set_context(p, NULL);
2149 cgroup_fork(p);
2150 if (args->kthread) {
2151 if (!set_kthread_struct(p))
2152 goto bad_fork_cleanup_delayacct;So now retval is success where previously it had been -EAGAIN
2153 }
regards,
dan carpenter
Jens Axboe
maintainerRe: [bug report] io_uring: add task fork hook
Quoted 42 lines · Dan Carpenter
[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]Hello Jens Axboe,
Commit
4f08520591a2("io_uring: add task fork hook") from Jan 16, 2026 (linux-next), leads to the following Smatch static checker warning:kernel/fork.c:2544 copy_process() warn: passing zero to 'ERR_PTR'
kernel/fork.c
2128 #ifdefCONFIG_IO_URING
2129p->io_uring= NULL;
2130 retval =io_uring_fork(p);The patch added this assignment.
2131 if (unlikely(retval)) 2132 goto bad_fork_cleanup_delayacct; 2133 #endif 2134 2135 p->default_timer_slack_ns = current->timer_slack_ns; 2136 2137 #ifdef CONFIG_PSI 2138 p->psi_flags = 0; 2139 #endif 2140 2141 task_io_accounting_init(&p->ioac); 2142 acct_clear_integrals(p); 2143 2144 posix_cputimers_init(&p->posix_cputimers); 2145 tick_dep_init_task(p); 2146 2147 p->io_context = NULL; 2148 audit_set_context(p, NULL); 2149 cgroup_fork(p); 2150 if (args->kthread) { 2151 if (!set_kthread_struct(p)) 2152 goto bad_fork_cleanup_delayacct;
Quoted 3 lines
So now retval is success where previously it had been
-EAGAIN2153 }
Thanks, fixed up.
Signature · 1 line
Jens Axboe
[bug report] ACPI: battery: Adjust event notification routine
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Rafael J. Wysocki,
This is a semi-automatic email about new static checker warnings.
Commit 08b54fd57782 ("ACPI: battery: Adjust event notification routine") from Dec 15, 2025, leads to the following Smatch complaint:
drivers/acpi/battery.c:1062 acpi_battery_notify()
warn: variable dereferenced before check 'battery' (see line 1059)
drivers/acpi/battery.c
1058 struct acpi_battery *battery = data;
1059 struct acpi_device *device = battery->device;
^^^^^^^^^^^^^^^The patch adds a dereference.
1060 struct power_supply *old;
1061
1062 if (!battery)
^^^^^^^^
Checked too late.
1063 return;
1064
regards,
dan carpenter
Rafael J. Wysocki
maintainerPATCH 1/1 ACPI: battery: Drop redundant check from acpi_battery_notify()
Quoted 20 lines · CET Dan Carpenter
[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]Hello Rafael J. Wysocki,
This is a semi-automatic email about new static checker warnings.
Commit
08b54fd57782("ACPI: battery: Adjust event notification routine") from Dec 15, 2025, leads to the following Smatch complaint:
drivers/acpi/battery.c:1062acpi_battery_notify()
warn: variable dereferenced before check 'battery' (see line 1059)
drivers/acpi/battery.c
1058 structacpi_battery*battery = data;1059 struct acpi_device *device = battery->device; ^^^^^^^^^^^^^^^The patch adds a dereference.
Quoted 8 lines
1060 struct
power_supply*old;
1061
1062 if (!battery)^^^^^^^^Checked too late.
1063 return;
1064
Thanks for the report, but the check above is redundant.
For the reason explained in the changelog of the patch below, the battery pointer above cannot be NULL.
---
From: Rafael J. Wysocki <[email protected]>
Subject: [PATCH v1] ACPI: battery: Drop redundant check from acpi_battery_notify()
The battery pointer check against NULL in acpi_battery_notify() is redundant because the value of that pointer is the one passed to acpi_dev_install_notify_handler() in acpi_battery_probe() as the last argument which is not NULL.
Drop the redundant check.
No intentional functional impact.
--- drivers/acpi/battery.c | 3 --- 1 file changed, 3 deletions(-)
drivers/acpi/battery.c +0 -3
@@ -1066,9 +1066,6 @@ static void acpi_battery_notify(acpi_hanstruct acpi_device *device = battery->device;struct power_supply *old; -if (!battery) -return ; -guard (mutex)(&battery->update_lock); old = battery->bat;
[bug report] iio: adc: Add support for ad4062
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Jorge Marques,
Commit d5284402d28f ("iio: adc: Add support for ad4062") from Dec 17, 2025 (linux-next), leads to the following Smatch static checker warning:
drivers/iio/adc/ad4062.c:1557 ad4062_probe() warn: passing positive error code 's32min-(-1),1-3' to 'dev_err_probe'
drivers/iio/adc/ad4062.c
1547 pm_runtime_set_active(dev);
1548 ret = devm_pm_runtime_enable(dev);
1549 if (ret)
1550 return dev_err_probe(dev, ret, "Failed to enable pm_runtime\n");
1551
1552 pm_runtime_set_autosuspend_delay(dev, 1000);
1553 pm_runtime_use_autosuspend(dev);
1554
1555 ret = ad4062_request_ibi(i3cdev);
1556 if (ret)--> 1557 return dev_err_probe(dev, ret, "Failed to request i3c ibi\n");
The comments for ad4062_request_ibi() say it returns negative error codes but the comments for i3c_master_enec_locked() say it returns "a positive I3C error code if the error is one of the official Mx error codes, and a negative error code otherwise."
1558
1559 ret = ad4062_gpio_init(st);
1560 if (ret)
1561 return ret;
1562
1563 ret = devm_work_autocancel(dev, &st->trig_conv, ad4062_trigger_work);
1564 if (ret)
1565 return ret;
1566
1567 return devm_iio_device_register(dev, indio_dev);
1568 }regards,
dan carpenter
Re: [bug report] iio: adc: Add support for ad4062
Quoted 2 lines · Dan Carpenter
[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Oh, this is indeed sad. Wondering if LF can donate...
Quoted 9 lines
Commit
d5284402d28f("iio: adc: Add support for ad4062") from Dec 17, 2025 (linux-next), leads to the following Smatch static checker warning:drivers/iio/adc/ad4062.c:1557 ad4062_probe() warn: passing positive error code 's32min-(-1),1-3' to 'dev_err_probe' 1555 ret = ad4062_request_ibi(i3cdev); 1556 if (ret)
if (ret < 0)
resolves immediate isssue, but...
Quoted 6 lines
--> 1557 return
dev_err_probe(dev, ret, "Failed to request i3c ibi\n");The comments for
ad4062_request_ibi()say it returns negative error codes but the comments fori3c_master_enec_locked()say it returns "a positive I3C error code if the error is one of the official Mx error codes, and a negative error code otherwise."
...would be nice to have a conversion helper to get Linux error codes from the Mx ones.
Signature · 2 lines
With Best Regards, Andy Shevchenko
Jonathan Cameron
maintainerRe: [bug report] iio: adc: Add support for ad4062
Quoted 22 lines · On Fri, 6 Feb 2026 16:07:36 +0200 Andy Shevchenko…
Quoted 2 lines · Dan Carpenter
[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]Oh, this is indeed sad. Wondering if LF can donate...
Quoted 9 lines
Commit
d5284402d28f("iio: adc: Add support for ad4062") from Dec 17, 2025 (linux-next), leads to the following Smatch static checker warning:drivers/iio/adc/ad4062.c:1557 ad4062_probe() warn: passing positive error code 's32min-(-1),1-3' to 'dev_err_probe' 1555 ret = ad4062_request_ibi(i3cdev); 1556 if (ret)if (ret < 0)resolves immediate isssue, but...
Quoted 2 lines
--> 1557 return
dev_err_probe(dev, ret, "Failed to request i3c ibi\n");
Quoted 8 lines
Quoted 4 lines
The comments for
ad4062_request_ibi()say it returns negative error codes but the comments fori3c_master_enec_locked()say it returns "a positive I3C error code if the error is one of the official Mx error codes, and a negative error code otherwise."...would be nice to have a conversion helper to get Linux error codes from the Mx ones.
@Jorge, can you take a look at this please and ideally send a fix.
Thanks,
Jonathan
Re: [bug report] iio: adc: Add support for ad4062
Quoted 30 lines · Jonathan Cameron
Quoted 27 lines · On Fri, 6 Feb 2026 16:07:36 +0200 Andy Shevchenko…
Quoted 2 lines · Dan Carpenter
[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]Oh, this is indeed sad. Wondering if LF can donate...
Quoted 9 lines
Commit
d5284402d28f("iio: adc: Add support for ad4062") from Dec 17, 2025 (linux-next), leads to the following Smatch static checker warning:drivers/iio/adc/ad4062.c:1557 ad4062_probe() warn: passing positive error code 's32min-(-1),1-3' to 'dev_err_probe' 1555 ret = ad4062_request_ibi(i3cdev); 1556 if (ret)if (ret < 0)resolves immediate isssue, but...
Quoted 6 lines
--> 1557 return
dev_err_probe(dev, ret, "Failed to request i3c ibi\n");The comments for
ad4062_request_ibi()say it returns negative error codes but the comments fori3c_master_enec_locked()say it returns "a positive I3C error code if the error is one of the official Mx error codes, and a negative error code otherwise."
Quoted 5 lines
Quoted 3 lines
...would be nice to have a conversion helper to get Linux error codes from the Mx ones.
@Jorge, can you take a look at this please and ideally send a fix.
Hi Andy, Jonathan,
I found nine paths that returned positive Mx error codes when 0 or negative was expected.
i3c/device.h suggests returning -EIO. The error codes range from M0 to M2; only M2 is suppressed during [RST|ENT]DAA (means "no active device on the bus"), which is already done internally but duplicated.
I will submit the changes to the i3c subsystem after CI/CD and hardware tests are run to make sure, since many paths are involved.
Note that the immediate fix is not valid, if a Mx code was returned as is, we would like to return an error still, since that would mean the target device did not acknowledge the enable target events (instead we would convert to -EIO).
Thanks,
Jorge
Quoted 4 lines
Thanks,
Jonathan
[bug report] ext4: refactor zeroout path and handle all cases
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Ojaswin Mujoo,
Commit a985e07c2645 ("ext4: refactor zeroout path and handle all cases") from Jan 23, 2026 (linux-next), leads to the following Smatch static checker warning:
fs/ext4/extents.c:3369 ext4_split_extent_zeroout() warn: duplicate zero check 'err' (previous on line 3363)
fs/ext4/extents.c
3361
3362 err = ext4_ext_get_access(handle, inode, path + depth);
3363 if (err)
3364 return err;
3365
3366 ext4_ext_mark_initialized(ex);
3367
3368 ext4_ext_dirty(handle, inode, path + depth);Presumably "err = ext4_ext_dirty()".
--> 3369 if (err)
3370 return err;
3371
3372 return 0;
3373 }regards,
dan carpenter
Re: [bug report] ext4: refactor zeroout path and handle all cases
Quoted 24 lines · Dan Carpenter
[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]Hello Ojaswin Mujoo,
Commit
a985e07c2645("ext4: refactor zeroout path and handle all cases") from Jan 23, 2026 (linux-next), leads to the following Smatch static checker warning:fs/ext4/extents.c:3369 ext4_split_extent_zeroout() warn: duplicate zero check 'err' (previous on line 3363)
fs/ext4/extents.c3361 3362 err = ext4_ext_get_access(handle, inode, path + depth); 3363 if (err) 3364 return err; 3365 3366 ext4_ext_mark_initialized(ex); 3367 3368 ext4_ext_dirty(handle, inode, path + depth);Presumably "err =
ext4_ext_dirty()".
Quoted 8 lines
--> 3369 if (err)
3370 return err; 3371 3372 return 0; 3373 }regards,
dan carpenter
Hi dan,
Thanks for the report, I'll send a patch for this.
Many thanks for all the work you do and hope you are able to work out a way to carry the smatch project forward!
Regards,
ojaswin
[bug report] media: chips-media: wave5: Fix Null reference while testing fluster
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Jackson Lee,
Commit e66ff2b08e4e ("media: chips-media: wave5: Fix Null reference while testing fluster") from Nov 19, 2025 (linux-next), leads to the following Smatch static checker warning:
drivers/media/platform/chips-media/wave5/wave5-vpu.c:415 wave5_vpu_probe() error: 'dev->irq_thread' dereferencing possible ERR_PTR()
drivers/media/platform/chips-media/wave5/wave5-vpu.c
261 static int wave5_vpu_probe(struct platform_device *pdev)
262 {
263 int ret;
264 struct vpu_device *dev;
265 const struct wave5_match_data *match_data;
266 u32 fw_revision;
267
268 match_data = device_get_match_data(&pdev->dev);
269 if (!match_data) {
270 dev_err(&pdev->dev, "missing device match data\n");
271 return -EINVAL;
272 }
273
274 /* physical addresses limited to 32 bits */
275 ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
276 if (ret) {
277 dev_err(&pdev->dev, "Failed to set DMA mask: %d\n", ret);
278 return ret;
279 }
280
281 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
282 if (!dev)
283 return -ENOMEM;
284
285 dev->vdb_register = devm_platform_ioremap_resource(pdev, 0);
286 if (IS_ERR(dev->vdb_register))
287 return PTR_ERR(dev->vdb_register);
288 ida_init(&dev->inst_ida);
289
290 mutex_init(&dev->dev_lock);
291 mutex_init(&dev->hw_lock);
292 mutex_init(&dev->irq_lock);
293 spin_lock_init(&dev->irq_spinlock);
294 dev_set_drvdata(&pdev->dev, dev);
295 dev->dev = &pdev->dev;
296
297 dev->resets = devm_reset_control_array_get_optional_exclusive(&pdev->dev);
298 if (IS_ERR(dev->resets)) {
299 return dev_err_probe(&pdev->dev, PTR_ERR(dev->resets),
300 "Failed to get reset control\n");
301 }
302
303 ret = reset_control_deassert(dev->resets);
304 if (ret)
305 return dev_err_probe(&pdev->dev, ret, "Failed to deassert resets\n");
306
307 ret = devm_clk_bulk_get_all(&pdev->dev, &dev->clks);
308
309 /* continue without clock, assume externally managed */
310 if (ret < 0) {
311 dev_warn(&pdev->dev, "Getting clocks, fail: %d\n", ret);
312 ret = 0;
313 }
314 dev->num_clks = ret;
315
316 ret = clk_bulk_prepare_enable(dev->num_clks, dev->clks);
317 if (ret) {
318 dev_err(&pdev->dev, "Enabling clocks, fail: %d\n", ret);
319 goto err_reset_assert;
320 }
321
322 dev->sram_pool = of_gen_pool_get(pdev->dev.of_node, "sram", 0);
323 if (!dev->sram_pool)
324 dev_warn(&pdev->dev, "sram node not found\n");
325
326 dev->sram_size = match_data->sram_size;
327
328 dev->product_code = wave5_vdi_read_register(dev, VPU_PRODUCT_CODE_REGISTER);
329 ret = wave5_vdi_init(&pdev->dev);
330 if (ret < 0) {
331 dev_err(&pdev->dev, "wave5_vdi_init, fail: %d\n", ret);
332 goto err_clk_dis;
333 }
334 dev->product = wave5_vpu_get_product_id(dev);
335
336 INIT_LIST_HEAD(&dev->instances);
337
338 dev->irq = platform_get_irq(pdev, 0);
339 if (dev->irq < 0) {
340 dev_err(&pdev->dev, "failed to get irq resource, falling back to polling\n");
341 sema_init(&dev->irq_sem, 1);
342 dev->irq_thread = kthread_run(irq_thread, dev, "irq thread");Add error checking for if kthread_run() fails?
343 hrtimer_setup(&dev->hrtimer, &wave5_vpu_timer_callback, CLOCK_MONOTONIC,
344 HRTIMER_MODE_REL_PINNED);
345 dev->worker = kthread_run_worker(0, "vpu_irq_thread");
346 if (IS_ERR(dev->worker)) {
347 dev_err(&pdev->dev, "failed to create vpu irq worker\n");
348 ret = PTR_ERR(dev->worker);
349 goto err_vdi_release;
350 }
351 dev->vpu_poll_interval = vpu_poll_interval;
352 kthread_init_work(&dev->work, wave5_vpu_irq_work_fn);
353 } else {
354 ret = devm_request_threaded_irq(&pdev->dev, dev->irq, wave5_vpu_irq,
355 wave5_vpu_irq_thread, IRQF_ONESHOT, "vpu_irq", dev);
356 if (ret) {
357 dev_err(&pdev->dev, "Register interrupt handler, fail: %d\n", ret);
358 goto err_enc_unreg;
359 }
360 }
361
362 ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
363 if (ret) {
364 dev_err(&pdev->dev, "v4l2_device_register, fail: %d\n", ret);
365 goto err_irq_release;
366 }
367
368 if (match_data->flags & WAVE5_IS_DEC) {
369 ret = wave5_vpu_dec_register_device(dev);
370 if (ret) {
371 dev_err(&pdev->dev, "wave5_vpu_dec_register_device, fail: %d\n", ret);
372 goto err_v4l2_unregister;
373 }
374 }
375 if (match_data->flags & WAVE5_IS_ENC) {
376 ret = wave5_vpu_enc_register_device(dev);
377 if (ret) {
378 dev_err(&pdev->dev, "wave5_vpu_enc_register_device, fail: %d\n", ret);
379 goto err_dec_unreg;
380 }
381 }
382
383 ret = wave5_vpu_load_firmware(&pdev->dev, match_data->fw_name, &fw_revision);
384 if (ret) {
385 dev_err(&pdev->dev, "wave5_vpu_load_firmware, fail: %d\n", ret);
386 goto err_enc_unreg;
387 }
388
389 dev_info(&pdev->dev, "Added wave5 driver with caps: %s %s\n",
390 (match_data->flags & WAVE5_IS_ENC) ? "'ENCODE'" : "",
391 (match_data->flags & WAVE5_IS_DEC) ? "'DECODE'" : "");
392 dev_info(&pdev->dev, "Product Code: 0x%x\n", dev->product_code);
393 dev_info(&pdev->dev, "Firmware Revision: %u\n", fw_revision);
394
395 pm_runtime_set_autosuspend_delay(&pdev->dev, 500);
396 pm_runtime_use_autosuspend(&pdev->dev);
397 pm_runtime_enable(&pdev->dev);
398 wave5_vpu_sleep_wake(&pdev->dev, true, NULL, 0);
399
400 return 0;
401
402 err_enc_unreg:
403 if (match_data->flags & WAVE5_IS_ENC)
404 wave5_vpu_enc_unregister_device(dev);
405 err_dec_unreg:
406 if (match_data->flags & WAVE5_IS_DEC)
407 wave5_vpu_dec_unregister_device(dev);
408 err_v4l2_unregister:
409 v4l2_device_unregister(&dev->v4l2_dev);
410 err_irq_release:
411 if (dev->irq < 0)
412 kthread_destroy_worker(dev->worker);
413 err_vdi_release:
414 if (dev->irq_thread) {
--> 415 kthread_stop(dev->irq_thread);
416 up(&dev->irq_sem);
417 dev->irq_thread = NULL;
418 }
419 wave5_vdi_release(&pdev->dev);
420 err_clk_dis:
421 clk_bulk_disable_unprepare(dev->num_clks, dev->clks);
422 err_reset_assert:
423 reset_control_assert(dev->resets);
424
425 return ret;
426 }regards,
dan carpenter
RE: [bug report] media: chips-media: wave5: Fix Null reference while testing fluster
Hi, Dan.
Quoted 41 lines
-----Original Message-----
From: Dan Carpenter <[email protected]>
Sent: Friday, February 6, 2026 10:41 PM
To: jackson.lee <[email protected]>
Cc: [email protected]; linux-kernel <linux- [email protected]>
Subject: [bug report] media: chips-media: wave5: Fix Null reference while testing fluster[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]Hello Jackson Lee,
Commit
e66ff2b08e4e("media: chips-media: wave5: Fix Null reference while testing fluster") from Nov 19, 2025 (linux-next), leads to the following Smatch static checker warning:
drivers/media/platform/chips-media/wave5/wave5-vpu.c:415wave5_vpu_probe()error: 'dev->irq_thread' dereferencing possible ERR_PTR()
drivers/media/platform/chips-media/wave5/wave5-vpu.c
327
328dev->product_code= wave5_vdi_read_register(dev,VPU_PRODUCT_CODE_REGISTER); 329 ret = wave5_vdi_init(&pdev->dev); 330 if (ret < 0) { 331 dev_err(&pdev->dev, "wave5_vdi_init, fail: %d\n", ret); 332 goto err_clk_dis; 333 } 334 dev->product = wave5_vpu_get_product_id(dev); 335 336 INIT_LIST_HEAD(&dev->instances); 337 338 dev->irq = platform_get_irq(pdev, 0); 339 if (dev->irq < 0) { 340 dev_err(&pdev->dev, "failed to get irq resource, falling back to polling\n"); 341 sema_init(&dev->irq_sem, 1); 342 dev->irq_thread = kthread_run(irq_thread, dev, "irq
Quoted 3 lines
thread");
Add error checking for if
kthread_run()fails?
Thanks for the report.
A fix has been proposed by Alper Ak in a separate thread:
https://lore.kernel.org/all/[email protected]/
I'm going to check it and run tests on my side.
Thanks.
Nas.
Quoted 7 lines
343 hrtimer_setup(&dev->hrtimer, &wave5_vpu_timer_callback,
CLOCK_MONOTONIC,
344HRTIMER_MODE_REL_PINNED);regards,
dan carpenter
[bug report] phy: apple: Add Apple Type-C PHY
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Sven Peter,
Commit 8e98ca1e74db ("phy: apple: Add Apple Type-C PHY") from Dec 14, 2025 (linux-next), leads to the following Smatch static checker warning:
drivers/phy/apple/atc.c:2209 atcphy_map_resources() warn: 'resources[i]->addr' isn't an ERR_PTR
drivers/phy/apple/atc.c
2191 static int atcphy_map_resources(struct platform_device *pdev, struct apple_atcphy *atcphy)
2192 {
2193 struct {
2194 const char *name;
2195 void __iomem **addr;
2196 struct resource **res;
2197 } resources[] = {
2198 { "core", &atcphy->regs.core, &atcphy->res.core },
2199 { "lpdptx", &atcphy->regs.lpdptx, NULL },
2200 { "axi2af", &atcphy->regs.axi2af, &atcphy->res.axi2af },
2201 { "usb2phy", &atcphy->regs.usb2phy, NULL },
2202 { "pipehandler", &atcphy->regs.pipehandler, NULL },
2203 };
2204 struct resource *res;
2205
2206 for (int i = 0; i < ARRAY_SIZE(resources); i++) {
2207 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, resources[i].name);
2208 *resources[i].addr = devm_ioremap_resource(&pdev->dev, res);--> 2209 if (IS_ERR(resources[i].addr))
This is checking the wrong variable. The * is missing. if (IS_ERR(*resources[i].addr)) {
2210 return dev_err_probe(atcphy->dev, PTR_ERR(resources[i].addr),
2211 "Unable to map %s regs", resources[i].name);
2212
2213 if (resources[i].res)
2214 *resources[i].res = res;
2215 }
2216
2217 return 0;
2218 }regards,
dan carpenter
Re: [bug report] phy: apple: Add Apple Type-C PHY
Quoted 2 lines · Dan Carpenter
[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
This is unfortunate, there have been useful bug reports.
Quoted 26 lines
Commit
8e98ca1e74db("phy: apple: Add Apple Type-C PHY") from Dec 14, 2025 (linux-next), leads to the following Smatch static checker warning:drivers/phy/apple/atc.c:2209 atcphy_map_resources() warn: 'resources[i]->addr' isn't an ERR_PTR
drivers/phy/apple/atc.c2191 static int atcphy_map_resources(struct platform_device *pdev, struct apple_atcphy *atcphy) 2192 { 2193 struct { 2194 const char *name; 2195 void __iomem **addr; 2196 struct resource **res; 2197 } resources[] = { 2198 { "core", &atcphy->regs.core, &atcphy->res.core }, 2199 { "lpdptx", &atcphy->regs.lpdptx, NULL }, 2200 { "axi2af", &atcphy->regs.axi2af, &atcphy->res.axi2af }, 2201 { "usb2phy", &atcphy->regs.usb2phy, NULL }, 2202 { "pipehandler", &atcphy->regs.pipehandler, NULL }, 2203 }; 2204 struct resource *res; 2205 2206 for (int i = 0; i < ARRAY_SIZE(resources); i++) { 2207 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, resources[i].name); 2208 *resources[i].addr = devm_ioremap_resource(&pdev->dev, res);
Quoted 4 lines
--> 2209 if (
IS_ERR(resources[i].addr))This is checking the wrong variable. The * is missing. if (
IS_ERR(*resources[i].addr)) {
This issue was identified by testing and is fixed in next by commit 7d55b44e2be1 ("phy: apple: atc: Actually check return value of devm_apple_tunable_parse").
https://lore.kernel.org/all/[email protected]/
Thanks for the report
Janne
Re: [bug report] phy: apple: Add Apple Type-C PHY
Quoted 34 lines · Janne Grunau
Quoted 2 lines · Dan Carpenter
[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]This is unfortunate, there have been useful bug reports.
Quoted 28 lines
Commit
8e98ca1e74db("phy: apple: Add Apple Type-C PHY") from Dec 14, 2025 (linux-next), leads to the following Smatch static checker warning:drivers/phy/apple/atc.c:2209 atcphy_map_resources() warn: 'resources[i]->addr' isn't an ERR_PTR
drivers/phy/apple/atc.c2191 static int atcphy_map_resources(struct platform_device *pdev, struct apple_atcphy *atcphy) 2192 { 2193 struct { 2194 const char *name; 2195 void __iomem **addr; 2196 struct resource **res; 2197 } resources[] = { 2198 { "core", &atcphy->regs.core, &atcphy->res.core }, 2199 { "lpdptx", &atcphy->regs.lpdptx, NULL }, 2200 { "axi2af", &atcphy->regs.axi2af, &atcphy->res.axi2af }, 2201 { "usb2phy", &atcphy->regs.usb2phy, NULL }, 2202 { "pipehandler", &atcphy->regs.pipehandler, NULL }, 2203 }; 2204 struct resource *res; 2205 2206 for (int i = 0; i < ARRAY_SIZE(resources); i++) { 2207 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, resources[i].name); 2208 *resources[i].addr = devm_ioremap_resource(&pdev->dev, res);--> 2209 if (
IS_ERR(resources[i].addr))
Quoted 8 lines
Quoted 2 lines
This is checking the wrong variable. The * is missing. if (
IS_ERR(*resources[i].addr)) {This issue was identified by testing and is fixed in next by commit
7d55b44e2be1("phy: apple: atc: Actually check return value ofdevm_apple_tunable_parse").
I think I actually messed this up *twice*! Once for the tunables and once again for the resources here :(
Sven
[bug report] spi: stm32: properly fail on dma_request_chan error
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Alain Volmat,
Commit c266d19b7d4e ("spi: stm32: properly fail on dma_request_chan error") from Dec 18, 2025 (linux-next), leads to the following Smatch static checker warning:
drivers/spi/spi-stm32.c:2578 stm32_spi_probe() error: 'spi->dma_rx' dereferencing possible ERR_PTR()
drivers/spi/spi-stm32.c
2480 if (STM32_SPI_DEVICE_MODE(spi))
2481 ctrl->target_abort = stm32h7_spi_device_abort;
2482
2483 spi->dma_tx = dma_request_chan(spi->dev, "tx");
2484 if (IS_ERR(spi->dma_tx)) {
2485 ret = PTR_ERR(spi->dma_tx);
2486 if (ret == -ENODEV) {
2487 dev_info(&pdev->dev, "tx dma disabled\n");
2488 spi->dma_tx = NULL;
2489 } else {
2490 dev_err_probe(&pdev->dev, ret, "failed to request tx dma channel\n");
2491 goto err_clk_disable;
2492 }
2493 } else {
2494 ctrl->dma_tx = spi->dma_tx;
2495 }
2496
2497 spi->dma_rx = dma_request_chan(spi->dev, "rx");
2498 if (IS_ERR(spi->dma_rx)) {
2499 ret = PTR_ERR(spi->dma_rx);
2500 if (ret == -ENODEV) {
2501 dev_info(&pdev->dev, "rx dma disabled\n");
2502 spi->dma_rx = NULL;
2503 } else {
2504 dev_err_probe(&pdev->dev, ret, "failed to request rx dma channel\n");
2505 goto err_dma_release;spi->dma_rx is an erorr pointer at this goto so it will crash.
2506 }
2507 } else {
2508 ctrl->dma_rx = spi->dma_rx;
2509 }
2510
2511 if (spi->dma_tx || spi->dma_rx)
2512 ctrl->can_dma = stm32_spi_can_dma;
2513
2514 spi->sram_pool = of_gen_pool_get(pdev->dev.of_node, "sram", 0);
2515 if (spi->sram_pool) {
2516 spi->sram_rx_buf_size = gen_pool_size(spi->sram_pool);
2517 dev_info(&pdev->dev, "SRAM pool: %zu KiB for RX DMA/MDMA chaining\n",
2518 spi->sram_rx_buf_size / 1024);
2519 spi->sram_rx_buf = gen_pool_dma_zalloc(spi->sram_pool, spi->sram_rx_buf_size,
2520 &spi->sram_dma_rx_buf);
2521 if (!spi->sram_rx_buf) {
2522 dev_err(&pdev->dev, "failed to allocate SRAM buffer\n");
2523 } else {
2524 spi->mdma_rx = dma_request_chan(spi->dev, "rxm2m");
2525 if (IS_ERR(spi->mdma_rx)) {
2526 ret = PTR_ERR(spi->mdma_rx);
2527 spi->mdma_rx = NULL;
2528 if (ret == -EPROBE_DEFER) {
2529 goto err_pool_free;
2530 } else {
2531 gen_pool_free(spi->sram_pool,
2532 (unsigned long)spi->sram_rx_buf,
2533 spi->sram_rx_buf_size);
2534 dev_warn(&pdev->dev,
2535 "failed to request rx mdma channel, DMA only\n");
2536 }
2537 }
2538 }
2539 }
2540
2541 pm_runtime_set_autosuspend_delay(&pdev->dev,
2542 STM32_SPI_AUTOSUSPEND_DELAY);
2543 pm_runtime_use_autosuspend(&pdev->dev);
2544 pm_runtime_set_active(&pdev->dev);
2545 pm_runtime_get_noresume(&pdev->dev);
2546 pm_runtime_enable(&pdev->dev);
2547
2548 ret = spi_register_controller(ctrl);
2549 if (ret) {
2550 dev_err(&pdev->dev, "spi controller registration failed: %d\n",
2551 ret);
2552 goto err_pm_disable;
2553 }
2554
2555 pm_runtime_put_autosuspend(&pdev->dev);
2556
2557 dev_info(&pdev->dev, "driver initialized (%s mode)\n",
2558 STM32_SPI_HOST_MODE(spi) ? "host" : "device");
2559
2560 return 0;
2561
2562 err_pm_disable:
2563 pm_runtime_disable(&pdev->dev);
2564 pm_runtime_put_noidle(&pdev->dev);
2565 pm_runtime_set_suspended(&pdev->dev);
2566 pm_runtime_dont_use_autosuspend(&pdev->dev);
2567
2568 if (spi->mdma_rx)
2569 dma_release_channel(spi->mdma_rx);
2570 err_pool_free:
2571 if (spi->sram_pool)
2572 gen_pool_free(spi->sram_pool, (unsigned long)spi->sram_rx_buf,
2573 spi->sram_rx_buf_size);
2574 err_dma_release:
2575 if (spi->dma_tx)
2576 dma_release_channel(spi->dma_tx);
2577 if (spi->dma_rx)
--> 2578 dma_release_channel(spi->dma_rx);
^^^^^^^^^^^Here.
2579 err_clk_disable:
2580 clk_disable_unprepare(spi->clk);
2581
2582 return ret;
2583 }regards,
dan carpenter
[bug report] tracing: Properly process error handling in event_hist_trigger_parse()
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Miaoqian Lin,
Commit 0550069cc25f ("tracing: Properly process error handling in event_hist_trigger_parse()") from Dec 11, 2025 (linux-next), leads to the following Smatch static checker warning:
kernel/trace/trace_events_hist.c:6925 event_hist_trigger_parse()
error: we previously assumed 'trigger_data' could be null (see line 6856)
kernel/trace/trace_events_hist.c
6855 trigger_data = trigger_data_alloc(cmd_ops, cmd, param, hist_data);
6856 if (!trigger_data) {
6857 ret = -ENOMEM;
6858 goto out_free;trigger_data is NULL here.
6859 }
6860
6861 ret = event_trigger_set_filter(cmd_ops, file, filter, trigger_data);
6862 if (ret < 0)
6863 goto out_free;
6864
6865 if (remove) {
6866 if (!have_hist_trigger_match(trigger_data, file))
6867 goto out_free;
6868
6869 if (hist_trigger_check_refs(trigger_data, file)) {
6870 ret = -EBUSY;
6871 goto out_free;
6872 }
6873
6874 event_trigger_unregister(cmd_ops, file, glob+1, trigger_data);
6875 se_name = trace_event_name(file->event_call);
6876 se = find_synth_event(se_name);
6877 if (se)
6878 se->ref--;
6879 ret = 0;
6880 goto out_free;
6881 }
6882
6883 if (existing_hist_update_only(glob, trigger_data, file))
6884 goto out_free;
6885
6886 if (!get_named_trigger_data(trigger_data)) {
6887
6888 ret = create_actions(hist_data);
6889 if (ret)
6890 goto out_free;
6891
6892 if (has_hist_vars(hist_data) || hist_data->n_var_refs) {
6893 ret = save_hist_vars(hist_data);
6894 if (ret)
6895 goto out_free;
6896 }
6897
6898 ret = tracing_map_init(hist_data->map);
6899 if (ret)
6900 goto out_free;
6901 }
6902
6903 ret = event_trigger_register(cmd_ops, file, glob, trigger_data);
6904 if (ret < 0)
6905 goto out_free;
6906
6907 ret = hist_trigger_enable(trigger_data, file);
6908 if (ret)
6909 goto out_unreg;
6910
6911 se_name = trace_event_name(file->event_call);
6912 se = find_synth_event(se_name);
6913 if (se)
6914 se->ref++;
6915 out:
6916 if (ret == 0 && glob[0])
6917 hist_err_clear();
6918
6919 return ret;
6920 out_unreg:
6921 event_trigger_unregister(cmd_ops, file, glob+1, trigger_data);
6922 out_free:
6923 remove_hist_vars(hist_data);
6924 --> 6925 trigger_data_free(trigger_data);
Originally this was kfree(trigger_data) so passing a NULL pointer was fine, but now it will crash.
6926
6927 destroy_hist_data(hist_data);
6928 goto out;
6929 }
6930
6931 static struct event_command trigger_hist_cmd = {
6932 .name = "hist",
6933 .trigger_type = ETT_EVENT_HIST,
6934 .flags = EVENT_CMD_FL_NEEDS_REC,
6935 .parse = event_hist_trigger_parse,regards,
dan carpenter
[bug report] drm/amd/display: Only poll analog connectors
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Timur Kristóf,
Commit f6cc7f1c11a7 ("drm/amd/display: Only poll analog connectors") from Jan 18, 2026 (linux-next), leads to the following Smatch static checker warning:
drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm_irq.c:940 amdgpu_dm_hpd_init() error: we previously assumed 'dc_link' could be null (see line 931)
drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm_irq.c
923 /*
924 * Analog connectors may be hot-plugged unlike other connector
925 * types that don't support HPD. Only poll analog connectors.
926 */
927 use_polling |=
928 amdgpu_dm_connector->dc_link &&
^^^^^^^^^^^^^^^^^^^^^^^^^^^^The patch adds this NULL check but hopefully it can be removed
929 dc_connector_supports_analog(amdgpu_dm_connector->dc_link->link_id.id);
930
931 dc_link = amdgpu_dm_connector->dc_link;dc_link assigned here.
932
933 /*
934 * Get a base driver irq reference for hpd ints for the lifetime
935 * of dm. Note that only hpd interrupt types are registered with
936 * base driver; hpd_rx types aren't. IOW, amdgpu_irq_get/put on
937 * hpd_rx isn't available. DM currently controls hpd_rx
938 * explicitly with dc_interrupt_set()
939 */
--> 940 if (dc_link->irq_source_hpd != DC_IRQ_SOURCE_INVALID) {
^^^^^^^^^^^^^^^^^^^^^^^If it's NULL then we are trouble because we dereference it here.
941 irq_type = dc_link->irq_source_hpd - DC_IRQ_SOURCE_HPD1;
942 /*
943 * TODO: There's a mismatch between mode_info.num_hpd
944 * and what bios reports as the # of connectors with hpd
regards,
dan carpenter
[bug report] fs/ntfs3: Add initialization of super block
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Konstantin Komarov,
Commit 82cae269cfa9 ("fs/ntfs3: Add initialization of super block") from Aug 13, 2021 (linux-next), leads to the following Smatch static checker warning:
fs/ntfs3/fsntfs.c:1260 ntfs_read_run_nb_ra() error: we previously assumed 'run' could be null (see line 1178) fs/ntfs3/fsntfs.c:1259 ntfs_read_run_nb_ra() error: uninitialized symbol 'clen'. fs/ntfs3/fsntfs.c:1260 ntfs_read_run_nb_ra() error: uninitialized symbol 'idx'.
fs/ntfs3/fsntfs.c
1161 int ntfs_read_run_nb_ra(struct ntfs_sb_info *sbi, const struct runs_tree *run,
1162 u64 vbo, void *buf, u32 bytes, struct ntfs_buffers *nb,
1163 struct file_ra_state *ra)
1164 {
1165 int err;
1166 struct super_block *sb = sbi->sb;
1167 struct address_space *mapping = sb->s_bdev->bd_mapping;
1168 u32 blocksize = sb->s_blocksize;
1169 u8 cluster_bits = sbi->cluster_bits;
1170 u32 off = vbo & sbi->cluster_mask;
1171 u32 nbh = 0;
1172 CLST vcn_next, vcn = vbo >> cluster_bits;
1173 CLST lcn, clen;
1174 u64 lbo, len;
1175 size_t idx;
1176 struct buffer_head *bh;
1177
1178 if (!run) {
1179 /* First reading of $Volume + $MFTMirr + $LogFile goes here. */
1180 if (vbo > MFT_REC_VOL * sbi->record_size) {
1181 err = -ENOENT;
1182 goto out;
1183 }
1184
1185 /* Use absolute boot's 'MFTCluster' to read record. */
1186 lbo = vbo + sbi->mft.lbo;
1187 len = sbi->record_size;If run is NULL then "clen" is uninitialized.
1188 } else if (!run_lookup_entry(run, vcn, &lcn, &clen, &idx)) {
1189 err = -ENOENT;
1190 goto out;
1191 } else {
1192 if (lcn == SPARSE_LCN) {
1193 err = -EINVAL;
1194 goto out;
1195 }
1196
1197 lbo = ((u64)lcn << cluster_bits) + off;
1198 len = ((u64)clen << cluster_bits) - off;
1199 }
1200
1201 off = lbo & (blocksize - 1);
1202 if (nb) {
1203 nb->off = off;
1204 nb->bytes = bytes;
1205 }
1206
1207 if (ra && !ra->ra_pages)
1208 file_ra_state_init(ra, mapping);
1209
1210 for (;;) {
1211 u32 len32 = len >= bytes ? bytes : len;
1212 sector_t block = lbo >> sb->s_blocksize_bits;
1213
1214 if (ra) {
1215 pgoff_t index = lbo >> PAGE_SHIFT;
1216 if (!ra_has_index(ra, index)) {
1217 page_cache_sync_readahead(mapping, ra, NULL,
1218 index, 1);
1219 ra->prev_pos = (loff_t)index << PAGE_SHIFT;
1220 }
1221 }
1222
1223 do {
1224 u32 op = blocksize - off;
1225
1226 if (op > len32)
1227 op = len32;
1228
1229 bh = ntfs_bread(sb, block);
1230 if (!bh) {
1231 err = -EIO;
1232 goto out;
1233 }
1234
1235 if (buf) {
1236 memcpy(buf, bh->b_data + off, op);
1237 buf = Add2Ptr(buf, op);
1238 }
1239
1240 if (!nb) {
1241 put_bh(bh);
1242 } else if (nbh >= ARRAY_SIZE(nb->bh)) {
1243 err = -EINVAL;
1244 goto out;
1245 } else {
1246 nb->bh[nbh++] = bh;
1247 nb->nbufs = nbh;
1248 }
1249
1250 bytes -= op;
1251 if (!bytes)
1252 return 0;
1253 len32 -= op;
1254 block += 1;
1255 off = 0;
1256
1257 } while (len32);
1258
--> 1259 vcn_next = vcn + clen;
^^^^Used uninitalized here.
1260 if (!run_get_entry(run, ++idx, &vcn, &lcn, &clen) ||
But also if we pass a NULL run to run_get_entry() it will crash. I'm a bit confused by this code.
1261 vcn != vcn_next) {
1262 err = -ENOENT;
1263 goto out;
1264 }
1265
1266 if (lcn == SPARSE_LCN) {
1267 err = -EINVAL;
1268 goto out;
1269 }
1270
1271 lbo = ((u64)lcn << cluster_bits);
1272 len = ((u64)clen << cluster_bits);
1273 }
1274
1275 out:
1276 if (!nbh)
1277 return err;
1278
1279 while (nbh) {
1280 put_bh(nb->bh[--nbh]);
1281 nb->bh[nbh] = NULL;
1282 }
1283
1284 nb->nbufs = 0;
1285 return err;
1286 }regards,
dan carpenter
Konstantin Komarov
maintainerRe: [bug report] fs/ntfs3: Add initialization of super block
Quoted 151 lines · Dan Carpenter
[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]Hello Konstantin Komarov,
Commit
82cae269cfa9("fs/ntfs3: Add initialization of super block") from Aug 13, 2021 (linux-next), leads to the following Smatch static checker warning:
fs/ntfs3/fsntfs.c:1260ntfs_read_run_nb_ra()error: we previously assumed 'run' could be null (see line 1178)fs/ntfs3/fsntfs.c:1259ntfs_read_run_nb_ra()error: uninitialized symbol 'clen'.fs/ntfs3/fsntfs.c:1260ntfs_read_run_nb_ra()error: uninitialized symbol 'idx'.
fs/ntfs3/fsntfs.c1161 int ntfs_read_run_nb_ra(struct ntfs_sb_info *sbi, const struct runs_tree *run, 1162 u64 vbo, void *buf, u32 bytes, struct ntfs_buffers *nb, 1163 struct file_ra_state *ra) 1164 { 1165 int err; 1166 struct super_block *sb = sbi->sb; 1167 struct address_space *mapping = sb->s_bdev->bd_mapping; 1168 u32 blocksize = sb->s_blocksize; 1169 u8 cluster_bits = sbi->cluster_bits; 1170 u32 off = vbo & sbi->cluster_mask; 1171 u32 nbh = 0; 1172 CLST vcn_next, vcn = vbo >> cluster_bits; 1173 CLST lcn, clen; 1174 u64 lbo, len; 1175 size_t idx; 1176 struct buffer_head *bh; 1177 1178 if (!run) { 1179 /* First reading of $Volume + $MFTMirr + $LogFile goes here. */ 1180 if (vbo > MFT_REC_VOL * sbi->record_size) { 1181 err = -ENOENT; 1182 goto out; 1183 } 1184 1185 /* Use absolute boot's 'MFTCluster' to read record. */ 1186 lbo = vbo + sbi->mft.lbo; 1187 len = sbi->record_size;If run is NULL then "clen" is uninitialized.
1188 } else if (!run_lookup_entry(run, vcn, &lcn, &clen, &idx)) { 1189 err = -ENOENT; 1190 goto out; 1191 } else { 1192 if (lcn == SPARSE_LCN) { 1193 err = -EINVAL; 1194 goto out; 1195 } 1196 1197 lbo = ((u64)lcn << cluster_bits) + off; 1198 len = ((u64)clen << cluster_bits) - off; 1199 } 1200 1201 off = lbo & (blocksize - 1); 1202 if (nb) { 1203 nb->off = off; 1204 nb->bytes = bytes; 1205 } 1206 1207 if (ra && !ra->ra_pages) 1208 file_ra_state_init(ra, mapping); 1209 1210 for (;;) { 1211 u32 len32 = len >= bytes ? bytes : len; 1212 sector_t block = lbo >> sb->s_blocksize_bits; 1213 1214 if (ra) { 1215 pgoff_t index = lbo >> PAGE_SHIFT; 1216 if (!ra_has_index(ra, index)) { 1217 page_cache_sync_readahead(mapping, ra, NULL, 1218 index, 1); 1219 ra->prev_pos = (loff_t)index << PAGE_SHIFT; 1220 } 1221 } 1222 1223 do { 1224 u32 op = blocksize - off; 1225 1226 if (op > len32) 1227 op = len32; 1228 1229 bh = ntfs_bread(sb, block); 1230 if (!bh) { 1231 err = -EIO; 1232 goto out; 1233 } 1234 1235 if (buf) { 1236 memcpy(buf, bh->b_data + off, op); 1237 buf = Add2Ptr(buf, op); 1238 } 1239 1240 if (!nb) { 1241 put_bh(bh); 1242 } else if (nbh >= ARRAY_SIZE(nb->bh)) { 1243 err = -EINVAL; 1244 goto out; 1245 } else { 1246 nb->bh[nbh++] = bh; 1247 nb->nbufs = nbh; 1248 } 1249 1250 bytes -= op; 1251 if (!bytes) 1252 return 0; 1253 len32 -= op; 1254 block += 1; 1255 off = 0; 1256 1257 } while (len32); 1258 --> 1259 vcn_next = vcn + clen; ^^^^Used uninitalized here.
1260 if (!run_get_entry(run, ++idx, &vcn, &lcn, &clen) ||But also if we pass a NULL run to
run_get_entry()it will crash. I'm a bit confused by this code.1261 vcn != vcn_next) { 1262 err = -ENOENT; 1263 goto out; 1264 } 1265 1266 if (lcn == SPARSE_LCN) { 1267 err = -EINVAL; 1268 goto out; 1269 } 1270 1271 lbo = ((u64)lcn << cluster_bits); 1272 len = ((u64)clen << cluster_bits); 1273 } 1274 1275 out: 1276 if (!nbh) 1277 return err; 1278 1279 while (nbh) { 1280 put_bh(nb->bh[--nbh]); 1281 nb->bh[nbh] = NULL; 1282 } 1283 1284 nb->nbufs = 0; 1285 return err; 1286 }
Quoted 2 lines
regards,
dan carpenter
Hello,
Thanks for the Smatch report. I’ll examine the warnings, prepare a fix, and post a patch.
Regards,
Konstantin
Konstantin Komarov
maintainerPATCH 1/1 (resend: correct threading) fs/ntfs3: avoid calling run_get_entry() when run == NULL in ntfs_read_run_nb_ra()
In reply to Dan CarpenterWhen ntfs_read_run_nb_ra() is invoked with run == NULL the code later assumes run is valid and may call run_get_entry(NULL, ...), and also uses clen/idx without initializing them. Smatch reported uninitialized variable warnings and this can lead to undefined behaviour. This patch fixes it.
--- fs/ntfs3/fsntfs.c | 6 ++++++ 1 file changed, 6 insertions(+)
fs/ntfs3/fsntfs.c +6 -0
@@ -1256,6 +1256,12 @@ int ntfs_read_run_nb_ra(struct ntfs_sb_info *sbi, const struct runs_tree *run, }while (len32); +if (!run) { + err = -EINVAL ; + goto out; + } + +/* Get next fragment to read. */ vcn_next = vcn + clen;if (!run_get_entry (run, ++idx, &vcn, &lcn, &clen) || vcn != vcn_next) {
Signature · 1 line
2.43.0
[bug report] remoteproc: imx_rproc: Introduce prepare ops for imx_rproc_dcfg
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Peng Fan,
Commit edd2a9956055 ("remoteproc: imx_rproc: Introduce prepare ops for imx_rproc_dcfg") from Jan 9, 2026 (linux-next), leads to the following Smatch static checker warning:
drivers/remoteproc/imx_rproc.c:648 imx_rproc_prepare()
warn: ignoring unreachable code.
drivers/remoteproc/imx_rproc.c
605 static int imx_rproc_prepare(struct rproc *rproc)
606 {
607 struct imx_rproc *priv = rproc->priv;
608 struct device_node *np = priv->dev->of_node;
609 struct rproc_mem_entry *mem;
610 int i = 0;
611 u32 da;
612
613 /* Register associated reserved memory regions */
614 while (1) {
615 int err;
616 struct resource res;
617
618 err = of_reserved_mem_region_to_resource(np, i++, &res);
619 if (err)
620 return 0;
621
622 /*
623 * Ignore the first memory region which will be used vdev buffer.
624 * No need to do extra handlings, rproc_add_virtio_dev will handle it.
625 */
626 if (strstarts(res.name, "vdev0buffer"))
627 continue;
628
629 if (strstarts(res.name, "rsc-table"))
630 continue;
631
632 /* No need to translate pa to da, i.MX use same map */
633 da = res.start;
634
635 /* Register memory region */
636 mem = rproc_mem_entry_init(priv->dev, NULL, (dma_addr_t)res.start,
637 resource_size(&res), da,
638 imx_rproc_mem_alloc, imx_rproc_mem_release,
639 "%.*s", strchrnul(res.name, '@') - res.name,
640 res.name);
641 if (!mem)
642 return -ENOMEM;
643
644 rproc_coredump_add_segment(rproc, da, resource_size(&res));
645 rproc_add_carveout(rproc, mem);
646 }
647
--> 648 if (priv->ops && priv->ops->prepare)
649 return priv->ops->prepare(rproc);This is unreachable code.
650
651 return 0;
652 }regards,
dan carpenter
Re: [bug report] remoteproc: imx_rproc: Introduce prepare ops for imx_rproc_dcfg
Quoted 59 lines · Dan Carpenter
[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]Hello Peng Fan,
Commit
edd2a9956055("remoteproc:imx_rproc: Introduce prepare ops forimx_rproc_dcfg") from Jan 9, 2026 (linux-next), leads to the following Smatch static checker warning:
drivers/remoteproc/imx_rproc.c:648imx_rproc_prepare()
warn: ignoring unreachable code.
drivers/remoteproc/imx_rproc.c605 static int imx_rproc_prepare(struct rproc *rproc) 606 { 607 struct imx_rproc *priv = rproc->priv; 608 struct device_node *np = priv->dev->of_node; 609 struct rproc_mem_entry *mem; 610 int i = 0; 611 u32 da; 612 613 /* Register associated reserved memory regions */ 614 while (1) { 615 int err; 616 struct resource res; 617 618 err = of_reserved_mem_region_to_resource(np, i++, &res); 619 if (err) 620 return 0; 621 622 /* 623 * Ignore the first memory region which will be used vdev buffer. 624 * No need to do extra handlings, rproc_add_virtio_dev will handle it. 625 */ 626 if (strstarts(res.name, "vdev0buffer")) 627 continue; 628 629 if (strstarts(res.name, "rsc-table")) 630 continue; 631 632 /* No need to translate pa to da, i.MX use same map */ 633 da = res.start; 634 635 /* Register memory region */ 636 mem = rproc_mem_entry_init(priv->dev, NULL, (dma_addr_t)res.start, 637 resource_size(&res), da, 638 imx_rproc_mem_alloc, imx_rproc_mem_release, 639 "%.*s", strchrnul(res.name, '@') - res.name, 640 res.name); 641 if (!mem) 642 return -ENOMEM; 643 644 rproc_coredump_add_segment(rproc, da, resource_size(&res)); 645 rproc_add_carveout(rproc, mem); 646 } 647 --> 648 if (priv->ops && priv->ops->prepare) 649 return priv->ops->prepare(rproc);
Quoted 1 line
This is unreachable code.
It looks like Dan (and Smatch) has a point.
Quoted 8 lines
650 651 return 0; 652 }regards,
dan carpenter
RE: [bug report] remoteproc: imx_rproc: Introduce prepare ops for imx_rproc_dcfg
In reply to Dan CarpenterHi Dan,
Thanks for your report.
Quoted 13 lines
Subject: [bug report] remoteproc:
imx_rproc: Introduce prepare ops forimx_rproc_dcfgHello Peng Fan,
Commit
edd2a9956055("remoteproc:imx_rproc: Introduce prepare ops forimx_rproc_dcfg") from Jan 9, 2026 (linux-next), leads to the following Smatch static checker warning:
drivers/remoteproc/imx_rproc.c:648imx_rproc_prepare()
warn: ignoring unreachable code.
drivers/remoteproc/imx_rproc.c
[...]
Quoted 11 lines
642 return -ENOMEM; 643 644 rproc_coredump_add_segment(rproc, da, resource_size(&res)); 645 rproc_add_carveout(rproc, mem); 646 } 647 --> 648 if (priv->ops && priv->ops->prepare) 649 return priv->ops->prepare(rproc);This is unreachable code.
Indeed.
The i.MX95 patches were developed quite some time ago. Later, there was another change [1] which modified the reserved-memory while-loop logic. When rebasing my changes on top of that, I overlooked this behavior change, which resulted in the early return making the prepare callback unreachable.
Regarding why this was not exposed earlier during testing: NXP U-Boot powers up the M7 (leaving it in reset) and initializes TCM ECC by default. As a result, even without calling the platform prepare ops, Linux can still load the M7 ELF correctly, so no issue was observed.
In hindsight, I should have tested the case where M7 remains powered off when rebasing these changes (:
I have just sent out a fix to address this issue. Thanks again for reporting it.
[1] 67a7bc7f0358b ("remoteproc: Use of_reserved_mem_region_* functions for "memory-region")
Thanks,
Peng
Quoted 6 lines
650 651 return 0; 652 }regards,
dan carpenter
[bug report] irqchip/ls-extirq: Convert to a platform driver to make it work again
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Ioana Ciornei,
Commit 05cd654829dd ("irqchip/ls-extirq: Convert to a platform driver to make it work again") from Jan 22, 2026 (linux-next), leads to the following Smatch static checker warning:
drivers/irqchip/irq-ls-extirq.c:180 ls_extirq_probe() warn: 'priv->intpcr' is an error pointer or valid
drivers/irqchip/irq-ls-extirq.c
158 static int ls_extirq_probe(struct platform_device *pdev)
159 {
160 struct irq_domain *domain, *parent_domain;
161 struct device_node *node, *parent;
162 struct device *dev = &pdev->dev;
163 struct ls_extirq_data *priv;
164 int ret;
165
166 node = dev->of_node;
167 parent = of_irq_find_parent(node);
168 if (!parent)
169 return dev_err_probe(dev, -ENODEV, "Failed to get IRQ parent node\n");
170
171 parent_domain = irq_find_host(parent);
172 if (!parent_domain)
173 return dev_err_probe(dev, -EPROBE_DEFER, "Cannot find parent domain\n");
174
175 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
176 if (!priv)
177 return dev_err_probe(dev, -ENOMEM, "Failed to allocate memory\n");
178
179 priv->intpcr = devm_of_iomap(dev, node, 0, NULL);--> 180 if (!priv->intpcr)
This should be an IS_ERR() check.
181 return dev_err_probe(dev, -ENOMEM, "Cannot ioremap OF node %pOF\n", node);
182
183 ret = ls_extirq_parse_map(priv, node);
184 if (ret)
185 return dev_err_probe(dev, ret, "Failed to parse IRQ map\n");
186
187 priv->big_endian = of_device_is_big_endian(node->parent);
188 priv->is_ls1021a_or_ls1043a = of_device_is_compatible(node, "fsl,ls1021a-extirq") ||
189 of_device_is_compatible(node, "fsl,ls1043a-extirq");
190 raw_spin_lock_init(&priv->lock);
191
192 domain = irq_domain_create_hierarchy(parent_domain, 0, priv->nirq, of_fwnode_handle(node),
193 &extirq_domain_ops, priv);
194 if (!domain)
195 return dev_err_probe(dev, -ENOMEM, "Failed to add IRQ domain\n");
196
197 return 0;
198 }regards,
dan carpenter
[bug report] soc: rockchip: grf: Support multiple grf to be handled
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Shawn Lin,
Commit 75fb63ae0312 ("soc: rockchip: grf: Support multiple grf to be handled") from Jan 16, 2026 (linux-next), leads to the following Smatch static checker warning:
drivers/soc/rockchip/grf.c:249 rockchip_grf_init() warn: inconsistent refcounting 'np->kobj.kref.refcount.refs.counter':
drivers/soc/rockchip/grf.c
212 static int __init rockchip_grf_init(void)
213 {
214 const struct rockchip_grf_info *grf_info;
215 const struct of_device_id *match;
216 struct device_node *np;
217 struct regmap *grf;
218 int ret, i;
219
220 for_each_matching_node_and_match(np, rockchip_grf_dt_match, &match) {
221 if (!of_device_is_available(np))
222 continue;
223 if (!match || !match->data) {
224 pr_err("%s: missing grf data\n", __func__);
225 of_node_put(np);
226 return -EINVAL; 227 }
228
229 grf_info = match->data;
230
231 grf = syscon_node_to_regmap(np);
232 if (IS_ERR(grf)) {
233 pr_err("%s: could not get grf syscon\n", __func__);
234 return PTR_ERR(grf);
Missing of_node_put(np) before returning.
235 }
236
237 for (i = 0; i < grf_info->num_values; i++) {
238 const struct rockchip_grf_value *val = &grf_info->values[i];
239
240 pr_debug("%s: adjusting %s in %#6x to %#10x\n", __func__,
241 val->desc, val->reg, val->val);
242 ret = regmap_write(grf, val->reg, val->val);
243 if (ret < 0)
244 pr_err("%s: write to %#6x failed with %d\n",
245 __func__, val->reg, ret);
246 }
247 }
248
249 return 0;
250 }regards,
dan carpenter
[bug report] drm/amdgpu: fix possible fence leaks from job structure
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Alex Deucher,
Commit f903b85ed0f1 ("drm/amdgpu: fix possible fence leaks from job structure") from Oct 22, 2025 (linux-next), leads to the following Smatch static checker warning:
drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c:232 amdgpu_ib_schedule()
warn: missing unwind goto?
drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
124 int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs,
125 struct amdgpu_ib *ibs, struct amdgpu_job *job,
126 struct dma_fence **f)
127 {
128 struct amdgpu_device *adev = ring->adev;
129 struct amdgpu_ib *ib = &ibs[0];
130 struct dma_fence *tmp = NULL;
131 struct amdgpu_fence *af;
132 bool need_ctx_switch;
133 struct amdgpu_vm *vm;
134 uint64_t fence_ctx;
135 uint32_t status = 0, alloc_size;
136 unsigned int fence_flags = 0;
137 bool secure, init_shadow;
138 u64 shadow_va, csa_va, gds_va;
139 int vmid = AMDGPU_JOB_GET_VMID(job);
140 bool need_pipe_sync = false;
141 unsigned int cond_exec;
142 unsigned int i;
143 int r = 0;
144
145 if (num_ibs == 0)
146 return -EINVAL;
147
148 /* ring tests don't use a job */
149 if (job) {
150 vm = job->vm;
151 fence_ctx = job->base.s_fence ?
152 job->base.s_fence->finished.context : 0;
153 shadow_va = job->shadow_va;
154 csa_va = job->csa_va;
155 gds_va = job->gds_va;
156 init_shadow = job->init_shadow;
157 af = job->hw_fence;
158 /* Save the context of the job for reset handling.
159 * The driver needs this so it can skip the ring
160 * contents for guilty contexts.
161 */
162 af->context = fence_ctx;
163 /* the vm fence is also part of the job's context */
164 job->hw_vm_fence->context = fence_ctx;
165 } else {
166 vm = NULL;
167 fence_ctx = 0;
168 shadow_va = 0;
169 csa_va = 0;
170 gds_va = 0;
171 init_shadow = false;
172 af = kzalloc(sizeof(*af), GFP_ATOMIC);
173 if (!af)
174 return -ENOMEM;
175 }
176
177 if (!ring->sched.ready) {
178 dev_err(adev->dev, "couldn't schedule ib on ring <%s>\n", ring->name);
179 r = -EINVAL;
180 goto free_fence;
181 }
182
183 if (vm && !job->vmid) {
184 dev_err(adev->dev, "VM IB without ID\n");
185 r = -EINVAL;
186 goto free_fence;
187 }
188
189 if ((ib->flags & AMDGPU_IB_FLAGS_SECURE) &&
190 (!ring->funcs->secure_submission_supported)) {
191 dev_err(adev->dev, "secure submissions not supported on ring <%s>\n", ring->name);
192 r = -EINVAL;
193 goto free_fence;
194 }
195
196 alloc_size = ring->funcs->emit_frame_size + num_ibs *
197 ring->funcs->emit_ib_size;
198
199 r = amdgpu_ring_alloc(ring, alloc_size);
200 if (r) {
201 dev_err(adev->dev, "scheduling IB failed (%d).\n", r);
202 goto free_fence;
203 }
204
205 need_ctx_switch = ring->current_ctx != fence_ctx;
206 if (ring->funcs->emit_pipeline_sync && job &&
207 ((tmp = amdgpu_sync_get_fence(&job->explicit_sync)) ||
208 need_ctx_switch || amdgpu_vm_need_pipeline_sync(ring, job))) {
209
210 need_pipe_sync = true;
211
212 if (tmp)
213 trace_amdgpu_ib_pipe_sync(job, tmp);
214
215 dma_fence_put(tmp);
216 }
217
218 if ((ib->flags & AMDGPU_IB_FLAG_EMIT_MEM_SYNC) && ring->funcs->emit_mem_sync)
219 ring->funcs->emit_mem_sync(ring);
220
221 if (ring->funcs->emit_wave_limit &&
222 ring->hw_prio == AMDGPU_GFX_PIPE_PRIO_HIGH)
223 ring->funcs->emit_wave_limit(ring, true);
224
225 if (ring->funcs->insert_start)
226 ring->funcs->insert_start(ring);
227
228 if (job) {
229 r = amdgpu_vm_flush(ring, job, need_pipe_sync);
230 if (r) {
231 amdgpu_ring_undo(ring);--> 232 return r;
The patch changed the other error paths to goto free_fence but this one was accidentally skipped.
233 }
234 }
235
236 amdgpu_ring_ib_begin(ring);
237
238 if (ring->funcs->emit_gfx_shadow && adev->gfx.cp_gfx_shadow)
239 amdgpu_ring_emit_gfx_shadow(ring, shadow_va, csa_va, gds_va,
240 init_shadow, vmid);
241
242 if (ring->funcs->init_cond_exec)
243 cond_exec = amdgpu_ring_init_cond_exec(ring,
244 ring->cond_exe_gpu_addr);
245
246 amdgpu_device_flush_hdp(adev, ring);
247
248 if (need_ctx_switch)
249 status |= AMDGPU_HAVE_CTX_SWITCH;
250
251 if (job && ring->funcs->emit_cntxcntl) {
252 status |= job->preamble_status;
253 status |= job->preemption_status;
254 amdgpu_ring_emit_cntxcntl(ring, status);
255 }
256
257 /* Setup initial TMZiness and send it off.
258 */
259 secure = false;
260 if (job && ring->funcs->emit_frame_cntl) {
261 secure = ib->flags & AMDGPU_IB_FLAGS_SECURE;
262 amdgpu_ring_emit_frame_cntl(ring, true, secure);
263 }
264
265 for (i = 0; i < num_ibs; ++i) {
266 ib = &ibs[i];
267
268 if (job && ring->funcs->emit_frame_cntl) {
269 if (secure != !!(ib->flags & AMDGPU_IB_FLAGS_SECURE)) {
270 amdgpu_ring_emit_frame_cntl(ring, false, secure);
271 secure = !secure;
272 amdgpu_ring_emit_frame_cntl(ring, true, secure);
273 }
274 }
275
276 amdgpu_ring_emit_ib(ring, job, ib, status);
277 status &= ~AMDGPU_HAVE_CTX_SWITCH;
278 }
279
280 if (job && ring->funcs->emit_frame_cntl)
281 amdgpu_ring_emit_frame_cntl(ring, false, secure);
282
283 amdgpu_device_invalidate_hdp(adev, ring);
284
285 if (ib->flags & AMDGPU_IB_FLAG_TC_WB_NOT_INVALIDATE)
286 fence_flags |= AMDGPU_FENCE_FLAG_TC_WB_ONLY;
287
288 /* wrap the last IB with fence */
289 if (job && job->uf_addr) {
290 amdgpu_ring_emit_fence(ring, job->uf_addr, job->uf_sequence,
291 fence_flags | AMDGPU_FENCE_FLAG_64BIT);
292 }
293
294 if (ring->funcs->emit_gfx_shadow && ring->funcs->init_cond_exec &&
295 adev->gfx.cp_gfx_shadow) {
296 amdgpu_ring_emit_gfx_shadow(ring, 0, 0, 0, false, 0);
297 amdgpu_ring_init_cond_exec(ring, ring->cond_exe_gpu_addr);
298 }
299
300 r = amdgpu_fence_emit(ring, af, fence_flags);
301 if (r) {
302 dev_err(adev->dev, "failed to emit fence (%d)\n", r);
303 if (job && job->vmid)
304 amdgpu_vmid_reset(adev, ring->vm_hub, job->vmid);
305 amdgpu_ring_undo(ring);
306 goto free_fence;
307 }
308 *f = &af->base;
309 /* get a ref for the job */
310 if (job)
311 dma_fence_get(*f);
312
313 if (ring->funcs->insert_end)
314 ring->funcs->insert_end(ring);
315
316 amdgpu_ring_patch_cond_exec(ring, cond_exec);
317
318 ring->current_ctx = fence_ctx;
319 if (job && ring->funcs->emit_switch_buffer)
320 amdgpu_ring_emit_switch_buffer(ring);
321
322 if (ring->funcs->emit_wave_limit &&
323 ring->hw_prio == AMDGPU_GFX_PIPE_PRIO_HIGH)
324 ring->funcs->emit_wave_limit(ring, false);
325
326 /* Save the wptr associated with this fence.
327 * This must be last for resets to work properly
328 * as we need to save the wptr associated with this
329 * fence so we know what rings contents to backup
330 * after we reset the queue.
331 */
332 amdgpu_fence_save_wptr(af);
333
334 amdgpu_ring_ib_end(ring);
335 amdgpu_ring_commit(ring);
336
337 return 0;
338
339 free_fence:
340 if (!job)
341 kfree(af);
342 return r;
343 }regards,
dan carpenter
[bug report] bio: add allocation cache abstraction
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Jens Axboe,
Commit be4d234d7aeb ("bio: add allocation cache abstraction") from Mar 8, 2021 (linux-next), leads to the following Smatch static checker warning:
block/bio.c:790 bio_cpu_dead() error: potential null dereference 'bs'. (hlist_entry_safe() returns null)
block/bio.c
785 static int bio_cpu_dead(unsigned int cpu, struct hlist_node *node)
786 {
787 struct bio_set *bs;
788
789 bs = hlist_entry_safe(node, struct bio_set, cpuhp_dead);--> 790 if (bs->cache) {
It doesn't really make sense to use hlist_entry_safe() instead of hlist_entry() if we're not going to check for NULL.
791 struct bio_alloc_cache *cache = per_cpu_ptr(bs->cache, cpu);
792
793 bio_alloc_cache_prune(cache, -1U);
794 }
795 return 0;
796 }regards,
dan carpenter
[bug report] ASoC: codecs: ACF bin parsing and check library file for aw88395
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Weidong Wang,
Commit 4345865b003b ("ASoC: codecs: ACF bin parsing and check library file for aw88395") from Jan 13, 2023 (linux-next), leads to the following Smatch static checker warning:
sound/soc/codecs/aw88395/aw88395_lib.c:712 aw_dev_create_prof_name_list_v1() warn: double check that we're allocating correct size: 8 vs 32
sound/soc/codecs/aw88395/aw88395_lib.c
701 static int aw_dev_create_prof_name_list_v1(struct aw_device *aw_dev)
702 {
703 struct aw_prof_info *prof_info = &aw_dev->prof_info;
704 struct aw_prof_desc *prof_desc = prof_info->prof_desc;
705 int i;
706
707 if (!prof_desc) {
708 dev_err(aw_dev->dev, "prof_desc is NULL");
709 return -EINVAL;
710 }
711
--> 712 prof_info->prof_name_list = devm_kzalloc(aw_dev->dev,
713 prof_info->count * PROFILE_STR_MAX,
^^^^^^^^^^^^^^^PROFILE_STR_MAX this is the maximum length of the string but we only need to allocate a pointer to the string sizeof(char *). So this allocates 32bytes instead of just 8.
It's a small waste of space but otherwise it's harmless.
714 GFP_KERNEL);
715 if (!prof_info->prof_name_list)
716 return -ENOMEM;
717
718 for (i = 0; i < prof_info->count; i++) {
719 prof_desc[i].id = i;
720 prof_info->prof_name_list[i] = prof_desc[i].prf_str;
721 dev_dbg(aw_dev->dev, "prof name is %s", prof_info->prof_name_list[i]);
722 }
723
724 return 0;
725 }regards,
dan carpenter
[bug report] xfrm: always fail xfrm_dev_{state,policy}_flush_secctx_check()
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Tetsuo Handa,
Commit 638361ad7ab2 ("xfrm: always fail xfrm_dev_{state,policy}_flush_secctx_check()") from Feb 2, 2026 (linux-next), leads to the following Smatch static checker warning:
net/xfrm/xfrm_state.c:898 xfrm_dev_state_flush_secctx_check() warn: was '== (-1)' instead of '='
net/xfrm/xfrm_state.c
888 int i, err = 0;
889
890 for (i = 0; i <= net->xfrm.state_hmask; i++) {
891 struct xfrm_state *x;
892 struct xfrm_dev_offload *xso;
893
894 hlist_for_each_entry(x, net->xfrm.state_bydst+i, bydst) {
895 xso = &x->xso;
896
897 if (xso->dev == dev &&
--> 898 (err = -EPERM) != 0) {
^= vs == bug.
899 pr_info("%s: LSM policy is rejecting this operation.\n", __func__);
900 dump_stack();
901 xfrm_audit_state_delete(x, 0, task_valid);
902 return err;
903 }
904 }
905 }
906
907 return err;
908 }regards,
dan carpenter
Re: [bug report] xfrm: always fail xfrm_dev_{state,policy}_flush_secctx_check()
Quoted 11 lines · Dan Carpenter
[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]Hello Tetsuo Handa,
Commit
638361ad7ab2("xfrm: always fail xfrm_dev_{state,policy}_flush_secctx_check()") from Feb 2, 2026 (linux-next), leads to the following Smatch static checker warning:net/xfrm/xfrm_state.c:898 xfrm_dev_state_flush_secctx_check() warn: was '== (-1)' instead of '='
Thank you, but this change is intended for demonstrating to SELinux people that making xfrm_dev_{state,policy}_flush() no-op results in hung task bug
( https://lkml.kernel.org/r/[email protected] ).
That change is already removed, and we are waiting for
https://lkml.kernel.org/r/[email protected]
to be applied.
[bug report] wifi: mwifiex: Allocate dev name earlier for interface workqueue name
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Chen-Yu Tsai,
Commit 7bab5bdb81e3 ("wifi: mwifiex: Allocate dev name earlier for interface workqueue name") from Jan 7, 2026 (linux-next), leads to the following Smatch static checker warning:
drivers/net/wireless/marvell/mwifiex/cfg80211.c:3214 mwifiex_add_virtual_intf() warn: passing positive error code '(-23)-(-22),(-12),1-64' to 'ERR_PTR'
drivers/net/wireless/marvell/mwifiex/cfg80211.c
3147
3148 SET_NETDEV_DEV(dev, adapter->dev);
3149
3150 ret = dev_alloc_name(dev, name);
3151 if (ret)
3152 goto err_alloc_name;
The dev_alloc_name() function can return 1-64 if the name has a "%d" in it. None of the other nine callers use the positive returns. The only thing it does is cause a crash here. We should probably fix dev_alloc_name() as well as changing this to if (ret < 0) {.
3153
3154 priv->dfs_cac_workqueue = alloc_workqueue("MWIFIEX_DFS_CAC-%s",
3155 WQ_HIGHPRI |
3156 WQ_MEM_RECLAIM |
3157 WQ_UNBOUND, 0, dev->name);
3158 if (!priv->dfs_cac_workqueue) {
3159 mwifiex_dbg(adapter, ERROR, "cannot alloc DFS CAC queue\n");
3160 ret = -ENOMEM;
3161 goto err_alloc_cac; 3162 }
3163
regards,
dan carpenter
[bug report] apparmor: add support loading per permission tagging
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello John Johansen,
Commit 3d28e2397af7 ("apparmor: add support loading per permission tagging") from Apr 1, 2025 (linux-next), leads to the following Smatch static checker warning:
security/apparmor/policy_unpack.c:966 unpack_pdb() warn: unsigned 'unpack_tags(e, &pdb->tags, info)' is never less than zero.
security/apparmor/policy_unpack.c
951 static int unpack_pdb(struct aa_ext *e, struct aa_policydb **policy,
952 bool required_dfa, bool required_trans,
953 const char **info)
954 {
955 struct aa_policydb *pdb;
956 void *pos = e->pos;
957 int i, flags, error = -EPROTO;
958 ssize_t size;
959 u32 version = 0;
960
961 pdb = aa_alloc_pdb(GFP_KERNEL);
962 if (!pdb)
963 return -ENOMEM;
964
965 AA_DEBUG(DEBUG_UNPACK, "unpacking tags");
--> 966 if (unpack_tags(e, &pdb->tags, info) < 0)
^^^^^^^^^^^Signedness bug. unpack_tags() is unsigned.
967 goto fail;
968 AA_DEBUG(DEBUG_UNPACK, "done unpacking tags");
969
970 size = unpack_perms_table(e, &pdb->perms);
971 if (size < 0) {
972 error = size;
973 pdb->perms = NULL;regards,
dan carpenter
PATCH 1/1 apparmor: fix signedness bug in unpack_tags()
Smatch static checker warning:
security/apparmor/policy_unpack.c:966 unpack_pdb()
warn: unsigned 'unpack_tags(e, &pdb->tags, info)' is never less than zero.unpack_tags() is declared with return type size_t (unsigned) but returns negative errno values on failure. The caller in unpack_pdb() tests the return with < 0, which is always false for an unsigned type, making error handling dead code. Malformed tag data would be silently accepted instead of causing a load failure.
Change return type of unpack_tags() from size_t to int to match the functions's actual semantic.
--- security/apparmor/policy_unpack.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
security/apparmor/policy_unpack.c +1 -1
@@ -835,7 +835,7 @@ static int unpack_tag_headers(struct aa_ext *e, struct aa_tags_struct *tags) } -static size_t unpack_tags (struct aa_ext *e,struct aa_tags_struct *tags, +static int unpack_tags (struct aa_ext *e,struct aa_tags_struct *tags,const char **info) {int error = -EPROTO ;
Signature · 1 line
2.51.0
[bug report] regulator: s2mps11: add S2MPG10 regulator
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello André Draszik,
Commit a2b8b9f33ce3 ("regulator: s2mps11: add S2MPG10 regulator") from Jan 22, 2026 (linux-next), leads to the following Smatch static checker warning:
drivers/regulator/s2mps11.c:483 s2mpg10_of_parse_cb() warn: off by one 'ext_control' == ARRAY_SIZE()?
drivers/regulator/s2mps11.c
458 if (of_property_read_u32(np, "samsung,ext-control", &ext_control))
459 return 0;
460
461 switch (s2mps11->dev_type) {
462 case S2MPG10:
463 switch (desc->id) {
464 case S2MPG10_BUCK1 ... S2MPG10_BUCK7:
465 case S2MPG10_BUCK10:
466 case S2MPG10_LDO3 ... S2MPG10_LDO19:
467 if (ext_control > S2MPG10_EXTCTRL_TCXO_ON2)
468 return -EINVAL;
469 break;
470
471 case S2MPG10_LDO20:
472 if (ext_control < S2MPG10_EXTCTRL_LDO20M_EN2 ||
473 ext_control > S2MPG10_EXTCTRL_LDO20M_EN)
474 return -EINVAL;
475 break;
476
477 default:
478 return -EINVAL;
479 }
480
481 if (ext_control > ARRAY_SIZE(ext_control_s2mpg10))This should be >= ARRAY_SIZE(). Although the earlier checks prevent an out of bounds access, it's still worth fixing the sanity check.
482 return -EINVAL;
--> 483 ext_control = ext_control_s2mpg10[ext_control];
484 break;
485
486 case S2MPG11:
487 switch (desc->id) {
488 case S2MPG11_BUCK1 ... S2MPG11_BUCK3:regards,
dan carpenter
Re: [bug report] regulator: s2mps11: add S2MPG10 regulator
Hi Dan,
Quoted 38 lines · Dan Carpenter
[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]Hello André Draszik,
Commit
a2b8b9f33ce3("regulator: s2mps11: add S2MPG10 regulator") from Jan 22, 2026 (linux-next), leads to the following Smatch static checker warning:drivers/regulator/s2mps11.c:483 s2mpg10_of_parse_cb() warn: off by one 'ext_control' == ARRAY_SIZE()?
drivers/regulator/s2mps11.c
458 if (of_property_read_u32(np, "samsung,ext-control", &ext_control)) 459 return 0;
460
461 switch (s2mps11->dev_type) {
462 case S2MPG10:
463 switch (desc->id) {
464 caseS2MPG10_BUCK1...S2MPG10_BUCK7:
465 caseS2MPG10_BUCK10:
466 caseS2MPG10_LDO3...S2MPG10_LDO19:
467 if (ext_control>S2MPG10_EXTCTRL_TCXO_ON2) 468 return-EINVAL;
469 break;
470
471 caseS2MPG10_LDO20:
472 if (ext_control<S2MPG10_EXTCTRL_LDO20M_EN2|| 473ext_control>S2MPG10_EXTCTRL_LDO20M_EN) 474 return-EINVAL;
475 break;
476
477 default:
478 return-EINVAL;
479 }
480
481 if (ext_control>ARRAY_SIZE(ext_control_s2mpg10))
Quoted 2 lines
This should be >= ARRAY_SIZE(). Although the earlier checks prevent an out of bounds access, it's still worth fixing the sanity check.
Thanks, yes. Although this was on purpose to avoid duplicated checks. I'd say this test could be removed altogether as it's just confusing and useless.
Cheers,
Andre'
[bug report] btrfs: tests: zoned: add tests cases for zoned code
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Naohiro Aota,
Commit df321b214f62 ("btrfs: tests: zoned: add tests cases for zoned code") from Feb 4, 2026 (linux-next), leads to the following Smatch static checker warning:
fs/btrfs/tests/zoned-tests.c:68 test_load_zone_info()
warn: duplicate check 'zone_info' (previous on line 62)
fs/btrfs/tests/zoned-tests.c
40 static int test_load_zone_info(struct btrfs_fs_info *fs_info,
41 const struct load_zone_info_test_vector *test)
42 {
43 struct btrfs_block_group *bg __free(btrfs_free_dummy_block_group) = NULL;
44 struct btrfs_chunk_map *map __free(btrfs_free_chunk_map) = NULL;
45 struct zone_info AUTO_KFREE(zone_info);
46 unsigned long AUTO_KFREE(active);
47 int ret;
48
49 bg = btrfs_alloc_dummy_block_group(fs_info, test->bg_length);
50 if (!bg) {
51 test_std_err(TEST_ALLOC_BLOCK_GROUP);
52 return -ENOMEM;
53 }
54
55 map = btrfs_alloc_chunk_map(test->num_stripes, GFP_KERNEL);
56 if (!map) {
57 test_std_err(TEST_ALLOC_EXTENT_MAP);
58 return -ENOMEM;
59 }
60
61 zone_info = kcalloc(test->num_stripes, sizeof(*zone_info), GFP_KERNEL);
62 if (!zone_info) {
63 test_err("cannot allocate zone info");
64 return -ENOMEM;
65 }
66
67 active = bitmap_zalloc(test->num_stripes, GFP_KERNEL);--> 68 if (!zone_info) {
s/zone_info/active/
69 test_err("cannot allocate active bitmap");
70 return -ENOMEM;
71 }
72 regards,
dan carpenter
Re: [bug report] btrfs: tests: zoned: add tests cases for zoned code
Quoted 40 lines · Dan Carpenter
[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Naohiro Aota,Commit
df321b214f62("btrfs: tests: zoned: add tests cases for zoned code") from Feb 4, 2026 (linux-next), leads to the following Smatch static checker warning:
fs/btrfs/tests/zoned-tests.c:68test_load_zone_info()
warn: duplicate check 'zone_info' (previous on line 62)
fs/btrfs/tests/zoned-tests.c40 static int test_load_zone_info(struct btrfs_fs_info *fs_info, 41 const struct load_zone_info_test_vector *test) 42 { 43 struct btrfs_block_group *bg __free(btrfs_free_dummy_block_group) = NULL; 44 struct btrfs_chunk_map *map __free(btrfs_free_chunk_map) = NULL; 45 struct zone_info AUTO_KFREE(zone_info); 46 unsigned long AUTO_KFREE(active); 47 int ret; 48 49 bg = btrfs_alloc_dummy_block_group(fs_info, test->bg_length); 50 if (!bg) { 51 test_std_err(TEST_ALLOC_BLOCK_GROUP); 52 return -ENOMEM; 53 } 54 55 map = btrfs_alloc_chunk_map(test->num_stripes, GFP_KERNEL); 56 if (!map) { 57 test_std_err(TEST_ALLOC_EXTENT_MAP); 58 return -ENOMEM; 59 } 60 61 zone_info = kcalloc(test->num_stripes, sizeof(*zone_info), GFP_KERNEL); 62 if (!zone_info) { 63 test_err("cannot allocate zone info"); 64 return -ENOMEM; 65 } 66 67 active = bitmap_zalloc(test->num_stripes, GFP_KERNEL);
Quoted 3 lines
--> 68 if (!zone_info) {
s/zone_info/active/
Thanks for the report, fixed in git.
[bug report] ASoC: SOF: sof-audio: Add support for loopback capture
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Ranjani Sridharan,
Commit c4b37c21c75d ("ASoC: SOF: sof-audio: Add support for loopback capture") from Feb 4, 2026 (linux-next), leads to the following Smatch static checker warning:
sound/soc/sof/sof-audio.c:534 sof_prepare_widgets_in_path() error: uninitialized symbol 'widget_ops'.
sound/soc/sof/sof-audio.c
478 static int
479 sof_prepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget *widget,
480 struct snd_pcm_hw_params *fe_params,
481 struct snd_sof_platform_stream_params *platform_params,
482 struct snd_pcm_hw_params *pipeline_params, int dir,
483 struct snd_soc_dapm_widget_list *list)
484 {
485 const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
486 struct snd_sof_widget *swidget = widget->dobj.private;
487 const struct sof_ipc_tplg_widget_ops *widget_ops;
488 struct snd_soc_dapm_path *p;
489 int ret;
490
491 if (is_virtual_widget(sdev, widget, __func__))
492 return 0;
493
494 if (!swidget)
495 goto sink_prepare;
^^^^^^^^^^^^^^^^^widget_ops is uninitialized.
496
497 widget_ops = tplg_ops ? tplg_ops->widget : NULL;
498 if (!widget_ops)
499 return 0;
500
501 if (swidget->spipe && swidget->spipe->direction_valid &&
502 !sof_widget_in_same_direction(swidget, dir))
503 return 0;
504
505 /* skip widgets already prepared or aggregated DAI widgets*/
506 if (!widget_ops[widget->id].ipc_prepare || swidget->prepared ||
507 is_aggregated_dai(swidget))
508 goto sink_prepare;
509
510 /* prepare the source widget */
511 ret = widget_ops[widget->id].ipc_prepare(swidget, fe_params, platform_params,
512 pipeline_params, dir);
513 if (ret < 0) {
514 dev_err(sdev->dev, "failed to prepare widget %s\n", widget->name);
515 return ret;
516 }
517
518 swidget->prepared = true;
519
520 sink_prepare:
521 /* prepare all widgets in the sink paths */
522 snd_soc_dapm_widget_for_each_sink_path(widget, p) {
523 if (!widget_in_list(list, p->sink))
524 continue;
525
526 if (!p->walking && p->sink->dobj.private) {
527 p->walking = true;
528 ret = sof_prepare_widgets_in_path(sdev, p->sink, fe_params,
529 platform_params, pipeline_params, dir,
530 list);
531 p->walking = false;
532 if (ret < 0) {
533 /* unprepare the source widget */
--> 534 if (widget_ops[widget->id].ipc_unprepare &&
535 swidget && swidget->prepared && swidget->use_count == 0) {We need to check that swidget is non-NULL first before checking widget_ops[widget->id].ipc_unprepare, otherwise widget_ops is uninitialized and it leads to a crash.
Wait, the zero day bot already reported this on Jan 5th.
https://lore.kernel.org/all/[email protected]/
536 widget_ops[widget->id].ipc_unprepare(swidget);
537 swidget->prepared = false;
538 }
539 return ret;
540 }
541 }
542 }
543
544 return 0;
545 }regards,
dan carpenter
[bug report] bpf: Fix a potential use-after-free of BTF object
In reply to Dan Carpenter[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]
Hello Anton Protopopov,
Commit c81e4322acf0 ("bpf: Fix a potential use-after-free of BTF object") from Feb 9, 2026 (linux-next), leads to the following Smatch static checker warning:
kernel/bpf/verifier.c:25375 add_fd_from_fd_array() warn: double fget(): 'fd'
kernel/bpf/verifier.c
25360 static int add_fd_from_fd_array(struct bpf_verifier_env *env, int fd)
25361 {
25362 struct bpf_map *map;
25363 struct btf *btf;
25364 CLASS(fd, f)(fd);This assigns f = fdget(fd);
25365 int err;
25366
25367 map = __bpf_map_get(f);
25368 if (!IS_ERR(map)) {
25369 err = __add_used_map(env, map);
25370 if (err < 0)
25371 return err;
25372 return 0;
25373 }
25374
--> 25375 btf = btf_get_by_fd(fd);
^^This re-uses the fd. The reason behind the warning is that the user could have changed the fd to point to a different file from the start of the function.
25376 if (!IS_ERR(btf))
25377 return __add_used_btf(env, btf);
25378
25379 verbose(env, "fd %d is not pointing to valid bpf_map or btf\n", fd);
25380 return PTR_ERR(map);
25381 }regards,
dan carpenter
Re: [bug report] bpf: Fix a potential use-after-free of BTF object
Quoted 33 lines · Dan Carpenter
[ Smatch checking is paused while we raise funding. #SadFace
https://lore.kernel.org/all/[email protected]/ -dan ]Hello Anton Protopopov,
Commit
c81e4322acf0("bpf: Fix a potential use-after-free of BTF object") from Feb 9, 2026 (linux-next), leads to the following Smatch static checker warning:kernel/bpf/verifier.c:25375 add_fd_from_fd_array() warn: double fget(): 'fd'
kernel/bpf/verifier.c25360 static int add_fd_from_fd_array(struct bpf_verifier_env *env, int fd) 25361 { 25362 struct bpf_map *map; 25363 struct btf *btf; 25364 CLASS(fd, f)(fd);This assigns f = fdget(fd);
25365 int err; 25366 25367 map = __bpf_map_get(f); 25368 if (!IS_ERR(map)) { 25369 err = __add_used_map(env, map); 25370 if (err < 0) 25371 return err; 25372 return 0; 25373 } 25374 --> 25375 btf = btf_get_by_fd(fd); ^^
Quoted 3 lines
This re-uses the fd. The reason behind the warning is that the user could have changed the fd to point to a different file from the start of the function.
True, this could happen. Not sure this is a real problem (if a user replaced this by a valid BTF, well...)
Quoted 2 lines
25376 if (!IS_ERR(btf))
25377 return __add_used_btf(env, btf);The problem with this piece of code is that originally I wanted to keep naming/appearance in sync, but the corresponding map/btf functions, historically, behave a bit different...
To keep things working and to address the bug report in this thread, one fix is required:
- btf = btf_get_by_fd(fd);
- if (!IS_ERR(btf))
+ btf = __btf_get_by_fd(f);
+ if (!IS_ERR(btf)) {
+ btf_get(btf);
return __add_used_btf(env, btf);+ }
I will send this fix later.
Quoted 6 lines
25379 verbose(env, "fd %d is not pointing to valid bpf_map or btf\n", fd); 25380 return PTR_ERR(map); 25381 }regards,
dan carpenter