Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARM: 8503/1: clk_register_clkdev: remove format string interface

Many callers either use NULL or const strings for the third argument of
clk_register_clkdev. For those that do not and use a non-const string,
this is a risk for format strings being accidentally processed (for
example in device names). As this interface is already used as if it
weren't a format string (prints nothing when NULL), and there are zero
users of the format strings, remove the format string interface to make
sure format strings will not leak into the clkdev.

$ git grep '\bclk_register_clkdev\b' | grep % | wc -l
0

Unfortunately, all the internals expect a va_list even though they treat
a NULL format string as special. To deal with this, we must pass either
(..., "%s", string) or (..., NULL) so that a the va_list will be created
correctly (passing the name as an argument, not as a format string).

Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

authored by

Kees Cook and committed by
Russell King
416dd13a a34c6635

+26 -8
+25 -6
drivers/clk/clkdev.c
··· 353 353 } 354 354 EXPORT_SYMBOL(clkdev_drop); 355 355 356 + static struct clk_lookup *__clk_register_clkdev(struct clk_hw *hw, 357 + const char *con_id, 358 + const char *dev_id, ...) 359 + { 360 + struct clk_lookup *cl; 361 + va_list ap; 362 + 363 + va_start(ap, dev_id); 364 + cl = vclkdev_create(hw, con_id, dev_id, ap); 365 + va_end(ap); 366 + 367 + return cl; 368 + } 369 + 356 370 /** 357 371 * clk_register_clkdev - register one clock lookup for a struct clk 358 372 * @clk: struct clk to associate with all clk_lookups 359 373 * @con_id: connection ID string on device 360 - * @dev_id: format string describing device name 374 + * @dev_id: string describing device name 361 375 * 362 376 * con_id or dev_id may be NULL as a wildcard, just as in the rest of 363 377 * clkdev. ··· 382 368 * after clk_register(). 383 369 */ 384 370 int clk_register_clkdev(struct clk *clk, const char *con_id, 385 - const char *dev_fmt, ...) 371 + const char *dev_id) 386 372 { 387 373 struct clk_lookup *cl; 388 - va_list ap; 389 374 390 375 if (IS_ERR(clk)) 391 376 return PTR_ERR(clk); 392 377 393 - va_start(ap, dev_fmt); 394 - cl = vclkdev_create(__clk_get_hw(clk), con_id, dev_fmt, ap); 395 - va_end(ap); 378 + /* 379 + * Since dev_id can be NULL, and NULL is handled specially, we must 380 + * pass it as either a NULL format string, or with "%s". 381 + */ 382 + if (dev_id) 383 + cl = __clk_register_clkdev(__clk_get_hw(clk), con_id, "%s", 384 + dev_id); 385 + else 386 + cl = __clk_register_clkdev(__clk_get_hw(clk), con_id, NULL); 396 387 397 388 return cl ? 0 : -ENOMEM; 398 389 }
+1 -2
include/linux/clkdev.h
··· 44 44 void clkdev_add_table(struct clk_lookup *, size_t); 45 45 int clk_add_alias(const char *, const char *, const char *, struct device *); 46 46 47 - int clk_register_clkdev(struct clk *, const char *, const char *, ...) 48 - __printf(3, 4); 47 + int clk_register_clkdev(struct clk *, const char *, const char *); 49 48 int clk_register_clkdevs(struct clk *, struct clk_lookup *, size_t); 50 49 51 50 #ifdef CONFIG_COMMON_CLK