When a network filesystem using folio_queue-backed iterators (e.g. ceph or NFS with folioq read paths) hits a short read and calls iov_iter_revert() to wind the iterator back, the revert walks backwards through the folio_queue linked list via folioq->prev. If the unroll amount exceeds the data preceding the current position — possible when a splice or sendfile operation miscalculates the revert distance after a partial transfer — the walk reaches the head of the queue where prev is NULL, and the subsequent folioq_nr_slots(NULL) dereferences it. This was found through code review examining the revert paths: the bvec and iovec revert loops have the same class of unbounded backward walk, but the folioq case is the easiest to reach in practice because folio_queue chains have an explicit NULL-terminated prev pointer. Add a NULL check and early return when folioq->prev is NULL to prevent the oops. Signed-off-by: Josh Law --- lib/iov_iter.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/iov_iter.c b/lib/iov_iter.c index 852f9ed40e5c..325669b103ed 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c @@ -600,6 +600,8 @@ static void iov_iter_folioq_revert(struct iov_iter *i, size_t unroll) size_t fsize; if (slot == 0) { + if (!folioq->prev) + return; folioq = folioq->prev; slot = folioq_nr_slots(folioq); } -- 2.34.1