Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7023676f authored by Jeff Layton's avatar Jeff Layton Committed by Steve French
Browse files

cifs: check for NULL last_entry before calling cifs_save_resume_key

Prior to commit eaf35b1e, cifs_save_resume_key had some NULL pointer
checks at the top. It turns out that at least one of those NULL
pointer checks is needed after all.

When the LastNameOffset in a FIND reply appears to be beyond the end of
the buffer, CIFSFindFirst and CIFSFindNext will set srch_inf.last_entry
to NULL. Since eaf35b1e, the code will now oops in this situation.

Fix this by having the callers check for a NULL last entry pointer
before calling cifs_save_resume_key. No change is needed for the
call site in cifs_readdir as it's not reachable with a NULL
current_entry pointer.

This should fix:

    https://bugzilla.redhat.com/show_bug.cgi?id=750247



Cc: stable@vger.kernel.org
Cc: Christoph Hellwig <hch@infradead.org>
Reported-by: default avatarAdam G. Metzler <adamgmetzler@gmail.com>
Signed-off-by: default avatarJeff Layton <jlayton@redhat.com>
Signed-off-by: default avatarSteve French <smfrench@gmail.com>
parent 95edcff4
Loading
Loading
Loading
Loading
+8 −2
Original line number Original line Diff line number Diff line
@@ -554,7 +554,10 @@ static int find_cifs_entry(const int xid, struct cifs_tcon *pTcon,
				 rc);
				 rc);
			return rc;
			return rc;
		}
		}
		cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile);
		/* FindFirst/Next set last_entry to NULL on malformed reply */
		if (cifsFile->srch_inf.last_entry)
			cifs_save_resume_key(cifsFile->srch_inf.last_entry,
						cifsFile);
	}
	}


	while ((index_to_find >= cifsFile->srch_inf.index_of_last_entry) &&
	while ((index_to_find >= cifsFile->srch_inf.index_of_last_entry) &&
@@ -562,7 +565,10 @@ static int find_cifs_entry(const int xid, struct cifs_tcon *pTcon,
		cFYI(1, "calling findnext2");
		cFYI(1, "calling findnext2");
		rc = CIFSFindNext(xid, pTcon, cifsFile->netfid,
		rc = CIFSFindNext(xid, pTcon, cifsFile->netfid,
				  &cifsFile->srch_inf);
				  &cifsFile->srch_inf);
		cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile);
		/* FindFirst/Next set last_entry to NULL on malformed reply */
		if (cifsFile->srch_inf.last_entry)
			cifs_save_resume_key(cifsFile->srch_inf.last_entry,
						cifsFile);
		if (rc)
		if (rc)
			return -ENOENT;
			return -ENOENT;
	}
	}