lkml.org 
[lkml]   [2022]   [Apr]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.15 328/913] vsprintf: Fix %pK with kptr_restrict == 0
    Date
    From: Christophe Leroy <christophe.leroy@csgroup.eu>

    [ Upstream commit 84842911322fc6a02a03ab9e728a48c691fe3efd ]

    Although kptr_restrict is set to 0 and the kernel is booted with
    no_hash_pointers parameter, the content of /proc/vmallocinfo is
    lacking the real addresses.

    / # cat /proc/vmallocinfo
    0x(ptrval)-0x(ptrval) 8192 load_module+0xc0c/0x2c0c pages=1 vmalloc
    0x(ptrval)-0x(ptrval) 12288 start_kernel+0x4e0/0x690 pages=2 vmalloc
    0x(ptrval)-0x(ptrval) 12288 start_kernel+0x4e0/0x690 pages=2 vmalloc
    0x(ptrval)-0x(ptrval) 8192 _mpic_map_mmio.constprop.0+0x20/0x44 phys=0x80041000 ioremap
    0x(ptrval)-0x(ptrval) 12288 _mpic_map_mmio.constprop.0+0x20/0x44 phys=0x80041000 ioremap
    ...

    According to the documentation for /proc/sys/kernel/, %pK is
    equivalent to %p when kptr_restrict is set to 0.

    Fixes: 5ead723a20e0 ("lib/vsprintf: no_hash_pointers prints all addresses as unhashed")
    Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
    Reviewed-by: Petr Mladek <pmladek@suse.com>
    Signed-off-by: Petr Mladek <pmladek@suse.com>
    Link: https://lore.kernel.org/r/107476128e59bff11a309b5bf7579a1753a41aca.1645087605.git.christophe.leroy@csgroup.eu
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    .../admin-guide/kernel-parameters.txt | 3 +-
    lib/vsprintf.c | 36 +++++++++++--------
    2 files changed, 22 insertions(+), 17 deletions(-)

    diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
    index ed55ea20352b..bb25aae69860 100644
    --- a/Documentation/admin-guide/kernel-parameters.txt
    +++ b/Documentation/admin-guide/kernel-parameters.txt
    @@ -3452,8 +3452,7 @@
    difficult since unequal pointers can no longer be
    compared. However, if this command-line option is
    specified, then all normal pointers will have their true
    - value printed. Pointers printed via %pK may still be
    - hashed. This option should only be specified when
    + value printed. This option should only be specified when
    debugging the kernel. Please do not use on production
    kernels.

    diff --git a/lib/vsprintf.c b/lib/vsprintf.c
    index 0621bbb20e0f..a3b73f28b7a9 100644
    --- a/lib/vsprintf.c
    +++ b/lib/vsprintf.c
    @@ -54,6 +54,10 @@
    #include <linux/string_helpers.h>
    #include "kstrtox.h"

    +/* Disable pointer hashing if requested */
    +bool no_hash_pointers __ro_after_init;
    +EXPORT_SYMBOL_GPL(no_hash_pointers);
    +
    static noinline unsigned long long simple_strntoull(const char *startp, size_t max_chars, char **endp, unsigned int base)
    {
    const char *cp;
    @@ -848,6 +852,19 @@ static char *ptr_to_id(char *buf, char *end, const void *ptr,
    return pointer_string(buf, end, (const void *)hashval, spec);
    }

    +static char *default_pointer(char *buf, char *end, const void *ptr,
    + struct printf_spec spec)
    +{
    + /*
    + * default is to _not_ leak addresses, so hash before printing,
    + * unless no_hash_pointers is specified on the command line.
    + */
    + if (unlikely(no_hash_pointers))
    + return pointer_string(buf, end, ptr, spec);
    +
    + return ptr_to_id(buf, end, ptr, spec);
    +}
    +
    int kptr_restrict __read_mostly;

    static noinline_for_stack
    @@ -857,7 +874,7 @@ char *restricted_pointer(char *buf, char *end, const void *ptr,
    switch (kptr_restrict) {
    case 0:
    /* Handle as %p, hash and do _not_ leak addresses. */
    - return ptr_to_id(buf, end, ptr, spec);
    + return default_pointer(buf, end, ptr, spec);
    case 1: {
    const struct cred *cred;

    @@ -2226,10 +2243,6 @@ char *fwnode_string(char *buf, char *end, struct fwnode_handle *fwnode,
    return widen_string(buf, buf - buf_start, end, spec);
    }

    -/* Disable pointer hashing if requested */
    -bool no_hash_pointers __ro_after_init;
    -EXPORT_SYMBOL_GPL(no_hash_pointers);
    -
    int __init no_hash_pointers_enable(char *str)
    {
    if (no_hash_pointers)
    @@ -2458,7 +2471,7 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
    case 'e':
    /* %pe with a non-ERR_PTR gets treated as plain %p */
    if (!IS_ERR(ptr))
    - break;
    + return default_pointer(buf, end, ptr, spec);
    return err_ptr(buf, end, ptr, spec);
    case 'u':
    case 'k':
    @@ -2468,16 +2481,9 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
    default:
    return error_string(buf, end, "(einval)", spec);
    }
    + default:
    + return default_pointer(buf, end, ptr, spec);
    }
    -
    - /*
    - * default is to _not_ leak addresses, so hash before printing,
    - * unless no_hash_pointers is specified on the command line.
    - */
    - if (unlikely(no_hash_pointers))
    - return pointer_string(buf, end, ptr, spec);
    - else
    - return ptr_to_id(buf, end, ptr, spec);
    }

    /*
    --
    2.34.1


    \
     
     \ /
      Last update: 2022-04-06 07:11    [W:4.426 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site