aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorCyrill Gorcunov <gorcunov@gmail.com>2007-07-16 02:39:47 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-16 12:05:41 -0400
commit647bd61a5f3a51a38c670f91af9d861ad66149a3 (patch)
treeacadac2740f3a482c6f3472fd0b0e62d158c5df4 /fs
parent9c1729db3e6d738f872bcb090212af00473bf666 (diff)
UDF: check for allocated memory for inode data
This patch adds checking for granted memory while filling up inode data to prevent possible NULL pointer usage. If there is not enough memory to fill inode data we just mark it as "bad". Also some whitespace cleanup. Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com> Cc: Jan Kara <jack@ucw.cz> Cc: Christoph Hellwig <hch@lst.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/udf/inode.c51
1 files changed, 39 insertions, 12 deletions
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index bf7de0bdbab3..5b82e489af78 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -49,6 +49,7 @@ MODULE_LICENSE("GPL");
49static mode_t udf_convert_permissions(struct fileEntry *); 49static mode_t udf_convert_permissions(struct fileEntry *);
50static int udf_update_inode(struct inode *, int); 50static int udf_update_inode(struct inode *, int);
51static void udf_fill_inode(struct inode *, struct buffer_head *); 51static void udf_fill_inode(struct inode *, struct buffer_head *);
52static int udf_alloc_i_data(struct inode *inode, size_t size);
52static struct buffer_head *inode_getblk(struct inode *, sector_t, int *, 53static struct buffer_head *inode_getblk(struct inode *, sector_t, int *,
53 long *, int *); 54 long *, int *);
54static int8_t udf_insert_aext(struct inode *, struct extent_position, 55static int8_t udf_insert_aext(struct inode *, struct extent_position,
@@ -734,7 +735,7 @@ static void udf_split_extents(struct inode *inode, int *c, int offset, int newbl
734 (*c) ++; 735 (*c) ++;
735 (*endnum) ++; 736 (*endnum) ++;
736 } 737 }
737 738
738 laarr[curr].extLocation.logicalBlockNum = newblocknum; 739 laarr[curr].extLocation.logicalBlockNum = newblocknum;
739 if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) 740 if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
740 laarr[curr].extLocation.partitionReferenceNum = 741 laarr[curr].extLocation.partitionReferenceNum =
@@ -836,7 +837,7 @@ static void udf_prealloc_extents(struct inode *inode, int c, int lastblock,
836 { 837 {
837 numalloc -= elen; 838 numalloc -= elen;
838 if (*endnum > (i+1)) 839 if (*endnum > (i+1))
839 memmove(&laarr[i], &laarr[i+1], 840 memmove(&laarr[i], &laarr[i+1],
840 sizeof(long_ad) * (*endnum - (i+1))); 841 sizeof(long_ad) * (*endnum - (i+1)));
841 i --; 842 i --;
842 (*endnum) --; 843 (*endnum) --;
@@ -1024,7 +1025,7 @@ void udf_truncate(struct inode * inode)
1024 { 1025 {
1025 block_truncate_page(inode->i_mapping, inode->i_size, udf_get_block); 1026 block_truncate_page(inode->i_mapping, inode->i_size, udf_get_block);
1026 udf_truncate_extents(inode); 1027 udf_truncate_extents(inode);
1027 } 1028 }
1028 1029
1029 inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb); 1030 inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb);
1030 if (IS_SYNC(inode)) 1031 if (IS_SYNC(inode))
@@ -1087,10 +1088,10 @@ __udf_read_inode(struct inode *inode)
1087 { 1088 {
1088 kernel_lb_addr loc; 1089 kernel_lb_addr loc;
1089 ie = (struct indirectEntry *)ibh->b_data; 1090 ie = (struct indirectEntry *)ibh->b_data;
1090 1091
1091 loc = lelb_to_cpu(ie->indirectICB.extLocation); 1092 loc = lelb_to_cpu(ie->indirectICB.extLocation);
1092 1093
1093 if (ie->indirectICB.extLength && 1094 if (ie->indirectICB.extLength &&
1094 (nbh = udf_read_ptagged(inode->i_sb, loc, 0, &ident))) 1095 (nbh = udf_read_ptagged(inode->i_sb, loc, 0, &ident)))
1095 { 1096 {
1096 if (ident == TAG_IDENT_FE || 1097 if (ident == TAG_IDENT_FE ||
@@ -1156,14 +1157,22 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
1156 { 1157 {
1157 UDF_I_EFE(inode) = 1; 1158 UDF_I_EFE(inode) = 1;
1158 UDF_I_USE(inode) = 0; 1159 UDF_I_USE(inode) = 0;
1159 UDF_I_DATA(inode) = kmalloc(inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry), GFP_KERNEL); 1160 if (udf_alloc_i_data(inode, inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry)))
1161 {
1162 make_bad_inode(inode);
1163 return;
1164 }
1160 memcpy(UDF_I_DATA(inode), bh->b_data + sizeof(struct extendedFileEntry), inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry)); 1165 memcpy(UDF_I_DATA(inode), bh->b_data + sizeof(struct extendedFileEntry), inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry));
1161 } 1166 }
1162 else if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_FE) 1167 else if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_FE)
1163 { 1168 {
1164 UDF_I_EFE(inode) = 0; 1169 UDF_I_EFE(inode) = 0;
1165 UDF_I_USE(inode) = 0; 1170 UDF_I_USE(inode) = 0;
1166 UDF_I_DATA(inode) = kmalloc(inode->i_sb->s_blocksize - sizeof(struct fileEntry), GFP_KERNEL); 1171 if (udf_alloc_i_data(inode, inode->i_sb->s_blocksize - sizeof(struct fileEntry)))
1172 {
1173 make_bad_inode(inode);
1174 return;
1175 }
1167 memcpy(UDF_I_DATA(inode), bh->b_data + sizeof(struct fileEntry), inode->i_sb->s_blocksize - sizeof(struct fileEntry)); 1176 memcpy(UDF_I_DATA(inode), bh->b_data + sizeof(struct fileEntry), inode->i_sb->s_blocksize - sizeof(struct fileEntry));
1168 } 1177 }
1169 else if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_USE) 1178 else if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_USE)
@@ -1173,7 +1182,11 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
1173 UDF_I_LENALLOC(inode) = 1182 UDF_I_LENALLOC(inode) =
1174 le32_to_cpu( 1183 le32_to_cpu(
1175 ((struct unallocSpaceEntry *)bh->b_data)->lengthAllocDescs); 1184 ((struct unallocSpaceEntry *)bh->b_data)->lengthAllocDescs);
1176 UDF_I_DATA(inode) = kmalloc(inode->i_sb->s_blocksize - sizeof(struct unallocSpaceEntry), GFP_KERNEL); 1185 if (udf_alloc_i_data(inode, inode->i_sb->s_blocksize - sizeof(struct unallocSpaceEntry)))
1186 {
1187 make_bad_inode(inode);
1188 return;
1189 }
1177 memcpy(UDF_I_DATA(inode), bh->b_data + sizeof(struct unallocSpaceEntry), inode->i_sb->s_blocksize - sizeof(struct unallocSpaceEntry)); 1190 memcpy(UDF_I_DATA(inode), bh->b_data + sizeof(struct unallocSpaceEntry), inode->i_sb->s_blocksize - sizeof(struct unallocSpaceEntry));
1178 return; 1191 return;
1179 } 1192 }
@@ -1191,7 +1204,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
1191 inode->i_nlink = le16_to_cpu(fe->fileLinkCount); 1204 inode->i_nlink = le16_to_cpu(fe->fileLinkCount);
1192 if (!inode->i_nlink) 1205 if (!inode->i_nlink)
1193 inode->i_nlink = 1; 1206 inode->i_nlink = 1;
1194 1207
1195 inode->i_size = le64_to_cpu(fe->informationLength); 1208 inode->i_size = le64_to_cpu(fe->informationLength);
1196 UDF_I_LENEXTENTS(inode) = inode->i_size; 1209 UDF_I_LENEXTENTS(inode) = inode->i_size;
1197 1210
@@ -1243,7 +1256,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
1243 } 1256 }
1244 else 1257 else
1245 { 1258 {
1246 inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) << 1259 inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) <<
1247 (inode->i_sb->s_blocksize_bits - 9); 1260 (inode->i_sb->s_blocksize_bits - 9);
1248 1261
1249 if ( udf_stamp_to_time(&convtime, &convtime_usec, 1262 if ( udf_stamp_to_time(&convtime, &convtime_usec,
@@ -1374,6 +1387,20 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
1374 } 1387 }
1375} 1388}
1376 1389
1390static int udf_alloc_i_data(struct inode *inode, size_t size)
1391{
1392 UDF_I_DATA(inode) = kmalloc(size, GFP_KERNEL);
1393
1394 if (!UDF_I_DATA(inode))
1395 {
1396 printk(KERN_ERR "udf:udf_alloc_i_data (ino %ld) no free memory\n",
1397 inode->i_ino);
1398 return -ENOMEM;
1399 }
1400
1401 return 0;
1402}
1403
1377static mode_t 1404static mode_t
1378udf_convert_permissions(struct fileEntry *fe) 1405udf_convert_permissions(struct fileEntry *fe)
1379{ 1406{
@@ -2072,7 +2099,7 @@ int8_t udf_delete_aext(struct inode *inode, struct extent_position epos,
2072 mark_buffer_dirty_inode(oepos.bh, inode); 2099 mark_buffer_dirty_inode(oepos.bh, inode);
2073 } 2100 }
2074 } 2101 }
2075 2102
2076 brelse(epos.bh); 2103 brelse(epos.bh);
2077 brelse(oepos.bh); 2104 brelse(oepos.bh);
2078 return (elen >> 30); 2105 return (elen >> 30);