RHEL 5.8 NFS server panics in tcp_sendpage
Issue:
NFS server on RHEL 5.8 may panic after being accessed by a client with rsize/wsize 1048576.
Environment:
- RHEL 5.8 NFS server with /proc/fs/nfsd/max_block_size set to 1048576
- NFS client mounting an export on the NFS server using an rsize/wsize of 1048576
- TCP being used for NFS communication
A fix is proposed for RHEL 5.9 (BZ 814626) and RHEL 5.8 z-stream (BZ 820358).
Workaround:
Decrease the maximum IO size to something less than 1MB by writing to /proc/fs/nfsd/max_block_size, for example:
echo 524288 >/proc/fs/nfsd/max_block_size
***Note this has to be done after mounting /proc/fs/nfsd, but before starting nfsd. It is recommended this change be made via modprobe.conf.dist as follows:
# grep max_block_size /etc/modprobe.d/modprobe.conf.dist
install nfsd /sbin/modprobe --first-time --ignore-install nfsd \
&& { /bin/mount -t nfsd nfsd /proc/fs/nfsd > /dev/null 2>&1 || :; \
echo 524288 > /proc/fs/nfsd/max_block_size; }
#
Root Cause:
The rq_pages array has 1MB/PAGE_SIZE+2 elements. The loop in svc_recv attempts to allocate sv_bufsz/PAGE_SIZE+2 pages. But the NFS server is setting sv_bufsiz to over a megabyte, with the result that svc_recv may attempt to allocate sv_bufsz/PAGE_SIZE+3 pages and run past the end of the array, overwriting rq_respages.