]> Git Repo - linux.git/blobdiff - lib/string_helpers.c
x86/config: Fix warning for 'make ARCH=x86_64 tinyconfig'
[linux.git] / lib / string_helpers.c
index 606c3099013fdd363098394adf88f4a679a03daa..69ba49b853c7755291886a2bff918fe0ffc4edaf 100644 (file)
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/string_helpers.h>
+#include <kunit/test.h>
+#include <kunit/test-bug.h>
 
 /**
  * string_get_size - get the size in the specified units
  * @size:      The size to be converted in blocks
  * @blk_size:  Size of the block (use 1 for size in bytes)
- * @units:     units to use (powers of 1000 or 1024)
+ * @units:     Units to use (powers of 1000 or 1024), whether to include space separator
  * @buf:       buffer to format to
  * @len:       length of buffer
  *
 int string_get_size(u64 size, u64 blk_size, const enum string_size_units units,
                    char *buf, int len)
 {
+       enum string_size_units units_base = units & STRING_UNITS_MASK;
        static const char *const units_10[] = {
-               "B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"
+               "", "k", "M", "G", "T", "P", "E", "Z", "Y",
        };
        static const char *const units_2[] = {
-               "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"
+               "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi",
        };
        static const char *const *const units_str[] = {
                [STRING_UNITS_10] = units_10,
@@ -66,7 +69,7 @@ int string_get_size(u64 size, u64 blk_size, const enum string_size_units units,
 
        /* This is Napier's algorithm.  Reduce the original block size to
         *
-        * coefficient * divisor[units]^i
+        * coefficient * divisor[units_base]^i
         *
         * we do the reduction so both coefficients are just under 32 bits so
         * that multiplying them together won't overflow 64 bits and we keep
@@ -76,12 +79,12 @@ int string_get_size(u64 size, u64 blk_size, const enum string_size_units units,
         * precision is in the coefficients.
         */
        while (blk_size >> 32) {
-               do_div(blk_size, divisor[units]);
+               do_div(blk_size, divisor[units_base]);
                i++;
        }
 
        while (size >> 32) {
-               do_div(size, divisor[units]);
+               do_div(size, divisor[units_base]);
                i++;
        }
 
@@ -90,8 +93,8 @@ int string_get_size(u64 size, u64 blk_size, const enum string_size_units units,
        size *= blk_size;
 
        /* and logarithmically reduce it until it's just under the divisor */
-       while (size >= divisor[units]) {
-               remainder = do_div(size, divisor[units]);
+       while (size >= divisor[units_base]) {
+               remainder = do_div(size, divisor[units_base]);
                i++;
        }
 
@@ -101,10 +104,10 @@ int string_get_size(u64 size, u64 blk_size, const enum string_size_units units,
        for (j = 0; sf_cap*10 < 1000; j++)
                sf_cap *= 10;
 
-       if (units == STRING_UNITS_2) {
+       if (units_base == STRING_UNITS_2) {
                /* express the remainder as a decimal.  It's currently the
                 * numerator of a fraction whose denominator is
-                * divisor[units], which is 1 << 10 for STRING_UNITS_2 */
+                * divisor[units_base], which is 1 << 10 for STRING_UNITS_2 */
                remainder *= 1000;
                remainder >>= 10;
        }
@@ -126,10 +129,12 @@ int string_get_size(u64 size, u64 blk_size, const enum string_size_units units,
        if (i >= ARRAY_SIZE(units_2))
                unit = "UNK";
        else
-               unit = units_str[units][i];
+               unit = units_str[units_base][i];
 
-       return snprintf(buf, len, "%u%s %s", (u32)size,
-                       tmp, unit);
+       return snprintf(buf, len, "%u%s%s%s%s", (u32)size, tmp,
+                       (units & STRING_UNITS_NO_SPACE) ? "" : " ",
+                       unit,
+                       (units & STRING_UNITS_NO_BYTES) ? "" : "B");
 }
 EXPORT_SYMBOL(string_get_size);
 
@@ -1008,10 +1013,28 @@ EXPORT_SYMBOL(__read_overflow2_field);
 void __write_overflow_field(size_t avail, size_t wanted) { }
 EXPORT_SYMBOL(__write_overflow_field);
 
-void fortify_panic(const char *name)
+static const char * const fortify_func_name[] = {
+#define MAKE_FORTIFY_FUNC_NAME(func)   [MAKE_FORTIFY_FUNC(func)] = #func
+       EACH_FORTIFY_FUNC(MAKE_FORTIFY_FUNC_NAME)
+#undef  MAKE_FORTIFY_FUNC_NAME
+};
+
+void __fortify_report(const u8 reason, const size_t avail, const size_t size)
+{
+       const u8 func = FORTIFY_REASON_FUNC(reason);
+       const bool write = FORTIFY_REASON_DIR(reason);
+       const char *name;
+
+       name = fortify_func_name[umin(func, FORTIFY_FUNC_UNKNOWN)];
+       WARN(1, "%s: detected buffer overflow: %zu byte %s of buffer size %zu\n",
+                name, size, str_read_write(!write), avail);
+}
+EXPORT_SYMBOL(__fortify_report);
+
+void __fortify_panic(const u8 reason, const size_t avail, const size_t size)
 {
-       pr_emerg("detected buffer overflow in %s\n", name);
+       __fortify_report(reason, avail, size);
        BUG();
 }
-EXPORT_SYMBOL(fortify_panic);
+EXPORT_SYMBOL(__fortify_panic);
 #endif /* CONFIG_FORTIFY_SOURCE */
This page took 0.037306 seconds and 4 git commands to generate.