summaryrefslogtreecommitdiffstats
path: root/recipes-kernel/linux/files/Fix-CVE-2014-5471_CVE-2014-5472.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-kernel/linux/files/Fix-CVE-2014-5471_CVE-2014-5472.patch')
-rw-r--r--recipes-kernel/linux/files/Fix-CVE-2014-5471_CVE-2014-5472.patch212
1 files changed, 0 insertions, 212 deletions
diff --git a/recipes-kernel/linux/files/Fix-CVE-2014-5471_CVE-2014-5472.patch b/recipes-kernel/linux/files/Fix-CVE-2014-5471_CVE-2014-5472.patch
deleted file mode 100644
index 65107d6..0000000
--- a/recipes-kernel/linux/files/Fix-CVE-2014-5471_CVE-2014-5472.patch
+++ /dev/null
@@ -1,212 +0,0 @@
1From 4488e1f5ef40441c9846b1d0a29152c208a05e66 Mon Sep 17 00:00:00 2001
2From: Jan Kara <jack@suse.cz>
3Date: Sun, 17 Aug 2014 11:49:57 +0200
4Subject: [PATCH] isofs: Fix unbounded recursion when processing relocated
5 directories
6
7commit 410dd3cf4c9b36f27ed4542ee18b1af5e68645a4 upstream.
8
9We did not check relocated directory in any way when processing Rock
10Ridge 'CL' tag. Thus a corrupted isofs image can possibly have a CL
11entry pointing to another CL entry leading to possibly unbounded
12recursion in kernel code and thus stack overflow or deadlocks (if there
13is a loop created from CL entries).
14
15Fix the problem by not allowing CL entry to point to a directory entry
16with CL entry (such use makes no good sense anyway) and by checking
17whether CL entry doesn't point to itself.
18
19Upstream status: backported (from v3.12 e4ca8b780c82c04ec0)
20
21Reported-by: Chris Evans <cevans@google.com>
22Signed-off-by: Jan Kara <jack@suse.cz>
23Signed-off-by: Jiri Slaby <jslaby@suse.cz>
24Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com>
25---
26 fs/isofs/inode.c | 15 ++++++++-------
27 fs/isofs/isofs.h | 23 +++++++++++++++++++----
28 fs/isofs/rock.c | 39 ++++++++++++++++++++++++++++-----------
29 3 files changed, 55 insertions(+), 22 deletions(-)
30
31diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
32index e5d408a..2e2af97 100644
33--- a/fs/isofs/inode.c
34+++ b/fs/isofs/inode.c
35@@ -61,7 +61,7 @@ static void isofs_put_super(struct super_block *sb)
36 return;
37 }
38
39-static int isofs_read_inode(struct inode *);
40+static int isofs_read_inode(struct inode *, int relocated);
41 static int isofs_statfs (struct dentry *, struct kstatfs *);
42
43 static struct kmem_cache *isofs_inode_cachep;
44@@ -1258,7 +1258,7 @@ out_toomany:
45 goto out;
46 }
47
48-static int isofs_read_inode(struct inode *inode)
49+static int isofs_read_inode(struct inode *inode, int relocated)
50 {
51 struct super_block *sb = inode->i_sb;
52 struct isofs_sb_info *sbi = ISOFS_SB(sb);
53@@ -1403,7 +1403,7 @@ static int isofs_read_inode(struct inode *inode)
54 */
55
56 if (!high_sierra) {
57- parse_rock_ridge_inode(de, inode);
58+ parse_rock_ridge_inode(de, inode, relocated);
59 /* if we want uid/gid set, override the rock ridge setting */
60 if (sbi->s_uid_set)
61 inode->i_uid = sbi->s_uid;
62@@ -1482,9 +1482,10 @@ static int isofs_iget5_set(struct inode *ino, void *data)
63 * offset that point to the underlying meta-data for the inode. The
64 * code below is otherwise similar to the iget() code in
65 * include/linux/fs.h */
66-struct inode *isofs_iget(struct super_block *sb,
67- unsigned long block,
68- unsigned long offset)
69+struct inode *__isofs_iget(struct super_block *sb,
70+ unsigned long block,
71+ unsigned long offset,
72+ int relocated)
73 {
74 unsigned long hashval;
75 struct inode *inode;
76@@ -1506,7 +1507,7 @@ struct inode *isofs_iget(struct super_block *sb,
77 return ERR_PTR(-ENOMEM);
78
79 if (inode->i_state & I_NEW) {
80- ret = isofs_read_inode(inode);
81+ ret = isofs_read_inode(inode, relocated);
82 if (ret < 0) {
83 iget_failed(inode);
84 inode = ERR_PTR(ret);
85diff --git a/fs/isofs/isofs.h b/fs/isofs/isofs.h
86index 9916723..0ac4c1f 100644
87--- a/fs/isofs/isofs.h
88+++ b/fs/isofs/isofs.h
89@@ -107,7 +107,7 @@ extern int iso_date(char *, int);
90
91 struct inode; /* To make gcc happy */
92
93-extern int parse_rock_ridge_inode(struct iso_directory_record *, struct inode *);
94+extern int parse_rock_ridge_inode(struct iso_directory_record *, struct inode *, int relocated);
95 extern int get_rock_ridge_filename(struct iso_directory_record *, char *, struct inode *);
96 extern int isofs_name_translate(struct iso_directory_record *, char *, struct inode *);
97
98@@ -118,9 +118,24 @@ extern struct dentry *isofs_lookup(struct inode *, struct dentry *, unsigned int
99 extern struct buffer_head *isofs_bread(struct inode *, sector_t);
100 extern int isofs_get_blocks(struct inode *, sector_t, struct buffer_head **, unsigned long);
101
102-extern struct inode *isofs_iget(struct super_block *sb,
103- unsigned long block,
104- unsigned long offset);
105+struct inode *__isofs_iget(struct super_block *sb,
106+ unsigned long block,
107+ unsigned long offset,
108+ int relocated);
109+
110+static inline struct inode *isofs_iget(struct super_block *sb,
111+ unsigned long block,
112+ unsigned long offset)
113+{
114+ return __isofs_iget(sb, block, offset, 0);
115+}
116+
117+static inline struct inode *isofs_iget_reloc(struct super_block *sb,
118+ unsigned long block,
119+ unsigned long offset)
120+{
121+ return __isofs_iget(sb, block, offset, 1);
122+}
123
124 /* Because the inode number is no longer relevant to finding the
125 * underlying meta-data for an inode, we are free to choose a more
126diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c
127index c0bf424..f488bba 100644
128--- a/fs/isofs/rock.c
129+++ b/fs/isofs/rock.c
130@@ -288,12 +288,16 @@ eio:
131 goto out;
132 }
133
134+#define RR_REGARD_XA 1
135+#define RR_RELOC_DE 2
136+
137 static int
138 parse_rock_ridge_inode_internal(struct iso_directory_record *de,
139- struct inode *inode, int regard_xa)
140+ struct inode *inode, int flags)
141 {
142 int symlink_len = 0;
143 int cnt, sig;
144+ unsigned int reloc_block;
145 struct inode *reloc;
146 struct rock_ridge *rr;
147 int rootflag;
148@@ -305,7 +309,7 @@ parse_rock_ridge_inode_internal(struct iso_directory_record *de,
149
150 init_rock_state(&rs, inode);
151 setup_rock_ridge(de, inode, &rs);
152- if (regard_xa) {
153+ if (flags & RR_REGARD_XA) {
154 rs.chr += 14;
155 rs.len -= 14;
156 if (rs.len < 0)
157@@ -485,12 +489,22 @@ repeat:
158 "relocated directory\n");
159 goto out;
160 case SIG('C', 'L'):
161- ISOFS_I(inode)->i_first_extent =
162- isonum_733(rr->u.CL.location);
163- reloc =
164- isofs_iget(inode->i_sb,
165- ISOFS_I(inode)->i_first_extent,
166- 0);
167+ if (flags & RR_RELOC_DE) {
168+ printk(KERN_ERR
169+ "ISOFS: Recursive directory relocation "
170+ "is not supported\n");
171+ goto eio;
172+ }
173+ reloc_block = isonum_733(rr->u.CL.location);
174+ if (reloc_block == ISOFS_I(inode)->i_iget5_block &&
175+ ISOFS_I(inode)->i_iget5_offset == 0) {
176+ printk(KERN_ERR
177+ "ISOFS: Directory relocation points to "
178+ "itself\n");
179+ goto eio;
180+ }
181+ ISOFS_I(inode)->i_first_extent = reloc_block;
182+ reloc = isofs_iget_reloc(inode->i_sb, reloc_block, 0);
183 if (IS_ERR(reloc)) {
184 ret = PTR_ERR(reloc);
185 goto out;
186@@ -637,9 +651,11 @@ static char *get_symlink_chunk(char *rpnt, struct rock_ridge *rr, char *plimit)
187 return rpnt;
188 }
189
190-int parse_rock_ridge_inode(struct iso_directory_record *de, struct inode *inode)
191+int parse_rock_ridge_inode(struct iso_directory_record *de, struct inode *inode,
192+ int relocated)
193 {
194- int result = parse_rock_ridge_inode_internal(de, inode, 0);
195+ int flags = relocated ? RR_RELOC_DE : 0;
196+ int result = parse_rock_ridge_inode_internal(de, inode, flags);
197
198 /*
199 * if rockridge flag was reset and we didn't look for attributes
200@@ -647,7 +663,8 @@ int parse_rock_ridge_inode(struct iso_directory_record *de, struct inode *inode)
201 */
202 if ((ISOFS_SB(inode->i_sb)->s_rock_offset == -1)
203 && (ISOFS_SB(inode->i_sb)->s_rock == 2)) {
204- result = parse_rock_ridge_inode_internal(de, inode, 14);
205+ result = parse_rock_ridge_inode_internal(de, inode,
206+ flags | RR_REGARD_XA);
207 }
208 return result;
209 }
210--
2111.9.1
212