09 Jul, 2019

1 commit

  • In ubifs_log_start_commit, the value of c->lhead_offs is zero or set
    to zero by code bellow.

    /* Switch to the next log LEB */
    if (c->lhead_offs) {
    c->lhead_lnum = ubifs_next_log_lnum(c, c->lhead_lnum);
    ubifs_assert(c->lhead_lnum != c->ltail_lnum);
    c->lhead_offs = 0;
    }

    The value of 'len' can not exceed 'max_len' which assigned value by
    code bellow.

    max_len = UBIFS_CS_NODE_SZ + c->jhead_cnt * UBIFS_REF_NODE_SZ;

    The value of c->lhead_offs changed by code bellow and cannot exceed
    'max_len'.

    c->lhead_offs += len;
    if (c->lhead_offs == c->leb_size) {
    c->lhead_lnum = ubifs_next_log_lnum(c, c->lhead_lnum);
    c->lhead_offs = 0;
    }

    Usually, the size of PEB is between 64KB and 256KB. So the value of
    c->lhead_offs is far less than c->leb_size. The check
    'if (c->lhead_offs == c->leb_size)' could never to be true.

    Signed-off-by: Liu Song
    Reviewed-by: Jiang Biao
    Signed-off-by: Richard Weinberger

    Liu Song
     

05 Jun, 2019

1 commit

  • Based on 1 normalized pattern(s):

    this program is free software you can redistribute it and or modify
    it under the terms of the gnu general public license version 2 as
    published by the free software foundation this program 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 51 franklin st fifth floor boston ma 02110
    1301 usa

    extracted by the scancode license scanner the SPDX license identifier

    GPL-2.0-only

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

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

    Thomas Gleixner
     

23 Oct, 2018

1 commit

  • Nodes that are written to flash can only be authenticated through the
    index after the next commit. When a journal replay is necessary the
    nodes are not yet referenced by the index and thus can't be
    authenticated.

    This patch overcomes this situation by creating a hash over all nodes
    beginning from the commit start node over the reference node(s) and
    the buds themselves. From
    time to time we insert authentication nodes. Authentication nodes
    contain a HMAC from the current hash state, so that they can be
    used to authenticate a journal replay up to the point where the
    authentication node is. The hash is continued afterwards
    so that theoretically we would only have to check the HMAC of
    the last authentication node we find.

    Overall we get this picture:

    ,,,,,,,,
    ,......,...........................................
    ,. CS , hash1.----. hash2.----.
    ,. | , . |hmac . |hmac
    ,. v , . v . v
    ,.REF#0,-> bud -> bud -> bud.-> auth -> bud -> bud.-> auth ...
    ,..|...,...........................................
    , | ,
    , | ,,,,,,,,,,,,,,,
    . | hash3,----.
    , | , |hmac
    , v , v
    , REF#1 -> bud -> bud,-> auth ...
    ,,,|,,,,,,,,,,,,,,,,,,
    v
    REF#2 -> ...
    |
    V
    ...

    Note how hash3 covers CS, REF#0 and REF#1 so that it is not possible to
    exchange or skip any reference nodes. Unlike the picture suggests the
    auth nodes themselves are not hashed.

    With this it is possible for an offline attacker to cut each journal
    head or to drop the last reference node(s), but not to skip any journal
    heads or to reorder any operations.

    Signed-off-by: Sascha Hauer
    Signed-off-by: Richard Weinberger

    Sascha Hauer
     

15 Aug, 2018

1 commit


07 Jun, 2018

1 commit


25 Mar, 2015

1 commit

  • In the case where we have more than one volumes on different UBI
    devices, it may be not that easy to tell which volume prints the
    messages. Add ubi number and volume id in ubifs_msg/warn/error
    to help debug. These two values are passed by struct ubifs_info.

    For those where ubifs_info is not initialized yet, ubifs_* is
    replaced by pr_*. For those where ubifs_info is not avaliable,
    ubifs_info is passed to the calling function as a const parameter.

    The output looks like,

    [ 95.444879] UBIFS (ubi0:1): background thread "ubifs_bgt0_1" started, PID 696
    [ 95.484688] UBIFS (ubi0:1): UBIFS: mounted UBI device 0, volume 1, name "test1"
    [ 95.484694] UBIFS (ubi0:1): LEB size: 126976 bytes (124 KiB), min./max. I/O unit sizes: 2048 bytes/2048 bytes
    [ 95.484699] UBIFS (ubi0:1): FS size: 30220288 bytes (28 MiB, 238 LEBs), journal size 1523712 bytes (1 MiB, 12 LEBs)
    [ 95.484703] UBIFS (ubi0:1): reserved for root: 1427378 bytes (1393 KiB)
    [ 95.484709] UBIFS (ubi0:1): media format: w4/r0 (latest is w4/r0), UUID 40DFFC0E-70BE-4193-8905-F7D6DFE60B17, small LPT model
    [ 95.489875] UBIFS (ubi1:0): background thread "ubifs_bgt1_0" started, PID 699
    [ 95.529713] UBIFS (ubi1:0): UBIFS: mounted UBI device 1, volume 0, name "test2"
    [ 95.529718] UBIFS (ubi1:0): LEB size: 126976 bytes (124 KiB), min./max. I/O unit sizes: 2048 bytes/2048 bytes
    [ 95.529724] UBIFS (ubi1:0): FS size: 19808256 bytes (18 MiB, 156 LEBs), journal size 1015809 bytes (0 MiB, 8 LEBs)
    [ 95.529727] UBIFS (ubi1:0): reserved for root: 935592 bytes (913 KiB)
    [ 95.529733] UBIFS (ubi1:0): media format: w4/r0 (latest is w4/r0), UUID EEB7779D-F419-4CA9-811B-831CAC7233D4, small LPT model

    [ 954.264767] UBIFS error (ubi1:0 pid 756): ubifs_read_node: bad node type (255 but expected 6)
    [ 954.367030] UBIFS error (ubi1:0 pid 756): ubifs_read_node: bad node at LEB 0:0, LEB mapping status 1

    Signed-off-by: Sheng Yong
    Signed-off-by: Artem Bityutskiy

    Sheng Yong
     

08 Sep, 2014

2 commits

  • Hu (hujianyang ) discovered an issue in the
    'empty_log_bytes()' function, which calculates how many bytes are left in the
    log:

    "
    If 'c->lhead_lnum + 1 == c->ltail_lnum' and 'c->lhead_offs == c->leb_size', 'h'
    would equalent to 't' and 'empty_log_bytes()' would return 'c->log_bytes'
    instead of 0.
    "

    At this point it is not clear what would be the consequences of this, and
    whether this may lead to any problems, but this patch addresses the issue just
    in case.

    Cc: stable@vger.kernel.org
    Tested-by: hujianyang
    Reported-by: hujianyang
    Signed-off-by: Artem Bityutskiy

    Artem Bityutskiy
     
  • Hu (hujianyang@huawei.com) discovered a race condition which may lead to a
    situation when UBIFS is unable to mount the file-system after an unclean
    reboot. The problem is theoretical, though.

    In UBIFS, we have the log, which basically a set of LEBs in a certain area. The
    log has the tail and the head.

    Every time user writes data to the file-system, the UBIFS journal grows, and
    the log grows as well, because we append new reference nodes to the head of the
    log. So the head moves forward all the time, while the log tail stays at the
    same position.

    At any time, the UBIFS master node points to the tail of the log. When we mount
    the file-system, we scan the log, and we always start from its tail, because
    this is where the master node points to. The only occasion when the tail of the
    log changes is the commit operation.

    The commit operation has 2 phases - "commit start" and "commit end". The former
    is relatively short, and does not involve much I/O. During this phase we mostly
    just build various in-memory lists of the things which have to be written to
    the flash media during "commit end" phase.

    During the commit start phase, what we do is we "clean" the log. Indeed, the
    commit operation will index all the data in the journal, so the entire journal
    "disappears", and therefore the data in the log become unneeded. So we just
    move the head of the log to the next LEB, and write the CS node there. This LEB
    will be the tail of the new log when the commit operation finishes.

    When the "commit start" phase finishes, users may write more data to the
    file-system, in parallel with the ongoing "commit end" operation. At this point
    the log tail was not changed yet, it is the same as it had been before we
    started the commit. The log head keeps moving forward, though.

    The commit operation now needs to write the new master node, and the new master
    node should point to the new log tail. After this the LEBs between the old log
    tail and the new log tail can be unmapped and re-used again.

    And here is the possible problem. We do 2 operations: (a) We first update the
    log tail position in memory (see 'ubifs_log_end_commit()'). (b) And then we
    write the master node (see the big lock of code in 'do_commit()').

    But nothing prevents the log head from moving forward between (a) and (b), and
    the log head may "wrap" now to the old log tail. And when the "wrap" happens,
    the contends of the log tail gets erased. Now a power cut happens and we are in
    trouble. We end up with the old master node pointing to the old tail, which was
    erased. And replay fails because it expects the master node to point to the
    correct log tail at all times.

    This patch merges the abovementioned (a) and (b) operations by moving the master
    node change code to the 'ubifs_log_end_commit()' function, so that it runs with
    the log mutex locked, which will prevent the log from being changed benween
    operations (a) and (b).

    Cc: stable@vger.kernel.org # 07e19df UBIFS: remove mst_mutex
    Cc: stable@vger.kernel.org
    Reported-by: hujianyang
    Tested-by: hujianyang
    Signed-off-by: Artem Bityutskiy

    Artem Bityutskiy
     

31 Jul, 2014

1 commit

  • We use a circle area to record the log nodes in ubifs. This log area
    should not be overlapped. But after researching the code, I found
    some conditions may lead log head wraps log ltail. Although we've
    fixed the problems discovered, there may be some other issues still
    left.

    This patch adds assertions where lhead changes to next leb to make
    sure ltail is not wrapped.

    Signed-off-by: hujianyang
    Signed-off-by: Artem Bityutskiy

    hujianyang
     

19 Jul, 2014

1 commit


24 Jan, 2014

1 commit


31 Aug, 2012

1 commit


21 May, 2012

1 commit

  • We do not need this feature and to our shame it even was not working
    and there was a bug found very recently.
    -- Artem Bityutskiy

    Without the data type hint UBI2 (fastmap) will be easier to implement.

    Signed-off-by: Richard Weinberger
    Signed-off-by: Artem Bityutskiy

    Richard Weinberger
     

17 May, 2012

1 commit


04 Jul, 2011

2 commits

  • Switch the rest of direct UBI calls to UBIFS helper functions.

    Signed-off-by: Artem Bityutskiy

    Artem Bityutskiy
     
  • This patch introduces helper functions for all debugging checks, so instead of
    doing

    if (!(ubifs_chk_flags & UBIFS_CHK_GEN))

    we now do

    if (!dbg_is_chk_gen(c))

    This is a preparation to further changes where the flags will go away, and
    we'll need to only change the helper functions, but the code which utilizes
    them won't be touched.

    At the same time this patch removes 'dbg_force_in_the_gaps()',
    'dbg_force_in_the_gaps_enabled()', and dbg_failure_mode helpers for
    consistency.

    Signed-off-by: Artem Bityutskiy

    Artem Bityutskiy
     

16 May, 2011

1 commit


03 May, 2011

1 commit

  • Currently UBIFS has a small optimization - it frees write-buffers when it is
    re-mounted from R/W mode to R/O mode. Of course, when it is mounted R/O, it
    does not allocate write-buffers as well.

    This optimization is nice but it leads to subtle problems and complications
    in recovery, which I can reproduce using the integck test. The symptoms are
    that after a power cut the file-system cannot be mounted if we first mount
    it R/O, and then re-mount R/W - 'ubifs_rcvry_gc_commit()' prints:

    UBIFS error (pid 34456): could not find an empty LEB

    Analysis of the problem.

    When mounting R/W, the reply process sets journal heads to buds [1], but
    when mounting R/O - it does not do this, because the write-buffers are not
    allocated. So 'ubifs_rcvry_gc_commit()' works completely differently for the
    same file-system but for the following 2 cases:

    1. mounting R/W after a power cut and recover
    2. mounting R/O after a power cut, re-mounting R/W and run deferred recovery

    In the former case, we have journal heads seeked to the a bud, in the latter
    case, they are non-seeked (wbuf->lnum == -1). So in the latter case we do not
    try to recover the GC LEB by garbage-collecting to the GC head, but we just
    try to find an empty LEB, and there may be no empty LEBs, so we just fail.
    On the other hand, in the former case (mount R/W), we are able to make a GC LEB
    (@c->gc_lnum) by garbage-collecting.

    Thus, let's remove this small nice optimization and always allocate
    write-buffers. This should not make too big difference - we have only 3
    of them, each of max. write unit size, which is usually 2KiB. So this is
    about 6KiB of RAM for the typical case, and only when mounted R/O.

    [1]: Note, currently the replay process is setting (seeking) the journal heads
    to _some_ buds, not necessarily to the buds which had been the journal heads
    before the power cut happened. This will be fixed separately.

    Signed-off-by: Artem Bityutskiy
    Cc: stable@kernel.org

    Artem Bityutskiy
     

20 Sep, 2010

1 commit

  • Commit 2fde99cb55fb9d9b88180512a5e8a5d939d27fec "UBIFS: mark VFS SB RO too"
    introduced regression. This commit made UBIFS set the 'MS_RDONLY' flag in the
    VFS superblock when it switches to R/O mode due to an error. This was done
    to make VFS show the R/O UBIFS flag in /proc/mounts.

    However, several places in UBIFS relied on the 'MS_RDONLY' flag and assume this
    flag can only change when we re-mount. For example, 'ubifs_put_super()'.

    This patch introduces new UBIFS flag - 'c->ro_mount' which changes only when
    we re-mount, and preserves the way UBIFS was originally mounted (R/W or R/O).
    This allows us to de-initialize UBIFS cleanly in 'ubifs_put_super()'.

    This patch also changes all 'ubifs_assert(!c->ro_media)' assertions to
    'ubifs_assert(!c->ro_media && !c->ro_mount)', because we never should write
    anything if the FS was mounter R/O.

    All the places where we test for 'MS_RDONLY' flag in the VFS SB were changed
    and now we test the 'c->ro_mount' flag instead, because it preserves the
    original UBIFS mount type, unlike the 'MS_RDONLY' flag.

    Signed-off-by: Artem Bityutskiy

    Artem Bityutskiy
     

17 Sep, 2010

1 commit

  • The R/O state may have various reasons:

    1. The UBI volume is R/O
    2. The FS is mounted R/O
    3. The FS switched to R/O mode because of an error

    However, in UBIFS we have only one variable which represents cases
    1 and 3 - 'c->ro_media'. Indeed, we set this to 1 if we switch to
    R/O mode due to an error, and then we test it in many places to
    make sure that we stop writing as soon as the error happens.

    But this is very unclean. One consequence of this, for example, is
    that in 'ubifs_remount_fs()' we use 'c->ro_media' to check whether
    we are in R/O mode because on an error, and we print a message
    in this case. However, if we are in R/O mode because the media
    is R/O, our message is bogus.

    This patch introduces new flag - 'c->ro_error' which is set when
    we switch to R/O mode because of an error. It also changes all
    "if (c->ro_media)" checks to "if (c->ro_error)" checks, because
    this is what the checks actually mean. We do not need to check
    for 'c->ro_media' because if the UBI volume is in R/O mode, we
    do not allow R/W mounting, and now writes can happen. This is
    guaranteed by VFS. But it is good to double-check this, so this
    patch also adds many "ubifs_assert(!c->ro_media)" checks.

    In the 'ubifs_remount_fs()' function this patch makes a bit more
    changes - it fixes the error messages as well.

    Signed-off-by: Artem Bityutskiy

    Artem Bityutskiy
     

15 Sep, 2009

1 commit


10 Sep, 2009

1 commit

  • At the moment UBIFS print large and scary error messages and
    flash dumps in case of nearly any corruption, even if it is
    a recoverable corruption. For example, if the master node is
    corrupted, ubifs_scan() prints error dumps, then UBIFS recovers
    just fine and goes on.

    This patch makes UBIFS print scary error messages only in
    real cases, which are not recoverable. It adds 'quiet' argument
    to the 'ubifs_scan()' function, so the caller may ask 'ubi_scan()'
    not to print error messages if the caller is able to do recovery.

    Signed-off-by: Artem Bityutskiy
    Reviewed-by: Adrian Hunter

    Artem Bityutskiy
     

21 Mar, 2009

1 commit


17 Feb, 2009

1 commit

  • Trivial cleanup, list_del(); list_add{,_tail}() is equivalent
    to list_move{,_tail}(). Semantic patch for coccinelle can be
    found at www.cccmz.de/~snakebyte/list_move_tail.spatch

    Signed-off-by: Eric Sesterhenn
    Signed-off-by: Artem Bityutskiy

    Eric Sesterhenn
     

13 Aug, 2008

2 commits

  • Increment the commit number at the beginnig of the commit, instead
    of doing this after the commit. This is needed for further
    optimizations.

    Signed-off-by: Artem Bityutskiy

    Artem Bityutskiy
     
  • UBI transparently handles write errors by automatically copying
    and remapping the affected eraseblock. If UBI is unable to do
    that, for example its pool of eraseblocks reserved for bad block
    handling is empty, then the error is propagated to UBIFS. UBIFS
    must protect the media from falling into an inconsistent state
    by immediately switching to read-only mode. In the case of log
    updates, this was not being done.

    Signed-off-by: Adrian Hunter

    Adrian Hunter
     

15 Jul, 2008

1 commit