On Tue, Mar 25, 2014 at 10:40 PM, <gregkh@xxxxxxxxxxxxxxxxxxx> wrote: > > The patch below does not apply to the 3.13-stable tree. > If someone wants it applied there, or to any other stable or longterm > tree, then please email the backport, including the original git commit > id to <stable@xxxxxxxxxxxxxxx>. > > thanks, > > greg k-h > > ------------------ original commit in Linus's tree ------------------ > > From f2be82b0058e90b5d9ac2cb896b4914276fb50ef Mon Sep 17 00:00:00 2001 > From: Ilya Dryomov <ilya.dryomov@xxxxxxxxxxx> > Date: Thu, 9 Jan 2014 20:08:21 +0200 > Subject: [PATCH] libceph: fix preallocation check in get_reply() > > The check that makes sure that we have enough memory allocated to read > in the entire header of the message in question is currently busted. > It compares front_len of the incoming message with iov_len field of > ceph_msg::front structure, which is used primarily to indicate the > amount of data already read in, and not the size of the allocated > buffer. Under certain conditions (e.g. a short read from a socket > followed by that socket's shutdown and owning ceph_connection reset) > this results in a warning similar to > > [85688.975866] libceph: get_reply front 198 > preallocated 122 (4#0) > > and, through another bug, leads to forever hung tasks and forced > reboots. Fix this by comparing front_len with front_alloc_len field of > struct ceph_msg, which stores the actual size of the buffer. > > Fixes: http://tracker.ceph.com/issues/5425 > > Signed-off-by: Ilya Dryomov <ilya.dryomov@xxxxxxxxxxx> > Reviewed-by: Sage Weil <sage@xxxxxxxxxxx> > > diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c > index f4d411c017e7..252ad4e01cf8 100644 > --- a/net/ceph/messenger.c > +++ b/net/ceph/messenger.c > @@ -3130,7 +3130,6 @@ struct ceph_msg *ceph_msg_new(int type, int front_len, gfp_t flags, > INIT_LIST_HEAD(&m->data); > > /* front */ > - m->front_alloc_len = front_len; > if (front_len) { > if (front_len > PAGE_CACHE_SIZE) { > m->front.iov_base = __vmalloc(front_len, flags, > @@ -3147,7 +3146,7 @@ struct ceph_msg *ceph_msg_new(int type, int front_len, gfp_t flags, > } else { > m->front.iov_base = NULL; > } > - m->front.iov_len = front_len; > + m->front_alloc_len = m->front.iov_len = front_len; > > dout("ceph_msg_new %p front %d\n", m, front_len); > return m; > diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c > index 7619c37bfed4..733195170490 100644 > --- a/net/ceph/osd_client.c > +++ b/net/ceph/osd_client.c > @@ -2522,9 +2522,9 @@ static struct ceph_msg *get_reply(struct ceph_connection *con, > req->r_reply, req->r_reply->con); > ceph_msg_revoke_incoming(req->r_reply); > > - if (front_len > req->r_reply->front.iov_len) { > + if (front_len > req->r_reply->front_alloc_len) { > pr_warning("get_reply front %d > preallocated %d (%u#%llu)\n", > - front_len, (int)req->r_reply->front.iov_len, > + front_len, req->r_reply->front_alloc_len, > (unsigned int)con->peer_name.type, > le64_to_cpu(con->peer_name.num)); > m = ceph_msg_new(CEPH_MSG_OSD_OPREPLY, front_len, GFP_NOFS, > This commit depends on two other commits, both of which are in mainline, but may not comply with stable rules (they are small renames). If that's OK, please apply to 3.13 and 3.12: 3cea4c3071d4e55e9d7356efe9d0ebf92f0c2204 libceph: rename ceph_msg::front_max to front_alloc_len 3f0a4ac55fe036902e3666be740da63528ad8639 libceph: rename front to front_len in get_reply() f2be82b0058e90b5d9ac2cb896b4914276fb50ef libceph: fix preallocation check in get_reply() Thanks, Ilya -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html