lkml.org 
[lkml]   [2016]   [May]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.2.y-ckt 11/53] get_rock_ridge_filename(): handle malformed NM entries
    Date
    4.2.8-ckt11 -stable review patch.  If anyone has any objections, please let me know.

    ---8<------------------------------------------------------------

    From: Al Viro <viro@zeniv.linux.org.uk>

    commit 99d825822eade8d827a1817357cbf3f889a552d6 upstream.

    Payloads of NM entries are not supposed to contain NUL. When we run
    into such, only the part prior to the first NUL goes into the
    concatenation (i.e. the directory entry name being encoded by a bunch
    of NM entries). We do stop when the amount collected so far + the
    claimed amount in the current NM entry exceed 254. So far, so good,
    but what we return as the total length is the sum of *claimed*
    sizes, not the actual amount collected. And that can grow pretty
    large - not unlimited, since you'd need to put CE entries in
    between to be able to get more than the maximum that could be
    contained in one isofs directory entry / continuation chunk and
    we are stop once we'd encountered 32 CEs, but you can get about 8Kb
    easily. And that's what will be passed to readdir callback as the
    name length. 8Kb __copy_to_user() from a buffer allocated by
    __get_free_page()

    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
    Signed-off-by: Kamal Mostafa <kamal@canonical.com>
    ---
    fs/isofs/rock.c | 13 ++++++++++---
    1 file changed, 10 insertions(+), 3 deletions(-)

    diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c
    index 735d752..204659a 100644
    --- a/fs/isofs/rock.c
    +++ b/fs/isofs/rock.c
    @@ -203,6 +203,8 @@ int get_rock_ridge_filename(struct iso_directory_record *de,
    int retnamlen = 0;
    int truncate = 0;
    int ret = 0;
    + char *p;
    + int len;

    if (!ISOFS_SB(inode->i_sb)->s_rock)
    return 0;
    @@ -267,12 +269,17 @@ repeat:
    rr->u.NM.flags);
    break;
    }
    - if ((strlen(retname) + rr->len - 5) >= 254) {
    + len = rr->len - 5;
    + if (retnamlen + len >= 254) {
    truncate = 1;
    break;
    }
    - strncat(retname, rr->u.NM.name, rr->len - 5);
    - retnamlen += rr->len - 5;
    + p = memchr(rr->u.NM.name, '\0', len);
    + if (unlikely(p))
    + len = p - rr->u.NM.name;
    + memcpy(retname + retnamlen, rr->u.NM.name, len);
    + retnamlen += len;
    + retname[retnamlen] = '\0';
    break;
    case SIG('R', 'E'):
    kfree(rs.buffer);
    --
    2.7.4
    \
     
     \ /
      Last update: 2016-05-24 20:41    [W:4.215 / U:0.016 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site