at v4.4-rc5 8.2 kB view raw
1/* 2 * Test cases for printf facility. 3 */ 4 5#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 6 7#include <linux/init.h> 8#include <linux/kernel.h> 9#include <linux/module.h> 10#include <linux/printk.h> 11#include <linux/random.h> 12#include <linux/slab.h> 13#include <linux/string.h> 14 15#include <linux/socket.h> 16#include <linux/in.h> 17 18#define BUF_SIZE 256 19#define FILL_CHAR '$' 20 21#define PTR1 ((void*)0x01234567) 22#define PTR2 ((void*)(long)(int)0xfedcba98) 23 24#if BITS_PER_LONG == 64 25#define PTR1_ZEROES "000000000" 26#define PTR1_SPACES " " 27#define PTR1_STR "1234567" 28#define PTR2_STR "fffffffffedcba98" 29#define PTR_WIDTH 16 30#else 31#define PTR1_ZEROES "0" 32#define PTR1_SPACES " " 33#define PTR1_STR "1234567" 34#define PTR2_STR "fedcba98" 35#define PTR_WIDTH 8 36#endif 37#define PTR_WIDTH_STR stringify(PTR_WIDTH) 38 39static unsigned total_tests __initdata; 40static unsigned failed_tests __initdata; 41static char *test_buffer __initdata; 42 43static int __printf(4, 0) __init 44do_test(int bufsize, const char *expect, int elen, 45 const char *fmt, va_list ap) 46{ 47 va_list aq; 48 int ret, written; 49 50 total_tests++; 51 52 memset(test_buffer, FILL_CHAR, BUF_SIZE); 53 va_copy(aq, ap); 54 ret = vsnprintf(test_buffer, bufsize, fmt, aq); 55 va_end(aq); 56 57 if (ret != elen) { 58 pr_warn("vsnprintf(buf, %d, \"%s\", ...) returned %d, expected %d\n", 59 bufsize, fmt, ret, elen); 60 return 1; 61 } 62 63 if (!bufsize) { 64 if (memchr_inv(test_buffer, FILL_CHAR, BUF_SIZE)) { 65 pr_warn("vsnprintf(buf, 0, \"%s\", ...) wrote to buffer\n", 66 fmt); 67 return 1; 68 } 69 return 0; 70 } 71 72 written = min(bufsize-1, elen); 73 if (test_buffer[written]) { 74 pr_warn("vsnprintf(buf, %d, \"%s\", ...) did not nul-terminate buffer\n", 75 bufsize, fmt); 76 return 1; 77 } 78 79 if (memcmp(test_buffer, expect, written)) { 80 pr_warn("vsnprintf(buf, %d, \"%s\", ...) wrote '%s', expected '%.*s'\n", 81 bufsize, fmt, test_buffer, written, expect); 82 return 1; 83 } 84 return 0; 85} 86 87static void __printf(3, 4) __init 88__test(const char *expect, int elen, const char *fmt, ...) 89{ 90 va_list ap; 91 int rand; 92 char *p; 93 94 BUG_ON(elen >= BUF_SIZE); 95 96 va_start(ap, fmt); 97 98 /* 99 * Every fmt+args is subjected to four tests: Three where we 100 * tell vsnprintf varying buffer sizes (plenty, not quite 101 * enough and 0), and then we also test that kvasprintf would 102 * be able to print it as expected. 103 */ 104 failed_tests += do_test(BUF_SIZE, expect, elen, fmt, ap); 105 rand = 1 + prandom_u32_max(elen+1); 106 /* Since elen < BUF_SIZE, we have 1 <= rand <= BUF_SIZE. */ 107 failed_tests += do_test(rand, expect, elen, fmt, ap); 108 failed_tests += do_test(0, expect, elen, fmt, ap); 109 110 p = kvasprintf(GFP_KERNEL, fmt, ap); 111 if (p) { 112 if (memcmp(p, expect, elen+1)) { 113 pr_warn("kvasprintf(..., \"%s\", ...) returned '%s', expected '%s'\n", 114 fmt, p, expect); 115 failed_tests++; 116 } 117 kfree(p); 118 } 119 va_end(ap); 120} 121 122#define test(expect, fmt, ...) \ 123 __test(expect, strlen(expect), fmt, ##__VA_ARGS__) 124 125static void __init 126test_basic(void) 127{ 128 /* Work around annoying "warning: zero-length gnu_printf format string". */ 129 char nul = '\0'; 130 131 test("", &nul); 132 test("100%", "100%%"); 133 test("xxx%yyy", "xxx%cyyy", '%'); 134 __test("xxx\0yyy", 7, "xxx%cyyy", '\0'); 135} 136 137static void __init 138test_number(void) 139{ 140 test("0x1234abcd ", "%#-12x", 0x1234abcd); 141 test(" 0x1234abcd", "%#12x", 0x1234abcd); 142 test("0|001| 12|+123| 1234|-123|-1234", "%d|%03d|%3d|%+d|% d|%+d|% d", 0, 1, 12, 123, 1234, -123, -1234); 143} 144 145static void __init 146test_string(void) 147{ 148 test("", "%s%.0s", "", "123"); 149 test("ABCD|abc|123", "%s|%.3s|%.*s", "ABCD", "abcdef", 3, "123456"); 150 test("1 | 2|3 | 4|5 ", "%-3s|%3s|%-*s|%*s|%*s", "1", "2", 3, "3", 3, "4", -3, "5"); 151 /* 152 * POSIX and C99 say that a missing precision should be 153 * treated as a precision of 0. However, the kernel's printf 154 * implementation treats this case as if the . wasn't 155 * present. Let's add a test case documenting the current 156 * behaviour; should anyone ever feel the need to follow the 157 * standards more closely, this can be revisited. 158 */ 159 test("a||", "%.s|%.0s|%.*s", "a", "b", 0, "c"); 160 test("a | | ", "%-3.s|%-3.0s|%-3.*s", "a", "b", 0, "c"); 161} 162 163static void __init 164plain(void) 165{ 166 test(PTR1_ZEROES PTR1_STR " " PTR2_STR, "%p %p", PTR1, PTR2); 167 /* 168 * The field width is overloaded for some %p extensions to 169 * pass another piece of information. For plain pointers, the 170 * behaviour is slightly odd: One cannot pass either the 0 171 * flag nor a precision to %p without gcc complaining, and if 172 * one explicitly gives a field width, the number is no longer 173 * zero-padded. 174 */ 175 test("|" PTR1_STR PTR1_SPACES " | " PTR1_SPACES PTR1_STR "|", 176 "|%-*p|%*p|", PTR_WIDTH+2, PTR1, PTR_WIDTH+2, PTR1); 177 test("|" PTR2_STR " | " PTR2_STR "|", 178 "|%-*p|%*p|", PTR_WIDTH+2, PTR2, PTR_WIDTH+2, PTR2); 179 180 /* 181 * Unrecognized %p extensions are treated as plain %p, but the 182 * alphanumeric suffix is ignored (that is, does not occur in 183 * the output.) 184 */ 185 test("|"PTR1_ZEROES PTR1_STR"|", "|%p0y|", PTR1); 186 test("|"PTR2_STR"|", "|%p0y|", PTR2); 187} 188 189static void __init 190symbol_ptr(void) 191{ 192} 193 194static void __init 195kernel_ptr(void) 196{ 197} 198 199static void __init 200struct_resource(void) 201{ 202} 203 204static void __init 205addr(void) 206{ 207} 208 209static void __init 210escaped_str(void) 211{ 212} 213 214static void __init 215hex_string(void) 216{ 217 const char buf[3] = {0xc0, 0xff, 0xee}; 218 219 test("c0 ff ee|c0:ff:ee|c0-ff-ee|c0ffee", 220 "%3ph|%3phC|%3phD|%3phN", buf, buf, buf, buf); 221 test("c0 ff ee|c0:ff:ee|c0-ff-ee|c0ffee", 222 "%*ph|%*phC|%*phD|%*phN", 3, buf, 3, buf, 3, buf, 3, buf); 223} 224 225static void __init 226mac(void) 227{ 228 const u8 addr[6] = {0x2d, 0x48, 0xd6, 0xfc, 0x7a, 0x05}; 229 230 test("2d:48:d6:fc:7a:05", "%pM", addr); 231 test("05:7a:fc:d6:48:2d", "%pMR", addr); 232 test("2d-48-d6-fc-7a-05", "%pMF", addr); 233 test("2d48d6fc7a05", "%pm", addr); 234 test("057afcd6482d", "%pmR", addr); 235} 236 237static void __init 238ip4(void) 239{ 240 struct sockaddr_in sa; 241 242 sa.sin_family = AF_INET; 243 sa.sin_port = cpu_to_be16(12345); 244 sa.sin_addr.s_addr = cpu_to_be32(0x7f000001); 245 246 test("127.000.000.001|127.0.0.1", "%pi4|%pI4", &sa.sin_addr, &sa.sin_addr); 247 test("127.000.000.001|127.0.0.1", "%piS|%pIS", &sa, &sa); 248 sa.sin_addr.s_addr = cpu_to_be32(0x01020304); 249 test("001.002.003.004:12345|1.2.3.4:12345", "%piSp|%pISp", &sa, &sa); 250} 251 252static void __init 253ip6(void) 254{ 255} 256 257static void __init 258ip(void) 259{ 260 ip4(); 261 ip6(); 262} 263 264static void __init 265uuid(void) 266{ 267 const char uuid[16] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 268 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf}; 269 270 test("00010203-0405-0607-0809-0a0b0c0d0e0f", "%pUb", uuid); 271 test("00010203-0405-0607-0809-0A0B0C0D0E0F", "%pUB", uuid); 272 test("03020100-0504-0706-0809-0a0b0c0d0e0f", "%pUl", uuid); 273 test("03020100-0504-0706-0809-0A0B0C0D0E0F", "%pUL", uuid); 274} 275 276static void __init 277dentry(void) 278{ 279} 280 281static void __init 282struct_va_format(void) 283{ 284} 285 286static void __init 287struct_clk(void) 288{ 289} 290 291static void __init 292bitmap(void) 293{ 294 DECLARE_BITMAP(bits, 20); 295 const int primes[] = {2,3,5,7,11,13,17,19}; 296 int i; 297 298 bitmap_zero(bits, 20); 299 test("00000|00000", "%20pb|%*pb", bits, 20, bits); 300 test("|", "%20pbl|%*pbl", bits, 20, bits); 301 302 for (i = 0; i < ARRAY_SIZE(primes); ++i) 303 set_bit(primes[i], bits); 304 test("a28ac|a28ac", "%20pb|%*pb", bits, 20, bits); 305 test("2-3,5,7,11,13,17,19|2-3,5,7,11,13,17,19", "%20pbl|%*pbl", bits, 20, bits); 306 307 bitmap_fill(bits, 20); 308 test("fffff|fffff", "%20pb|%*pb", bits, 20, bits); 309 test("0-19|0-19", "%20pbl|%*pbl", bits, 20, bits); 310} 311 312static void __init 313netdev_features(void) 314{ 315} 316 317static void __init 318test_pointer(void) 319{ 320 plain(); 321 symbol_ptr(); 322 kernel_ptr(); 323 struct_resource(); 324 addr(); 325 escaped_str(); 326 hex_string(); 327 mac(); 328 ip(); 329 uuid(); 330 dentry(); 331 struct_va_format(); 332 struct_clk(); 333 bitmap(); 334 netdev_features(); 335} 336 337static int __init 338test_printf_init(void) 339{ 340 test_buffer = kmalloc(BUF_SIZE, GFP_KERNEL); 341 if (!test_buffer) 342 return -ENOMEM; 343 344 test_basic(); 345 test_number(); 346 test_string(); 347 test_pointer(); 348 349 kfree(test_buffer); 350 351 if (failed_tests == 0) 352 pr_info("all %u tests passed\n", total_tests); 353 else 354 pr_warn("failed %u out of %u tests\n", failed_tests, total_tests); 355 356 return failed_tests ? -EINVAL : 0; 357} 358 359module_init(test_printf_init); 360 361MODULE_AUTHOR("Rasmus Villemoes <linux@rasmusvillemoes.dk>"); 362MODULE_LICENSE("GPL");