In the Linux kernel, a crucial vulnerability (CVE-2021-46968) has been resolved in the s390/zcrypt subsystem. The problem was identified as a memory leak that occurs during the hot-unplug process of zcard and zqueue structures. In this article, we'll discuss the details of this vulnerability, provide a code snippet that fixes the issue, and include the original references for further information.

Exploit details

When using a KVM and a kernel with kmemdebug, it was discovered that zcard and zqueue structures for the unplugged card or queue aren't properly freed due to the improper handling of kref counter values in the get/put operations. Consequently, memory leaks occur during the hot-unplug process.

The fix resolves this issue by properly managing the kref counter values during the initialization and unregistering processes. Specifically, the kref counter should be initialized with a value of 1, and upon unregistering the card or queue, the value should be reduced to zero. This change successfully triggers the release and frees the object, preventing the memory leak.

Here's the relevant code snippet from the kernel source that addresses the vulnerability

void zcard_put(struct zcard *zc)
{
	kref_put(&zc->refcount, zcard_release);
}

static void zcard_release(struct kref *kref)
{
	struct zcard *zc = container_of(kref, struct zcard, refcount);
...
}

This code ensures the correct handling of the kref counter via the zcard_put() and zcard_release() functions. By using kref_put() and kref_release(), the kernel effectively maintains the correct kref counter values and ultimately resolves the memory leak issue during hot-unplug.

Here are some helpful references for further information on this issue

1. Official Linux kernel mailing list announcement about the fix
2. Linux kernel Git commit incorporating the fix
3. National Vulnerability Database (NVD) page on CVE-2021-46968

Conclusion

In summary, CVE-2021-46968 was a memory leak vulnerability in the Linux kernel's s390/zcrypt subsystem. Due to improper management of kref counter values, zcard and zqueue structures weren't properly freed during the hot-unplug process. The fix for this issue involved adjusting kref counter value handling. The kernel now initializes the counter with a value of 1 and reduces it to zero when unregistering the card or queue, successfully releasing and freeing the object to prevent memory leaks.

Timeline

Published on: 02/27/2024 19:04:07 UTC
Last modified on: 02/28/2024 14:06:45 UTC