Commit a1d47b262952a45aae62bd49cfaf33dd76c11a2c

Authored by Jan Kara
1 parent e159332b9a

udf: Verify symlink size before loading it

UDF specification allows arbitrarily large symlinks. However we support
only symlinks at most one block large. Check the length of the symlink
so that we don't access memory beyond end of the symlink block.

CC: stable@vger.kernel.org
Reported-by: Carl Henrik Lunde <chlunde@gmail.com>
Signed-off-by: Jan Kara <jack@suse.cz>

Showing 1 changed file with 13 additions and 4 deletions Side-by-side Diff

... ... @@ -80,11 +80,17 @@
80 80 struct inode *inode = page->mapping->host;
81 81 struct buffer_head *bh = NULL;
82 82 unsigned char *symlink;
83   - int err = -EIO;
  83 + int err;
84 84 unsigned char *p = kmap(page);
85 85 struct udf_inode_info *iinfo;
86 86 uint32_t pos;
87 87  
  88 + /* We don't support symlinks longer than one block */
  89 + if (inode->i_size > inode->i_sb->s_blocksize) {
  90 + err = -ENAMETOOLONG;
  91 + goto out_unmap;
  92 + }
  93 +
88 94 iinfo = UDF_I(inode);
89 95 pos = udf_block_map(inode, 0);
90 96  
... ... @@ -94,8 +100,10 @@
94 100 } else {
95 101 bh = sb_bread(inode->i_sb, pos);
96 102  
97   - if (!bh)
98   - goto out;
  103 + if (!bh) {
  104 + err = -EIO;
  105 + goto out_unlock_inode;
  106 + }
99 107  
100 108 symlink = bh->b_data;
101 109 }
102 110  
... ... @@ -109,9 +117,10 @@
109 117 unlock_page(page);
110 118 return 0;
111 119  
112   -out:
  120 +out_unlock_inode:
113 121 up_read(&iinfo->i_data_sem);
114 122 SetPageError(page);
  123 +out_unmap:
115 124 kunmap(page);
116 125 unlock_page(page);
117 126 return err;