Powered by Linux
[PATCH 3/3] check_kernel_printf.c: warn about "%lx", (long)ptr — Semantic Matching Tool

[PATCH 3/3] check_kernel_printf.c: warn about "%lx", (long)ptr

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



For some reason this spits out an enourmous amount of false positives,
making this entirely useless. We hit a lot of "%lx", (long)(a - b),
but I don't understand why the a-b expression (a pointer difference)
passes is_ptr_type().

Signed-off-by: Rasmus Villemoes <rv@xxxxxxxxxxxxxxxxxx>
---
 check_kernel_printf.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/check_kernel_printf.c b/check_kernel_printf.c
index e5f788bd..f9f5ea6b 100644
--- a/check_kernel_printf.c
+++ b/check_kernel_printf.c
@@ -939,6 +939,35 @@ static bool is_integer_specifier(int type)
 	}
 }
 
+static int
+is_cast_expr(struct expression *expr)
+{
+	switch (expr->type) {
+	case EXPR_CAST:
+	case EXPR_FORCE_CAST:
+		/* not EXPR_IMPLIED_CAST for our purposes */
+		return 1;
+	default:
+		return 0;
+	}
+}
+
+static void
+check_cast_from_pointer(const char *fmt, int len, struct expression *arg, int va_idx)
+{
+	/*
+	 * This can easily be fooled by passing 0+(long)ptr or doing
+	 * "long local_var = (long)ptr" and passing local_var to
+	 * %lx. Tough.
+	 */
+	if (!is_cast_expr(arg))
+		return;
+	while (is_cast_expr(arg))
+		arg = arg->cast_expression;
+	if (is_ptr_type(get_type(arg)))
+		sm_msg("warn: argument %d to %.*s specifier is cast from pointer",
+			va_idx, len, fmt);
+}
 
 static void
 do_check_printf_call(const char *caller, const char *name, struct expression *callexpr, struct expression *fmtexpr, int vaidx)
@@ -1015,6 +1044,8 @@ do_check_printf_call(const char *caller, const char *name, struct expression *ca
 			if (spec.base != 16 && has_hex_prefix(orig_fmt, old_fmt))
 				sm_msg("warn: '%.2s' prefix is confusing together with '%.*s' specifier",
 				       old_fmt-2, (int)(fmt-old_fmt), old_fmt);
+
+			check_cast_from_pointer(old_fmt, read, arg, vaidx);
 		}
 
 		switch (spec.type) {
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe smatch" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux