Serious security: Linux kernel bugs surfaced 15 years later

On March 12, GRIMM cybersecurity researchers released information on three interesting bugs in the Linux kernel. In code that has been ignored for about 15 years. Fortunately, no one seems to have been looking closely at the code all this time; at least not so hard as to spot mistakes. The CVEs listed below have already been fixed.


  • CVE-2021-27365. Heap buffer overflow due to sprintf ().

  • CVE-2021-27363. Kernel address leaked due to pointer as unique ID.

  • CVE-2021-27364. Reading memory out of bounds, leading to data leakage or kernel panic.

The bugs found affect iSCSI: the component responsible for the venerable SCSI data interface in the sense of a network: through it you can communicate with a SCSI device such as a tape or disk drive that is not directly connected to the computer.

If iSCSI and SCSI are no longer on your network, you are probably shrugging your shoulders and thinking, “Don’t worry, I don’t have a single iSCSI driver in my kernel: I just don’t use them.”

After all, kernel code with vulnerabilities cannot be exploited when it just lies on disk – before this code becomes a problem, it must be loaded into memory and actively operate on the system.

Except, of course, that most (or at least many) Linux systems come with hundreds or even thousands of kernel modules in a folder lib/modules; they are ready to use when needed, and even configured so that authorized applications can trigger module loading on demand.

Note: To the best of our knowledge, these bugs have been fixed in the following officially supported Linux kernels dated March 7, 2021: 5.11.4, 5.10.21, 5.4.103, 4.19.179, 4.1.4.224, 4.9.260, 4.4.260. If your kernel has been modified by the vendor, is unofficial, or is not on this list, consult your kernel developer. To check your kernel version, run uname -r in terminal

My Linux came with about 4500 kernel modules just in case:

   root@slack:/lib/modules/5.10.23# find . -name '*.ko'
   ./kernel/arch/x86/crypto/aegis128-aesni.ko
   ./kernel/arch/x86/crypto/blake2s-x86_64.ko
   ./kernel/arch/x86/crypto/blowfish-x86_64.ko
   [...4472 lines deleted...]
   ./kernel/sound/usb/usx2y/snd-usb-usx2y.ko
   ./kernel/sound/x86/snd-hdmi-lpe-audio.ko
   ./kernel/virt/lib/irqbypass.ko  
   #

And while I really wouldn’t mind the cool Tascam Ux2y sound card (e.g. US122, US224, US428), I don’t have a need or space for it, so I doubt I’ll ever need any driver. snd-usb-usx2y.ko

However, there are unnecessary drivers, and, accidentally or intentionally, some may be loaded automatically, depending on the software used for the occasion, even if I’m not under the root.

Nice to look twice

The risk from unhelpful and in most cases overlooked drivers caused GRIMM to look twice for bugs. Researchers have found software that can be used by an unprivileged attacker to activate buggy driver code and achieve the following results:

  • Escalation of privileges, that is, they gave the common user kernel-level privileges.

  • Retrieving kernel memory addressesto facilitate other attacks that involve knowing where the kernel is booted to.

  • Kernel crash, and hence the entire system.

  • Reading chunks of data from kernel memorywhen they are supposed to be out of reach.

As vague and limited as the latest exploit is, it looks like an unprivileged user could accidentally spy on the actual data transmitted via iSCSI. In theory, this means that an attacker with an unprivileged account on the server where iSCSI was used could run an innocent program in the background that compromises privileged data randomly selected in memory.

Even a fragmented and unstructured stream of sensitive data, periodically stolen from a privileged process (remember the infamous error Heartbleed?) can reveal our secrets. Don’t forget how easy it is for the program to recognize and “scrape” data patterns flying into RAM: credit card numbers, e-mail addresses.

Let’s take a closer look at the bugs

It was mentioned above that the first error is caused by applying sprintf()… This is a C function, short for formatted print into string – formatted print to stringso the text message is printed into a memory block for later use. Let’s take a look at this code:

   char buf[64];      /* Reserve a 64-byte block of bytes           */
   char *str = "42";  /* Actually has 3 bytes, thus: '4'  '2'  NUL  */
                      /* Trailing zero auto-added:   0x34 0x32 0x00 */
   sprintf(buf,"Answer is %s",str)

It reserves a block of memory buf containing 12 characters “Answer is 42” followed by an ASCII NUL terminal null byte, and 51 untouched bytes at the end of the 64-byte buffer.

but sprintf() is dangerous and should never be used: it does not check if there is enough space for the printed data in the final block of memory. Above if string in variable str is longer than 54 bytes, including a zero byte at the end, then together with the text “Answer is” it will not fit into buf ..

Worse when text data str do not have a null byte at the end: in C it is a stop sign for copying a string, that is, you could accidentally copy thousands or even millions of bytes of memory after str and copy them until a zero byte is encountered, by which time the kernel will almost certainly crash.

Modern code should not contain C functions that operate on copies of memory of unlimited length. Use snprintf(): this is formatted string, maximum N bytesand also work with family functions snprintf()

Don’t give out your addresses

The second error occurred due to the use of memory addresses as unique identifiers.

The idea sounds good: if you need to designate a data object with an ID in the kernel code without conflicts with other IDs, you can use the numbers 1, 2, 3, and so on.

But if you want a unique identifier that does not conflict with other numbered objects in the kernel, then you might think, “Why not use the memory address where my object is stored: it is obviously unique, given that two objects cannot be simultaneously located in one place in RAM? ” (unless a crisis has already occurred with the use of memory).

The problem is that if your object identifier is at some point visible outside the kernel, for example, so that unauthorized programs can refer to it in the so-called user space, it turns out that you just give out information about the internal memory location of the kernel, and this happens shouldn’t.

Modern kernels use the so-called KASLR, short for kernel address space layout randomization (kernel address space randomization), specifically to prevent unprivileged users from figuring out the kernel structure.

If you’ve ever picked locks (it’s a popular, surprisingly relaxing hobby among hackers and cybersecurity researchers: you can just buy a transparent lock and have fun), you’ll find that things get easier when you already know the mechanism of the lock.

Likewise, knowing what is loaded and where inside the kernel almost always makes it easier to exploit other bugs, such as buffer overflows.

What to do?

  • Upgrade your kernel. If you rely on a kernel developer, be sure to install the latest update. Above, see the kernel versions in which the listed vulnerabilities are fixed.

  • Don’t use problematic C functions. Avoid all functions that do not track the maximum amount of data used. In the operating system or IDE of your choice, stick to the functions officially documented as “safe C string functions”, and work with safe functions wherever possible. This approach is more likely to prevent buffer overflows.

  • To avoid surprises, block the loading of kernel modules. If you set the Linux system variable kernel.modules_disable=1 after your server has loaded and started working correctly, no modules will be loaded; neither by accident nor by design. This setting is disabled only on reboot. Here are two options:

    sysctl -w kernel.modules_disable=1
    
    echo 1 > /proc/sys/kernel/modules_disable
  • Understand which kernel modules are needed and only use them. You can build a static kernel by compiling only the modules you need, or create a kernel package for your servers, while removing all unnecessary modules. If desired, with a static kernel, module loading can be disabled completely.

On our comprehensive course Ethical hacker we teach students to look for vulnerabilities and maintain the security of any IT systems. If you feel strong and inclined towards cybersecurity, come and learn. It will be difficult, but interesting!

find outhow to upgrade in other specialties or master them from scratch:

Other professions and courses

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *