xorl %eax, %eax

CVE-2008-4933: HFS+ Local Buffer Overflow

leave a comment »

On November 4 2008, the well known Linux kernel developer Greg KH. published a patch for a vulnerability initially found by Eric Sesterhenn. HFS+ (Hierarchical File System Plus) is a filesystem developed by Apple Inc. which is commonly referred as Mac OS Extended. In Linux this filesystem provides compatibility with Apple images.

According to the patch the vulnerability is located at the hfsplus_find_cat() function of fs/hfsplus/catalog.c file. The following code snippets are from Linux kernel 2.6.27.1
This function is used to retrieve a catalog entry for a given catalog id.

153 int hfsplus_find_cat(struct super_block *sb, u32 cnid,
154                     struct hfs_find_data *fd)
155 {
156         hfsplus_cat_entry tmp;
157         int err;
158         u16 type;
159
160         hfsplus_cat_build_key(sb, fd->search_key, cnid, NULL);
161         err = hfs_brec_read(fd, &tmp, sizeof(hfsplus_cat_entry));
162         if (err)
163                 return err;
164

At line 160 the function retrieves the search key for the requested catalog ID (cnid). Following, at line 161, the call to hfs_brec_read() finds and stores the requsted entry to tmp.

165         type = be16_to_cpu(tmp.type);
166         if (type != HFSPLUS_FOLDER_THREAD && type != HFSPLUS_FILE_THREAD) {
167                 printk(KERN_ERR "hfs: found bad thread record in catalog\n");
168                 return -EIO;
169         }
170

This is a simple check that the catalog has a regular thread record and at last:

171         hfsplus_cat_build_key_uni(fd->search_key, be32_to_cpu(tmp.thread.parentID),
172                                  &tmp.thread.nodeName);
173         return hfs_brec_find(fd);
174 }

The call at line 171 is used to copy the tmp node name to the fd->search_key and perform the final call to hfs_brec_find() with this request as argument. The copy of this node name is performed on hfsplus_cat_build_key_uni() like this:

57 static void hfsplus_cat_build_key_uni(hfsplus_btree_key *key, u32 parent,
58                                       struct hfsplus_unistr *name)
59 {
60         int ustrlen;
61
62         ustrlen = be16_to_cpu(name->length);
63         key->cat.parent = cpu_to_be32(parent);
64         key->cat.name.length = cpu_to_be16(ustrlen);

The length of the user controlled node name is stored at ustrlen integer. Next, the tmp ID is copied to the corresponding element of the btree key structure as well as the node
name length. The next snippet is the most interesting.

65         ustrlen *= 2;
66         memcpy(key->cat.name.unicode, name->unicode, ustrlen);
67         key->key_len = cpu_to_be16(6 + ustrlen);
68 }

The length is multiplied by two and then the user controlled name is copied to the fixed size buffer which is 255 bytes. If a corrupted image is loaded, with a catalog node name larger than 255 then memory corruption occurs since no bound check is being performed.

Written by xorl

January 2, 2009 at 22:21

Posted in bugs, linux

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s