mm/page_owner: use scnprintf() to avoid excessive buffer overrun check
authorWaiman Long <longman@redhat.com>
Fri, 25 Mar 2022 01:09:05 +0000 (18:09 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 25 Mar 2022 02:06:44 +0000 (19:06 -0700)
The snprintf() function can return a length greater than the given input
size.  That will require a check for buffer overrun after each
invocation of snprintf().  scnprintf(), on the other hand, will never
return a greater length.

By using scnprintf() in selected places, we can avoid some buffer
overrun checks except after stack_depot_snprint() and after the last
snprintf().

Link: https://lkml.kernel.org/r/20220202203036.744010-3-longman@redhat.com
Signed-off-by: Waiman Long <longman@redhat.com>
Acked-by: David Rientjes <rientjes@google.com>
Reviewed-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Acked-by: Rafael Aquini <aquini@redhat.com>
Acked-by: Mike Rapoport <rppt@linux.ibm.com>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Ira Weiny <ira.weiny@intel.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Petr Mladek <pmladek@suse.com>
Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Steven Rostedt (Google) <rostedt@goodmis.org>
Cc: Vladimir Davydov <vdavydov.dev@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
mm/page_owner.c

index 99e360d..28dac73 100644 (file)
@@ -338,19 +338,16 @@ print_page_owner(char __user *buf, size_t count, unsigned long pfn,
        if (!kbuf)
                return -ENOMEM;
 
-       ret = snprintf(kbuf, count,
+       ret = scnprintf(kbuf, count,
                        "Page allocated via order %u, mask %#x(%pGg), pid %d, ts %llu ns, free_ts %llu ns\n",
                        page_owner->order, page_owner->gfp_mask,
                        &page_owner->gfp_mask, page_owner->pid,
                        page_owner->ts_nsec, page_owner->free_ts_nsec);
 
-       if (ret >= count)
-               goto err;
-
        /* Print information relevant to grouping pages by mobility */
        pageblock_mt = get_pageblock_migratetype(page);
        page_mt  = gfp_migratetype(page_owner->gfp_mask);
-       ret += snprintf(kbuf + ret, count - ret,
+       ret += scnprintf(kbuf + ret, count - ret,
                        "PFN %lu type %s Block %lu type %s Flags %pGp\n",
                        pfn,
                        migratetype_names[page_mt],
@@ -358,19 +355,14 @@ print_page_owner(char __user *buf, size_t count, unsigned long pfn,
                        migratetype_names[pageblock_mt],
                        &page->flags);
 
-       if (ret >= count)
-               goto err;
-
        ret += stack_depot_snprint(handle, kbuf + ret, count - ret, 0);
        if (ret >= count)
                goto err;
 
        if (page_owner->last_migrate_reason != -1) {
-               ret += snprintf(kbuf + ret, count - ret,
+               ret += scnprintf(kbuf + ret, count - ret,
                        "Page has been migrated, last migrate reason: %s\n",
                        migrate_reason_names[page_owner->last_migrate_reason]);
-               if (ret >= count)
-                       goto err;
        }
 
        ret += snprintf(kbuf + ret, count - ret, "\n");