Universal NFS Server vulnerable to MAX_PATH buffer overflow
10 Nov. 1999
Summary
It is possible to overflow NFSd's path+filename string buffer, causing the program to crash and execute arbitrary code, by creating a very large directory structure and a very long file name. When both are combined in a "DELETE FILE" command under NFSd the path+filename are larger than the buffer intended to hold them, causing a buffer overflow and potentially allowing the execution of arbitrary code.
Vulnerable systems:
Universal NFS Server 2.2beta46 and below.
Non vulnerable systems:
Universal NFS Server 2.2beta47 and above.
The cause of the problem is that the code relies on the total length of a path to not exceed PATH_MAX + NAME_MAX. It's not clean whether this is a common Unix problem, but it was verified on Linux. While PATH_MAX merely seems to put an upper limit on the length of a single path you can hand to a syscall (size of a page - 1, i.e. 4095), it still allows you to create files within that directory as long as you use relative names only.
As to the impact of the problem, it's nasty, but the attacker will need to have a directory-exported read/write in order to exploit it (or at least to be able to impersonate a host with this kind of access).
Patch:
Below is a patch for 2.2beta46 that rectifies this problem.
----------------------
diff -ur nfs-server-2.2beta46/ChangeLog nfs-server-2.2beta47/ChangeLog
--- nfs-server-2.2beta46/ChangeLog Tue Sep 14 11:21:15 1999
+++ nfs-server-2.2beta47/ChangeLog Wed Nov 10 10:17:51 1999
@@ -1,3 +1,9 @@
+Wed Nov 10 10:17:16 1999
+
+ * Security fix for buffer overflow in fh_buildpath
+ No thanks to Mariusz who reported it to bugtraq
+ rather than me.
+
Wed Sep 8 09:07:38 1999
* If a host is listed by IP addr, do a reverse lookup
diff -ur nfs-server-2.2beta46/auth_clnt.c nfs-server-2.2beta47/auth_clnt.c
--- nfs-server-2.2beta46/auth_clnt.c Tue Sep 7 09:54:50 1999
+++ nfs-server-2.2beta47/auth_clnt.c Wed Nov 10 10:18:06 1999
@@ -12,6 +12,7 @@
*/
diff -ur nfs-server-2.2beta46/exports.man nfs-server-2.2beta47/exports.man
--- nfs-server-2.2beta46/exports.man Mon Dec 8 16:59:50 1997
+++ nfs-server-2.2beta47/exports.man Wed Nov 10 10:18:49 1999
@@ -75,11 +75,12 @@
off, specify
.IR insecure .
.TP
-.IR ro
-Allow only read-only requests on this NFS volume. The default is to
-allow write requests as well, which can also be made explicit by using
-the
-.IR rw " option.
+.\" This used to be a documentation bug in previous versions...
+.IR rw
+Allow the client to modify files and directories. The default is to
+restrict the client to read-only request, which can be made explicit
+by using the
+.IR ro " option.
.TP
.I noaccess
This makes everything below the directory inaccessible for the named
diff -ur nfs-server-2.2beta46/fh.c nfs-server-2.2beta47/fh.c
--- nfs-server-2.2beta46/fh.c Mon Nov 23 14:08:11 1998
+++ nfs-server-2.2beta47/fh.c Wed Nov 10 10:31:49 1999
@@ -43,6 +43,10 @@
* This software maybe be used for any purpose provided
* the above copyright notice is retained. It is supplied
* as is, with no warranty expressed or implied.
+ *
+ * Note: the original code mistakenly assumes that the overall path
+ * length remains within the value given by PATH_MAX... that leads
+ * to interesting buffer overflows all over the place.
*/
#include <assert.h>
@@ -533,7 +537,7 @@
char *slash_stack[HP_LEN];
struct stat sbuf;
psi_t psi;
- int i;
+ int i, pathlen;