blob: 23aaa64725b8ab2c132ece4d1b42c4285267f986 [file] [log] [blame]
{
"containers": {
"cna": {
"providerMetadata": {
"orgId": "f4215fc3-5b6b-47ff-a258-f7189bd81038"
},
"descriptions": [
{
"lang": "en",
"value": "In the Linux kernel, the following vulnerability has been resolved:\n\neventfs: Do not create dentries nor inodes in iterate_shared\n\nThe original eventfs code added a wrapper around the dcache_readdir open\ncallback and created all the dentries and inodes at open, and increment\ntheir ref count. A wrapper was added around the dcache_readdir release\nfunction to decrement all the ref counts of those created inodes and\ndentries. But this proved to be buggy[1] for when a kprobe was created\nduring a dir read, it would create a dentry between the open and the\nrelease, and because the release would decrement all ref counts of all\nfiles and directories, that would include the kprobe directory that was\nnot there to have its ref count incremented in open. This would cause the\nref count to go to negative and later crash the kernel.\n\nTo solve this, the dentries and inodes that were created and had their ref\ncount upped in open needed to be saved. That list needed to be passed from\nthe open to the release, so that the release would only decrement the ref\ncounts of the entries that were incremented in the open.\n\nUnfortunately, the dcache_readdir logic was already using the\nfile->private_data, which is the only field that can be used to pass\ninformation from the open to the release. What was done was the eventfs\ncreated another descriptor that had a void pointer to save the\ndcache_readdir pointer, and it wrapped all the callbacks, so that it could\nsave the list of entries that had their ref counts incremented in the\nopen, and pass it to the release. The wrapped callbacks would just put\nback the dcache_readdir pointer and call the functions it used so it could\nstill use its data[2].\n\nBut Linus had an issue with the \"hijacking\" of the file->private_data\n(unfortunately this discussion was on a security list, so no public link).\nWhich we finally agreed on doing everything within the iterate_shared\ncallback and leave the dcache_readdir out of it[3]. All the information\nneeded for the getents() could be created then.\n\nBut this ended up being buggy too[4]. The iterate_shared callback was not\nthe right place to create the dentries and inodes. Even Christian Brauner\nhad issues with that[5].\n\nAn attempt was to go back to creating the inodes and dentries at\nthe open, create an array to store the information in the\nfile->private_data, and pass that information to the other callbacks.[6]\n\nThe difference between that and the original method, is that it does not\nuse dcache_readdir. It also does not up the ref counts of the dentries and\npass them. Instead, it creates an array of a structure that saves the\ndentry's name and inode number. That information is used in the\niterate_shared callback, and the array is freed in the dir release. The\ndentries and inodes created in the open are not used for the iterate_share\nor release callbacks. Just their names and inode numbers.\n\nLinus did not like that either[7] and just wanted to remove the dentries\nbeing created in iterate_shared and use the hard coded inode numbers.\n\n[ All this while Linus enjoyed an unexpected vacation during the merge\n window due to lack of power. ]\n\n[1] https://lore.kernel.org/linux-trace-kernel/20230919211804.230edf1e@gandalf.local.home/\n[2] https://lore.kernel.org/linux-trace-kernel/20230922163446.1431d4fa@gandalf.local.home/\n[3] https://lore.kernel.org/linux-trace-kernel/20240104015435.682218477@goodmis.org/\n[4] https://lore.kernel.org/all/202401152142.bfc28861-oliver.sang@intel.com/\n[5] https://lore.kernel.org/all/20240111-unzahl-gefegt-433acb8a841d@brauner/\n[6] https://lore.kernel.org/all/20240116114711.7e8637be@gandalf.local.home/\n[7] https://lore.kernel.org/all/20240116170154.5bf0a250@gandalf.local.home/"
}
],
"affected": [
{
"product": "Linux",
"vendor": "Linux",
"defaultStatus": "unaffected",
"repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git"
},
{
"product": "Linux",
"vendor": "Linux",
"defaultStatus": "unaffected",
"repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git"
}
],
"title": "eventfs: Do not create dentries nor inodes in iterate_shared",
"x_generator": {
"engine": "bippy-d3b290d2becc"
}
}
},
"cveMetadata": {
"assignerOrgId": "f4215fc3-5b6b-47ff-a258-f7189bd81038",
"cveID": "CVE-2024-26701",
"requesterUserId": "gregkh@kernel.org",
"serial": "1",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.0"
}