9p-for-6.1-rc7
Two fixes: - 9p now uses a variable size for its recv buffer, but every place hadn't been updated properly to use it and some buffer overflows have been found and needed fixing. There's still one place where msize is incorrectly used in a safety check (p9_check_errors), but all paths leading to it should already be avoiding overflows and that patch took a bit more time to get right for zero-copy requests so I'll send it for 6.2 - yet another race condition in p9_conn_cancel introduced by a fix of a syzbot report in the same place, maybe at some point we'll get it right without burning it all down... -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE/IPbcYBuWt0zoYhOq06b7GqY5nAFAmN9q0QACgkQq06b7GqY 5nAYfhAAkV4BuDAxkq1J9m2tAr32bNgSWRbwHGoiO3yOgN3OQcl0MRR910VLPaBe rRMbggIZKp6SjKpL5CQUbIcf+ubvcHZQpglCWdJT6Cch9VAidwKB4y48V0nb9Gos Z2lAtKCdlczmmbYY+KQ4KrFXKXkHXV7FPH7aLLaVg6VxckbRwunDMAPIQJ2wtUDq GP+J0OBL6NGb1N1TrAx9uQMzM9Zbu/pfQ8Ik/PdwzcT5fWm6OOlICOe/ImAlFfiN AU0+jc1c01DhQiGedEytOLWMlvcUtgbN2VoMszAuIdn3MFdRFiklQ/5IYFvEu4z4 vWeSL5ctsrgqhG0i5gNTDspzmX05amBaN7UOyQ8yvCYs9Jgv7x9EghdXA4XMX3UD l8QcNQgthTVtI2waspAmWOV4anPjr4VJIcoLKapzAXTpd7SCJazzap/0CvXjTINK IX4Fjeg9eKeQPsHgeLiO00zokM0LPZ+W4X6Xus1rrwzHVtde78bqokrUV/U6wVKF UT0i06oEYlB79ySOmgqoZuFRbos7VZI6l6hLkbo+XJOPalWzP5MwexGS2JVo4ymS Xu5DYlqnSdQQxScHdK906Ksbusa3n5jxAURqOIQxJ1UZyC7CPusVy2KA4FiZsL/x OkYGlSg60tvsOfaNQoXOlziG2u3FJrZFjsurvgBgsgtUWEgVaU0= =MQOZ -----END PGP SIGNATURE----- Merge tag '9p-for-6.1-rc7' of https://github.com/martinetd/linux Pull 9p fixes from Dominique Martinet: - 9p now uses a variable size for its recv buffer, but every place hadn't been updated properly to use it and some buffer overflows have been found and needed fixing. There's still one place where msize is incorrectly used in a safety check (p9_check_errors), but all paths leading to it should already be avoiding overflows and that patch took a bit more time to get right for zero-copy requests so I'll send it for 6.2 - yet another race condition in p9_conn_cancel introduced by a fix for a syzbot report in the same place. Maybe at some point we'll get it right without burning it all down... * tag '9p-for-6.1-rc7' of https://github.com/martinetd/linux: 9p/xen: check logical size for buffer size 9p/fd: Use P9_HDRSZ for header size 9p/fd: Fix write overflow in p9_read_work 9p/fd: fix issue of list_del corruption in p9_fd_cancel()
This commit is contained in:
commit
fd64898dfe
|
@ -120,7 +120,7 @@ struct p9_conn {
|
|||
struct list_head unsent_req_list;
|
||||
struct p9_req_t *rreq;
|
||||
struct p9_req_t *wreq;
|
||||
char tmp_buf[7];
|
||||
char tmp_buf[P9_HDRSZ];
|
||||
struct p9_fcall rc;
|
||||
int wpos;
|
||||
int wsize;
|
||||
|
@ -202,9 +202,11 @@ static void p9_conn_cancel(struct p9_conn *m, int err)
|
|||
|
||||
list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) {
|
||||
list_move(&req->req_list, &cancel_list);
|
||||
req->status = REQ_STATUS_ERROR;
|
||||
}
|
||||
list_for_each_entry_safe(req, rtmp, &m->unsent_req_list, req_list) {
|
||||
list_move(&req->req_list, &cancel_list);
|
||||
req->status = REQ_STATUS_ERROR;
|
||||
}
|
||||
|
||||
spin_unlock(&m->req_lock);
|
||||
|
@ -291,7 +293,7 @@ static void p9_read_work(struct work_struct *work)
|
|||
if (!m->rc.sdata) {
|
||||
m->rc.sdata = m->tmp_buf;
|
||||
m->rc.offset = 0;
|
||||
m->rc.capacity = 7; /* start by reading header */
|
||||
m->rc.capacity = P9_HDRSZ; /* start by reading header */
|
||||
}
|
||||
|
||||
clear_bit(Rpending, &m->wsched);
|
||||
|
@ -314,7 +316,7 @@ static void p9_read_work(struct work_struct *work)
|
|||
p9_debug(P9_DEBUG_TRANS, "got new header\n");
|
||||
|
||||
/* Header size */
|
||||
m->rc.size = 7;
|
||||
m->rc.size = P9_HDRSZ;
|
||||
err = p9_parse_header(&m->rc, &m->rc.size, NULL, NULL, 0);
|
||||
if (err) {
|
||||
p9_debug(P9_DEBUG_ERROR,
|
||||
|
@ -322,14 +324,6 @@ static void p9_read_work(struct work_struct *work)
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (m->rc.size >= m->client->msize) {
|
||||
p9_debug(P9_DEBUG_ERROR,
|
||||
"requested packet size too big: %d\n",
|
||||
m->rc.size);
|
||||
err = -EIO;
|
||||
goto error;
|
||||
}
|
||||
|
||||
p9_debug(P9_DEBUG_TRANS,
|
||||
"mux %p pkt: size: %d bytes tag: %d\n",
|
||||
m, m->rc.size, m->rc.tag);
|
||||
|
@ -342,6 +336,14 @@ static void p9_read_work(struct work_struct *work)
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (m->rc.size > m->rreq->rc.capacity) {
|
||||
p9_debug(P9_DEBUG_ERROR,
|
||||
"requested packet size too big: %d for tag %d with capacity %zd\n",
|
||||
m->rc.size, m->rc.tag, m->rreq->rc.capacity);
|
||||
err = -EIO;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!m->rreq->rc.sdata) {
|
||||
p9_debug(P9_DEBUG_ERROR,
|
||||
"No recv fcall for tag %d (req %p), disconnecting!\n",
|
||||
|
|
|
@ -208,6 +208,14 @@ static void p9_xen_response(struct work_struct *work)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (h.size > req->rc.capacity) {
|
||||
dev_warn(&priv->dev->dev,
|
||||
"requested packet size too big: %d for tag %d with capacity %zd\n",
|
||||
h.size, h.tag, req->rc.capacity);
|
||||
req->status = REQ_STATUS_ERROR;
|
||||
goto recv_error;
|
||||
}
|
||||
|
||||
memcpy(&req->rc, &h, sizeof(h));
|
||||
req->rc.offset = 0;
|
||||
|
||||
|
@ -217,6 +225,7 @@ static void p9_xen_response(struct work_struct *work)
|
|||
masked_prod, &masked_cons,
|
||||
XEN_9PFS_RING_SIZE(ring));
|
||||
|
||||
recv_error:
|
||||
virt_mb();
|
||||
cons += h.size;
|
||||
ring->intf->in_cons = cons;
|
||||
|
|
Loading…
Reference in New Issue