Hi,

I have this .cocci:

/// Unchecked use of snprintf() return values can lead to bugs, especially
/// when returned or used to increment a buffer position. This is because
/// snprintf() can return how much it WOULD have written, had it not run out
/// of space. Instead, use scnprintf() which will report only how much was
/// actually written, keeping any overflows from happening.
///
// Confidence: Moderate
// Copyright: (C) 2018 Kees Cook, Google. GPLv2.
// URL: http://coccinelle.lip6.fr/
// Options: --all-includes --include-headers

virtual patch

@sum_patch depends on patch exists@
expression LEN, BUF, SIZE;
identifier FUNC !~ "^\(snprintf\|scnprintf\)$";
@@

(
  LEN =
-snprintf
+scnprintf
  (BUF, SIZE, ...);
|
  LEN +=
-snprintf
+scnprintf
  (BUF + LEN, SIZE - LEN, ...);
)
  ... when != LEN > SIZE
      when != LEN >= SIZE
      when any
(
  return LEN;
|
  FUNC(..., <+...LEN...+>, ...)
)

It matches net/sunrpc/addr.c:

--- net/sunrpc/addr.c
+++ /tmp/cocci-output-43547-394eff-addr.c
@@ -79,7 +79,7 @@ static size_t rpc_ntop6(const struct soc
        if (sin6->sin6_scope_id == 0)
                return len;

-       rc = snprintf(scopebuf, sizeof(scopebuf), "%c%u",
+       rc = scnprintf(scopebuf, sizeof(scopebuf), "%c%u",
                        IPV6_SCOPE_DELIMITER, sin6->sin6_scope_id);
        if (unlikely((size_t)rc > sizeof(scopebuf)))
                return 0;

But I can't figure out why. I was trying to exclude matches against
sc?nprintf, but the FUNC line appears to make things crazy and break
the "when" check. If I remove the FUNC portion of the pattern, it's
fine, but then I miss a bunch of cases I *do* want to catch, etc.

Thanks!

-- 
Kees Cook
_______________________________________________
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci

Reply via email to