clkdev: report over-sized strings when creating clkdev entries
authorRussell King (Oracle) <rmk+kernel@armlinux.org.uk>
Fri, 15 Mar 2024 11:45:11 +0000 (11:45 +0000)
committerRussell King (Oracle) <rmk+kernel@armlinux.org.uk>
Wed, 8 May 2024 15:26:30 +0000 (16:26 +0100)
Report an error when an attempt to register a clkdev entry results in a
truncated string so the problem can be easily spotted.

Reported by: Duanqiang Wen <duanqiangwen@net-swift.com>
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
drivers/clk/clkdev.c

index ee37d0be6877db7070f51ad264bdc1a9da02d36a..56a12f1da472d70f9a504b49a13c7a5fb5f5b793 100644 (file)
@@ -158,23 +158,54 @@ vclkdev_alloc(struct clk_hw *hw, const char *con_id, const char *dev_fmt,
        va_list ap)
 {
        struct clk_lookup_alloc *cla;
+       struct va_format vaf;
+       const char *failure;
+       va_list ap_copy;
+       size_t max_size;
+       ssize_t res;
 
        cla = kzalloc(sizeof(*cla), GFP_KERNEL);
        if (!cla)
                return NULL;
 
+       va_copy(ap_copy, ap);
+
        cla->cl.clk_hw = hw;
        if (con_id) {
-               strscpy(cla->con_id, con_id, sizeof(cla->con_id));
+               res = strscpy(cla->con_id, con_id, sizeof(cla->con_id));
+               if (res < 0) {
+                       max_size = sizeof(cla->con_id);
+                       failure = "connection";
+                       goto fail;
+               }
                cla->cl.con_id = cla->con_id;
        }
 
        if (dev_fmt) {
-               vscnprintf(cla->dev_id, sizeof(cla->dev_id), dev_fmt, ap);
+               res = vsnprintf(cla->dev_id, sizeof(cla->dev_id), dev_fmt, ap);
+               if (res >= sizeof(cla->dev_id)) {
+                       max_size = sizeof(cla->dev_id);
+                       failure = "device";
+                       goto fail;
+               }
                cla->cl.dev_id = cla->dev_id;
        }
 
+       va_end(ap_copy);
+
        return &cla->cl;
+
+fail:
+       if (dev_fmt)
+               vaf.fmt = dev_fmt;
+       else
+               vaf.fmt = "null-device";
+       vaf.va = &ap_copy;
+       pr_err("%pV:%s: %s ID is greater than %zu\n",
+              &vaf, con_id, failure, max_size);
+       va_end(ap_copy);
+       kfree(cla);
+       return NULL;
 }
 
 static struct clk_lookup *