Hi Pádraig,
> There is a later cast to (long int) that would
> similarly truncate large values on LLP64 systems.
> How about something like this as well?
>
> @@ -311,7 +312,7 @@ __realpath (const char *name, char *resolved)
> }
>
> len = strlen (end);
> - if ((long int) (n + len) >= path_max)
> + if (SIZE_MAX - len <= n || path_max <= n + len)
> {
> freea (buf);
> __set_errno (ENAMETOOLONG);
Thanks, also for the integer overflow check (useful also for the LP64
platforms). Here is the proposed revised patch.
Bruno
>From fcce5d7501a8ea0224ffb0f35340fbe5dfc483ef Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Fri, 14 Oct 2016 02:49:05 +0200
Subject: [PATCH] canonicalize-lgpl: Support the case path_max > INT_MAX.
* lib/canonicalize-lgpl.c (__realpath): Declare n as ssize_t, not int.
---
ChangeLog | 7 +++++++
lib/canonicalize-lgpl.c | 5 +++--
2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 32bddf8..510f191 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2016-10-14 Bruno Haible <[email protected]>
+ Pádraig Brady <[email protected]>
+
+ canonicalize-lgpl: Support the case path_max > INT_MAX.
+ * lib/canonicalize-lgpl.c (__realpath): Declare n as ssize_t, not int.
+ Fix overflow check, for platforms where 'size_t' is larger than 'long'.
+
2016-10-13 Paul Eggert <[email protected]>
stdint: port SIZE_MAX to glibc s390
diff --git a/lib/canonicalize-lgpl.c b/lib/canonicalize-lgpl.c
index 4a38a46..7f54008 100644
--- a/lib/canonicalize-lgpl.c
+++ b/lib/canonicalize-lgpl.c
@@ -194,7 +194,6 @@ __realpath (const char *name, char *resolved)
#else
struct stat st;
#endif
- int n;
/* Skip sequence of multiple path-separators. */
while (ISSLASH (*start))
@@ -275,6 +274,7 @@ __realpath (const char *name, char *resolved)
{
char *buf;
size_t len;
+ ssize_t n;
if (++num_links > MAXSYMLINKS)
{
@@ -311,7 +311,8 @@ __realpath (const char *name, char *resolved)
}
len = strlen (end);
- if ((long int) (n + len) >= path_max)
+ /* Check that n + len + 1 doesn't overflow and is <= path_max. */
+ if (n >= SIZE_MAX - len || n + len >= path_max)
{
freea (buf);
__set_errno (ENAMETOOLONG);
--
2.6.4