• Ilya Dryomov's avatar
    libceph: check data_len in ->alloc_msg() · d15f9d69
    Ilya Dryomov authored
    Only ->alloc_msg() should check data_len of the incoming message
    against the preallocated ceph_msg, doing it in the messenger is not
    right.  The contract is that either ->alloc_msg() returns a ceph_msg
    which will fit all of the portions of the incoming message, or it
    returns NULL and possibly sets skip, signaling whether NULL is due to
    an -ENOMEM.  ->alloc_msg() should be the only place where we make the
    skip/no-skip decision.
    
    I stumbled upon this while looking at con/osd ref counting.  Right now,
    if we get a non-extent message with a larger data portion than we are
    prepared for, ->alloc_msg() returns a ceph_msg, and then, when we skip
    it in the messenger, we don't put the con/osd ref acquired in
    ceph_con_in_msg_alloc() (which is normally put in process_message()),
    so this also fixes a memory leak.
    
    An existing BUG_ON in ceph_msg_data_cursor_init() ensures we don't
    corrupt random memory should a buggy ->alloc_msg() return an unfit
    ceph_msg.
    
    While at it, I changed the "unknown tid" dout() to a pr_warn() to make
    sure all skips are seen and unified format strings.
    Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
    Reviewed-by: default avatarAlex Elder <elder@linaro.org>
    d15f9d69
osd_client.c 78.4 KB