22 Aug, 2019

1 commit

  • Clang errors out when building this macro:

    lib/mpi/generic_mpih-mul1.c:37:24: error: invalid use of a cast in a
    inline asm context requiring an l-value: remove the cast or build with
    -fheinous-gnu-extensions
    umul_ppmm(prod_high, prod_low, s1_ptr[j], s2_limb);
    ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    lib/mpi/longlong.h:652:20: note: expanded from macro 'umul_ppmm'
    : "=l" ((USItype)(w0)), \
    ~~~~~~~~~~^~~
    lib/mpi/generic_mpih-mul1.c:37:3: error: invalid output constraint '=h'
    in asm
    umul_ppmm(prod_high, prod_low, s1_ptr[j], s2_limb);
    ^
    lib/mpi/longlong.h:653:7: note: expanded from macro 'umul_ppmm'
    "=h" ((USItype)(w1)) \
    ^
    2 errors generated.

    The C version that is used for GCC 4.4 and up works well with clang;
    however, it is not currently being used because Clang masks itself
    as GCC 4.2.1 for compatibility reasons. As Nick points out, we require
    GCC 4.6 and newer in the kernel so we can eliminate all of the
    versioning checks and just use the C version of umul_ppmm for all
    supported compilers.

    Link: https://github.com/ClangBuiltLinux/linux/issues/605
    Suggested-by: Nick Desaulniers
    Signed-off-by: Nathan Chancellor
    Reviewed-by: Nick Desaulniers
    Signed-off-by: Herbert Xu

    Nathan Chancellor
     

17 Jul, 2019

1 commit

  • The mpi library contains some rather old inline assembly statements that
    produce a lot of warnings for 32-bit x86, such as:

    lib/mpi/mpih-div.c:76:16: error: invalid use of a cast in a inline asm context requiring an l-value: remove the cast or build with -fheinous-gnu-extensions
    udiv_qrnnd(qp[i], n1, n1, np[i], d);
    ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
    lib/mpi/longlong.h:423:20: note: expanded from macro 'udiv_qrnnd'
    : "=a" ((USItype)(q)), \
    ~~~~~~~~~~^~

    There is no point in doing a type cast for the output of an inline
    assembler statement, so just remove the cast here, as we have done for
    other architectures in the past.

    See also dea632cadd12 ("lib/mpi: fix build with clang").

    Link: http://lkml.kernel.org/r/20190712090740.340186-1-arnd@arndb.de
    Signed-off-by: Arnd Bergmann
    Reviewed-by: Nick Desaulniers
    Cc: Stefan Agner
    Cc: Dmitry Kasatkin
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Arnd Bergmann
     

05 Jul, 2019

1 commit


03 Jul, 2019

1 commit

  • Sometimes mpi_powm will leak karactx because a memory allocation
    failure causes a bail-out that skips the freeing of karactx. This
    patch moves the freeing of karactx to the end of the function like
    everything else so that it can't be skipped.

    Reported-by: syzbot+f7baccc38dcc1e094e77@syzkaller.appspotmail.com
    Fixes: cdec9cb5167a ("crypto: GnuPG based MPI lib - source files...")
    Cc:
    Signed-off-by: Herbert Xu
    Reviewed-by: Eric Biggers
    Signed-off-by: Herbert Xu

    Herbert Xu
     

24 May, 2019

1 commit

  • Based on 1 normalized pattern(s):

    gnupg is free software you can redistribute it and or modify it
    under the terms of the gnu general public license as published by
    the free software foundation either version 2 of the license or at
    your option any later version gnupg is distributed in the hope that
    it will be useful but without any warranty without even the implied
    warranty of merchantability or fitness for a particular purpose see
    the gnu general public license for more details you should have
    received a copy of the gnu general public license along with this
    program if not write to the free software foundation inc 59 temple
    place suite 330 boston ma 02111 1307 usa note this code is heavily
    based on the gnu mp library actually it s the same code with only
    minor changes in the way the data is stored this is to support the
    abstraction of an optional secure memory allocation which may be
    used to avoid revealing of sensitive data due to paging etc the gnu
    mp library itself is published under the lgpl however i decided to
    publish this code under the plain gpl

    extracted by the scancode license scanner the SPDX license identifier

    GPL-2.0-or-later

    has been chosen to replace the boilerplate/reference in 14 file(s).

    Signed-off-by: Thomas Gleixner
    Reviewed-by: Allison Randal
    Reviewed-by: Kate Stewart
    Cc: linux-spdx@vger.kernel.org
    Link: https://lkml.kernel.org/r/20190520170856.639982569@linutronix.de
    Signed-off-by: Greg Kroah-Hartman

    Thomas Gleixner
     

07 Aug, 2018

1 commit


13 Jun, 2018

2 commits

  • The kzalloc() function has a 2-factor argument form, kcalloc(). This
    patch replaces cases of:

    kzalloc(a * b, gfp)

    with:
    kcalloc(a * b, gfp)

    as well as handling cases of:

    kzalloc(a * b * c, gfp)

    with:

    kzalloc(array3_size(a, b, c), gfp)

    as it's slightly less ugly than:

    kzalloc_array(array_size(a, b), c, gfp)

    This does, however, attempt to ignore constant size factors like:

    kzalloc(4 * 1024, gfp)

    though any constants defined via macros get caught up in the conversion.

    Any factors with a sizeof() of "unsigned char", "char", and "u8" were
    dropped, since they're redundant.

    The Coccinelle script used for this was:

    // Fix redundant parens around sizeof().
    @@
    type TYPE;
    expression THING, E;
    @@

    (
    kzalloc(
    - (sizeof(TYPE)) * E
    + sizeof(TYPE) * E
    , ...)
    |
    kzalloc(
    - (sizeof(THING)) * E
    + sizeof(THING) * E
    , ...)
    )

    // Drop single-byte sizes and redundant parens.
    @@
    expression COUNT;
    typedef u8;
    typedef __u8;
    @@

    (
    kzalloc(
    - sizeof(u8) * (COUNT)
    + COUNT
    , ...)
    |
    kzalloc(
    - sizeof(__u8) * (COUNT)
    + COUNT
    , ...)
    |
    kzalloc(
    - sizeof(char) * (COUNT)
    + COUNT
    , ...)
    |
    kzalloc(
    - sizeof(unsigned char) * (COUNT)
    + COUNT
    , ...)
    |
    kzalloc(
    - sizeof(u8) * COUNT
    + COUNT
    , ...)
    |
    kzalloc(
    - sizeof(__u8) * COUNT
    + COUNT
    , ...)
    |
    kzalloc(
    - sizeof(char) * COUNT
    + COUNT
    , ...)
    |
    kzalloc(
    - sizeof(unsigned char) * COUNT
    + COUNT
    , ...)
    )

    // 2-factor product with sizeof(type/expression) and identifier or constant.
    @@
    type TYPE;
    expression THING;
    identifier COUNT_ID;
    constant COUNT_CONST;
    @@

    (
    - kzalloc
    + kcalloc
    (
    - sizeof(TYPE) * (COUNT_ID)
    + COUNT_ID, sizeof(TYPE)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(TYPE) * COUNT_ID
    + COUNT_ID, sizeof(TYPE)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(TYPE) * (COUNT_CONST)
    + COUNT_CONST, sizeof(TYPE)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(TYPE) * COUNT_CONST
    + COUNT_CONST, sizeof(TYPE)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(THING) * (COUNT_ID)
    + COUNT_ID, sizeof(THING)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(THING) * COUNT_ID
    + COUNT_ID, sizeof(THING)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(THING) * (COUNT_CONST)
    + COUNT_CONST, sizeof(THING)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(THING) * COUNT_CONST
    + COUNT_CONST, sizeof(THING)
    , ...)
    )

    // 2-factor product, only identifiers.
    @@
    identifier SIZE, COUNT;
    @@

    - kzalloc
    + kcalloc
    (
    - SIZE * COUNT
    + COUNT, SIZE
    , ...)

    // 3-factor product with 1 sizeof(type) or sizeof(expression), with
    // redundant parens removed.
    @@
    expression THING;
    identifier STRIDE, COUNT;
    type TYPE;
    @@

    (
    kzalloc(
    - sizeof(TYPE) * (COUNT) * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kzalloc(
    - sizeof(TYPE) * (COUNT) * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kzalloc(
    - sizeof(TYPE) * COUNT * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kzalloc(
    - sizeof(TYPE) * COUNT * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kzalloc(
    - sizeof(THING) * (COUNT) * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    |
    kzalloc(
    - sizeof(THING) * (COUNT) * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    |
    kzalloc(
    - sizeof(THING) * COUNT * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    |
    kzalloc(
    - sizeof(THING) * COUNT * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    )

    // 3-factor product with 2 sizeof(variable), with redundant parens removed.
    @@
    expression THING1, THING2;
    identifier COUNT;
    type TYPE1, TYPE2;
    @@

    (
    kzalloc(
    - sizeof(TYPE1) * sizeof(TYPE2) * COUNT
    + array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
    , ...)
    |
    kzalloc(
    - sizeof(TYPE1) * sizeof(THING2) * (COUNT)
    + array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
    , ...)
    |
    kzalloc(
    - sizeof(THING1) * sizeof(THING2) * COUNT
    + array3_size(COUNT, sizeof(THING1), sizeof(THING2))
    , ...)
    |
    kzalloc(
    - sizeof(THING1) * sizeof(THING2) * (COUNT)
    + array3_size(COUNT, sizeof(THING1), sizeof(THING2))
    , ...)
    |
    kzalloc(
    - sizeof(TYPE1) * sizeof(THING2) * COUNT
    + array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
    , ...)
    |
    kzalloc(
    - sizeof(TYPE1) * sizeof(THING2) * (COUNT)
    + array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
    , ...)
    )

    // 3-factor product, only identifiers, with redundant parens removed.
    @@
    identifier STRIDE, SIZE, COUNT;
    @@

    (
    kzalloc(
    - (COUNT) * STRIDE * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - COUNT * (STRIDE) * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - COUNT * STRIDE * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - (COUNT) * (STRIDE) * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - COUNT * (STRIDE) * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - (COUNT) * STRIDE * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - (COUNT) * (STRIDE) * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - COUNT * STRIDE * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    )

    // Any remaining multi-factor products, first at least 3-factor products,
    // when they're not all constants...
    @@
    expression E1, E2, E3;
    constant C1, C2, C3;
    @@

    (
    kzalloc(C1 * C2 * C3, ...)
    |
    kzalloc(
    - (E1) * E2 * E3
    + array3_size(E1, E2, E3)
    , ...)
    |
    kzalloc(
    - (E1) * (E2) * E3
    + array3_size(E1, E2, E3)
    , ...)
    |
    kzalloc(
    - (E1) * (E2) * (E3)
    + array3_size(E1, E2, E3)
    , ...)
    |
    kzalloc(
    - E1 * E2 * E3
    + array3_size(E1, E2, E3)
    , ...)
    )

    // And then all remaining 2 factors products when they're not all constants,
    // keeping sizeof() as the second factor argument.
    @@
    expression THING, E1, E2;
    type TYPE;
    constant C1, C2, C3;
    @@

    (
    kzalloc(sizeof(THING) * C2, ...)
    |
    kzalloc(sizeof(TYPE) * C2, ...)
    |
    kzalloc(C1 * C2 * C3, ...)
    |
    kzalloc(C1 * C2, ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(TYPE) * (E2)
    + E2, sizeof(TYPE)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(TYPE) * E2
    + E2, sizeof(TYPE)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(THING) * (E2)
    + E2, sizeof(THING)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(THING) * E2
    + E2, sizeof(THING)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - (E1) * E2
    + E1, E2
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - (E1) * (E2)
    + E1, E2
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - E1 * E2
    + E1, E2
    , ...)
    )

    Signed-off-by: Kees Cook

    Kees Cook
     
  • The kmalloc() function has a 2-factor argument form, kmalloc_array(). This
    patch replaces cases of:

    kmalloc(a * b, gfp)

    with:
    kmalloc_array(a * b, gfp)

    as well as handling cases of:

    kmalloc(a * b * c, gfp)

    with:

    kmalloc(array3_size(a, b, c), gfp)

    as it's slightly less ugly than:

    kmalloc_array(array_size(a, b), c, gfp)

    This does, however, attempt to ignore constant size factors like:

    kmalloc(4 * 1024, gfp)

    though any constants defined via macros get caught up in the conversion.

    Any factors with a sizeof() of "unsigned char", "char", and "u8" were
    dropped, since they're redundant.

    The tools/ directory was manually excluded, since it has its own
    implementation of kmalloc().

    The Coccinelle script used for this was:

    // Fix redundant parens around sizeof().
    @@
    type TYPE;
    expression THING, E;
    @@

    (
    kmalloc(
    - (sizeof(TYPE)) * E
    + sizeof(TYPE) * E
    , ...)
    |
    kmalloc(
    - (sizeof(THING)) * E
    + sizeof(THING) * E
    , ...)
    )

    // Drop single-byte sizes and redundant parens.
    @@
    expression COUNT;
    typedef u8;
    typedef __u8;
    @@

    (
    kmalloc(
    - sizeof(u8) * (COUNT)
    + COUNT
    , ...)
    |
    kmalloc(
    - sizeof(__u8) * (COUNT)
    + COUNT
    , ...)
    |
    kmalloc(
    - sizeof(char) * (COUNT)
    + COUNT
    , ...)
    |
    kmalloc(
    - sizeof(unsigned char) * (COUNT)
    + COUNT
    , ...)
    |
    kmalloc(
    - sizeof(u8) * COUNT
    + COUNT
    , ...)
    |
    kmalloc(
    - sizeof(__u8) * COUNT
    + COUNT
    , ...)
    |
    kmalloc(
    - sizeof(char) * COUNT
    + COUNT
    , ...)
    |
    kmalloc(
    - sizeof(unsigned char) * COUNT
    + COUNT
    , ...)
    )

    // 2-factor product with sizeof(type/expression) and identifier or constant.
    @@
    type TYPE;
    expression THING;
    identifier COUNT_ID;
    constant COUNT_CONST;
    @@

    (
    - kmalloc
    + kmalloc_array
    (
    - sizeof(TYPE) * (COUNT_ID)
    + COUNT_ID, sizeof(TYPE)
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - sizeof(TYPE) * COUNT_ID
    + COUNT_ID, sizeof(TYPE)
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - sizeof(TYPE) * (COUNT_CONST)
    + COUNT_CONST, sizeof(TYPE)
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - sizeof(TYPE) * COUNT_CONST
    + COUNT_CONST, sizeof(TYPE)
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - sizeof(THING) * (COUNT_ID)
    + COUNT_ID, sizeof(THING)
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - sizeof(THING) * COUNT_ID
    + COUNT_ID, sizeof(THING)
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - sizeof(THING) * (COUNT_CONST)
    + COUNT_CONST, sizeof(THING)
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - sizeof(THING) * COUNT_CONST
    + COUNT_CONST, sizeof(THING)
    , ...)
    )

    // 2-factor product, only identifiers.
    @@
    identifier SIZE, COUNT;
    @@

    - kmalloc
    + kmalloc_array
    (
    - SIZE * COUNT
    + COUNT, SIZE
    , ...)

    // 3-factor product with 1 sizeof(type) or sizeof(expression), with
    // redundant parens removed.
    @@
    expression THING;
    identifier STRIDE, COUNT;
    type TYPE;
    @@

    (
    kmalloc(
    - sizeof(TYPE) * (COUNT) * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kmalloc(
    - sizeof(TYPE) * (COUNT) * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kmalloc(
    - sizeof(TYPE) * COUNT * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kmalloc(
    - sizeof(TYPE) * COUNT * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kmalloc(
    - sizeof(THING) * (COUNT) * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    |
    kmalloc(
    - sizeof(THING) * (COUNT) * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    |
    kmalloc(
    - sizeof(THING) * COUNT * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    |
    kmalloc(
    - sizeof(THING) * COUNT * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    )

    // 3-factor product with 2 sizeof(variable), with redundant parens removed.
    @@
    expression THING1, THING2;
    identifier COUNT;
    type TYPE1, TYPE2;
    @@

    (
    kmalloc(
    - sizeof(TYPE1) * sizeof(TYPE2) * COUNT
    + array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
    , ...)
    |
    kmalloc(
    - sizeof(TYPE1) * sizeof(THING2) * (COUNT)
    + array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
    , ...)
    |
    kmalloc(
    - sizeof(THING1) * sizeof(THING2) * COUNT
    + array3_size(COUNT, sizeof(THING1), sizeof(THING2))
    , ...)
    |
    kmalloc(
    - sizeof(THING1) * sizeof(THING2) * (COUNT)
    + array3_size(COUNT, sizeof(THING1), sizeof(THING2))
    , ...)
    |
    kmalloc(
    - sizeof(TYPE1) * sizeof(THING2) * COUNT
    + array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
    , ...)
    |
    kmalloc(
    - sizeof(TYPE1) * sizeof(THING2) * (COUNT)
    + array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
    , ...)
    )

    // 3-factor product, only identifiers, with redundant parens removed.
    @@
    identifier STRIDE, SIZE, COUNT;
    @@

    (
    kmalloc(
    - (COUNT) * STRIDE * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kmalloc(
    - COUNT * (STRIDE) * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kmalloc(
    - COUNT * STRIDE * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kmalloc(
    - (COUNT) * (STRIDE) * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kmalloc(
    - COUNT * (STRIDE) * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kmalloc(
    - (COUNT) * STRIDE * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kmalloc(
    - (COUNT) * (STRIDE) * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kmalloc(
    - COUNT * STRIDE * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    )

    // Any remaining multi-factor products, first at least 3-factor products,
    // when they're not all constants...
    @@
    expression E1, E2, E3;
    constant C1, C2, C3;
    @@

    (
    kmalloc(C1 * C2 * C3, ...)
    |
    kmalloc(
    - (E1) * E2 * E3
    + array3_size(E1, E2, E3)
    , ...)
    |
    kmalloc(
    - (E1) * (E2) * E3
    + array3_size(E1, E2, E3)
    , ...)
    |
    kmalloc(
    - (E1) * (E2) * (E3)
    + array3_size(E1, E2, E3)
    , ...)
    |
    kmalloc(
    - E1 * E2 * E3
    + array3_size(E1, E2, E3)
    , ...)
    )

    // And then all remaining 2 factors products when they're not all constants,
    // keeping sizeof() as the second factor argument.
    @@
    expression THING, E1, E2;
    type TYPE;
    constant C1, C2, C3;
    @@

    (
    kmalloc(sizeof(THING) * C2, ...)
    |
    kmalloc(sizeof(TYPE) * C2, ...)
    |
    kmalloc(C1 * C2 * C3, ...)
    |
    kmalloc(C1 * C2, ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - sizeof(TYPE) * (E2)
    + E2, sizeof(TYPE)
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - sizeof(TYPE) * E2
    + E2, sizeof(TYPE)
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - sizeof(THING) * (E2)
    + E2, sizeof(THING)
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - sizeof(THING) * E2
    + E2, sizeof(THING)
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - (E1) * E2
    + E1, E2
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - (E1) * (E2)
    + E1, E2
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - E1 * E2
    + E1, E2
    , ...)
    )

    Signed-off-by: Kees Cook

    Kees Cook
     

08 Jun, 2018

1 commit

  • MPI headers contain definitions for huge number of non-existing
    functions.

    Most part of these functions was removed in 2012 by Dmitry Kasatkin
    - 7cf4206a99d1 ("Remove unused code from MPI library")
    - 9e235dcaf4f6 ("Revert "crypto: GnuPG based MPI lib - additional ...")
    - bc95eeadf5c6 ("lib/mpi: removed unused functions")
    however headers wwere not updated properly.

    Also I deleted some unused macros.

    Link: http://lkml.kernel.org/r/fb2fc1ef-1185-f0a3-d8d0-173d2f97bbaf@virtuozzo.com
    Signed-off-by: Vasily Averin
    Reviewed-by: Andrew Morton
    Cc: Dmitry Kasatkin
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Vasily Averin
     

22 Dec, 2017

1 commit

  • Current MIPS64r6 toolchains aren't able to generate efficient
    DMULU/DMUHU based code for the C implementation of umul_ppmm(), which
    performs an unsigned 64 x 64 bit multiply and returns the upper and
    lower 64-bit halves of the 128-bit result. Instead it widens the 64-bit
    inputs to 128-bits and emits a __multi3 intrinsic call to perform a 128
    x 128 multiply. This is both inefficient, and it results in a link error
    since we don't include __multi3 in MIPS linux.

    For example commit 90a53e4432b1 ("cfg80211: implement regdb signature
    checking") merged in v4.15-rc1 recently broke the 64r6_defconfig and
    64r6el_defconfig builds by indirectly selecting MPILIB. The same build
    errors can be reproduced on older kernels by enabling e.g. CRYPTO_RSA:

    lib/mpi/generic_mpih-mul1.o: In function `mpihelp_mul_1':
    lib/mpi/generic_mpih-mul1.c:50: undefined reference to `__multi3'
    lib/mpi/generic_mpih-mul2.o: In function `mpihelp_addmul_1':
    lib/mpi/generic_mpih-mul2.c:49: undefined reference to `__multi3'
    lib/mpi/generic_mpih-mul3.o: In function `mpihelp_submul_1':
    lib/mpi/generic_mpih-mul3.c:49: undefined reference to `__multi3'
    lib/mpi/mpih-div.o In function `mpihelp_divrem':
    lib/mpi/mpih-div.c:205: undefined reference to `__multi3'
    lib/mpi/mpih-div.c:142: undefined reference to `__multi3'

    Therefore add an efficient MIPS64r6 implementation of umul_ppmm() using
    inline assembly and the DMULU/DMUHU instructions, to prevent __multi3
    calls being emitted.

    Fixes: 7fd08ca58ae6 ("MIPS: Add build support for the MIPS R6 ISA")
    Signed-off-by: James Hogan
    Cc: Ralf Baechle
    Cc: Herbert Xu
    Cc: "David S. Miller"
    Cc: linux-mips@linux-mips.org
    Cc: linux-crypto@vger.kernel.org
    Signed-off-by: Herbert Xu

    James Hogan
     

15 Nov, 2017

1 commit

  • Pull crypto updates from Herbert Xu:
    "Here is the crypto update for 4.15:

    API:

    - Disambiguate EBUSY when queueing crypto request by adding ENOSPC.
    This change touches code outside the crypto API.
    - Reset settings when empty string is written to rng_current.

    Algorithms:

    - Add OSCCA SM3 secure hash.

    Drivers:

    - Remove old mv_cesa driver (replaced by marvell/cesa).
    - Enable rfc3686/ecb/cfb/ofb AES in crypto4xx.
    - Add ccm/gcm AES in crypto4xx.
    - Add support for BCM7278 in iproc-rng200.
    - Add hash support on Exynos in s5p-sss.
    - Fix fallback-induced error in vmx.
    - Fix output IV in atmel-aes.
    - Fix empty GCM hash in mediatek.

    Others:

    - Fix DoS potential in lib/mpi.
    - Fix potential out-of-order issues with padata"

    * 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: (162 commits)
    lib/mpi: call cond_resched() from mpi_powm() loop
    crypto: stm32/hash - Fix return issue on update
    crypto: dh - Remove pointless checks for NULL 'p' and 'g'
    crypto: qat - Clean up error handling in qat_dh_set_secret()
    crypto: dh - Don't permit 'key' or 'g' size longer than 'p'
    crypto: dh - Don't permit 'p' to be 0
    crypto: dh - Fix double free of ctx->p
    hwrng: iproc-rng200 - Add support for BCM7278
    dt-bindings: rng: Document BCM7278 RNG200 compatible
    crypto: chcr - Replace _manual_ swap with swap macro
    crypto: marvell - Add a NULL entry at the end of mv_cesa_plat_id_table[]
    hwrng: virtio - Virtio RNG devices need to be re-registered after suspend/resume
    crypto: atmel - remove empty functions
    crypto: ecdh - remove empty exit()
    MAINTAINERS: update maintainer for qat
    crypto: caam - remove unused param of ctx_map_to_sec4_sg()
    crypto: caam - remove unneeded edesc zeroization
    crypto: atmel-aes - Reset the controller before each use
    crypto: atmel-aes - properly set IV after {en,de}crypt
    hwrng: core - Reset user selected rng by writing "" to rng_current
    ...

    Linus Torvalds
     

10 Nov, 2017

1 commit

  • On a non-preemptible kernel, if KEYCTL_DH_COMPUTE is called with the
    largest permitted inputs (16384 bits), the kernel spends 10+ seconds
    doing modular exponentiation in mpi_powm() without rescheduling. If all
    threads do it, it locks up the system. Moreover, it can cause
    rcu_sched-stall warnings.

    Notwithstanding the insanity of doing this calculation in kernel mode
    rather than in userspace, fix it by calling cond_resched() as each bit
    from the exponent is processed. It's still noninterruptible, but at
    least it's preemptible now.

    Do the cond_resched() once per bit rather than once per MPI limb because
    each limb might still easily take 100+ milliseconds on slow CPUs.

    Cc: # v4.12+
    Signed-off-by: Eric Biggers
    Signed-off-by: Herbert Xu

    Eric Biggers
     

02 Nov, 2017

1 commit

  • Many source files in the tree are missing licensing information, which
    makes it harder for compliance tools to determine the correct license.

    By default all files without license information are under the default
    license of the kernel, which is GPL version 2.

    Update the files which contain no license information with the 'GPL-2.0'
    SPDX license identifier. The SPDX identifier is a legally binding
    shorthand, which can be used instead of the full boiler plate text.

    This patch is based on work done by Thomas Gleixner and Kate Stewart and
    Philippe Ombredanne.

    How this work was done:

    Patches were generated and checked against linux-4.14-rc6 for a subset of
    the use cases:
    - file had no licensing information it it.
    - file was a */uapi/* one with no licensing information in it,
    - file was a */uapi/* one with existing licensing information,

    Further patches will be generated in subsequent months to fix up cases
    where non-standard license headers were used, and references to license
    had to be inferred by heuristics based on keywords.

    The analysis to determine which SPDX License Identifier to be applied to
    a file was done in a spreadsheet of side by side results from of the
    output of two independent scanners (ScanCode & Windriver) producing SPDX
    tag:value files created by Philippe Ombredanne. Philippe prepared the
    base worksheet, and did an initial spot review of a few 1000 files.

    The 4.13 kernel was the starting point of the analysis with 60,537 files
    assessed. Kate Stewart did a file by file comparison of the scanner
    results in the spreadsheet to determine which SPDX license identifier(s)
    to be applied to the file. She confirmed any determination that was not
    immediately clear with lawyers working with the Linux Foundation.

    Criteria used to select files for SPDX license identifier tagging was:
    - Files considered eligible had to be source code files.
    - Make and config files were included as candidates if they contained >5
    lines of source
    - File already had some variant of a license header in it (even if
    Reviewed-by: Philippe Ombredanne
    Reviewed-by: Thomas Gleixner
    Signed-off-by: Greg Kroah-Hartman

    Greg Kroah-Hartman
     

22 Aug, 2017

2 commits


17 Aug, 2017

1 commit

  • Use just @ to denote comments which works with gcc and clang.
    Otherwise clang reports an escape sequence error:
    error: invalid % escape in inline assembly string

    Use %0-%3 as operand references, this avoids:
    error: invalid operand in inline asm: 'umull ${1:r}, ${0:r}, ${2:r}, ${3:r}'

    Also remove superfluous casts on output operands to avoid warnings
    such as:
    warning: invalid use of a cast in an inline asm context requiring an l-value

    Signed-off-by: Stefan Agner
    Acked-by: Arnd Bergmann
    Signed-off-by: Herbert Xu

    Stefan Agner
     

25 Nov, 2016

1 commit

  • This fixes CVE-2016-8650.

    If mpi_powm() is given a zero exponent, it wants to immediately return
    either 1 or 0, depending on the modulus. However, if the result was
    initalised with zero limb space, no limbs space is allocated and a
    NULL-pointer exception ensues.

    Fix this by allocating a minimal amount of limb space for the result when
    the 0-exponent case when the result is 1 and not touching the limb space
    when the result is 0.

    This affects the use of RSA keys and X.509 certificates that carry them.

    BUG: unable to handle kernel NULL pointer dereference at (null)
    IP: [] mpi_powm+0x32/0x7e6
    PGD 0
    Oops: 0002 [#1] SMP
    Modules linked in:
    CPU: 3 PID: 3014 Comm: keyctl Not tainted 4.9.0-rc6-fscache+ #278
    Hardware name: ASUS All Series/H97-PLUS, BIOS 2306 10/09/2014
    task: ffff8804011944c0 task.stack: ffff880401294000
    RIP: 0010:[] [] mpi_powm+0x32/0x7e6
    RSP: 0018:ffff880401297ad8 EFLAGS: 00010212
    RAX: 0000000000000000 RBX: ffff88040868bec0 RCX: ffff88040868bba0
    RDX: ffff88040868b260 RSI: ffff88040868bec0 RDI: ffff88040868bee0
    RBP: ffff880401297ba8 R08: 0000000000000000 R09: 0000000000000000
    R10: 0000000000000047 R11: ffffffff8183b210 R12: 0000000000000000
    R13: ffff8804087c7600 R14: 000000000000001f R15: ffff880401297c50
    FS: 00007f7a7918c700(0000) GS:ffff88041fb80000(0000) knlGS:0000000000000000
    CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    CR2: 0000000000000000 CR3: 0000000401250000 CR4: 00000000001406e0
    Stack:
    ffff88040868bec0 0000000000000020 ffff880401297b00 ffffffff81376cd4
    0000000000000100 ffff880401297b10 ffffffff81376d12 ffff880401297b30
    ffffffff81376f37 0000000000000100 0000000000000000 ffff880401297ba8
    Call Trace:
    [] ? __sg_page_iter_next+0x43/0x66
    [] ? sg_miter_get_next_page+0x1b/0x5d
    [] ? sg_miter_next+0x17/0xbd
    [] ? mpi_read_raw_from_sgl+0xf2/0x146
    [] rsa_verify+0x9d/0xee
    [] ? pkcs1pad_sg_set_buf+0x2e/0xbb
    [] pkcs1pad_verify+0xc0/0xe1
    [] public_key_verify_signature+0x1b0/0x228
    [] x509_check_for_self_signed+0xa1/0xc4
    [] x509_cert_parse+0x167/0x1a1
    [] x509_key_preparse+0x21/0x1a1
    [] asymmetric_key_preparse+0x34/0x61
    [] key_create_or_update+0x145/0x399
    [] SyS_add_key+0x154/0x19e
    [] do_syscall_64+0x80/0x191
    [] entry_SYSCALL64_slow_path+0x25/0x25
    Code: 56 41 55 41 54 53 48 81 ec a8 00 00 00 44 8b 71 04 8b 42 04 4c 8b 67 18 45 85 f6 89 45 80 0f 84 b4 06 00 00 85 c0 75 2f 41 ff ce c7 04 24 01 00 00 00 b0 01 75 0b 48 8b 41 18 48 83 38 01 0f
    RIP [] mpi_powm+0x32/0x7e6
    RSP
    CR2: 0000000000000000
    ---[ end trace d82015255d4a5d8d ]---

    Basically, this is a backport of a libgcrypt patch:

    http://git.gnupg.org/cgi-bin/gitweb.cgi?p=libgcrypt.git;a=patch;h=6e1adb05d290aeeb1c230c763970695f4a538526

    Fixes: cdec9cb5167a ("crypto: GnuPG based MPI lib - source files (part 1)")
    Signed-off-by: Andrey Ryabinin
    Signed-off-by: David Howells
    cc: Dmitry Kasatkin
    cc: linux-ima-devel@lists.sourceforge.net
    cc: stable@vger.kernel.org
    Signed-off-by: James Morris

    Andrey Ryabinin
     

29 Jul, 2016

1 commit

  • In mpi_read_raw_from_sgl we may leak the SG miter resouces after
    reading the leading zeroes. This patch fixes this by stopping the
    iteration once the leading zeroes have been read.

    Fixes: 127827b9c295 ("lib/mpi: Do not do sg_virt")
    Reported-by: Nicolai Stange
    Tested-by: Nicolai Stange
    Signed-off-by: Herbert Xu

    Herbert Xu
     

01 Jul, 2016

2 commits

  • Currently the mpi SG helpers use sg_virt which is completely
    broken. It happens to work with normal kernel memory but will
    fail with anything that is not linearly mapped.

    This patch fixes this by using the SG iterator helpers.

    Signed-off-by: Herbert Xu

    Herbert Xu
     
  • Every implementation of RSA that we have naturally generates
    output with leading zeroes. The one and only user of RSA,
    pkcs1pad wants to have those leading zeroes in place, in fact
    because they are currently absent it has to write those zeroes
    itself.

    So we shouldn't be stripping leading zeroes in the first place.
    In fact this patch makes rsa-generic produce output with fixed
    length so that pkcs1pad does not need to do any extra work.

    This patch also changes DH to use the new interface.

    Signed-off-by: Herbert Xu

    Herbert Xu
     

31 May, 2016

7 commits

  • mpi_read_from_buffer() and mpi_read_raw_data() do basically the same thing
    except that the former extracts the number of payload bits from the first
    two bytes of the input buffer.

    Besides that, the data copying logic is exactly the same.

    Replace the open coded buffer to MPI instance conversion by a call to
    mpi_read_raw_data().

    Signed-off-by: Nicolai Stange
    Signed-off-by: Herbert Xu

    Nicolai Stange
     
  • The first two bytes of the input buffer encode its expected length and
    mpi_read_from_buffer() prints a console message if the given buffer is too
    short.

    However, there are some oddities with how this message is printed:
    - It is printed at the default loglevel. This is different from the
    one used in the case that the first two bytes' value is unsupportedly
    large, i.e. KERN_INFO.
    - The format specifier '%d' is used for unsigned ints.
    - It prints the values of nread and *ret_nread. This is redundant since
    the former is always the latter + 1.

    Clean this up as follows:
    - Use pr_info() rather than printk() with no loglevel.
    - Use the format specifiers '%u' in place if '%d'.
    - Do not print the redundant 'nread' but the more helpful 'nbytes' value.

    Signed-off-by: Nicolai Stange
    Signed-off-by: Herbert Xu

    Nicolai Stange
     
  • Currently, if the input buffer is shorter than the expected length as
    indicated by its first two bytes, an MPI instance of this expected length
    will be allocated and filled with as much data as is available. The rest
    will remain uninitialized.

    Instead of leaving this condition undetected, an error code should be
    reported to the caller.

    Since this situation indicates that the input buffer's first two bytes,
    encoding the number of expected bits, are garbled, -EINVAL is appropriate
    here.

    If the input buffer is shorter than indicated by its first two bytes,
    make mpi_read_from_buffer() return -EINVAL.
    Get rid of the 'nread' variable: with the new semantics, the total number
    of bytes read from the input buffer is known in advance.

    Signed-off-by: Nicolai Stange
    Signed-off-by: Herbert Xu

    Nicolai Stange
     
  • mpi_read_from_buffer() reads a MPI from a buffer into a newly allocated
    MPI instance. It expects the buffer's leading two bytes to contain the
    number of bits, followed by the actual payload.

    On failure, it returns NULL and updates the in/out argument ret_nread
    somewhat inconsistently:
    - If the given buffer is too short to contain the leading two bytes
    encoding the number of bits or their value is unsupported, then
    ret_nread will be cleared.
    - If the allocation of the resulting MPI instance fails, ret_nread is left
    as is.

    The only user of mpi_read_from_buffer(), digsig_verify_rsa(), simply checks
    for a return value of NULL and returns -ENOMEM if that happens.

    While this is all of cosmetic nature only, there is another error condition
    which currently isn't detectable by the caller of mpi_read_from_buffer():
    if the given buffer is too small to hold the number of bits as encoded in
    its first two bytes, the return value will be non-NULL and *ret_nread > 0.

    In preparation of communicating this condition to the caller, let
    mpi_read_from_buffer() return error values by means of the ERR_PTR()
    mechanism.

    Make the sole caller of mpi_read_from_buffer(), digsig_verify_rsa(),
    check the return value for IS_ERR() rather than == NULL. If IS_ERR() is
    true, return the associated error value rather than the fixed -ENOMEM.

    Signed-off-by: Nicolai Stange
    Signed-off-by: Herbert Xu

    Nicolai Stange
     
  • The number of bits, nbits, is calculated in mpi_read_raw_data() as follows:

    nbits = nbytes * 8;

    Afterwards, the number of leading zero bits of the first byte get
    subtracted:

    nbits -= count_leading_zeros(buffer[0]);

    However, count_leading_zeros() takes an unsigned long and thus,
    the u8 gets promoted to an unsigned long.

    Thus, the above doesn't subtract the number of leading zeros in the most
    significant nonzero input byte from nbits, but the number of leading
    zeros of the most significant nonzero input byte promoted to unsigned long,
    i.e. BITS_PER_LONG - 8 too many.

    Fix this by subtracting

    count_leading_zeros(...) - (BITS_PER_LONG - 8)

    from nbits only.

    Fixes: e1045992949 ("MPILIB: Provide a function to read raw data into an
    MPI")
    Signed-off-by: Nicolai Stange
    Signed-off-by: Herbert Xu

    Nicolai Stange
     
  • In mpi_read_raw_data(), unsigned nbits is calculated as follows:

    nbits = nbytes * 8;

    and redundantly cleared later on if nbytes == 0:

    if (nbytes > 0)
    ...
    else
    nbits = 0;

    Purge this redundant clearing for the sake of clarity.

    Signed-off-by: Nicolai Stange
    Signed-off-by: Herbert Xu

    Nicolai Stange
     
  • mpi_set_buffer() has no in-tree users and similar functionality is provided
    by mpi_read_raw_data().

    Remove mpi_set_buffer().

    Signed-off-by: Nicolai Stange
    Signed-off-by: Herbert Xu

    Nicolai Stange
     

05 Apr, 2016

13 commits

  • Within the copying loop in mpi_read_raw_from_sgl(), the last input SGE's
    byte count gets artificially extended as follows:

    if (sg_is_last(sg) && (len % BYTES_PER_MPI_LIMB))
    len += BYTES_PER_MPI_LIMB - (len % BYTES_PER_MPI_LIMB);

    Within the following byte copying loop, this causes reads beyond that
    SGE's allocated buffer:

    BUG: KASAN: slab-out-of-bounds in mpi_read_raw_from_sgl+0x331/0x650
    at addr ffff8801e168d4d8
    Read of size 1 by task systemd-udevd/721
    [...]
    Call Trace:
    [] dump_stack+0xbc/0x117
    [] ? _atomic_dec_and_lock+0x169/0x169
    [] ? print_section+0x61/0xb0
    [] print_trailer+0x179/0x2c0
    [] object_err+0x34/0x40
    [] kasan_report_error+0x307/0x8c0
    [] ? kasan_unpoison_shadow+0x35/0x50
    [] ? kasan_kmalloc+0x5e/0x70
    [] kasan_report+0x71/0xa0
    [] ? mpi_read_raw_from_sgl+0x331/0x650
    [] __asan_load1+0x46/0x50
    [] mpi_read_raw_from_sgl+0x331/0x650
    [] rsa_verify+0x106/0x260
    [] ? rsa_set_pub_key+0xf0/0xf0
    [] ? sg_init_table+0x29/0x50
    [] ? pkcs1pad_sg_set_buf+0xb2/0x2e0
    [] pkcs1pad_verify+0x1f4/0x2b0
    [] public_key_verify_signature+0x3a7/0x5e0
    [] ? public_key_describe+0x80/0x80
    [] ? keyring_search_aux+0x150/0x150
    [] ? x509_request_asymmetric_key+0x114/0x370
    [] ? kfree+0x220/0x370
    [] public_key_verify_signature_2+0x32/0x50
    [] verify_signature+0x7c/0xb0
    [] pkcs7_validate_trust+0x42c/0x5f0
    [] system_verify_data+0xca/0x170
    [] ? top_trace_array+0x9b/0x9b
    [] ? __vfs_read+0x279/0x3d0
    [] mod_verify_sig+0x1ff/0x290
    [...]

    The exact purpose of the len extension isn't clear to me, but due to
    its form, I suspect that it's a leftover somehow accounting for leading
    zero bytes within the most significant output limb.

    Note however that without that len adjustement, the total number of bytes
    ever processed by the inner loop equals nbytes and thus, the last output
    limb gets written at this point. Thus the net effect of the len adjustement
    cited above is just to keep the inner loop running for some more
    iterations, namely < BYTES_PER_MPI_LIMB ones, reading some extra bytes from
    beyond the last SGE's buffer and discarding them afterwards.

    Fix this issue by purging the extension of len beyond the last input SGE's
    buffer length.

    Fixes: 2d4d1eea540b ("lib/mpi: Add mpi sgl helpers")
    Signed-off-by: Nicolai Stange
    Signed-off-by: Herbert Xu

    Nicolai Stange
     
  • Within the byte reading loop in mpi_read_raw_sgl(), there are two
    housekeeping indices used, z and x.

    At all times, the index z represents the number of output bytes covered
    by the input SGEs for which processing has completed so far. This includes
    any leading zero bytes within the most significant limb.

    The index x changes its meaning after the first outer loop's iteration
    though: while processing the first input SGE, it represents

    "number of leading zero bytes in most significant output limb" +
    "current position within current SGE"

    For the remaining SGEs OTOH, x corresponds just to

    "current position within current SGE"

    After all, it is only the sum of z and x that has any meaning for the
    output buffer and thus, the

    "number of leading zero bytes in most significant output limb"

    part can be moved away from x into z from the beginning, opening up the
    opportunity for cleaner code.

    Before the outer loop iterating over the SGEs, don't initialize z with
    zero, but with the number of leading zero bytes in the most significant
    output limb. For the inner loop iterating over a single SGE's bytes,
    get rid of the buf_shift offset to x' bounds and let x run from zero to
    sg->length - 1.

    Signed-off-by: Nicolai Stange
    Signed-off-by: Herbert Xu

    Nicolai Stange
     
  • The number of bits, nbits, is calculated in mpi_read_raw_from_sgl() as
    follows:

    nbits = nbytes * 8;

    Afterwards, the number of leading zero bits of the first byte get
    subtracted:

    nbits -= count_leading_zeros(*(u8 *)(sg_virt(sgl) + lzeros));

    However, count_leading_zeros() takes an unsigned long and thus,
    the u8 gets promoted to an unsigned long.

    Thus, the above doesn't subtract the number of leading zeros in the most
    significant nonzero input byte from nbits, but the number of leading
    zeros of the most significant nonzero input byte promoted to unsigned long,
    i.e. BITS_PER_LONG - 8 too many.

    Fix this by subtracting

    count_leading_zeros(...) - (BITS_PER_LONG - 8)

    from nbits only.

    Fixes: 2d4d1eea540b ("lib/mpi: Add mpi sgl helpers")
    Signed-off-by: Nicolai Stange
    Signed-off-by: Herbert Xu

    Nicolai Stange
     
  • In mpi_read_raw_from_sgl(), unsigned nbits is calculated as follows:

    nbits = nbytes * 8;

    and redundantly cleared later on if nbytes == 0:

    if (nbytes > 0)
    ...
    else
    nbits = 0;

    Purge this redundant clearing for the sake of clarity.

    Signed-off-by: Nicolai Stange
    Signed-off-by: Herbert Xu

    Nicolai Stange
     
  • At the very beginning of mpi_read_raw_from_sgl(), the leading zeros of
    the input scatterlist are counted:

    lzeros = 0;
    for_each_sg(sgl, sg, ents, i) {
    ...
    if (/* sg contains nonzero bytes */)
    break;

    /* sg contains nothing but zeros here */
    ents--;
    lzeros = 0;
    }

    Later on, the total number of trailing nonzero bytes is calculated by
    subtracting the number of leading zero bytes from the total number of input
    bytes:

    nbytes -= lzeros;

    However, since lzeros gets reset to zero for each completely zero leading
    sg in the loop above, it doesn't include those.

    Besides wasting resources by allocating a too large output buffer,
    this mistake propagates into the calculation of x, the number of
    leading zeros within the most significant output limb:

    x = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;

    What's more, the low order bytes of the output, equal in number to the
    extra bytes in nbytes, are left uninitialized.

    Fix this by adjusting nbytes for each completely zero leading scatterlist
    entry.

    Fixes: 2d4d1eea540b ("lib/mpi: Add mpi sgl helpers")
    Signed-off-by: Nicolai Stange
    Signed-off-by: Herbert Xu

    Nicolai Stange
     
  • Currently, the nbytes local variable is calculated from the len argument
    as follows:

    ... mpi_read_raw_from_sgl(..., unsigned int len)
    {
    unsigned nbytes;
    ...
    if (!ents)
    nbytes = 0;
    else
    nbytes = len - lzeros;
    ...
    }

    Given that nbytes is derived from len in a trivial way and that the len
    argument is shadowed by a local len variable in several loops, this is just
    confusing.

    Rename the len argument to nbytes and get rid of the nbytes local variable.
    Do the nbytes calculation in place.

    Signed-off-by: Nicolai Stange
    Signed-off-by: Herbert Xu

    Nicolai Stange
     
  • Currently, mpi_read_buffer() writes full limbs to the output buffer
    and moves memory around to purge leading zero limbs afterwards.

    However, with

    commit 9cbe21d8f89d ("lib/mpi: only require buffers as big as needed for
    the integer")

    the caller is only required to provide a buffer large enough to hold the
    result without the leading zeros.

    This might result in a buffer overflow for small MP numbers with leading
    zeros.

    Fix this by coping the result to its final destination within the output
    buffer and not copying the leading zeros at all.

    Fixes: 9cbe21d8f89d ("lib/mpi: only require buffers as big as needed for
    the integer")
    Signed-off-by: Nicolai Stange
    Signed-off-by: Herbert Xu

    Nicolai Stange
     
  • Currently, the endian conversion from CPU order to BE is open coded in
    mpi_read_buffer().

    Replace this by the centrally provided cpu_to_be*() macros.
    Copy from the temporary storage on stack to the destination buffer
    by means of memcpy().

    Signed-off-by: Nicolai Stange
    Signed-off-by: Herbert Xu

    Nicolai Stange
     
  • Currently, if the number of leading zeros is greater than fits into a
    complete limb, mpi_read_buffer() skips them by iterating over them
    limb-wise.

    Instead of skipping the high order zero limbs within the loop as shown
    above, adjust the copying loop's bounds.

    Signed-off-by: Nicolai Stange
    Signed-off-by: Herbert Xu

    Nicolai Stange
     
  • Currently, the endian conversion from CPU order to BE is open coded in
    mpi_write_sgl().

    Replace this by the centrally provided cpu_to_be*() macros.

    Signed-off-by: Nicolai Stange
    Signed-off-by: Herbert Xu

    Nicolai Stange
     
  • Within the copying loop in mpi_write_sgl(), we have

    if (lzeros) {
    mpi_limb_t *limb1 = (void *)p - sizeof(alimb);
    mpi_limb_t *limb2 = (void *)p - sizeof(alimb)
    + lzeros;
    *limb1 = *limb2;
    ...
    }

    where p points past the end of alimb2 which lives on the stack and contains
    the current limb in BE order.

    The purpose of the above is to shift the non-zero bytes of alimb2 to its
    beginning in memory, i.e. to skip its leading zero bytes.

    However, limb2 points somewhere into the middle of alimb2 and thus, reading
    *limb2 pulls in lzero bytes from somewhere.

    Indeed, KASAN splats:

    BUG: KASAN: stack-out-of-bounds in mpi_write_to_sgl+0x4e3/0x6f0
    at addr ffff8800cb04f601
    Read of size 8 by task systemd-udevd/391
    page:ffffea00032c13c0 count:0 mapcount:0 mapping: (null) index:0x0
    flags: 0x3fff8000000000()
    page dumped because: kasan: bad access detected
    CPU: 3 PID: 391 Comm: systemd-udevd Tainted: G B L
    4.5.0-next-20160316+ #12
    [...]
    Call Trace:
    [] dump_stack+0xdc/0x15e
    [] ? _atomic_dec_and_lock+0xa2/0xa2
    [] ? __dump_page+0x185/0x330
    [] kasan_report_error+0x5e6/0x8b0
    [] ? kzfree+0x2d/0x40
    [] ? mpi_free_limb_space+0xe/0x20
    [] ? mpi_powm+0x37e/0x16f0
    [] kasan_report+0x71/0xa0
    [] ? mpi_write_to_sgl+0x4e3/0x6f0
    [] __asan_load8+0x64/0x70
    [] mpi_write_to_sgl+0x4e3/0x6f0
    [] ? mpi_set_buffer+0x620/0x620
    [] ? mpi_cmp+0xbf/0x180
    [] rsa_verify+0x202/0x260

    What's more, since lzeros can be anything from 1 to sizeof(mpi_limb_t)-1,
    the above will cause unaligned accesses which is bad on non-x86 archs.

    Fix the issue, by preparing the starting point p for the upcoming copy
    operation instead of shifting the source memory, i.e. alimb2.

    Fixes: 2d4d1eea540b ("lib/mpi: Add mpi sgl helpers")
    Signed-off-by: Nicolai Stange
    Signed-off-by: Herbert Xu

    Nicolai Stange
     
  • Within the copying loop in mpi_write_sgl(), we have

    if (lzeros) {
    ...
    p -= lzeros;
    y = lzeros;
    }
    p = p - (sizeof(alimb) - y);

    If lzeros == 0, then y == 0, too. Thus, lzeros gets subtracted and added
    back again to p.

    Purge this redundancy.

    Signed-off-by: Nicolai Stange
    Signed-off-by: Herbert Xu

    Nicolai Stange
     
  • Within the copying loop in mpi_write_sgl(), we have

    if (lzeros > 0) {
    ...
    lzeros -= sizeof(alimb);
    }

    However, at this point, lzeros < sizeof(alimb) holds. Make this fact
    explicit by rewriting the above to

    if (lzeros) {
    ...
    lzeros = 0;
    }

    Signed-off-by: Nicolai Stange
    Signed-off-by: Herbert Xu

    Nicolai Stange