Skip to content

Commit dc9dc2f

Browse files
author
Trond Myklebust
committed
NFS: Fix use-after-free issues in nfs_pageio_add_request()
We need to ensure that we create the mirror requests before calling nfs_pageio_add_request_mirror() on the request we are adding. Otherwise, we can end up with a use-after-free if the call to nfs_pageio_add_request_mirror() triggers I/O. Fixes: c917cfa ("NFS: Fix up NFS I/O subrequest creation") Cc: [email protected] Signed-off-by: Trond Myklebust <[email protected]>
1 parent 08ca8b2 commit dc9dc2f

File tree

1 file changed

+24
-24
lines changed

1 file changed

+24
-24
lines changed

fs/nfs/pagelist.c

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1191,38 +1191,38 @@ int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,
11911191
if (desc->pg_error < 0)
11921192
goto out_failed;
11931193

1194-
for (midx = 0; midx < desc->pg_mirror_count; midx++) {
1195-
if (midx) {
1196-
nfs_page_group_lock(req);
1197-
1198-
/* find the last request */
1199-
for (lastreq = req->wb_head;
1200-
lastreq->wb_this_page != req->wb_head;
1201-
lastreq = lastreq->wb_this_page)
1202-
;
1203-
1204-
dupreq = nfs_create_subreq(req, lastreq,
1205-
pgbase, offset, bytes);
1206-
1207-
nfs_page_group_unlock(req);
1208-
if (IS_ERR(dupreq)) {
1209-
desc->pg_error = PTR_ERR(dupreq);
1210-
goto out_failed;
1211-
}
1212-
} else
1213-
dupreq = req;
1194+
/* Create the mirror instances first, and fire them off */
1195+
for (midx = 1; midx < desc->pg_mirror_count; midx++) {
1196+
nfs_page_group_lock(req);
1197+
1198+
/* find the last request */
1199+
for (lastreq = req->wb_head;
1200+
lastreq->wb_this_page != req->wb_head;
1201+
lastreq = lastreq->wb_this_page)
1202+
;
1203+
1204+
dupreq = nfs_create_subreq(req, lastreq,
1205+
pgbase, offset, bytes);
1206+
1207+
nfs_page_group_unlock(req);
1208+
if (IS_ERR(dupreq)) {
1209+
desc->pg_error = PTR_ERR(dupreq);
1210+
goto out_failed;
1211+
}
12141212

1215-
if (nfs_pgio_has_mirroring(desc))
1216-
desc->pg_mirror_idx = midx;
1213+
desc->pg_mirror_idx = midx;
12171214
if (!nfs_pageio_add_request_mirror(desc, dupreq))
12181215
goto out_cleanup_subreq;
12191216
}
12201217

1218+
desc->pg_mirror_idx = 0;
1219+
if (!nfs_pageio_add_request_mirror(desc, req))
1220+
goto out_failed;
1221+
12211222
return 1;
12221223

12231224
out_cleanup_subreq:
1224-
if (req != dupreq)
1225-
nfs_pageio_cleanup_request(desc, dupreq);
1225+
nfs_pageio_cleanup_request(desc, dupreq);
12261226
out_failed:
12271227
nfs_pageio_error_cleanup(desc);
12281228
return 0;

0 commit comments

Comments
 (0)