hc
2024-05-10 ee930fffee469d076998274a2ca55e13dc1efb67
kernel/fs/jfs/jfs_dmap.c
....@@ -1,20 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Copyright (C) International Business Machines Corp., 2000-2004
34 * Portions Copyright (C) Tino Reichardt, 2012
4
- *
5
- * This program is free software; you can redistribute it and/or modify
6
- * it under the terms of the GNU General Public License as published by
7
- * the Free Software Foundation; either version 2 of the License, or
8
- * (at your option) any later version.
9
- *
10
- * This program is distributed in the hope that it will be useful,
11
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13
- * the GNU General Public License for more details.
14
- *
15
- * You should have received a copy of the GNU General Public License
16
- * along with this program; if not, write to the Free Software
17
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
185 */
196
207 #include <linux/fs.h>
....@@ -161,13 +148,14 @@
161148 * 0 - success
162149 * -ENOMEM - insufficient memory
163150 * -EIO - i/o error
151
+ * -EINVAL - wrong bmap data
164152 */
165153 int dbMount(struct inode *ipbmap)
166154 {
167155 struct bmap *bmp;
168156 struct dbmap_disk *dbmp_le;
169157 struct metapage *mp;
170
- int i;
158
+ int i, err;
171159
172160 /*
173161 * allocate/initialize the in-memory bmap descriptor
....@@ -182,16 +170,27 @@
182170 BMAPBLKNO << JFS_SBI(ipbmap->i_sb)->l2nbperpage,
183171 PSIZE, 0);
184172 if (mp == NULL) {
185
- kfree(bmp);
186
- return -EIO;
173
+ err = -EIO;
174
+ goto err_kfree_bmp;
187175 }
188176
189177 /* copy the on-disk bmap descriptor to its in-memory version. */
190178 dbmp_le = (struct dbmap_disk *) mp->data;
191179 bmp->db_mapsize = le64_to_cpu(dbmp_le->dn_mapsize);
192180 bmp->db_nfree = le64_to_cpu(dbmp_le->dn_nfree);
181
+
193182 bmp->db_l2nbperpage = le32_to_cpu(dbmp_le->dn_l2nbperpage);
183
+ if (bmp->db_l2nbperpage > L2PSIZE - L2MINBLOCKSIZE) {
184
+ err = -EINVAL;
185
+ goto err_release_metapage;
186
+ }
187
+
194188 bmp->db_numag = le32_to_cpu(dbmp_le->dn_numag);
189
+ if (!bmp->db_numag) {
190
+ err = -EINVAL;
191
+ goto err_release_metapage;
192
+ }
193
+
195194 bmp->db_maxlevel = le32_to_cpu(dbmp_le->dn_maxlevel);
196195 bmp->db_maxag = le32_to_cpu(dbmp_le->dn_maxag);
197196 bmp->db_agpref = le32_to_cpu(dbmp_le->dn_agpref);
....@@ -200,6 +199,17 @@
200199 bmp->db_agwidth = le32_to_cpu(dbmp_le->dn_agwidth);
201200 bmp->db_agstart = le32_to_cpu(dbmp_le->dn_agstart);
202201 bmp->db_agl2size = le32_to_cpu(dbmp_le->dn_agl2size);
202
+ if (bmp->db_agl2size > L2MAXL2SIZE - L2MAXAG ||
203
+ bmp->db_agl2size < 0) {
204
+ err = -EINVAL;
205
+ goto err_release_metapage;
206
+ }
207
+
208
+ if (((bmp->db_mapsize - 1) >> bmp->db_agl2size) > MAXAG) {
209
+ err = -EINVAL;
210
+ goto err_release_metapage;
211
+ }
212
+
203213 for (i = 0; i < MAXAG; i++)
204214 bmp->db_agfree[i] = le64_to_cpu(dbmp_le->dn_agfree[i]);
205215 bmp->db_agsize = le64_to_cpu(dbmp_le->dn_agsize);
....@@ -220,6 +230,12 @@
220230 BMAP_LOCK_INIT(bmp);
221231
222232 return (0);
233
+
234
+err_release_metapage:
235
+ release_metapage(mp);
236
+err_kfree_bmp:
237
+ kfree(bmp);
238
+ return err;
223239 }
224240
225241
....@@ -253,6 +269,7 @@
253269
254270 /* free the memory for the in-memory bmap. */
255271 kfree(bmp);
272
+ JFS_SBI(ipbmap->i_sb)->bmap = NULL;
256273
257274 return (0);
258275 }
....@@ -391,7 +408,8 @@
391408 }
392409
393410 /* write the last buffer. */
394
- write_metapage(mp);
411
+ if (mp)
412
+ write_metapage(mp);
395413
396414 IREAD_UNLOCK(ipbmap);
397415
....@@ -2009,6 +2027,9 @@
20092027 */
20102028 if (dbFindLeaf((dmtree_t *) & dp->tree, l2nb, &leafidx))
20112029 return -ENOSPC;
2030
+
2031
+ if (leafidx < 0)
2032
+ return -EIO;
20122033
20132034 /* determine the block number within the file system corresponding
20142035 * to the leaf at which free space was found.
....@@ -4040,7 +4061,6 @@
40404061 */
40414062 #define MAXL0PAGES (1 + LPERCTL)
40424063 #define MAXL1PAGES (1 + LPERCTL * MAXL0PAGES)
4043
-#define MAXL2PAGES (1 + LPERCTL * MAXL1PAGES)
40444064
40454065 /*
40464066 * convert number of map pages to the zero origin top dmapctl level