Skip to content

Commit 2139152

Browse files
committed
Merge tag '9p-for-5.8-2' of git://github.com/martinetd/linux into master
Pull 9p fixes from Dominique Martinet: "A couple of syzcaller fixes for 5.8 The first one in particular has been quite noisy ("broke" in -rc5) so this would be worth landing even this late even if users likely won't see a difference" * tag '9p-for-5.8-2' of git://github.com/martinetd/linux: 9p/trans_fd: Fix concurrency del of req_list in p9_fd_cancelled/p9_read_work net/9p: validate fds in p9_fd_open
2 parents c2f3850 + 74d6a5d commit 2139152

File tree

1 file changed

+30
-9
lines changed

1 file changed

+30
-9
lines changed

net/9p/trans_fd.c

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,10 @@ static void p9_read_work(struct work_struct *work)
362362
if (m->rreq->status == REQ_STATUS_SENT) {
363363
list_del(&m->rreq->req_list);
364364
p9_client_cb(m->client, m->rreq, REQ_STATUS_RCVD);
365+
} else if (m->rreq->status == REQ_STATUS_FLSHD) {
366+
/* Ignore replies associated with a cancelled request. */
367+
p9_debug(P9_DEBUG_TRANS,
368+
"Ignore replies associated with a cancelled request\n");
365369
} else {
366370
spin_unlock(&m->client->lock);
367371
p9_debug(P9_DEBUG_ERROR,
@@ -703,11 +707,20 @@ static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req)
703707
{
704708
p9_debug(P9_DEBUG_TRANS, "client %p req %p\n", client, req);
705709

710+
spin_lock(&client->lock);
711+
/* Ignore cancelled request if message has been received
712+
* before lock.
713+
*/
714+
if (req->status == REQ_STATUS_RCVD) {
715+
spin_unlock(&client->lock);
716+
return 0;
717+
}
718+
706719
/* we haven't received a response for oldreq,
707720
* remove it from the list.
708721
*/
709-
spin_lock(&client->lock);
710722
list_del(&req->req_list);
723+
req->status = REQ_STATUS_FLSHD;
711724
spin_unlock(&client->lock);
712725
p9_req_put(req);
713726

@@ -803,20 +816,28 @@ static int p9_fd_open(struct p9_client *client, int rfd, int wfd)
803816
return -ENOMEM;
804817

805818
ts->rd = fget(rfd);
819+
if (!ts->rd)
820+
goto out_free_ts;
821+
if (!(ts->rd->f_mode & FMODE_READ))
822+
goto out_put_rd;
806823
ts->wr = fget(wfd);
807-
if (!ts->rd || !ts->wr) {
808-
if (ts->rd)
809-
fput(ts->rd);
810-
if (ts->wr)
811-
fput(ts->wr);
812-
kfree(ts);
813-
return -EIO;
814-
}
824+
if (!ts->wr)
825+
goto out_put_rd;
826+
if (!(ts->wr->f_mode & FMODE_WRITE))
827+
goto out_put_wr;
815828

816829
client->trans = ts;
817830
client->status = Connected;
818831

819832
return 0;
833+
834+
out_put_wr:
835+
fput(ts->wr);
836+
out_put_rd:
837+
fput(ts->rd);
838+
out_free_ts:
839+
kfree(ts);
840+
return -EIO;
820841
}
821842

822843
static int p9_socket_open(struct p9_client *client, struct socket *csocket)

0 commit comments

Comments
 (0)