summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2014-12-19 14:27:55 +0100
committerWilly Tarreau <w@1wt.eu>2015-09-18 13:51:56 +0200
commit56de771cef061319e172130ae71e281e340e13bd (patch)
tree4cda71ce0694df37f6f8dd7022fc0b5cc3a5d5e1
parent2897fe8d016c32b83a70a645a545d78152356f36 (diff)
udf: Check component length before reading it
commit e237ec37ec154564f8690c5bd1795339955eeef9 upstream. Check that length specified in a component of a symlink fits in the input buffer we are reading. Also properly ignore component length for component types that do not use it. Otherwise we read memory after end of buffer for corrupted udf image. Reported-by: Carl Henrik Lunde <chlunde@ping.uio.no> Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Ben Hutchings <ben@decadent.org.uk> CVE-2014-9728, CVE-2014-9730 Signed-off-by: Willy Tarreau <w@1wt.eu>
-rw-r--r--fs/udf/symlink.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c
index 500c14605546..c45bb43d77d0 100644
--- a/fs/udf/symlink.c
+++ b/fs/udf/symlink.c
@@ -44,14 +44,17 @@ static int udf_pc_to_char(struct super_block *sb, char *from,
tolen--;
while (elen < fromlen) {
pc = (struct pathComponent *)(from + elen);
+ elen += sizeof(struct pathComponent);
switch (pc->componentType) {
case 1:
/*
* Symlink points to some place which should be agreed
* upon between originator and receiver of the media. Ignore.
*/
- if (pc->lengthComponentIdent > 0)
+ if (pc->lengthComponentIdent > 0) {
+ elen += pc->lengthComponentIdent;
break;
+ }
/* Fall through */
case 2:
if (tolen == 0)
@@ -76,6 +79,9 @@ static int udf_pc_to_char(struct super_block *sb, char *from,
/* that would be . - just ignore */
break;
case 5:
+ elen += pc->lengthComponentIdent;
+ if (elen > fromlen)
+ return -EIO;
comp_len = udf_get_filename(sb, pc->componentIdent,
pc->lengthComponentIdent,
p, tolen);
@@ -87,7 +93,6 @@ static int udf_pc_to_char(struct super_block *sb, char *from,
tolen--;
break;
}
- elen += sizeof(struct pathComponent) + pc->lengthComponentIdent;
}
if (p > to + 1)
p[-1] = '\0';