120 lines
3.8 KiB
Diff
120 lines
3.8 KiB
Diff
From 212e2fcac834dec25a4fa0f4fd4652bfd19cdeea Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
|
|
Date: Fri, 4 Jan 2013 13:35:27 +0100
|
|
Subject: [PATCH 2/2] Fix CVE-2012-6090
|
|
|
|
Upstream fix ported to 5.10.2:
|
|
|
|
From b2c88972e7515ada025e97e7d3ce3e34f81cf33e Mon Sep 17 00:00:00 2001
|
|
From: Jan Wielemaker <J.Wielemaker@cs.vu.nl>
|
|
Date: Sun, 16 Dec 2012 17:29:37 +0100
|
|
Subject: [PATCH] SECURITY: Possible buffer overflows when expanding
|
|
file-names with long paths. Affects expand_file_name/2.
|
|
|
|
Can lead to crashes (DoS attacks) and possibly execution of arbitrary
|
|
code if an attacker can control the names of the files searched for,
|
|
e.g., if expand_file_name/2 is used in a directory to which an attacker
|
|
can upload files for which he can control the name.
|
|
---
|
|
src/pl-glob.c | 46 ++++++++++++++++++++++++++++------------------
|
|
1 file changed, 28 insertions(+), 18 deletions(-)
|
|
|
|
diff --git a/src/pl-glob.c b/src/pl-glob.c
|
|
index 417a69c..1fad6ca 100644
|
|
--- a/src/pl-glob.c
|
|
+++ b/src/pl-glob.c
|
|
@@ -423,6 +423,7 @@ expand(const char *pattern, GlobInfo info)
|
|
compiled_pattern cbuf;
|
|
char prefix[MAXPATHLEN]; /* before first pattern */
|
|
char patbuf[MAXPATHLEN]; /* pattern buffer */
|
|
+ size_t prefix_len;
|
|
int end, dot;
|
|
|
|
initBuffer(&info->files);
|
|
@@ -441,20 +442,25 @@ expand(const char *pattern, GlobInfo info)
|
|
switch( (c=*s++) )
|
|
{ case EOS:
|
|
if ( s > pat ) /* something left and expanded */
|
|
- { un_escape(prefix, pat, s);
|
|
+ { size_t prefix_len;
|
|
+
|
|
+ un_escape(prefix, pat, s);
|
|
+ prefix_len = strlen(prefix);
|
|
|
|
end = info->end;
|
|
for( ; info->start < end; info->start++ )
|
|
{ char path[MAXPATHLEN];
|
|
- size_t plen;
|
|
-
|
|
- strcpy(path, expand_entry(info, info->start));
|
|
- plen = strlen(path);
|
|
- if ( prefix[0] && plen > 0 && path[plen-1] != '/' )
|
|
- path[plen++] = '/';
|
|
- strcpy(&path[plen], prefix);
|
|
- if ( end == 1 || AccessFile(path, ACCESS_EXIST) )
|
|
- add_path(path, info);
|
|
+ const char *entry = expand_entry(info, info->start);
|
|
+ size_t plen = strlen(entry);
|
|
+
|
|
+ if ( plen+prefix_len+2 <= MAXPATHLEN )
|
|
+ { strcpy(path, entry);
|
|
+ if ( prefix[0] && plen > 0 && path[plen-1] != '/' )
|
|
+ path[plen++] = '/';
|
|
+ strcpy(&path[plen], prefix);
|
|
+ if ( end == 1 || AccessFile(path, ACCESS_EXIST) )
|
|
+ add_path(path, info);
|
|
+ }
|
|
}
|
|
}
|
|
succeed;
|
|
@@ -489,8 +495,9 @@ expand(const char *pattern, GlobInfo info)
|
|
*/
|
|
un_escape(prefix, pat, head);
|
|
un_escape(patbuf, head, tail);
|
|
+ prefix_len = strlen(prefix);
|
|
|
|
- if ( !compilePattern(patbuf, &cbuf) ) /* syntax error */
|
|
+ if ( !compilePattern(patbuf, &cbuf) ) /* syntax error */
|
|
fail;
|
|
dot = (patbuf[0] == '.'); /* do dots as well */
|
|
|
|
@@ -502,12 +509,16 @@ expand(const char *pattern, GlobInfo info)
|
|
char path[MAXPATHLEN];
|
|
char tmp[MAXPATHLEN];
|
|
const char *current = expand_entry(info, info->start);
|
|
+ size_t clen = strlen(current);
|
|
+
|
|
+ if ( clen+prefix_len+1 > sizeof(path) )
|
|
+ continue;
|
|
|
|
strcpy(path, current);
|
|
- strcat(path, prefix);
|
|
+ strcpy(&path[clen], prefix);
|
|
|
|
if ( (d=opendir(path[0] ? OsPath(path, tmp) : ".")) )
|
|
- { size_t plen = strlen(path);
|
|
+ { size_t plen = clen+prefix_len;
|
|
|
|
if ( plen > 0 && path[plen-1] != '/' )
|
|
path[plen++] = '/';
|
|
@@ -521,12 +532,11 @@ expand(const char *pattern, GlobInfo info)
|
|
matchPattern(e->d_name, &cbuf) )
|
|
{ char newp[MAXPATHLEN];
|
|
|
|
- strcpy(newp, path);
|
|
- strcpy(&newp[plen], e->d_name);
|
|
-/* if ( !tail[0] || ExistsDirectory(newp) )
|
|
- Saves memory, but involves one more file-access
|
|
-*/
|
|
+ if ( plen+strlen(e->d_name)+1 < sizeof(newp) )
|
|
+ { strcpy(newp, path);
|
|
+ strcpy(&newp[plen], e->d_name);
|
|
add_path(newp, info);
|
|
+ }
|
|
}
|
|
}
|
|
closedir(d);
|
|
--
|
|
1.7.11.7
|
|
|