]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Fix possible UDF deadlock and memory corruption (CVE-2006-4145)
authorJan Kara <jack@suse.cz>
Tue, 15 Aug 2006 11:56:26 +0000 (13:56 +0200)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 22 Aug 2006 19:04:55 +0000 (12:04 -0700)
UDF code is not really ready to handle extents larger that 1GB. This is
the easy way to forbid creating those.

Also truncation code did not count with the case when there are no
extents in the file and we are extending the file.

Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
fs/udf/super.c
fs/udf/truncate.c

index e45789fe38e8da1e69dec52c6c7c11be82cac855..73fc0d8ae8be7db6180bd37dd8398694e63d65b9 100644 (file)
@@ -1653,7 +1653,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
                iput(inode);
                goto error_out;
        }
-       sb->s_maxbytes = MAX_LFS_FILESIZE;
+       sb->s_maxbytes = 1<<30;
        return 0;
 
 error_out:
index e1b0e8cfecb4947a120c2c5eeb78848b7604fa32..0abd66ce36ea042091bd6564ff17b003257a2d24 100644 (file)
@@ -239,37 +239,51 @@ void udf_truncate_extents(struct inode * inode)
        {
                if (offset)
                {
-                       extoffset -= adsize;
-                       etype = udf_next_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 1);
-                       if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
-                       {
-                               extoffset -= adsize;
-                               elen = EXT_NOT_RECORDED_NOT_ALLOCATED | (elen + offset);
-                               udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 0);
+                       /*
+                        *  OK, there is not extent covering inode->i_size and
+                        *  no extent above inode->i_size => truncate is
+                        *  extending the file by 'offset'.
+                        */
+                       if ((!bh && extoffset == udf_file_entry_alloc_offset(inode)) ||
+                           (bh && extoffset == sizeof(struct allocExtDesc))) {
+                               /* File has no extents at all! */
+                               memset(&eloc, 0x00, sizeof(kernel_lb_addr));
+                               elen = EXT_NOT_RECORDED_NOT_ALLOCATED | offset;
+                               udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1);
                        }
-                       else if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30))
-                       {
-                               kernel_lb_addr neloc = { 0, 0 };
+                       else {
                                extoffset -= adsize;
-                               nelen = EXT_NOT_RECORDED_NOT_ALLOCATED |
-                                       ((elen + offset + inode->i_sb->s_blocksize - 1) &
-                                       ~(inode->i_sb->s_blocksize - 1));
-                               udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1);
-                               udf_add_aext(inode, &bloc, &extoffset, eloc, (etype << 30) | elen, &bh, 1);
-                       }
-                       else
-                       {
-                               if (elen & (inode->i_sb->s_blocksize - 1))
+                               etype = udf_next_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 1);
+                               if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
+                               {
+                                       extoffset -= adsize;
+                                       elen = EXT_NOT_RECORDED_NOT_ALLOCATED | (elen + offset);
+                                       udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 0);
+                               }
+                               else if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30))
                                {
+                                       kernel_lb_addr neloc = { 0, 0 };
                                        extoffset -= adsize;
-                                       elen = EXT_RECORDED_ALLOCATED |
-                                               ((elen + inode->i_sb->s_blocksize - 1) &
+                                       nelen = EXT_NOT_RECORDED_NOT_ALLOCATED |
+                                               ((elen + offset + inode->i_sb->s_blocksize - 1) &
                                                ~(inode->i_sb->s_blocksize - 1));
-                                       udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 1);
+                                       udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1);
+                                       udf_add_aext(inode, &bloc, &extoffset, eloc, (etype << 30) | elen, &bh, 1);
+                               }
+                               else
+                               {
+                                       if (elen & (inode->i_sb->s_blocksize - 1))
+                                       {
+                                               extoffset -= adsize;
+                                               elen = EXT_RECORDED_ALLOCATED |
+                                                       ((elen + inode->i_sb->s_blocksize - 1) &
+                                                       ~(inode->i_sb->s_blocksize - 1));
+                                               udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 1);
+                                       }
+                                       memset(&eloc, 0x00, sizeof(kernel_lb_addr));
+                                       elen = EXT_NOT_RECORDED_NOT_ALLOCATED | offset;
+                                       udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1);
                                }
-                               memset(&eloc, 0x00, sizeof(kernel_lb_addr));
-                               elen = EXT_NOT_RECORDED_NOT_ALLOCATED | offset;
-                               udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1);
                        }
                }
        }