summaryrefslogtreecommitdiff
path: root/testing/nfs-utils/kernel-3.0-segfault.patch
blob: 3dba94a05d8e690a4d3a7b10225c611cce9f26b5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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@...>
---
 utils/mount/version.h |   16 +++++++++-------
 1 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/utils/mount/version.h b/utils/mount/version.h
index af61a6f..531cf68 100644
--- a/utils/mount/version.h
+++ b/utils/mount/version.h
@@ -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);
 }