.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * linux/lib/vsprintf.c |
---|
3 | 4 | * |
---|
.. | .. |
---|
17 | 18 | */ |
---|
18 | 19 | |
---|
19 | 20 | #include <stdarg.h> |
---|
| 21 | +#include <linux/build_bug.h> |
---|
20 | 22 | #include <linux/clk.h> |
---|
21 | 23 | #include <linux/clk-provider.h> |
---|
| 24 | +#include <linux/errname.h> |
---|
22 | 25 | #include <linux/module.h> /* for KSYM_SYMBOL_LEN */ |
---|
23 | 26 | #include <linux/types.h> |
---|
24 | 27 | #include <linux/string.h> |
---|
.. | .. |
---|
30 | 33 | #include <linux/ioport.h> |
---|
31 | 34 | #include <linux/dcache.h> |
---|
32 | 35 | #include <linux/cred.h> |
---|
| 36 | +#include <linux/rtc.h> |
---|
| 37 | +#include <linux/time.h> |
---|
33 | 38 | #include <linux/uuid.h> |
---|
34 | 39 | #include <linux/of.h> |
---|
35 | 40 | #include <net/addrconf.h> |
---|
36 | 41 | #include <linux/siphash.h> |
---|
37 | 42 | #include <linux/compiler.h> |
---|
| 43 | +#include <linux/property.h> |
---|
38 | 44 | #ifdef CONFIG_BLOCK |
---|
39 | 45 | #include <linux/blkdev.h> |
---|
40 | 46 | #endif |
---|
.. | .. |
---|
46 | 52 | |
---|
47 | 53 | #include <linux/string_helpers.h> |
---|
48 | 54 | #include "kstrtox.h" |
---|
| 55 | + |
---|
| 56 | +/* Disable pointer hashing if requested */ |
---|
| 57 | +bool no_hash_pointers __ro_after_init; |
---|
| 58 | +EXPORT_SYMBOL_GPL(no_hash_pointers); |
---|
49 | 59 | |
---|
50 | 60 | static unsigned long long simple_strntoull(const char *startp, size_t max_chars, |
---|
51 | 61 | char **endp, unsigned int base) |
---|
.. | .. |
---|
78 | 88 | * @endp: A pointer to the end of the parsed string will be placed here |
---|
79 | 89 | * @base: The number base to use |
---|
80 | 90 | * |
---|
81 | | - * This function is obsolete. Please use kstrtoull instead. |
---|
| 91 | + * This function has caveats. Please use kstrtoull instead. |
---|
82 | 92 | */ |
---|
83 | 93 | unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base) |
---|
84 | 94 | { |
---|
.. | .. |
---|
92 | 102 | * @endp: A pointer to the end of the parsed string will be placed here |
---|
93 | 103 | * @base: The number base to use |
---|
94 | 104 | * |
---|
95 | | - * This function is obsolete. Please use kstrtoul instead. |
---|
| 105 | + * This function has caveats. Please use kstrtoul instead. |
---|
96 | 106 | */ |
---|
97 | 107 | unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base) |
---|
98 | 108 | { |
---|
.. | .. |
---|
106 | 116 | * @endp: A pointer to the end of the parsed string will be placed here |
---|
107 | 117 | * @base: The number base to use |
---|
108 | 118 | * |
---|
109 | | - * This function is obsolete. Please use kstrtol instead. |
---|
| 119 | + * This function has caveats. Please use kstrtol instead. |
---|
110 | 120 | */ |
---|
111 | 121 | long simple_strtol(const char *cp, char **endp, unsigned int base) |
---|
112 | 122 | { |
---|
.. | .. |
---|
138 | 148 | * @endp: A pointer to the end of the parsed string will be placed here |
---|
139 | 149 | * @base: The number base to use |
---|
140 | 150 | * |
---|
141 | | - * This function is obsolete. Please use kstrtoll instead. |
---|
| 151 | + * This function has caveats. Please use kstrtoll instead. |
---|
142 | 152 | */ |
---|
143 | 153 | long long simple_strtoll(const char *cp, char **endp, unsigned int base) |
---|
144 | 154 | { |
---|
.. | .. |
---|
401 | 411 | #define SMALL 32 /* use lowercase in hex (must be 32 == 0x20) */ |
---|
402 | 412 | #define SPECIAL 64 /* prefix hex with "0x", octal with "0" */ |
---|
403 | 413 | |
---|
| 414 | +static_assert(ZEROPAD == ('0' - ' ')); |
---|
| 415 | +static_assert(SMALL == ' '); |
---|
| 416 | + |
---|
404 | 417 | enum format_type { |
---|
405 | 418 | FORMAT_TYPE_NONE, /* Just a string part */ |
---|
406 | 419 | FORMAT_TYPE_WIDTH, |
---|
.. | .. |
---|
430 | 443 | unsigned int base:8; /* number base, 8, 10 or 16 only */ |
---|
431 | 444 | signed int precision:16; /* # of digits/chars */ |
---|
432 | 445 | } __packed; |
---|
| 446 | +static_assert(sizeof(struct printf_spec) == 8); |
---|
| 447 | + |
---|
433 | 448 | #define FIELD_WIDTH_MAX ((1 << 23) - 1) |
---|
434 | 449 | #define PRECISION_MAX ((1 << 15) - 1) |
---|
435 | 450 | |
---|
.. | .. |
---|
446 | 461 | bool is_zero = num == 0LL; |
---|
447 | 462 | int field_width = spec.field_width; |
---|
448 | 463 | int precision = spec.precision; |
---|
449 | | - |
---|
450 | | - BUILD_BUG_ON(sizeof(struct printf_spec) != 8); |
---|
451 | 464 | |
---|
452 | 465 | /* locase = 0 or 0x20. ORing digits or letters with 'locase' |
---|
453 | 466 | * produces same digits or (maybe lowercased) letters */ |
---|
.. | .. |
---|
527 | 540 | /* zero or space padding */ |
---|
528 | 541 | if (!(spec.flags & LEFT)) { |
---|
529 | 542 | char c = ' ' + (spec.flags & ZEROPAD); |
---|
530 | | - BUILD_BUG_ON(' ' + ZEROPAD != '0'); |
---|
| 543 | + |
---|
531 | 544 | while (--field_width >= 0) { |
---|
532 | 545 | if (buf < end) |
---|
533 | 546 | *buf = c; |
---|
.. | .. |
---|
617 | 630 | return buf; |
---|
618 | 631 | } |
---|
619 | 632 | |
---|
620 | | -static noinline_for_stack |
---|
621 | | -char *string(char *buf, char *end, const char *s, struct printf_spec spec) |
---|
| 633 | +/* Handle string from a well known address. */ |
---|
| 634 | +static char *string_nocheck(char *buf, char *end, const char *s, |
---|
| 635 | + struct printf_spec spec) |
---|
622 | 636 | { |
---|
623 | 637 | int len = 0; |
---|
624 | | - size_t lim = spec.precision; |
---|
625 | | - |
---|
626 | | - if ((unsigned long)s < PAGE_SIZE) |
---|
627 | | - s = "(null)"; |
---|
| 638 | + int lim = spec.precision; |
---|
628 | 639 | |
---|
629 | 640 | while (lim--) { |
---|
630 | 641 | char c = *s++; |
---|
.. | .. |
---|
636 | 647 | ++len; |
---|
637 | 648 | } |
---|
638 | 649 | return widen_string(buf, len, end, spec); |
---|
| 650 | +} |
---|
| 651 | + |
---|
| 652 | +static char *err_ptr(char *buf, char *end, void *ptr, |
---|
| 653 | + struct printf_spec spec) |
---|
| 654 | +{ |
---|
| 655 | + int err = PTR_ERR(ptr); |
---|
| 656 | + const char *sym = errname(err); |
---|
| 657 | + |
---|
| 658 | + if (sym) |
---|
| 659 | + return string_nocheck(buf, end, sym, spec); |
---|
| 660 | + |
---|
| 661 | + /* |
---|
| 662 | + * Somebody passed ERR_PTR(-1234) or some other non-existing |
---|
| 663 | + * Efoo - or perhaps CONFIG_SYMBOLIC_ERRNAME=n. Fall back to |
---|
| 664 | + * printing it as its decimal representation. |
---|
| 665 | + */ |
---|
| 666 | + spec.flags |= SIGN; |
---|
| 667 | + spec.base = 10; |
---|
| 668 | + return number(buf, end, err, spec); |
---|
| 669 | +} |
---|
| 670 | + |
---|
| 671 | +/* Be careful: error messages must fit into the given buffer. */ |
---|
| 672 | +static char *error_string(char *buf, char *end, const char *s, |
---|
| 673 | + struct printf_spec spec) |
---|
| 674 | +{ |
---|
| 675 | + /* |
---|
| 676 | + * Hard limit to avoid a completely insane messages. It actually |
---|
| 677 | + * works pretty well because most error messages are in |
---|
| 678 | + * the many pointer format modifiers. |
---|
| 679 | + */ |
---|
| 680 | + if (spec.precision == -1) |
---|
| 681 | + spec.precision = 2 * sizeof(void *); |
---|
| 682 | + |
---|
| 683 | + return string_nocheck(buf, end, s, spec); |
---|
| 684 | +} |
---|
| 685 | + |
---|
| 686 | +/* |
---|
| 687 | + * Do not call any complex external code here. Nested printk()/vsprintf() |
---|
| 688 | + * might cause infinite loops. Failures might break printk() and would |
---|
| 689 | + * be hard to debug. |
---|
| 690 | + */ |
---|
| 691 | +static const char *check_pointer_msg(const void *ptr) |
---|
| 692 | +{ |
---|
| 693 | + if (!ptr) |
---|
| 694 | + return "(null)"; |
---|
| 695 | + |
---|
| 696 | + if ((unsigned long)ptr < PAGE_SIZE || IS_ERR_VALUE(ptr)) |
---|
| 697 | + return "(efault)"; |
---|
| 698 | + |
---|
| 699 | + return NULL; |
---|
| 700 | +} |
---|
| 701 | + |
---|
| 702 | +static int check_pointer(char **buf, char *end, const void *ptr, |
---|
| 703 | + struct printf_spec spec) |
---|
| 704 | +{ |
---|
| 705 | + const char *err_msg; |
---|
| 706 | + |
---|
| 707 | + err_msg = check_pointer_msg(ptr); |
---|
| 708 | + if (err_msg) { |
---|
| 709 | + *buf = error_string(*buf, end, err_msg, spec); |
---|
| 710 | + return -EFAULT; |
---|
| 711 | + } |
---|
| 712 | + |
---|
| 713 | + return 0; |
---|
| 714 | +} |
---|
| 715 | + |
---|
| 716 | +static noinline_for_stack |
---|
| 717 | +char *string(char *buf, char *end, const char *s, |
---|
| 718 | + struct printf_spec spec) |
---|
| 719 | +{ |
---|
| 720 | + if (check_pointer(&buf, end, s, spec)) |
---|
| 721 | + return buf; |
---|
| 722 | + |
---|
| 723 | + return string_nocheck(buf, end, s, spec); |
---|
| 724 | +} |
---|
| 725 | + |
---|
| 726 | +static char *pointer_string(char *buf, char *end, |
---|
| 727 | + const void *ptr, |
---|
| 728 | + struct printf_spec spec) |
---|
| 729 | +{ |
---|
| 730 | + spec.base = 16; |
---|
| 731 | + spec.flags |= SMALL; |
---|
| 732 | + if (spec.field_width == -1) { |
---|
| 733 | + spec.field_width = 2 * sizeof(ptr); |
---|
| 734 | + spec.flags |= ZEROPAD; |
---|
| 735 | + } |
---|
| 736 | + |
---|
| 737 | + return number(buf, end, (unsigned long int)ptr, spec); |
---|
| 738 | +} |
---|
| 739 | + |
---|
| 740 | +/* Make pointers available for printing early in the boot sequence. */ |
---|
| 741 | +static int debug_boot_weak_hash __ro_after_init; |
---|
| 742 | + |
---|
| 743 | +static int __init debug_boot_weak_hash_enable(char *str) |
---|
| 744 | +{ |
---|
| 745 | + debug_boot_weak_hash = 1; |
---|
| 746 | + pr_info("debug_boot_weak_hash enabled\n"); |
---|
| 747 | + return 0; |
---|
| 748 | +} |
---|
| 749 | +early_param("debug_boot_weak_hash", debug_boot_weak_hash_enable); |
---|
| 750 | + |
---|
| 751 | +static DEFINE_STATIC_KEY_TRUE(not_filled_random_ptr_key); |
---|
| 752 | +static siphash_key_t ptr_key __read_mostly; |
---|
| 753 | + |
---|
| 754 | +static void enable_ptr_key_workfn(struct work_struct *work) |
---|
| 755 | +{ |
---|
| 756 | + get_random_bytes(&ptr_key, sizeof(ptr_key)); |
---|
| 757 | + /* Needs to run from preemptible context */ |
---|
| 758 | + static_branch_disable(¬_filled_random_ptr_key); |
---|
| 759 | +} |
---|
| 760 | + |
---|
| 761 | +static DECLARE_WORK(enable_ptr_key_work, enable_ptr_key_workfn); |
---|
| 762 | + |
---|
| 763 | +static int fill_random_ptr_key(struct notifier_block *nb, |
---|
| 764 | + unsigned long action, void *data) |
---|
| 765 | +{ |
---|
| 766 | + /* This may be in an interrupt handler. */ |
---|
| 767 | + queue_work(system_unbound_wq, &enable_ptr_key_work); |
---|
| 768 | + return 0; |
---|
| 769 | +} |
---|
| 770 | + |
---|
| 771 | +static struct notifier_block random_ready = { |
---|
| 772 | + .notifier_call = fill_random_ptr_key |
---|
| 773 | +}; |
---|
| 774 | + |
---|
| 775 | +static int __init initialize_ptr_random(void) |
---|
| 776 | +{ |
---|
| 777 | + int key_size = sizeof(ptr_key); |
---|
| 778 | + int ret; |
---|
| 779 | + |
---|
| 780 | + /* Use hw RNG if available. */ |
---|
| 781 | + if (get_random_bytes_arch(&ptr_key, key_size) == key_size) { |
---|
| 782 | + static_branch_disable(¬_filled_random_ptr_key); |
---|
| 783 | + return 0; |
---|
| 784 | + } |
---|
| 785 | + |
---|
| 786 | + ret = register_random_ready_notifier(&random_ready); |
---|
| 787 | + if (!ret) { |
---|
| 788 | + return 0; |
---|
| 789 | + } else if (ret == -EALREADY) { |
---|
| 790 | + /* This is in preemptible context */ |
---|
| 791 | + enable_ptr_key_workfn(&enable_ptr_key_work); |
---|
| 792 | + return 0; |
---|
| 793 | + } |
---|
| 794 | + |
---|
| 795 | + return ret; |
---|
| 796 | +} |
---|
| 797 | +early_initcall(initialize_ptr_random); |
---|
| 798 | + |
---|
| 799 | +/* Maps a pointer to a 32 bit unique identifier. */ |
---|
| 800 | +static inline int __ptr_to_hashval(const void *ptr, unsigned long *hashval_out) |
---|
| 801 | +{ |
---|
| 802 | + unsigned long hashval; |
---|
| 803 | + |
---|
| 804 | + if (static_branch_unlikely(¬_filled_random_ptr_key)) |
---|
| 805 | + return -EAGAIN; |
---|
| 806 | + |
---|
| 807 | +#ifdef CONFIG_64BIT |
---|
| 808 | + hashval = (unsigned long)siphash_1u64((u64)ptr, &ptr_key); |
---|
| 809 | + /* |
---|
| 810 | + * Mask off the first 32 bits, this makes explicit that we have |
---|
| 811 | + * modified the address (and 32 bits is plenty for a unique ID). |
---|
| 812 | + */ |
---|
| 813 | + hashval = hashval & 0xffffffff; |
---|
| 814 | +#else |
---|
| 815 | + hashval = (unsigned long)siphash_1u32((u32)ptr, &ptr_key); |
---|
| 816 | +#endif |
---|
| 817 | + *hashval_out = hashval; |
---|
| 818 | + return 0; |
---|
| 819 | +} |
---|
| 820 | + |
---|
| 821 | +int ptr_to_hashval(const void *ptr, unsigned long *hashval_out) |
---|
| 822 | +{ |
---|
| 823 | + return __ptr_to_hashval(ptr, hashval_out); |
---|
| 824 | +} |
---|
| 825 | + |
---|
| 826 | +static char *ptr_to_id(char *buf, char *end, const void *ptr, |
---|
| 827 | + struct printf_spec spec) |
---|
| 828 | +{ |
---|
| 829 | + const char *str = sizeof(ptr) == 8 ? "(____ptrval____)" : "(ptrval)"; |
---|
| 830 | + unsigned long hashval; |
---|
| 831 | + int ret; |
---|
| 832 | + |
---|
| 833 | + /* |
---|
| 834 | + * Print the real pointer value for NULL and error pointers, |
---|
| 835 | + * as they are not actual addresses. |
---|
| 836 | + */ |
---|
| 837 | + if (IS_ERR_OR_NULL(ptr)) |
---|
| 838 | + return pointer_string(buf, end, ptr, spec); |
---|
| 839 | + |
---|
| 840 | + /* When debugging early boot use non-cryptographically secure hash. */ |
---|
| 841 | + if (unlikely(debug_boot_weak_hash)) { |
---|
| 842 | + hashval = hash_long((unsigned long)ptr, 32); |
---|
| 843 | + return pointer_string(buf, end, (const void *)hashval, spec); |
---|
| 844 | + } |
---|
| 845 | + |
---|
| 846 | + ret = __ptr_to_hashval(ptr, &hashval); |
---|
| 847 | + if (ret) { |
---|
| 848 | + spec.field_width = 2 * sizeof(ptr); |
---|
| 849 | + /* string length must be less than default_width */ |
---|
| 850 | + return error_string(buf, end, str, spec); |
---|
| 851 | + } |
---|
| 852 | + |
---|
| 853 | + return pointer_string(buf, end, (const void *)hashval, spec); |
---|
| 854 | +} |
---|
| 855 | + |
---|
| 856 | +static char *default_pointer(char *buf, char *end, const void *ptr, |
---|
| 857 | + struct printf_spec spec) |
---|
| 858 | +{ |
---|
| 859 | + /* |
---|
| 860 | + * default is to _not_ leak addresses, so hash before printing, |
---|
| 861 | + * unless no_hash_pointers is specified on the command line. |
---|
| 862 | + */ |
---|
| 863 | + if (unlikely(no_hash_pointers)) |
---|
| 864 | + return pointer_string(buf, end, ptr, spec); |
---|
| 865 | + |
---|
| 866 | + return ptr_to_id(buf, end, ptr, spec); |
---|
| 867 | +} |
---|
| 868 | + |
---|
| 869 | +int kptr_restrict __read_mostly; |
---|
| 870 | + |
---|
| 871 | +static noinline_for_stack |
---|
| 872 | +char *restricted_pointer(char *buf, char *end, const void *ptr, |
---|
| 873 | + struct printf_spec spec) |
---|
| 874 | +{ |
---|
| 875 | + switch (kptr_restrict) { |
---|
| 876 | + case 0: |
---|
| 877 | + /* Handle as %p, hash and do _not_ leak addresses. */ |
---|
| 878 | + return default_pointer(buf, end, ptr, spec); |
---|
| 879 | + case 1: { |
---|
| 880 | + const struct cred *cred; |
---|
| 881 | + |
---|
| 882 | + /* |
---|
| 883 | + * kptr_restrict==1 cannot be used in IRQ context |
---|
| 884 | + * because its test for CAP_SYSLOG would be meaningless. |
---|
| 885 | + */ |
---|
| 886 | + if (in_irq() || in_serving_softirq() || in_nmi()) { |
---|
| 887 | + if (spec.field_width == -1) |
---|
| 888 | + spec.field_width = 2 * sizeof(ptr); |
---|
| 889 | + return error_string(buf, end, "pK-error", spec); |
---|
| 890 | + } |
---|
| 891 | + |
---|
| 892 | + /* |
---|
| 893 | + * Only print the real pointer value if the current |
---|
| 894 | + * process has CAP_SYSLOG and is running with the |
---|
| 895 | + * same credentials it started with. This is because |
---|
| 896 | + * access to files is checked at open() time, but %pK |
---|
| 897 | + * checks permission at read() time. We don't want to |
---|
| 898 | + * leak pointer values if a binary opens a file using |
---|
| 899 | + * %pK and then elevates privileges before reading it. |
---|
| 900 | + */ |
---|
| 901 | + cred = current_cred(); |
---|
| 902 | + if (!has_capability_noaudit(current, CAP_SYSLOG) || |
---|
| 903 | + !uid_eq(cred->euid, cred->uid) || |
---|
| 904 | + !gid_eq(cred->egid, cred->gid)) |
---|
| 905 | + ptr = NULL; |
---|
| 906 | + break; |
---|
| 907 | + } |
---|
| 908 | + case 2: |
---|
| 909 | + default: |
---|
| 910 | + /* Always print 0's for %pK */ |
---|
| 911 | + ptr = NULL; |
---|
| 912 | + break; |
---|
| 913 | + } |
---|
| 914 | + |
---|
| 915 | + return pointer_string(buf, end, ptr, spec); |
---|
639 | 916 | } |
---|
640 | 917 | |
---|
641 | 918 | static noinline_for_stack |
---|
.. | .. |
---|
657 | 934 | |
---|
658 | 935 | rcu_read_lock(); |
---|
659 | 936 | for (i = 0; i < depth; i++, d = p) { |
---|
| 937 | + if (check_pointer(&buf, end, d, spec)) { |
---|
| 938 | + rcu_read_unlock(); |
---|
| 939 | + return buf; |
---|
| 940 | + } |
---|
| 941 | + |
---|
660 | 942 | p = READ_ONCE(d->d_parent); |
---|
661 | 943 | array[i] = READ_ONCE(d->d_name.name); |
---|
662 | 944 | if (p == d) { |
---|
.. | .. |
---|
682 | 964 | return widen_string(buf, n, end, spec); |
---|
683 | 965 | } |
---|
684 | 966 | |
---|
| 967 | +static noinline_for_stack |
---|
| 968 | +char *file_dentry_name(char *buf, char *end, const struct file *f, |
---|
| 969 | + struct printf_spec spec, const char *fmt) |
---|
| 970 | +{ |
---|
| 971 | + if (check_pointer(&buf, end, f, spec)) |
---|
| 972 | + return buf; |
---|
| 973 | + |
---|
| 974 | + return dentry_name(buf, end, f->f_path.dentry, spec, fmt); |
---|
| 975 | +} |
---|
685 | 976 | #ifdef CONFIG_BLOCK |
---|
686 | 977 | static noinline_for_stack |
---|
687 | 978 | char *bdev_name(char *buf, char *end, struct block_device *bdev, |
---|
688 | 979 | struct printf_spec spec, const char *fmt) |
---|
689 | 980 | { |
---|
690 | | - struct gendisk *hd = bdev->bd_disk; |
---|
691 | | - |
---|
| 981 | + struct gendisk *hd; |
---|
| 982 | + |
---|
| 983 | + if (check_pointer(&buf, end, bdev, spec)) |
---|
| 984 | + return buf; |
---|
| 985 | + |
---|
| 986 | + hd = bdev->bd_disk; |
---|
692 | 987 | buf = string(buf, end, hd->disk_name, spec); |
---|
693 | | - if (bdev->bd_part->partno) { |
---|
| 988 | + if (bdev->bd_partno) { |
---|
694 | 989 | if (isdigit(hd->disk_name[strlen(hd->disk_name)-1])) { |
---|
695 | 990 | if (buf < end) |
---|
696 | 991 | *buf = 'p'; |
---|
697 | 992 | buf++; |
---|
698 | 993 | } |
---|
699 | | - buf = number(buf, end, bdev->bd_part->partno, spec); |
---|
| 994 | + buf = number(buf, end, bdev->bd_partno, spec); |
---|
700 | 995 | } |
---|
701 | 996 | return buf; |
---|
702 | 997 | } |
---|
.. | .. |
---|
718 | 1013 | #ifdef CONFIG_KALLSYMS |
---|
719 | 1014 | if (*fmt == 'B') |
---|
720 | 1015 | sprint_backtrace(sym, value); |
---|
721 | | - else if (*fmt != 'f' && *fmt != 's') |
---|
| 1016 | + else if (*fmt != 's') |
---|
722 | 1017 | sprint_symbol(sym, value); |
---|
723 | 1018 | else |
---|
724 | 1019 | sprint_symbol_no_offset(sym, value); |
---|
725 | 1020 | |
---|
726 | | - return string(buf, end, sym, spec); |
---|
| 1021 | + return string_nocheck(buf, end, sym, spec); |
---|
727 | 1022 | #else |
---|
728 | 1023 | return special_hex_number(buf, end, value, sizeof(void *)); |
---|
729 | 1024 | #endif |
---|
.. | .. |
---|
743 | 1038 | static const struct printf_spec default_dec_spec = { |
---|
744 | 1039 | .base = 10, |
---|
745 | 1040 | .precision = -1, |
---|
| 1041 | +}; |
---|
| 1042 | + |
---|
| 1043 | +static const struct printf_spec default_dec02_spec = { |
---|
| 1044 | + .base = 10, |
---|
| 1045 | + .field_width = 2, |
---|
| 1046 | + .precision = -1, |
---|
| 1047 | + .flags = ZEROPAD, |
---|
| 1048 | +}; |
---|
| 1049 | + |
---|
| 1050 | +static const struct printf_spec default_dec04_spec = { |
---|
| 1051 | + .base = 10, |
---|
| 1052 | + .field_width = 4, |
---|
| 1053 | + .precision = -1, |
---|
| 1054 | + .flags = ZEROPAD, |
---|
746 | 1055 | }; |
---|
747 | 1056 | |
---|
748 | 1057 | static noinline_for_stack |
---|
.. | .. |
---|
793 | 1102 | int decode = (fmt[0] == 'R') ? 1 : 0; |
---|
794 | 1103 | const struct printf_spec *specp; |
---|
795 | 1104 | |
---|
| 1105 | + if (check_pointer(&buf, end, res, spec)) |
---|
| 1106 | + return buf; |
---|
| 1107 | + |
---|
796 | 1108 | *p++ = '['; |
---|
797 | 1109 | if (res->flags & IORESOURCE_IO) { |
---|
798 | | - p = string(p, pend, "io ", str_spec); |
---|
| 1110 | + p = string_nocheck(p, pend, "io ", str_spec); |
---|
799 | 1111 | specp = &io_spec; |
---|
800 | 1112 | } else if (res->flags & IORESOURCE_MEM) { |
---|
801 | | - p = string(p, pend, "mem ", str_spec); |
---|
| 1113 | + p = string_nocheck(p, pend, "mem ", str_spec); |
---|
802 | 1114 | specp = &mem_spec; |
---|
803 | 1115 | } else if (res->flags & IORESOURCE_IRQ) { |
---|
804 | | - p = string(p, pend, "irq ", str_spec); |
---|
| 1116 | + p = string_nocheck(p, pend, "irq ", str_spec); |
---|
805 | 1117 | specp = &default_dec_spec; |
---|
806 | 1118 | } else if (res->flags & IORESOURCE_DMA) { |
---|
807 | | - p = string(p, pend, "dma ", str_spec); |
---|
| 1119 | + p = string_nocheck(p, pend, "dma ", str_spec); |
---|
808 | 1120 | specp = &default_dec_spec; |
---|
809 | 1121 | } else if (res->flags & IORESOURCE_BUS) { |
---|
810 | | - p = string(p, pend, "bus ", str_spec); |
---|
| 1122 | + p = string_nocheck(p, pend, "bus ", str_spec); |
---|
811 | 1123 | specp = &bus_spec; |
---|
812 | 1124 | } else { |
---|
813 | | - p = string(p, pend, "??? ", str_spec); |
---|
| 1125 | + p = string_nocheck(p, pend, "??? ", str_spec); |
---|
814 | 1126 | specp = &mem_spec; |
---|
815 | 1127 | decode = 0; |
---|
816 | 1128 | } |
---|
817 | 1129 | if (decode && res->flags & IORESOURCE_UNSET) { |
---|
818 | | - p = string(p, pend, "size ", str_spec); |
---|
| 1130 | + p = string_nocheck(p, pend, "size ", str_spec); |
---|
819 | 1131 | p = number(p, pend, resource_size(res), *specp); |
---|
820 | 1132 | } else { |
---|
821 | 1133 | p = number(p, pend, res->start, *specp); |
---|
.. | .. |
---|
826 | 1138 | } |
---|
827 | 1139 | if (decode) { |
---|
828 | 1140 | if (res->flags & IORESOURCE_MEM_64) |
---|
829 | | - p = string(p, pend, " 64bit", str_spec); |
---|
| 1141 | + p = string_nocheck(p, pend, " 64bit", str_spec); |
---|
830 | 1142 | if (res->flags & IORESOURCE_PREFETCH) |
---|
831 | | - p = string(p, pend, " pref", str_spec); |
---|
| 1143 | + p = string_nocheck(p, pend, " pref", str_spec); |
---|
832 | 1144 | if (res->flags & IORESOURCE_WINDOW) |
---|
833 | | - p = string(p, pend, " window", str_spec); |
---|
| 1145 | + p = string_nocheck(p, pend, " window", str_spec); |
---|
834 | 1146 | if (res->flags & IORESOURCE_DISABLED) |
---|
835 | | - p = string(p, pend, " disabled", str_spec); |
---|
| 1147 | + p = string_nocheck(p, pend, " disabled", str_spec); |
---|
836 | 1148 | } else { |
---|
837 | | - p = string(p, pend, " flags ", str_spec); |
---|
| 1149 | + p = string_nocheck(p, pend, " flags ", str_spec); |
---|
838 | 1150 | p = number(p, pend, res->flags, default_flag_spec); |
---|
839 | 1151 | } |
---|
840 | 1152 | *p++ = ']'; |
---|
841 | 1153 | *p = '\0'; |
---|
842 | 1154 | |
---|
843 | | - return string(buf, end, sym, spec); |
---|
| 1155 | + return string_nocheck(buf, end, sym, spec); |
---|
844 | 1156 | } |
---|
845 | 1157 | |
---|
846 | 1158 | static noinline_for_stack |
---|
.. | .. |
---|
855 | 1167 | /* nothing to print */ |
---|
856 | 1168 | return buf; |
---|
857 | 1169 | |
---|
858 | | - if (ZERO_OR_NULL_PTR(addr)) |
---|
859 | | - /* NULL pointer */ |
---|
860 | | - return string(buf, end, NULL, spec); |
---|
| 1170 | + if (check_pointer(&buf, end, addr, spec)) |
---|
| 1171 | + return buf; |
---|
861 | 1172 | |
---|
862 | 1173 | switch (fmt[1]) { |
---|
863 | 1174 | case 'C': |
---|
.. | .. |
---|
904 | 1215 | int i, chunksz; |
---|
905 | 1216 | bool first = true; |
---|
906 | 1217 | |
---|
| 1218 | + if (check_pointer(&buf, end, bitmap, spec)) |
---|
| 1219 | + return buf; |
---|
| 1220 | + |
---|
907 | 1221 | /* reused to print numbers */ |
---|
908 | 1222 | spec = (struct printf_spec){ .flags = SMALL | ZEROPAD, .base = 16 }; |
---|
909 | 1223 | |
---|
.. | .. |
---|
945 | 1259 | int cur, rbot, rtop; |
---|
946 | 1260 | bool first = true; |
---|
947 | 1261 | |
---|
| 1262 | + if (check_pointer(&buf, end, bitmap, spec)) |
---|
| 1263 | + return buf; |
---|
| 1264 | + |
---|
948 | 1265 | rbot = cur = find_first_bit(bitmap, nr_bits); |
---|
949 | 1266 | while (cur < nr_bits) { |
---|
950 | 1267 | rtop = cur; |
---|
.. | .. |
---|
983 | 1300 | char separator; |
---|
984 | 1301 | bool reversed = false; |
---|
985 | 1302 | |
---|
| 1303 | + if (check_pointer(&buf, end, addr, spec)) |
---|
| 1304 | + return buf; |
---|
| 1305 | + |
---|
986 | 1306 | switch (fmt[1]) { |
---|
987 | 1307 | case 'F': |
---|
988 | 1308 | separator = '-'; |
---|
.. | .. |
---|
1008 | 1328 | } |
---|
1009 | 1329 | *p = '\0'; |
---|
1010 | 1330 | |
---|
1011 | | - return string(buf, end, mac_addr, spec); |
---|
| 1331 | + return string_nocheck(buf, end, mac_addr, spec); |
---|
1012 | 1332 | } |
---|
1013 | 1333 | |
---|
1014 | 1334 | static noinline_for_stack |
---|
.. | .. |
---|
1171 | 1491 | else |
---|
1172 | 1492 | ip6_string(ip6_addr, addr, fmt); |
---|
1173 | 1493 | |
---|
1174 | | - return string(buf, end, ip6_addr, spec); |
---|
| 1494 | + return string_nocheck(buf, end, ip6_addr, spec); |
---|
1175 | 1495 | } |
---|
1176 | 1496 | |
---|
1177 | 1497 | static noinline_for_stack |
---|
.. | .. |
---|
1182 | 1502 | |
---|
1183 | 1503 | ip4_string(ip4_addr, addr, fmt); |
---|
1184 | 1504 | |
---|
1185 | | - return string(buf, end, ip4_addr, spec); |
---|
| 1505 | + return string_nocheck(buf, end, ip4_addr, spec); |
---|
1186 | 1506 | } |
---|
1187 | 1507 | |
---|
1188 | 1508 | static noinline_for_stack |
---|
.. | .. |
---|
1244 | 1564 | } |
---|
1245 | 1565 | *p = '\0'; |
---|
1246 | 1566 | |
---|
1247 | | - return string(buf, end, ip6_addr, spec); |
---|
| 1567 | + return string_nocheck(buf, end, ip6_addr, spec); |
---|
1248 | 1568 | } |
---|
1249 | 1569 | |
---|
1250 | 1570 | static noinline_for_stack |
---|
.. | .. |
---|
1279 | 1599 | } |
---|
1280 | 1600 | *p = '\0'; |
---|
1281 | 1601 | |
---|
1282 | | - return string(buf, end, ip4_addr, spec); |
---|
| 1602 | + return string_nocheck(buf, end, ip4_addr, spec); |
---|
| 1603 | +} |
---|
| 1604 | + |
---|
| 1605 | +static noinline_for_stack |
---|
| 1606 | +char *ip_addr_string(char *buf, char *end, const void *ptr, |
---|
| 1607 | + struct printf_spec spec, const char *fmt) |
---|
| 1608 | +{ |
---|
| 1609 | + char *err_fmt_msg; |
---|
| 1610 | + |
---|
| 1611 | + if (check_pointer(&buf, end, ptr, spec)) |
---|
| 1612 | + return buf; |
---|
| 1613 | + |
---|
| 1614 | + switch (fmt[1]) { |
---|
| 1615 | + case '6': |
---|
| 1616 | + return ip6_addr_string(buf, end, ptr, spec, fmt); |
---|
| 1617 | + case '4': |
---|
| 1618 | + return ip4_addr_string(buf, end, ptr, spec, fmt); |
---|
| 1619 | + case 'S': { |
---|
| 1620 | + const union { |
---|
| 1621 | + struct sockaddr raw; |
---|
| 1622 | + struct sockaddr_in v4; |
---|
| 1623 | + struct sockaddr_in6 v6; |
---|
| 1624 | + } *sa = ptr; |
---|
| 1625 | + |
---|
| 1626 | + switch (sa->raw.sa_family) { |
---|
| 1627 | + case AF_INET: |
---|
| 1628 | + return ip4_addr_string_sa(buf, end, &sa->v4, spec, fmt); |
---|
| 1629 | + case AF_INET6: |
---|
| 1630 | + return ip6_addr_string_sa(buf, end, &sa->v6, spec, fmt); |
---|
| 1631 | + default: |
---|
| 1632 | + return error_string(buf, end, "(einval)", spec); |
---|
| 1633 | + }} |
---|
| 1634 | + } |
---|
| 1635 | + |
---|
| 1636 | + err_fmt_msg = fmt[0] == 'i' ? "(%pi?)" : "(%pI?)"; |
---|
| 1637 | + return error_string(buf, end, err_fmt_msg, spec); |
---|
1283 | 1638 | } |
---|
1284 | 1639 | |
---|
1285 | 1640 | static noinline_for_stack |
---|
.. | .. |
---|
1294 | 1649 | if (spec.field_width == 0) |
---|
1295 | 1650 | return buf; /* nothing to print */ |
---|
1296 | 1651 | |
---|
1297 | | - if (ZERO_OR_NULL_PTR(addr)) |
---|
1298 | | - return string(buf, end, NULL, spec); /* NULL pointer */ |
---|
1299 | | - |
---|
| 1652 | + if (check_pointer(&buf, end, addr, spec)) |
---|
| 1653 | + return buf; |
---|
1300 | 1654 | |
---|
1301 | 1655 | do { |
---|
1302 | 1656 | switch (fmt[count++]) { |
---|
.. | .. |
---|
1342 | 1696 | return buf; |
---|
1343 | 1697 | } |
---|
1344 | 1698 | |
---|
| 1699 | +static char *va_format(char *buf, char *end, struct va_format *va_fmt, |
---|
| 1700 | + struct printf_spec spec, const char *fmt) |
---|
| 1701 | +{ |
---|
| 1702 | + va_list va; |
---|
| 1703 | + |
---|
| 1704 | + if (check_pointer(&buf, end, va_fmt, spec)) |
---|
| 1705 | + return buf; |
---|
| 1706 | + |
---|
| 1707 | + va_copy(va, *va_fmt->va); |
---|
| 1708 | + buf += vsnprintf(buf, end > buf ? end - buf : 0, va_fmt->fmt, va); |
---|
| 1709 | + va_end(va); |
---|
| 1710 | + |
---|
| 1711 | + return buf; |
---|
| 1712 | +} |
---|
| 1713 | + |
---|
1345 | 1714 | static noinline_for_stack |
---|
1346 | 1715 | char *uuid_string(char *buf, char *end, const u8 *addr, |
---|
1347 | 1716 | struct printf_spec spec, const char *fmt) |
---|
.. | .. |
---|
1352 | 1721 | const u8 *index = uuid_index; |
---|
1353 | 1722 | bool uc = false; |
---|
1354 | 1723 | |
---|
| 1724 | + if (check_pointer(&buf, end, addr, spec)) |
---|
| 1725 | + return buf; |
---|
| 1726 | + |
---|
1355 | 1727 | switch (*(++fmt)) { |
---|
1356 | 1728 | case 'L': |
---|
1357 | | - uc = true; /* fall-through */ |
---|
| 1729 | + uc = true; |
---|
| 1730 | + /* fall through */ |
---|
1358 | 1731 | case 'l': |
---|
1359 | 1732 | index = guid_index; |
---|
1360 | 1733 | break; |
---|
.. | .. |
---|
1380 | 1753 | |
---|
1381 | 1754 | *p = 0; |
---|
1382 | 1755 | |
---|
1383 | | - return string(buf, end, uuid, spec); |
---|
| 1756 | + return string_nocheck(buf, end, uuid, spec); |
---|
1384 | 1757 | } |
---|
1385 | 1758 | |
---|
1386 | 1759 | static noinline_for_stack |
---|
1387 | | -char *pointer_string(char *buf, char *end, const void *ptr, |
---|
1388 | | - struct printf_spec spec) |
---|
1389 | | -{ |
---|
1390 | | - spec.base = 16; |
---|
1391 | | - spec.flags |= SMALL; |
---|
1392 | | - if (spec.field_width == -1) { |
---|
1393 | | - spec.field_width = 2 * sizeof(ptr); |
---|
1394 | | - spec.flags |= ZEROPAD; |
---|
1395 | | - } |
---|
1396 | | - |
---|
1397 | | - return number(buf, end, (unsigned long int)ptr, spec); |
---|
1398 | | -} |
---|
1399 | | - |
---|
1400 | | -int kptr_restrict __read_mostly; |
---|
1401 | | - |
---|
1402 | | -static noinline_for_stack |
---|
1403 | | -char *restricted_pointer(char *buf, char *end, const void *ptr, |
---|
1404 | | - struct printf_spec spec) |
---|
1405 | | -{ |
---|
1406 | | - switch (kptr_restrict) { |
---|
1407 | | - case 0: |
---|
1408 | | - /* Always print %pK values */ |
---|
1409 | | - break; |
---|
1410 | | - case 1: { |
---|
1411 | | - const struct cred *cred; |
---|
1412 | | - |
---|
1413 | | - /* |
---|
1414 | | - * kptr_restrict==1 cannot be used in IRQ context |
---|
1415 | | - * because its test for CAP_SYSLOG would be meaningless. |
---|
1416 | | - */ |
---|
1417 | | - if (in_irq() || in_serving_softirq() || in_nmi()) { |
---|
1418 | | - if (spec.field_width == -1) |
---|
1419 | | - spec.field_width = 2 * sizeof(ptr); |
---|
1420 | | - return string(buf, end, "pK-error", spec); |
---|
1421 | | - } |
---|
1422 | | - |
---|
1423 | | - /* |
---|
1424 | | - * Only print the real pointer value if the current |
---|
1425 | | - * process has CAP_SYSLOG and is running with the |
---|
1426 | | - * same credentials it started with. This is because |
---|
1427 | | - * access to files is checked at open() time, but %pK |
---|
1428 | | - * checks permission at read() time. We don't want to |
---|
1429 | | - * leak pointer values if a binary opens a file using |
---|
1430 | | - * %pK and then elevates privileges before reading it. |
---|
1431 | | - */ |
---|
1432 | | - cred = current_cred(); |
---|
1433 | | - if (!has_capability_noaudit(current, CAP_SYSLOG) || |
---|
1434 | | - !uid_eq(cred->euid, cred->uid) || |
---|
1435 | | - !gid_eq(cred->egid, cred->gid)) |
---|
1436 | | - ptr = NULL; |
---|
1437 | | - break; |
---|
1438 | | - } |
---|
1439 | | - case 2: |
---|
1440 | | - default: |
---|
1441 | | - /* Always print 0's for %pK */ |
---|
1442 | | - ptr = NULL; |
---|
1443 | | - break; |
---|
1444 | | - } |
---|
1445 | | - |
---|
1446 | | - return pointer_string(buf, end, ptr, spec); |
---|
1447 | | -} |
---|
1448 | | - |
---|
1449 | | -static noinline_for_stack |
---|
1450 | | -char *netdev_bits(char *buf, char *end, const void *addr, const char *fmt) |
---|
| 1760 | +char *netdev_bits(char *buf, char *end, const void *addr, |
---|
| 1761 | + struct printf_spec spec, const char *fmt) |
---|
1451 | 1762 | { |
---|
1452 | 1763 | unsigned long long num; |
---|
1453 | 1764 | int size; |
---|
| 1765 | + |
---|
| 1766 | + if (check_pointer(&buf, end, addr, spec)) |
---|
| 1767 | + return buf; |
---|
1454 | 1768 | |
---|
1455 | 1769 | switch (fmt[1]) { |
---|
1456 | 1770 | case 'F': |
---|
.. | .. |
---|
1458 | 1772 | size = sizeof(netdev_features_t); |
---|
1459 | 1773 | break; |
---|
1460 | 1774 | default: |
---|
1461 | | - num = (unsigned long)addr; |
---|
1462 | | - size = sizeof(unsigned long); |
---|
1463 | | - break; |
---|
| 1775 | + return error_string(buf, end, "(%pN?)", spec); |
---|
1464 | 1776 | } |
---|
1465 | 1777 | |
---|
1466 | 1778 | return special_hex_number(buf, end, num, size); |
---|
1467 | 1779 | } |
---|
1468 | 1780 | |
---|
1469 | 1781 | static noinline_for_stack |
---|
1470 | | -char *address_val(char *buf, char *end, const void *addr, const char *fmt) |
---|
| 1782 | +char *address_val(char *buf, char *end, const void *addr, |
---|
| 1783 | + struct printf_spec spec, const char *fmt) |
---|
1471 | 1784 | { |
---|
1472 | 1785 | unsigned long long num; |
---|
1473 | 1786 | int size; |
---|
| 1787 | + |
---|
| 1788 | + if (check_pointer(&buf, end, addr, spec)) |
---|
| 1789 | + return buf; |
---|
1474 | 1790 | |
---|
1475 | 1791 | switch (fmt[1]) { |
---|
1476 | 1792 | case 'd': |
---|
.. | .. |
---|
1488 | 1804 | } |
---|
1489 | 1805 | |
---|
1490 | 1806 | static noinline_for_stack |
---|
| 1807 | +char *date_str(char *buf, char *end, const struct rtc_time *tm, bool r) |
---|
| 1808 | +{ |
---|
| 1809 | + int year = tm->tm_year + (r ? 0 : 1900); |
---|
| 1810 | + int mon = tm->tm_mon + (r ? 0 : 1); |
---|
| 1811 | + |
---|
| 1812 | + buf = number(buf, end, year, default_dec04_spec); |
---|
| 1813 | + if (buf < end) |
---|
| 1814 | + *buf = '-'; |
---|
| 1815 | + buf++; |
---|
| 1816 | + |
---|
| 1817 | + buf = number(buf, end, mon, default_dec02_spec); |
---|
| 1818 | + if (buf < end) |
---|
| 1819 | + *buf = '-'; |
---|
| 1820 | + buf++; |
---|
| 1821 | + |
---|
| 1822 | + return number(buf, end, tm->tm_mday, default_dec02_spec); |
---|
| 1823 | +} |
---|
| 1824 | + |
---|
| 1825 | +static noinline_for_stack |
---|
| 1826 | +char *time_str(char *buf, char *end, const struct rtc_time *tm, bool r) |
---|
| 1827 | +{ |
---|
| 1828 | + buf = number(buf, end, tm->tm_hour, default_dec02_spec); |
---|
| 1829 | + if (buf < end) |
---|
| 1830 | + *buf = ':'; |
---|
| 1831 | + buf++; |
---|
| 1832 | + |
---|
| 1833 | + buf = number(buf, end, tm->tm_min, default_dec02_spec); |
---|
| 1834 | + if (buf < end) |
---|
| 1835 | + *buf = ':'; |
---|
| 1836 | + buf++; |
---|
| 1837 | + |
---|
| 1838 | + return number(buf, end, tm->tm_sec, default_dec02_spec); |
---|
| 1839 | +} |
---|
| 1840 | + |
---|
| 1841 | +static noinline_for_stack |
---|
| 1842 | +char *rtc_str(char *buf, char *end, const struct rtc_time *tm, |
---|
| 1843 | + struct printf_spec spec, const char *fmt) |
---|
| 1844 | +{ |
---|
| 1845 | + bool have_t = true, have_d = true; |
---|
| 1846 | + bool raw = false; |
---|
| 1847 | + int count = 2; |
---|
| 1848 | + |
---|
| 1849 | + if (check_pointer(&buf, end, tm, spec)) |
---|
| 1850 | + return buf; |
---|
| 1851 | + |
---|
| 1852 | + switch (fmt[count]) { |
---|
| 1853 | + case 'd': |
---|
| 1854 | + have_t = false; |
---|
| 1855 | + count++; |
---|
| 1856 | + break; |
---|
| 1857 | + case 't': |
---|
| 1858 | + have_d = false; |
---|
| 1859 | + count++; |
---|
| 1860 | + break; |
---|
| 1861 | + } |
---|
| 1862 | + |
---|
| 1863 | + raw = fmt[count] == 'r'; |
---|
| 1864 | + |
---|
| 1865 | + if (have_d) |
---|
| 1866 | + buf = date_str(buf, end, tm, raw); |
---|
| 1867 | + if (have_d && have_t) { |
---|
| 1868 | + /* Respect ISO 8601 */ |
---|
| 1869 | + if (buf < end) |
---|
| 1870 | + *buf = 'T'; |
---|
| 1871 | + buf++; |
---|
| 1872 | + } |
---|
| 1873 | + if (have_t) |
---|
| 1874 | + buf = time_str(buf, end, tm, raw); |
---|
| 1875 | + |
---|
| 1876 | + return buf; |
---|
| 1877 | +} |
---|
| 1878 | + |
---|
| 1879 | +static noinline_for_stack |
---|
| 1880 | +char *time64_str(char *buf, char *end, const time64_t time, |
---|
| 1881 | + struct printf_spec spec, const char *fmt) |
---|
| 1882 | +{ |
---|
| 1883 | + struct rtc_time rtc_time; |
---|
| 1884 | + struct tm tm; |
---|
| 1885 | + |
---|
| 1886 | + time64_to_tm(time, 0, &tm); |
---|
| 1887 | + |
---|
| 1888 | + rtc_time.tm_sec = tm.tm_sec; |
---|
| 1889 | + rtc_time.tm_min = tm.tm_min; |
---|
| 1890 | + rtc_time.tm_hour = tm.tm_hour; |
---|
| 1891 | + rtc_time.tm_mday = tm.tm_mday; |
---|
| 1892 | + rtc_time.tm_mon = tm.tm_mon; |
---|
| 1893 | + rtc_time.tm_year = tm.tm_year; |
---|
| 1894 | + rtc_time.tm_wday = tm.tm_wday; |
---|
| 1895 | + rtc_time.tm_yday = tm.tm_yday; |
---|
| 1896 | + |
---|
| 1897 | + rtc_time.tm_isdst = 0; |
---|
| 1898 | + |
---|
| 1899 | + return rtc_str(buf, end, &rtc_time, spec, fmt); |
---|
| 1900 | +} |
---|
| 1901 | + |
---|
| 1902 | +static noinline_for_stack |
---|
| 1903 | +char *time_and_date(char *buf, char *end, void *ptr, struct printf_spec spec, |
---|
| 1904 | + const char *fmt) |
---|
| 1905 | +{ |
---|
| 1906 | + switch (fmt[1]) { |
---|
| 1907 | + case 'R': |
---|
| 1908 | + return rtc_str(buf, end, (const struct rtc_time *)ptr, spec, fmt); |
---|
| 1909 | + case 'T': |
---|
| 1910 | + return time64_str(buf, end, *(const time64_t *)ptr, spec, fmt); |
---|
| 1911 | + default: |
---|
| 1912 | + return error_string(buf, end, "(%pt?)", spec); |
---|
| 1913 | + } |
---|
| 1914 | +} |
---|
| 1915 | + |
---|
| 1916 | +static noinline_for_stack |
---|
1491 | 1917 | char *clock(char *buf, char *end, struct clk *clk, struct printf_spec spec, |
---|
1492 | 1918 | const char *fmt) |
---|
1493 | 1919 | { |
---|
1494 | | - if (!IS_ENABLED(CONFIG_HAVE_CLK) || !clk) |
---|
1495 | | - return string(buf, end, NULL, spec); |
---|
| 1920 | + if (!IS_ENABLED(CONFIG_HAVE_CLK)) |
---|
| 1921 | + return error_string(buf, end, "(%pC?)", spec); |
---|
| 1922 | + |
---|
| 1923 | + if (check_pointer(&buf, end, clk, spec)) |
---|
| 1924 | + return buf; |
---|
1496 | 1925 | |
---|
1497 | 1926 | switch (fmt[1]) { |
---|
1498 | 1927 | case 'n': |
---|
.. | .. |
---|
1500 | 1929 | #ifdef CONFIG_COMMON_CLK |
---|
1501 | 1930 | return string(buf, end, __clk_get_name(clk), spec); |
---|
1502 | 1931 | #else |
---|
1503 | | - return special_hex_number(buf, end, (unsigned long)clk, sizeof(unsigned long)); |
---|
| 1932 | + return ptr_to_id(buf, end, clk, spec); |
---|
1504 | 1933 | #endif |
---|
1505 | 1934 | } |
---|
1506 | 1935 | } |
---|
.. | .. |
---|
1533 | 1962 | } |
---|
1534 | 1963 | |
---|
1535 | 1964 | static noinline_for_stack |
---|
1536 | | -char *flags_string(char *buf, char *end, void *flags_ptr, const char *fmt) |
---|
| 1965 | +char *flags_string(char *buf, char *end, void *flags_ptr, |
---|
| 1966 | + struct printf_spec spec, const char *fmt) |
---|
1537 | 1967 | { |
---|
1538 | 1968 | unsigned long flags; |
---|
1539 | 1969 | const struct trace_print_flags *names; |
---|
| 1970 | + |
---|
| 1971 | + if (check_pointer(&buf, end, flags_ptr, spec)) |
---|
| 1972 | + return buf; |
---|
1540 | 1973 | |
---|
1541 | 1974 | switch (fmt[1]) { |
---|
1542 | 1975 | case 'p': |
---|
.. | .. |
---|
1550 | 1983 | names = vmaflag_names; |
---|
1551 | 1984 | break; |
---|
1552 | 1985 | case 'g': |
---|
1553 | | - flags = *(gfp_t *)flags_ptr; |
---|
| 1986 | + flags = (__force unsigned long)(*(gfp_t *)flags_ptr); |
---|
1554 | 1987 | names = gfpflag_names; |
---|
1555 | 1988 | break; |
---|
1556 | 1989 | default: |
---|
1557 | | - WARN_ONCE(1, "Unsupported flags modifier: %c\n", fmt[1]); |
---|
1558 | | - return buf; |
---|
| 1990 | + return error_string(buf, end, "(%pG?)", spec); |
---|
1559 | 1991 | } |
---|
1560 | 1992 | |
---|
1561 | 1993 | return format_flags(buf, end, flags, names); |
---|
1562 | 1994 | } |
---|
1563 | 1995 | |
---|
1564 | | -static const char *device_node_name_for_depth(const struct device_node *np, int depth) |
---|
1565 | | -{ |
---|
1566 | | - for ( ; np && depth; depth--) |
---|
1567 | | - np = np->parent; |
---|
1568 | | - |
---|
1569 | | - return kbasename(np->full_name); |
---|
1570 | | -} |
---|
1571 | | - |
---|
1572 | 1996 | static noinline_for_stack |
---|
1573 | | -char *device_node_gen_full_name(const struct device_node *np, char *buf, char *end) |
---|
| 1997 | +char *fwnode_full_name_string(struct fwnode_handle *fwnode, char *buf, |
---|
| 1998 | + char *end) |
---|
1574 | 1999 | { |
---|
1575 | 2000 | int depth; |
---|
1576 | | - const struct device_node *parent = np->parent; |
---|
1577 | 2001 | |
---|
1578 | | - /* special case for root node */ |
---|
1579 | | - if (!parent) |
---|
1580 | | - return string(buf, end, "/", default_str_spec); |
---|
| 2002 | + /* Loop starting from the root node to the current node. */ |
---|
| 2003 | + for (depth = fwnode_count_parents(fwnode); depth >= 0; depth--) { |
---|
| 2004 | + struct fwnode_handle *__fwnode = |
---|
| 2005 | + fwnode_get_nth_parent(fwnode, depth); |
---|
1581 | 2006 | |
---|
1582 | | - for (depth = 0; parent->parent; depth++) |
---|
1583 | | - parent = parent->parent; |
---|
1584 | | - |
---|
1585 | | - for ( ; depth >= 0; depth--) { |
---|
1586 | | - buf = string(buf, end, "/", default_str_spec); |
---|
1587 | | - buf = string(buf, end, device_node_name_for_depth(np, depth), |
---|
| 2007 | + buf = string(buf, end, fwnode_get_name_prefix(__fwnode), |
---|
1588 | 2008 | default_str_spec); |
---|
| 2009 | + buf = string(buf, end, fwnode_get_name(__fwnode), |
---|
| 2010 | + default_str_spec); |
---|
| 2011 | + |
---|
| 2012 | + fwnode_handle_put(__fwnode); |
---|
1589 | 2013 | } |
---|
| 2014 | + |
---|
1590 | 2015 | return buf; |
---|
1591 | 2016 | } |
---|
1592 | 2017 | |
---|
.. | .. |
---|
1600 | 2025 | char *buf_start = buf; |
---|
1601 | 2026 | struct property *prop; |
---|
1602 | 2027 | bool has_mult, pass; |
---|
1603 | | - static const struct printf_spec num_spec = { |
---|
1604 | | - .flags = SMALL, |
---|
1605 | | - .field_width = -1, |
---|
1606 | | - .precision = -1, |
---|
1607 | | - .base = 10, |
---|
1608 | | - }; |
---|
1609 | 2028 | |
---|
1610 | 2029 | struct printf_spec str_spec = spec; |
---|
1611 | 2030 | str_spec.field_width = -1; |
---|
1612 | 2031 | |
---|
1613 | | - if (!IS_ENABLED(CONFIG_OF)) |
---|
1614 | | - return string(buf, end, "(!OF)", spec); |
---|
| 2032 | + if (fmt[0] != 'F') |
---|
| 2033 | + return error_string(buf, end, "(%pO?)", spec); |
---|
1615 | 2034 | |
---|
1616 | | - if ((unsigned long)dn < PAGE_SIZE) |
---|
1617 | | - return string(buf, end, "(null)", spec); |
---|
| 2035 | + if (!IS_ENABLED(CONFIG_OF)) |
---|
| 2036 | + return error_string(buf, end, "(%pOF?)", spec); |
---|
| 2037 | + |
---|
| 2038 | + if (check_pointer(&buf, end, dn, spec)) |
---|
| 2039 | + return buf; |
---|
1618 | 2040 | |
---|
1619 | 2041 | /* simple case without anything any more format specifiers */ |
---|
1620 | 2042 | fmt++; |
---|
.. | .. |
---|
1622 | 2044 | fmt = "f"; |
---|
1623 | 2045 | |
---|
1624 | 2046 | for (pass = false; strspn(fmt,"fnpPFcC"); fmt++, pass = true) { |
---|
| 2047 | + int precision; |
---|
1625 | 2048 | if (pass) { |
---|
1626 | 2049 | if (buf < end) |
---|
1627 | 2050 | *buf = ':'; |
---|
.. | .. |
---|
1630 | 2053 | |
---|
1631 | 2054 | switch (*fmt) { |
---|
1632 | 2055 | case 'f': /* full_name */ |
---|
1633 | | - buf = device_node_gen_full_name(dn, buf, end); |
---|
| 2056 | + buf = fwnode_full_name_string(of_fwnode_handle(dn), buf, |
---|
| 2057 | + end); |
---|
1634 | 2058 | break; |
---|
1635 | 2059 | case 'n': /* name */ |
---|
1636 | | - buf = string(buf, end, dn->name, str_spec); |
---|
| 2060 | + p = fwnode_get_name(of_fwnode_handle(dn)); |
---|
| 2061 | + precision = str_spec.precision; |
---|
| 2062 | + str_spec.precision = strchrnul(p, '@') - p; |
---|
| 2063 | + buf = string(buf, end, p, str_spec); |
---|
| 2064 | + str_spec.precision = precision; |
---|
1637 | 2065 | break; |
---|
1638 | 2066 | case 'p': /* phandle */ |
---|
1639 | | - buf = number(buf, end, (unsigned int)dn->phandle, num_spec); |
---|
| 2067 | + buf = number(buf, end, (unsigned int)dn->phandle, default_dec_spec); |
---|
1640 | 2068 | break; |
---|
1641 | 2069 | case 'P': /* path-spec */ |
---|
1642 | | - p = kbasename(of_node_full_name(dn)); |
---|
| 2070 | + p = fwnode_get_name(of_fwnode_handle(dn)); |
---|
1643 | 2071 | if (!p[1]) |
---|
1644 | 2072 | p = "/"; |
---|
1645 | 2073 | buf = string(buf, end, p, str_spec); |
---|
.. | .. |
---|
1650 | 2078 | tbuf[2] = of_node_check_flag(dn, OF_POPULATED) ? 'P' : '-'; |
---|
1651 | 2079 | tbuf[3] = of_node_check_flag(dn, OF_POPULATED_BUS) ? 'B' : '-'; |
---|
1652 | 2080 | tbuf[4] = 0; |
---|
1653 | | - buf = string(buf, end, tbuf, str_spec); |
---|
| 2081 | + buf = string_nocheck(buf, end, tbuf, str_spec); |
---|
1654 | 2082 | break; |
---|
1655 | 2083 | case 'c': /* major compatible string */ |
---|
1656 | 2084 | ret = of_property_read_string(dn, "compatible", &p); |
---|
.. | .. |
---|
1661 | 2089 | has_mult = false; |
---|
1662 | 2090 | of_property_for_each_string(dn, "compatible", prop, p) { |
---|
1663 | 2091 | if (has_mult) |
---|
1664 | | - buf = string(buf, end, ",", str_spec); |
---|
1665 | | - buf = string(buf, end, "\"", str_spec); |
---|
| 2092 | + buf = string_nocheck(buf, end, ",", str_spec); |
---|
| 2093 | + buf = string_nocheck(buf, end, "\"", str_spec); |
---|
1666 | 2094 | buf = string(buf, end, p, str_spec); |
---|
1667 | | - buf = string(buf, end, "\"", str_spec); |
---|
| 2095 | + buf = string_nocheck(buf, end, "\"", str_spec); |
---|
1668 | 2096 | |
---|
1669 | 2097 | has_mult = true; |
---|
1670 | 2098 | } |
---|
.. | .. |
---|
1677 | 2105 | return widen_string(buf, buf - buf_start, end, spec); |
---|
1678 | 2106 | } |
---|
1679 | 2107 | |
---|
1680 | | -/* Make pointers available for printing early in the boot sequence. */ |
---|
1681 | | -static int debug_boot_weak_hash __ro_after_init; |
---|
1682 | | - |
---|
1683 | | -static int __init debug_boot_weak_hash_enable(char *str) |
---|
| 2108 | +static noinline_for_stack |
---|
| 2109 | +char *fwnode_string(char *buf, char *end, struct fwnode_handle *fwnode, |
---|
| 2110 | + struct printf_spec spec, const char *fmt) |
---|
1684 | 2111 | { |
---|
1685 | | - debug_boot_weak_hash = 1; |
---|
1686 | | - pr_info("debug_boot_weak_hash enabled\n"); |
---|
| 2112 | + struct printf_spec str_spec = spec; |
---|
| 2113 | + char *buf_start = buf; |
---|
| 2114 | + |
---|
| 2115 | + str_spec.field_width = -1; |
---|
| 2116 | + |
---|
| 2117 | + if (*fmt != 'w') |
---|
| 2118 | + return error_string(buf, end, "(%pf?)", spec); |
---|
| 2119 | + |
---|
| 2120 | + if (check_pointer(&buf, end, fwnode, spec)) |
---|
| 2121 | + return buf; |
---|
| 2122 | + |
---|
| 2123 | + fmt++; |
---|
| 2124 | + |
---|
| 2125 | + switch (*fmt) { |
---|
| 2126 | + case 'P': /* name */ |
---|
| 2127 | + buf = string(buf, end, fwnode_get_name(fwnode), str_spec); |
---|
| 2128 | + break; |
---|
| 2129 | + case 'f': /* full_name */ |
---|
| 2130 | + default: |
---|
| 2131 | + buf = fwnode_full_name_string(fwnode, buf, end); |
---|
| 2132 | + break; |
---|
| 2133 | + } |
---|
| 2134 | + |
---|
| 2135 | + return widen_string(buf, buf - buf_start, end, spec); |
---|
| 2136 | +} |
---|
| 2137 | + |
---|
| 2138 | +static int __init no_hash_pointers_enable(char *str) |
---|
| 2139 | +{ |
---|
| 2140 | + no_hash_pointers = true; |
---|
| 2141 | + |
---|
| 2142 | + pr_warn("**********************************************************\n"); |
---|
| 2143 | + pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **\n"); |
---|
| 2144 | + pr_warn("** **\n"); |
---|
| 2145 | + pr_warn("** This system shows unhashed kernel memory addresses **\n"); |
---|
| 2146 | + pr_warn("** via the console, logs, and other interfaces. This **\n"); |
---|
| 2147 | + pr_warn("** might reduce the security of your system. **\n"); |
---|
| 2148 | + pr_warn("** **\n"); |
---|
| 2149 | + pr_warn("** If you see this message and you are not debugging **\n"); |
---|
| 2150 | + pr_warn("** the kernel, report this immediately to your system **\n"); |
---|
| 2151 | + pr_warn("** administrator! **\n"); |
---|
| 2152 | + pr_warn("** **\n"); |
---|
| 2153 | + pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **\n"); |
---|
| 2154 | + pr_warn("**********************************************************\n"); |
---|
| 2155 | + |
---|
1687 | 2156 | return 0; |
---|
1688 | 2157 | } |
---|
1689 | | -early_param("debug_boot_weak_hash", debug_boot_weak_hash_enable); |
---|
1690 | | - |
---|
1691 | | -static DEFINE_STATIC_KEY_TRUE(not_filled_random_ptr_key); |
---|
1692 | | -static siphash_key_t ptr_key __read_mostly; |
---|
1693 | | - |
---|
1694 | | -static void enable_ptr_key_workfn(struct work_struct *work) |
---|
1695 | | -{ |
---|
1696 | | - get_random_bytes(&ptr_key, sizeof(ptr_key)); |
---|
1697 | | - /* Needs to run from preemptible context */ |
---|
1698 | | - static_branch_disable(¬_filled_random_ptr_key); |
---|
1699 | | -} |
---|
1700 | | - |
---|
1701 | | -static DECLARE_WORK(enable_ptr_key_work, enable_ptr_key_workfn); |
---|
1702 | | - |
---|
1703 | | -static void fill_random_ptr_key(struct random_ready_callback *unused) |
---|
1704 | | -{ |
---|
1705 | | - /* This may be in an interrupt handler. */ |
---|
1706 | | - queue_work(system_unbound_wq, &enable_ptr_key_work); |
---|
1707 | | -} |
---|
1708 | | - |
---|
1709 | | -static struct random_ready_callback random_ready = { |
---|
1710 | | - .func = fill_random_ptr_key |
---|
1711 | | -}; |
---|
1712 | | - |
---|
1713 | | -static int __init initialize_ptr_random(void) |
---|
1714 | | -{ |
---|
1715 | | - int key_size = sizeof(ptr_key); |
---|
1716 | | - int ret; |
---|
1717 | | - |
---|
1718 | | - /* Use hw RNG if available. */ |
---|
1719 | | - if (get_random_bytes_arch(&ptr_key, key_size) == key_size) { |
---|
1720 | | - static_branch_disable(¬_filled_random_ptr_key); |
---|
1721 | | - return 0; |
---|
1722 | | - } |
---|
1723 | | - |
---|
1724 | | - ret = add_random_ready_callback(&random_ready); |
---|
1725 | | - if (!ret) { |
---|
1726 | | - return 0; |
---|
1727 | | - } else if (ret == -EALREADY) { |
---|
1728 | | - /* This is in preemptible context */ |
---|
1729 | | - enable_ptr_key_workfn(&enable_ptr_key_work); |
---|
1730 | | - return 0; |
---|
1731 | | - } |
---|
1732 | | - |
---|
1733 | | - return ret; |
---|
1734 | | -} |
---|
1735 | | -early_initcall(initialize_ptr_random); |
---|
1736 | | - |
---|
1737 | | -static inline int __ptr_to_hashval(const void *ptr, unsigned long *hashval_out) |
---|
1738 | | -{ |
---|
1739 | | - unsigned long hashval; |
---|
1740 | | - |
---|
1741 | | - if (static_branch_unlikely(¬_filled_random_ptr_key)) |
---|
1742 | | - return -EAGAIN; |
---|
1743 | | - |
---|
1744 | | -#ifdef CONFIG_64BIT |
---|
1745 | | - hashval = (unsigned long)siphash_1u64((u64)ptr, &ptr_key); |
---|
1746 | | - /* |
---|
1747 | | - * Mask off the first 32 bits, this makes explicit that we have |
---|
1748 | | - * modified the address (and 32 bits is plenty for a unique ID). |
---|
1749 | | - */ |
---|
1750 | | - hashval = hashval & 0xffffffff; |
---|
1751 | | -#else |
---|
1752 | | - hashval = (unsigned long)siphash_1u32((u32)ptr, &ptr_key); |
---|
1753 | | -#endif |
---|
1754 | | - *hashval_out = hashval; |
---|
1755 | | - return 0; |
---|
1756 | | -} |
---|
1757 | | - |
---|
1758 | | -int ptr_to_hashval(const void *ptr, unsigned long *hashval_out) |
---|
1759 | | -{ |
---|
1760 | | - return __ptr_to_hashval(ptr, hashval_out); |
---|
1761 | | -} |
---|
1762 | | -EXPORT_SYMBOL_GPL(ptr_to_hashval); |
---|
1763 | | - |
---|
1764 | | -/* Maps a pointer to a 32 bit unique identifier. */ |
---|
1765 | | -static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec) |
---|
1766 | | -{ |
---|
1767 | | - const char *str = sizeof(ptr) == 8 ? "(____ptrval____)" : "(ptrval)"; |
---|
1768 | | - unsigned long hashval; |
---|
1769 | | - int ret; |
---|
1770 | | - |
---|
1771 | | - /* When debugging early boot use non-cryptographically secure hash. */ |
---|
1772 | | - if (unlikely(debug_boot_weak_hash)) { |
---|
1773 | | - hashval = hash_long((unsigned long)ptr, 32); |
---|
1774 | | - return pointer_string(buf, end, (const void *)hashval, spec); |
---|
1775 | | - } |
---|
1776 | | - |
---|
1777 | | - ret = __ptr_to_hashval(ptr, &hashval); |
---|
1778 | | - if (ret) { |
---|
1779 | | - spec.field_width = 2 * sizeof(ptr); |
---|
1780 | | - /* string length must be less than default_width */ |
---|
1781 | | - return string(buf, end, str, spec); |
---|
1782 | | - } |
---|
1783 | | - |
---|
1784 | | - return pointer_string(buf, end, (const void *)hashval, spec); |
---|
1785 | | -} |
---|
| 2158 | +early_param("no_hash_pointers", no_hash_pointers_enable); |
---|
1786 | 2159 | |
---|
1787 | 2160 | /* |
---|
1788 | 2161 | * Show a '%p' thing. A kernel extension is that the '%p' is followed |
---|
.. | .. |
---|
1796 | 2169 | * |
---|
1797 | 2170 | * - 'S' For symbolic direct pointers (or function descriptors) with offset |
---|
1798 | 2171 | * - 's' For symbolic direct pointers (or function descriptors) without offset |
---|
1799 | | - * - 'F' Same as 'S' |
---|
1800 | | - * - 'f' Same as 's' |
---|
1801 | | - * - '[FfSs]R' as above with __builtin_extract_return_addr() translation |
---|
| 2172 | + * - '[Ss]R' as above with __builtin_extract_return_addr() translation |
---|
| 2173 | + * - '[Ff]' %pf and %pF were obsoleted and later removed in favor of |
---|
| 2174 | + * %ps and %pS. Be careful when re-using these specifiers. |
---|
1802 | 2175 | * - 'B' For backtraced symbolic direct pointers with offset |
---|
1803 | 2176 | * - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref] |
---|
1804 | 2177 | * - 'r' For raw struct resource, e.g., [mem 0x0-0x1f flags 0x201] |
---|
.. | .. |
---|
1826 | 2199 | * [4] or [6] and is able to print port [p], flowinfo [f], scope [s] |
---|
1827 | 2200 | * - '[Ii][4S][hnbl]' IPv4 addresses in host, network, big or little endian order |
---|
1828 | 2201 | * - 'I[6S]c' for IPv6 addresses printed as specified by |
---|
1829 | | - * http://tools.ietf.org/html/rfc5952 |
---|
| 2202 | + * https://tools.ietf.org/html/rfc5952 |
---|
1830 | 2203 | * - 'E[achnops]' For an escaped buffer, where rules are defined by combination |
---|
1831 | 2204 | * of the following flags (see string_escape_mem() for the |
---|
1832 | 2205 | * details): |
---|
.. | .. |
---|
1868 | 2241 | * - 'd[234]' For a dentry name (optionally 2-4 last components) |
---|
1869 | 2242 | * - 'D[234]' Same as 'd' but for a struct file |
---|
1870 | 2243 | * - 'g' For block_device name (gendisk + partition number) |
---|
| 2244 | + * - 't[RT][dt][r]' For time and date as represented by: |
---|
| 2245 | + * R struct rtc_time |
---|
| 2246 | + * T time64_t |
---|
1871 | 2247 | * - 'C' For a clock, it prints the name (Common Clock Framework) or address |
---|
1872 | 2248 | * (legacy clock framework) of the clock |
---|
1873 | 2249 | * - 'Cn' For a clock, it prints the name (Common Clock Framework) or address |
---|
1874 | 2250 | * (legacy clock framework) of the clock |
---|
1875 | | - * - 'Cr' For a clock, it prints the current rate of the clock |
---|
1876 | 2251 | * - 'G' For flags to be printed as a collection of symbolic strings that would |
---|
1877 | 2252 | * construct the specific value. Supported flags given by option: |
---|
1878 | 2253 | * p page flags (see struct page) given as pointer to unsigned long |
---|
1879 | 2254 | * g gfp flags (GFP_* and __GFP_*) given as pointer to gfp_t |
---|
1880 | 2255 | * v vma flags (VM_*) given as pointer to unsigned long |
---|
1881 | | - * - 'O' For a kobject based struct. Must be one of the following: |
---|
1882 | | - * - 'OF[fnpPcCF]' For a device tree object |
---|
1883 | | - * Without any optional arguments prints the full_name |
---|
1884 | | - * f device node full_name |
---|
1885 | | - * n device node name |
---|
1886 | | - * p device node phandle |
---|
1887 | | - * P device node path spec (name + @unit) |
---|
1888 | | - * F device node flags |
---|
1889 | | - * c major compatible string |
---|
1890 | | - * C full compatible string |
---|
1891 | | - * |
---|
| 2256 | + * - 'OF[fnpPcCF]' For a device tree object |
---|
| 2257 | + * Without any optional arguments prints the full_name |
---|
| 2258 | + * f device node full_name |
---|
| 2259 | + * n device node name |
---|
| 2260 | + * p device node phandle |
---|
| 2261 | + * P device node path spec (name + @unit) |
---|
| 2262 | + * F device node flags |
---|
| 2263 | + * c major compatible string |
---|
| 2264 | + * C full compatible string |
---|
| 2265 | + * - 'fw[fP]' For a firmware node (struct fwnode_handle) pointer |
---|
| 2266 | + * Without an option prints the full name of the node |
---|
| 2267 | + * f full name |
---|
| 2268 | + * P node name, including a possible unit address |
---|
1892 | 2269 | * - 'x' For printing the address. Equivalent to "%lx". |
---|
| 2270 | + * - '[ku]s' For a BPF/tracing related format specifier, e.g. used out of |
---|
| 2271 | + * bpf_trace_printk() where [ku] prefix specifies either kernel (k) |
---|
| 2272 | + * or user (u) memory to probe, and: |
---|
| 2273 | + * s a string, equivalent to "%s" on direct vsnprintf() use |
---|
1893 | 2274 | * |
---|
1894 | 2275 | * ** When making changes please also update: |
---|
1895 | 2276 | * Documentation/core-api/printk-formats.rst |
---|
.. | .. |
---|
1901 | 2282 | char *pointer(const char *fmt, char *buf, char *end, void *ptr, |
---|
1902 | 2283 | struct printf_spec spec) |
---|
1903 | 2284 | { |
---|
1904 | | - const int default_width = 2 * sizeof(void *); |
---|
1905 | | - |
---|
1906 | | - if (!ptr && *fmt != 'K' && *fmt != 'x') { |
---|
1907 | | - /* |
---|
1908 | | - * Print (null) with the same width as a pointer so it makes |
---|
1909 | | - * tabular output look nice. |
---|
1910 | | - */ |
---|
1911 | | - if (spec.field_width == -1) |
---|
1912 | | - spec.field_width = default_width; |
---|
1913 | | - return string(buf, end, "(null)", spec); |
---|
1914 | | - } |
---|
1915 | | - |
---|
1916 | 2285 | switch (*fmt) { |
---|
1917 | | - case 'F': |
---|
1918 | | - case 'f': |
---|
1919 | 2286 | case 'S': |
---|
1920 | 2287 | case 's': |
---|
1921 | 2288 | ptr = dereference_symbol_descriptor(ptr); |
---|
1922 | | - /* Fallthrough */ |
---|
| 2289 | + /* fall through */ |
---|
1923 | 2290 | case 'B': |
---|
1924 | 2291 | return symbol_string(buf, end, ptr, spec, fmt); |
---|
1925 | 2292 | case 'R': |
---|
.. | .. |
---|
1948 | 2315 | * 4: 001.002.003.004 |
---|
1949 | 2316 | * 6: 000102...0f |
---|
1950 | 2317 | */ |
---|
1951 | | - switch (fmt[1]) { |
---|
1952 | | - case '6': |
---|
1953 | | - return ip6_addr_string(buf, end, ptr, spec, fmt); |
---|
1954 | | - case '4': |
---|
1955 | | - return ip4_addr_string(buf, end, ptr, spec, fmt); |
---|
1956 | | - case 'S': { |
---|
1957 | | - const union { |
---|
1958 | | - struct sockaddr raw; |
---|
1959 | | - struct sockaddr_in v4; |
---|
1960 | | - struct sockaddr_in6 v6; |
---|
1961 | | - } *sa = ptr; |
---|
1962 | | - |
---|
1963 | | - switch (sa->raw.sa_family) { |
---|
1964 | | - case AF_INET: |
---|
1965 | | - return ip4_addr_string_sa(buf, end, &sa->v4, spec, fmt); |
---|
1966 | | - case AF_INET6: |
---|
1967 | | - return ip6_addr_string_sa(buf, end, &sa->v6, spec, fmt); |
---|
1968 | | - default: |
---|
1969 | | - return string(buf, end, "(invalid address)", spec); |
---|
1970 | | - }} |
---|
1971 | | - } |
---|
1972 | | - break; |
---|
| 2318 | + return ip_addr_string(buf, end, ptr, spec, fmt); |
---|
1973 | 2319 | case 'E': |
---|
1974 | 2320 | return escaped_string(buf, end, ptr, spec, fmt); |
---|
1975 | 2321 | case 'U': |
---|
1976 | 2322 | return uuid_string(buf, end, ptr, spec, fmt); |
---|
1977 | 2323 | case 'V': |
---|
1978 | | - { |
---|
1979 | | - va_list va; |
---|
1980 | | - |
---|
1981 | | - va_copy(va, *((struct va_format *)ptr)->va); |
---|
1982 | | - buf += vsnprintf(buf, end > buf ? end - buf : 0, |
---|
1983 | | - ((struct va_format *)ptr)->fmt, va); |
---|
1984 | | - va_end(va); |
---|
1985 | | - return buf; |
---|
1986 | | - } |
---|
| 2324 | + return va_format(buf, end, ptr, spec, fmt); |
---|
1987 | 2325 | case 'K': |
---|
1988 | | - if (!kptr_restrict) |
---|
1989 | | - break; |
---|
1990 | 2326 | return restricted_pointer(buf, end, ptr, spec); |
---|
1991 | 2327 | case 'N': |
---|
1992 | | - return netdev_bits(buf, end, ptr, fmt); |
---|
| 2328 | + return netdev_bits(buf, end, ptr, spec, fmt); |
---|
1993 | 2329 | case 'a': |
---|
1994 | | - return address_val(buf, end, ptr, fmt); |
---|
| 2330 | + return address_val(buf, end, ptr, spec, fmt); |
---|
1995 | 2331 | case 'd': |
---|
1996 | 2332 | return dentry_name(buf, end, ptr, spec, fmt); |
---|
| 2333 | + case 't': |
---|
| 2334 | + return time_and_date(buf, end, ptr, spec, fmt); |
---|
1997 | 2335 | case 'C': |
---|
1998 | 2336 | return clock(buf, end, ptr, spec, fmt); |
---|
1999 | 2337 | case 'D': |
---|
2000 | | - return dentry_name(buf, end, |
---|
2001 | | - ((const struct file *)ptr)->f_path.dentry, |
---|
2002 | | - spec, fmt); |
---|
| 2338 | + return file_dentry_name(buf, end, ptr, spec, fmt); |
---|
2003 | 2339 | #ifdef CONFIG_BLOCK |
---|
2004 | 2340 | case 'g': |
---|
2005 | 2341 | return bdev_name(buf, end, ptr, spec, fmt); |
---|
2006 | 2342 | #endif |
---|
2007 | 2343 | |
---|
2008 | 2344 | case 'G': |
---|
2009 | | - return flags_string(buf, end, ptr, fmt); |
---|
| 2345 | + return flags_string(buf, end, ptr, spec, fmt); |
---|
2010 | 2346 | case 'O': |
---|
2011 | | - switch (fmt[1]) { |
---|
2012 | | - case 'F': |
---|
2013 | | - return device_node_string(buf, end, ptr, spec, fmt + 1); |
---|
2014 | | - } |
---|
2015 | | - break; |
---|
| 2347 | + return device_node_string(buf, end, ptr, spec, fmt + 1); |
---|
| 2348 | + case 'f': |
---|
| 2349 | + return fwnode_string(buf, end, ptr, spec, fmt + 1); |
---|
2016 | 2350 | case 'x': |
---|
2017 | 2351 | return pointer_string(buf, end, ptr, spec); |
---|
| 2352 | + case 'e': |
---|
| 2353 | + /* %pe with a non-ERR_PTR gets treated as plain %p */ |
---|
| 2354 | + if (!IS_ERR(ptr)) |
---|
| 2355 | + return default_pointer(buf, end, ptr, spec); |
---|
| 2356 | + return err_ptr(buf, end, ptr, spec); |
---|
| 2357 | + case 'u': |
---|
| 2358 | + case 'k': |
---|
| 2359 | + switch (fmt[1]) { |
---|
| 2360 | + case 's': |
---|
| 2361 | + return string(buf, end, ptr, spec); |
---|
| 2362 | + default: |
---|
| 2363 | + return error_string(buf, end, "(einval)", spec); |
---|
| 2364 | + } |
---|
| 2365 | + default: |
---|
| 2366 | + return default_pointer(buf, end, ptr, spec); |
---|
2018 | 2367 | } |
---|
2019 | | - |
---|
2020 | | - /* default is to _not_ leak addresses, hash before printing */ |
---|
2021 | | - return ptr_to_id(buf, end, ptr, spec); |
---|
2022 | 2368 | } |
---|
2023 | 2369 | |
---|
2024 | 2370 | /* |
---|
.. | .. |
---|
2188 | 2534 | * utility, treat it as any other invalid or |
---|
2189 | 2535 | * unsupported format specifier. |
---|
2190 | 2536 | */ |
---|
2191 | | - /* Fall-through */ |
---|
| 2537 | + /* fall through */ |
---|
2192 | 2538 | |
---|
2193 | 2539 | default: |
---|
2194 | 2540 | WARN_ONCE(1, "Please remove unsupported %%%c in format string\n", *fmt); |
---|
.. | .. |
---|
2627 | 2973 | |
---|
2628 | 2974 | case FORMAT_TYPE_STR: { |
---|
2629 | 2975 | const char *save_str = va_arg(args, char *); |
---|
| 2976 | + const char *err_msg; |
---|
2630 | 2977 | size_t len; |
---|
2631 | 2978 | |
---|
2632 | | - if ((unsigned long)save_str > (unsigned long)-PAGE_SIZE |
---|
2633 | | - || (unsigned long)save_str < PAGE_SIZE) |
---|
2634 | | - save_str = "(null)"; |
---|
| 2979 | + err_msg = check_pointer_msg(save_str); |
---|
| 2980 | + if (err_msg) |
---|
| 2981 | + save_str = err_msg; |
---|
| 2982 | + |
---|
2635 | 2983 | len = strlen(save_str) + 1; |
---|
2636 | 2984 | if (str + len < end) |
---|
2637 | 2985 | memcpy(str, save_str, len); |
---|
.. | .. |
---|
2645 | 2993 | /* Dereference of functions is still OK */ |
---|
2646 | 2994 | case 'S': |
---|
2647 | 2995 | case 's': |
---|
2648 | | - case 'F': |
---|
2649 | | - case 'f': |
---|
2650 | 2996 | case 'x': |
---|
2651 | 2997 | case 'K': |
---|
| 2998 | + case 'e': |
---|
2652 | 2999 | save_arg(void *); |
---|
2653 | 3000 | break; |
---|
2654 | 3001 | default: |
---|
.. | .. |
---|
2821 | 3168 | switch (*fmt) { |
---|
2822 | 3169 | case 'S': |
---|
2823 | 3170 | case 's': |
---|
2824 | | - case 'F': |
---|
2825 | | - case 'f': |
---|
2826 | 3171 | case 'x': |
---|
2827 | 3172 | case 'K': |
---|
| 3173 | + case 'e': |
---|
2828 | 3174 | process = true; |
---|
2829 | 3175 | break; |
---|
2830 | 3176 | default: |
---|