Embedded Programming and the Internet of Things

Embedded Programming and the Internet of Things

The total word count is 2502 words

Estimated reading time is about 5 minutes

There are two types of IoT devices: high-end and low-end devices. The operating systems for high-end devices are fully functional, including Windows, Linux, or Android. For example, Amazon’s Echo device uses the Android-based Fire OS, while Samsung’s smartwatches use the Linux-based Tizen. These devices can connect to power or have batteries that are charged regularly. However, low-end devices have very small memory capacities and typically have a fixed lifespan with minimal energy that cannot be recharged. These devices use operating systems such as Contiki or even custom-designed systems specifically created for such limited low-memory/low-energy scenarios.

Embedded Programming and the Internet of Things

With the rapid growth of low-end IoT devices and the emergence of numerous companies creating these devices, many developers are facing the challenge of writing suitable small applications. Choosing the right programming language for writing embedded software is crucial for delivering high-performance and efficient devices.

“If you are writing sensors on bare metal, you are most likely using C!”

Ian Skerrett, Eclipse Foundation

On the device side, computational power is often very limited. The C/C++ programming languages are most appropriate here because they are ideal for writing code close to the hardware layer, requiring minimal computational power and allowing direct manipulation of memory. This is undoubtedly the choice for sensor and gateway hardware layer applications. However, one of the drawbacks of C/C++ is that if developers are not familiar with best practices, the syntax can quickly become messy and confusing.

A fundamental requirement for programming in C/C++ is a solid understanding of memory management. Many developers today are proficient in programming languages like Java and JavaScript, which have built-in memory handling mechanisms, essentially being “managed runtimes.” Programming in these languages allows programmers to avoid the tedious task of memory management without manually allocating and freeing memory. When programming in C/C++, you can manipulate nearly every part of the code to achieve optimal performance, but you may make countless small mistakes that often lead to longer development times due to the need for manual memory management.

C has been around since the early 1970s, and C++ emerged in the early 1980s. Both are still actively used today for a reason. They were created as compiled languages capable of providing low-level memory access, with logic that can be efficiently mapped to machine instructions. This feature, combined with minimal runtime, can support higher performance. However, one criticism is the perceived complexity. For this reason, many developers face a steeper learning curve with C and C++ compared to other newer languages.

“Because C and C++ are not memory-safe languages, attacks can exploit memory vulnerabilities in C/C++ code to gain unauthorized access.”

Liang Yuning, Jian Shi

When programming in C, writing poor-quality code can lead to strange vulnerabilities that may take weeks or months to discover, exhibiting transient and misleading behavior. They can corrupt the stack or heap, leading to eventual failures or creating vulnerabilities; failures may occur after hundreds of instructions have been executed following an incident. These are often challenges brought about by manual memory management.

Here are some common issues encountered when manual memory management is required in code:

Memory Leak (MSF)

The program has allocated heap memory but failed to release that memory. You must manually allocate and free data on the heap using malloc and free. As a programmer, you are responsible for freeing heap memory that is no longer needed.

Failure to release memory can lead to memory leaks. If the process runs for a long time, this can become problematic. It can lead to core dumps, unexpected behavior, and impact system performance. If an attacker can cause a memory leak, they can exploit issues that occur under low memory conditions or initiate a denial-of-service (DoS) attack.

Related Vulnerability – CWE-401: Missing Release of Memory after Effective Lifetime

https://cwe.mitre.org/data/definitions/401.html

Null Pointer Dereference (NPD)

It is always necessary to check pointers that point to memory returned by calloc/malloc. If that pointer is null, we should assume that memory allocation was unsuccessful and should not use that pointer for any operations. This can lead to segmentation faults or unpredictable program behavior. NPD is often caused by rarely encountered error conditions, making them difficult to find during normal testing phases.

This results in the integrity of the application being compromised, confidential data being exposed, and system availability being interrupted.

Related Vulnerability – CWE-476: NULL Pointer Dereference

https://cwe.mitre.org/data/definitions/476.html

Use After Free (UAF)

If a program attempts to access memory that has been freed, it can cause the program to crash or exhibit unexpected behavior. Use after free situations are directly related to dangling pointers.

This situation can affect integrity by corrupting valid data, cause program crashes due to corrupted data, and allow attackers to launch malicious code.

Related Vulnerability – CWE-416: Use After Free

https://cwe.mitre.org/data/definitions/416.html

There are many more issues not listed above. The industry-standard method for identifying these issues is to utilize static code analysis tools during program compilation. The static code analysis tool “Aikosi” developed by Jian Shi can address these memory issues and many more.

Embedded Programming and the Internet of Things

Many of Jian Shi’s clients develop IoT products and are acutely aware of the necessity to maintain a competitive edge to bring their products to market as quickly as possible without sacrificing quality and safety. Using Aikosi can help them identify these hard-to-find vulnerabilities “statically” rather than at runtime, as they are more difficult to fix, thus significantly reducing repair time. By delving deeper into the compiler process, we can investigate data flows and point out improper memory management. This is achieved through the use of flow-sensitive analysis, inter-function analysis, context-sensitive analysis, and object-sensitive analysis.

It is becoming increasingly difficult to find developers with the skills and techniques required to truly understand the complexities of programming in C/C++, as more and more developers focus on learning interpreted languages rather than compiled languages. Few developers prefer programming in languages closer to machine code without the added benefits of automatic memory management (e.g., garbage collection). However, the demand for C/C++ remains as critical as when they were first developed; some would even say these languages drive the world. Let us not forget that mainstream operating systems such as Windows, Linux, and MacOS are fundamentally written in C. In everyday life, C/C++ are behind various activities, such as the alarm clock that wakes you up in the morning, the dashboard display in your car that provides information, and the electronic payment system you use to buy your first cup of coffee before work.

For both novice and experienced developers, using static code analysis tools helps ensure peace of mind at every stage of software development. They assist in ensuring that your memory management is of high quality, allowing your software to maintain integrity, high performance, and security.

Click “Read the original” to learn how Aikosi helps developers identify memory management-related and hard-to-find vulnerabilities. Or, follow Jian Shi’s public account and reply “Trial” to get a product trial.

Author Bio

Embedded Programming and the Internet of Things

Tan Rahman

Marketing Manager at Jian Shi, with years of international market experience, previously worked at Huawei’s headquarters in Shenzhen, China.

Embedded Programming and the Internet of Things

Jane Yang

Marketing Assistant at Jian Shi, has been responsible for brand and product promotion in the marketing department since joining Jian Shi in 2018.

Previous Issues

Embedded Programming and the Internet of ThingsEmbedded Programming and the Internet of ThingsEmbedded Programming and the Internet of ThingsEmbedded Programming and the Internet of Things

Leave a Comment