The Common Vulnerabilities and Exposures (CVE) database has recently added a new entry: CVE-2021-46934. This post will take an in-depth look at this vulnerability, focusing on its impact on the Linux kernel, specifically in the i2c compat ioctl function, and how it has been fixed. We will also provide code snippets and references to the original sources for further understanding.

Vulnerability Details

In the Linux kernel, there is a vulnerability in the i2c compat ioctl function due to incorrect validation of user data. This issue can cause warnings in the i2c_transfer() function, particularly when the user data contains zero messages. Userspace should not be able to trigger such warnings; thus, a patch has been applied to add validation checks to the compat ioctl function.

Exploit Details

An attacker could potentially exploit this vulnerability by providing invalid user data to the i2c compat ioctl function. These improper validation checks can cause issues within the kernel and ultimately result in unexpected system behavior or crashes.

Below is an example of the i2c compat ioctl code before the patch was applied

static long i2cdev_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
{
       // ...
       case I2C_RDWR:
           if (copy_from_user(&rdwr_arg, (struct i2c_rdwr_ioctl_data32 __user *)arg, sizeof(rdwr_arg)))
               return -EFAULT;
 
           msgs = memdup_user(compat_ptr(rdwr_arg.msgs), rdwr_arg.nmsgs * sizeof(struct i2c_msg));
           if (IS_ERR(msgs))
               return PTR_ERR(msgs);
       // ...
}

And here is a code snippet showing the added validation checks in the patched i2c compat ioctl function:

static long i2cdev_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
{
       // ...
       case I2C_RDWR:
           if (copy_from_user(&rdwr_arg, (struct i2c_rdwr_ioctl_data32 __user *)arg, sizeof(rdwr_arg)))
               return -EFAULT;

           if (rdwr_arg.nmsgs ==  || rdwr_arg.nmsgs > INT_MAX / sizeof(struct i2c_msg))
               return -EINVAL;
 
           msgs = memdup_user(compat_ptr(rdwr_arg.msgs), rdwr_arg.nmsgs * sizeof(struct i2c_msg));
           if (IS_ERR(msgs))
               return PTR_ERR(msgs);
       // ...
}

The modified code adds a conditional check to validate the user data in the i2c compat ioctl function. It now checks if the message count is zero or if the message count is greater than the maximum allowed value.

For further details regarding this vulnerability and patch, consult the following resources

1. CVE-2021-46934 entry in the CVE database: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-46934
2. Linux kernel commit addressing the vulnerability: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=01054559dbc8326da23e9587a1fbe3978f856bb
3. Linux kernel mailing list discussion: https://lore.kernel.org/linux-i2c/d126663fb42e50f03ef417a73fefd80b235bf.camel@perches.com/

Conclusion

The Linux kernel vulnerability CVE-2021-46934 has been patched by adding validation checks to the suspect compat ioctl function, which prevents user data warnings caused by incorrect user data. Although this vulnerability may not result in severe consequences, it's essential to be aware of these issues and apply timely patches to ensure your Linux-based systems remain secure.

Timeline

Published on: 02/27/2024 10:15:07 UTC
Last modified on: 04/10/2024 18:19:53 UTC