diff options
| author | Sona Sarmadi <sona.sarmadi@enea.com> | 2015-01-19 14:37:06 +0100 |
|---|---|---|
| committer | Zhenhua Luo <zhenhua.luo@freescale.com> | 2015-01-22 15:06:38 +0800 |
| commit | d59902329c7554727bfd0456891fbc6807021864 (patch) | |
| tree | 673da928dd3bb47ab487b8b24c4fe154635983f8 | |
| parent | e95bdf7590600d0d38427227f081d4a19a3c3e64 (diff) | |
| download | meta-freescale-d59902329c7554727bfd0456891fbc6807021864.tar.gz | |
udf: CVE-2014-6410
Avoid infinite loop when processing indirect ICBs
References:
http://seclists.org/oss-sec/2014/q3/600
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6410
Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com>
| -rw-r--r-- | meta-fsl-ppc/recipes-kernel/linux/files/udf-CVE-2014-6410.patch | 96 | ||||
| -rw-r--r-- | meta-fsl-ppc/recipes-kernel/linux/linux-qoriq_3.12.bb | 1 |
2 files changed, 97 insertions, 0 deletions
diff --git a/meta-fsl-ppc/recipes-kernel/linux/files/udf-CVE-2014-6410.patch b/meta-fsl-ppc/recipes-kernel/linux/files/udf-CVE-2014-6410.patch new file mode 100644 index 000000000..9086e0a16 --- /dev/null +++ b/meta-fsl-ppc/recipes-kernel/linux/files/udf-CVE-2014-6410.patch | |||
| @@ -0,0 +1,96 @@ | |||
| 1 | From 07d209bd092d023976fdb881ba6d4b30fe18aebe Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Jan Kara <jack@suse.cz> | ||
| 3 | Date: Thu, 4 Sep 2014 14:06:55 +0200 | ||
| 4 | Subject: [PATCH] udf: Avoid infinite loop when processing indirect ICBs | ||
| 5 | |||
| 6 | commit c03aa9f6e1f938618e6db2e23afef0574efeeb65 upstream. | ||
| 7 | |||
| 8 | We did not implement any bound on number of indirect ICBs we follow when | ||
| 9 | loading inode. Thus corrupted medium could cause kernel to go into an | ||
| 10 | infinite loop, possibly causing a stack overflow. | ||
| 11 | |||
| 12 | Fix the possible stack overflow by removing recursion from | ||
| 13 | __udf_read_inode() and limit number of indirect ICBs we follow to avoid | ||
| 14 | infinite loops. | ||
| 15 | |||
| 16 | Upstream-Status: Backport | ||
| 17 | |||
| 18 | Signed-off-by: Jan Kara <jack@suse.cz> | ||
| 19 | Cc: Chuck Ebbert <cebbert.lkml@gmail.com> | ||
| 20 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||
| 21 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
| 22 | --- | ||
| 23 | fs/udf/inode.c | 35 +++++++++++++++++++++-------------- | ||
| 24 | 1 file changed, 21 insertions(+), 14 deletions(-) | ||
| 25 | |||
| 26 | diff --git a/fs/udf/inode.c b/fs/udf/inode.c | ||
| 27 | index b6d15d3..aa02328 100644 | ||
| 28 | --- a/fs/udf/inode.c | ||
| 29 | +++ b/fs/udf/inode.c | ||
| 30 | @@ -1270,13 +1270,22 @@ update_time: | ||
| 31 | return 0; | ||
| 32 | } | ||
| 33 | |||
| 34 | +/* | ||
| 35 | + * Maximum length of linked list formed by ICB hierarchy. The chosen number is | ||
| 36 | + * arbitrary - just that we hopefully don't limit any real use of rewritten | ||
| 37 | + * inode on write-once media but avoid looping for too long on corrupted media. | ||
| 38 | + */ | ||
| 39 | +#define UDF_MAX_ICB_NESTING 1024 | ||
| 40 | + | ||
| 41 | static void __udf_read_inode(struct inode *inode) | ||
| 42 | { | ||
| 43 | struct buffer_head *bh = NULL; | ||
| 44 | struct fileEntry *fe; | ||
| 45 | uint16_t ident; | ||
| 46 | struct udf_inode_info *iinfo = UDF_I(inode); | ||
| 47 | + unsigned int indirections = 0; | ||
| 48 | |||
| 49 | +reread: | ||
| 50 | /* | ||
| 51 | * Set defaults, but the inode is still incomplete! | ||
| 52 | * Note: get_new_inode() sets the following on a new inode: | ||
| 53 | @@ -1313,28 +1322,26 @@ static void __udf_read_inode(struct inode *inode) | ||
| 54 | ibh = udf_read_ptagged(inode->i_sb, &iinfo->i_location, 1, | ||
| 55 | &ident); | ||
| 56 | if (ident == TAG_IDENT_IE && ibh) { | ||
| 57 | - struct buffer_head *nbh = NULL; | ||
| 58 | struct kernel_lb_addr loc; | ||
| 59 | struct indirectEntry *ie; | ||
| 60 | |||
| 61 | ie = (struct indirectEntry *)ibh->b_data; | ||
| 62 | loc = lelb_to_cpu(ie->indirectICB.extLocation); | ||
| 63 | |||
| 64 | - if (ie->indirectICB.extLength && | ||
| 65 | - (nbh = udf_read_ptagged(inode->i_sb, &loc, 0, | ||
| 66 | - &ident))) { | ||
| 67 | - if (ident == TAG_IDENT_FE || | ||
| 68 | - ident == TAG_IDENT_EFE) { | ||
| 69 | - memcpy(&iinfo->i_location, | ||
| 70 | - &loc, | ||
| 71 | - sizeof(struct kernel_lb_addr)); | ||
| 72 | - brelse(bh); | ||
| 73 | - brelse(ibh); | ||
| 74 | - brelse(nbh); | ||
| 75 | - __udf_read_inode(inode); | ||
| 76 | + if (ie->indirectICB.extLength) { | ||
| 77 | + brelse(bh); | ||
| 78 | + brelse(ibh); | ||
| 79 | + memcpy(&iinfo->i_location, &loc, | ||
| 80 | + sizeof(struct kernel_lb_addr)); | ||
| 81 | + if (++indirections > UDF_MAX_ICB_NESTING) { | ||
| 82 | + udf_err(inode->i_sb, | ||
| 83 | + "too many ICBs in ICB hierarchy" | ||
| 84 | + " (max %d supported)\n", | ||
| 85 | + UDF_MAX_ICB_NESTING); | ||
| 86 | + make_bad_inode(inode); | ||
| 87 | return; | ||
| 88 | } | ||
| 89 | - brelse(nbh); | ||
| 90 | + goto reread; | ||
| 91 | } | ||
| 92 | } | ||
| 93 | brelse(ibh); | ||
| 94 | -- | ||
| 95 | 1.9.1 | ||
| 96 | |||
diff --git a/meta-fsl-ppc/recipes-kernel/linux/linux-qoriq_3.12.bb b/meta-fsl-ppc/recipes-kernel/linux/linux-qoriq_3.12.bb index 12fa2a6a6..48a67c0d9 100644 --- a/meta-fsl-ppc/recipes-kernel/linux/linux-qoriq_3.12.bb +++ b/meta-fsl-ppc/recipes-kernel/linux/linux-qoriq_3.12.bb | |||
| @@ -11,6 +11,7 @@ SRC_URI = "git://git.freescale.com/ppc/sdk/linux.git;nobranch=1 \ | |||
| 11 | file://0003-mnt-CVE-2014-5206_CVE-2014-5207.patch \ | 11 | file://0003-mnt-CVE-2014-5206_CVE-2014-5207.patch \ |
| 12 | file://0004-mnt-CVE-2014-5206_CVE-2014-5207.patch \ | 12 | file://0004-mnt-CVE-2014-5206_CVE-2014-5207.patch \ |
| 13 | file://0005-mnt-CVE-2014-5206_CVE-2014-5207.patch \ | 13 | file://0005-mnt-CVE-2014-5206_CVE-2014-5207.patch \ |
| 14 | file://udf-CVE-2014-6410.patch \ | ||
| 14 | " | 15 | " |
| 15 | SRCREV = "6619b8b55796cdf0cec04b66a71288edd3057229" | 16 | SRCREV = "6619b8b55796cdf0cec04b66a71288edd3057229" |
| 16 | 17 | ||
