mount.nfs: Do not segfault because of kernel version
authorLuk Claes <luk@debian.org>
Tue, 12 Jul 2011 14:38:03 +0000 (10:38 -0400)
committerSteve Dickson <steved@redhat.com>
Tue, 12 Jul 2011 14:39:02 +0000 (10:39 -0400)
mount.nfs segfaults if kernel version number does not contain
at least 3 components delimited with a dot.

Avoid this by matching up to three unsigned integers inialised
to zero, separated by dots.

A version that does not start with an integer is probably a future
version where the versioning evolved to another scheme.
Return UINT_MAX which is guaranteed to be higher than existing
versions. This would also make it possible to easily identify
versions that do not start with an integer.

Signed-off-by: Luk Claes <luk@debian.org>
Signed-off-by: Steve Dickson <steved@redhat.com>
utils/mount/version.h

index af61a6f..531cf68 100644 (file)
@@ -23,8 +23,8 @@
 #ifndef _NFS_UTILS_MOUNT_VERSION_H
 #define _NFS_UTILS_MOUNT_VERSION_H
 
-#include <stdlib.h>
-#include <string.h>
+#include <stdio.h>
+#include <limits.h>
 
 #include <sys/utsname.h>
 
@@ -37,14 +37,16 @@ static inline unsigned int MAKE_VERSION(unsigned int p, unsigned int q,
 static inline unsigned int linux_version_code(void)
 {
        struct utsname my_utsname;
-       unsigned int p, q, r;
+       unsigned int p, q = 0, r = 0;
 
+       /* UINT_MAX as backward compatibility code should not be run */
        if (uname(&my_utsname))
-               return 0;
+               return UINT_MAX;
 
-       p = (unsigned int)atoi(strtok(my_utsname.release, "."));
-       q = (unsigned int)atoi(strtok(NULL, "."));
-       r = (unsigned int)atoi(strtok(NULL, "."));
+       /* UINT_MAX as future versions might not start with an integer */
+       if (sscanf(my_utsname.release, "%u.%u.%u", &p, &q, &r) < 1)
+               return UINT_MAX;
+       
        return MAKE_VERSION(p, q, r);
 }