On Utilizing Rust Programming Language for
Internet of Things
Tunç Uzlu, Ediz Şaykol
Beykent University, Department of Computer Engineering,
Ayazağa, 34396, İstanbul, Turkey
tuncuzlu9@[Link]; [Link]@[Link]
Abstract—Rust, as being a systems programming language, Rust is also the development language of Servo2 , Mozilla
offers memory safety with zero cost and without any runtime Foundations massively parallel web browsing engine, which is
penalty like high level languages while providing complete unique because of its concurrent process rendering and com-
memory safety unlike others like C, C++ or Cyclone. Todays
world is in a transition from dumb devices to smart devices that positing steps [5]. Rust is open-source and hosted on Github.
are connected to the Internet all the time. Low cost embedded Nightlies are suitable for testing new features, embedding
hardware is a key element for this kind of devices. Software needs inline assembly and feature gates (language semantics that are
to be smaller, lighter and power efficient. How one can operate not enabled by default, mostly experimental ones), which may
with such limited hardware while preserving reliability? At the be the key for communicating with helper co-processors in
end, high level designs require runtime penalties while low level
designs are known for memory unsafety and complicated design embedded Internet of Things (IoT) hardware.
paradigms. Rust is higher level than other systems program- Here, we intended to compare Rust with several program-
ming languages, has a rich standard library and compile-time ming languages based on the concepts that we extracted in
abstractions for blazingly fast execution. While being completely our literature study. Since the main idea behind using Rust
available in mobile world, Internet of Things (IoT) devices are to is programming a critical-and-safe low-level task with utiliz-
be operated by all known mobile hardware as well. To this end,
Rust, pushes limits of systems programming for two different ing high-level programming concepts, designs with miniscule
views; first, at the core of hardware, running as daemon and embedded hardware found on smart devices are a typical
talking to firmware, second, as a mobile controller software application for this purpose. The basic aim of our study is to
talking to mobile operating system. In this study, we summarize make the Rust programming language useful on collection of
some concepts, employed in Rust, in terms of embedded systems IoT devices for both practitioners and technology developers.
development to clarify the appropriateness of using Rust within
IoT world. The paper starts with presenting comparisons of Rust to
some other languages in Section II. Then, in Section III, Rust
I. I NTRODUCTION language basics and the design choices on protocol level that
make Rust suitable are mentioned. In Section IV, we discuss
Rust1 is a systems programming language that is being security issues with memory safety and the Internet access,
developed by Mozilla Foundation. Like other similar lan- and finally, Section V concludes our paper.
guages – C, C++, Cyclone or Assembly – Rust is low level,
allows raw memory managements, and has a detachable stan- II. C OMPARISON WITH OTHER L ANGUAGES
dard library [1]. Unlike comparable alternatives Rust ensures First, we provide a comparison of Rust with several pro-
compile time memory safety (even across threads) and offers gramming languages based on the concepts that we extracted
rich standard library with functional elements. Cyclone is the in our literature study. The tabular comparison in Figure 1
closest language to Rust and aimed to provide memory safety indicates that Rust performs at a great balance with zero
on top of C language by preserving language structure that red/blue cells. Columns contain several architectural software
means with little to no modification, it is possible to reuse concepts while implicitly covering safety, size, performance
existing codebase. This rationale allowed porting applications and energy consumption. Green cells indicate the best possible
from C to Cyclone so much easier [2], but at the end semantics choice for the feature. Yellows indicate that, for the attribute,
are restricted. Memory safety with high performance is the another language probably has a better perspective. Blues show
raison d’etre for Rust language even for a recent bootloader that it may be possible to practice in the specified language, but
design [3]. This is one of the main reasons that Rust enforces involves feature gates, modification of the compiler, language
compile time semantics and be a complete memory safe extensions or require an extreme skill set.
language (even across threads). Rust also prevents access to MC (compiled to machine language) and ZCA (zero cost
unallocated, uninitialized, freed memory along with pointer abstractions) are about the performance. Being able to compile
addresses beyond data boundaries; which are seemed as fun- directly to target hardware is the key for high execution speeds.
damental rules for memory safety [4]. For example, Python has to be compiled into C language
1 [Link] 2 [Link]
first in order to produce an executable. With the help of firmware level; hardware specific system code and daemon
modern build tools, it is extremely easy one to make builds for applications. That may be the operating system counterpart
production and testing builds with a common Rust codebase. in desktop computers. In complicated scenarios with pro-
The safety guarantees with Rust contain compile time checks grammable devices by the end user, Rust can be used in
with runtime additions that are only baked when it is necessary. combination with byte-coded high level languages (e.g. Pawn).
The result is C-like speeds with high level language semantics. When user scripts are loaded from a USB mass storage device
As far as limited resources on IoT hardware is concerned, this and interpreted by the ANSI-C abstract machine, Rust inter-
actually helps a lot to decrease both space and time complexity. action is imminent; thanks to zero-cost Rust foreign function
IL (intermediate language), FSL (functional standard li- interface.
brary), GN (generics) and PM (package manager) are about
convenience. Rust utilize LLVM compiler infrastructure so III. R ELATED RUST CONCEPTS
that the same back-end optimizations for C and C++ are Rust memory safety semantics are compile time checks. Run
available also for Rust. The LLVM stack is open-source time support when it is not possible to enforce otherwise, e.g.
and has wide platform support. Most IoT applications share bounds checking or I/O. Rust’s nature of being decoupled from
common design methodologies. Rust generics allows reusable operating system core is significant improvement when it is
designs. With rich and high level elements from the standard compared with other systems languages. One example with
library, functional elements like higher order functions or lazy C language is one can not disable signed integer overflow
iterators are ready to use. Cargo, Rusts package manager, optimizations when IBM XL or Intel C compiler is used [6].
builds and tests Rust applications for multiple targets natively.
Strict version tagging of dependent resources, scriptability A. Ownership
through rs (filename extension of Rust code files) recipes and Rust ownership semantics are similar to Singularity oper-
document generation shows us Cargo is capable enough for ating systems resource management model. Singularity ex-
multi-platform oriented purposes. Cargo also compiles tools change heap operates on interprocess communication on
from other sources, accomplishing to have a rich environment. memory, is not garbage collected, reference counted, divides
IO (interoperable with de-facto systems languages), PA memory regions into chunks called region, creates a handle
(platform agnosticity), NOS (operable in no-OS environment) struct called allocation for read-only memory sharing [7]. Here
and RMM (raw memory management) are about accessibility. idea of having a unique ownership of data is similar to Rust
Rust provides zero-cost and unsafe foreign function interface, ownership model and read-only sharing is very similar to
making almost every resource from C language on hand. Rust’s immutable borrowing. Rust RC and Weak reference
Cross compiled toolchains target most Linux distributions counting primitives are also similar. Besides Rust also allows
(other major operating systems are also supported). Rusts lacks mutable borrowing (as long as there is one mutable borrower
garbage collector at core (although there are GC packages – and there is no access of the owner) and multiple ownership
called crates) so does non-deterministic delays. C languages via RefCell with dynamic checking (runtime performance
have special standard libraries for extreme low-level purposes. penalty).
Rust has libcore for such purpose. By sacrificing the actual
standard library, one can operate on device drivers or when B. Unsafe Rust
there is no operating system exists. With unsafe Rust, complex Unsafe is the key for situations where application takes
systems magics are easy; volatile memory regions, memory control of Rust safety mechanisms. In such occasion, one may
fence, unpadded data structures and so on. workaround Rust’s ownership and borrowing models; aliasing
TS (type safety), SMM (safe memory model) and SBT data by having two or more owners is possible. Mutating
(safety between threads) are about preventing memory cor- immutable data and casting to/from raw pointers is also
ruption and stability. Rust assures bindings on data has a possible. Unsafe Rust is more like designing in C language.
unique owner with immutable borrows or only one mutable Rust foreign function interface is build upon unsafety and
borrow. This simple ownership model is the foundation of making binding modules possible. Such modules are Rust’s
memory safety in Rust even between threads. One of a kind way to build safe abstractions over foreign function interface,
safe inter-thread communication (with the help of special low level memory operations, interactions with hardware and
Marker Traits), read-write or read-only locking of bindings operating system so they include collection of unsafe functions
(not the code itself), compile-time static type checking and dy- (unsafe fn; entire function is unsafe and are also unsafe to call).
namic ownership/mutability checks with Cell/RefCell/RefMut
synchronization primitives at runtime constructs a bucket of C. Protocols
credibility. For instance, C++ is also a type-safe language, but Extensible Messaging and Presence Protocol (XMPP) and
implicit conversions between types weakens its type system a Message Queuing Telemetry Transport (MQTT) are suitable
lot. protocols for IoT service designs. Even though XMPP protocol
With embedded IoT applications, line between the firmware, – formerly named as Jabber – is designed as messaging proto-
kernel and the high level daemons are sometimes blurry. Most col, its lightweight and text-based design makes it suitable for
devices benefit from Linux kernel and Rust is located at IoT applications. Facebook utilizes MQTT in their Messenger
Fig. 1. Rust compared to other programming languages. MC=compiled to machine architecture, IL=intermediate language, FSL=functional standard library,
IO=interoperable with de-facto systems languages, GN=generics, SBT=safety between threads, SMM=safe memory model, PM=package manager, TS=thread
safety, PA=platform agnosticity, NOS=operable in no-OS environment, ZCA=zero cost abstractions, RMM=raw memory management (e.g. volatile or memory
fence).
service; MQTT is actually designed for sending telemetry data When the back-end engine is loaded from a module that
to space probes [8]. This makes the protocol highly sensitive is written in another language than Rust, it should provide
to bandwidth and energy consumption. data pointer parameters in callbacks. This is because second
Applying XMPP with Rust applications is fairly possible. channel of Rust must be passed to the callback routines as
Rust language has strong C bindings, called foreign function an unknown data pointer. When an engine event is triggered,
interface. This makes every C codebase available for the effort. the back-end library passes this pointer back to Rust foreign
Talking to C routines is very fast as it is emulated through function wrapper and then this address is casted (this is the
zero-cost (like most Rust abstractions) function calls. This major reason for using unsafety here) back to transmitting
makes catching program errors much easier, as errors are channel end. This channel data must be hold in heap area
now encapsulated in unsafe blocks. Along with C interface, inside a Box, but under this circumstances, twice. The reason
functional Rust elements makes the language highly suitable is first boxing converts the object into a Trait Object which
for design of XML parsers and socket/event handling. is a pack of multiple pointers (actually a vtable like structure,
but may be changed in the future as this is an internal detail)
D. Hands-on Experience and then second boxing covers the Trait Object yielding a
A typical event based approach states that the design re- C compatible pointer. Every single event, sharing a mutual
quires two Rust channels (Due to Rust’s module scopes, ones channel or not, can be paired with a Rust synchronization
configuration may have multiple channel types; here we mean mechanism without using a hash table (C++ equivalent is map
mpsc :: sync :: channel type), one for main event loop and structure, not an actual hashmap).
another for foreign function interface [1]. As Rust channels
are thread-safe, memory safety is assured automatically on In order to send commands to the back-end engine, Rust
main event loop. As the second loop works across foreign closures are implemented over traits [9]. There are three
library boundaries, it is unsafe by nature. The channel type closure types; Fn (takes &self as argument and can not mutate
has handler of a tuple type (tx, rx). Front-end application the state), FnMut (takes &mut self as argument so can mutate
owns receiving channel end and transfers ownership of the the state) and the special FnOnce (takes self as argument,
transmitting channel end to the XMPP back-end that later so the ownership, and can be called only once). Traits are
exposes two handles; Context and Plug. Context denotes an interfaces much like Haskell typeclasses. In order to pass a
abstract interface to operating system IO and XML parser and closure argument to the back-end the closure should be a
Plug denotes active connection to host. As XMPP is fully move. Moving closures take ownership of its elements (content
decentralized, there should be a hosting end (or collection of of the closure) so when it is sent into another back-end thread
servers as server-to-server communication is also part of the through a Rust channel, its elements are ensured to be safe.
standard. This can be thought as a smart home environment The closure must have the ownership to transfer it to the
with numerous devices that listens for incoming connections). channel later on and the contained data can not be dropped
(Rust equivalent of throwing out of memory via Drop trait) IV. S ECURITY
if they’ve been allocated on stack; moved closure creates a Current status of SOHO network devices should be noted
copied stack. With this kind of design, it is not possible to here. More intelligent SOHO devices used in combination
pass Rust closures by value into channel as their size (as they with IoT setups means more effective firewalling and handling
are simply a lambda function with anonymized name after all) of connection states. These devices utilize Linux operating
is unknown at compile time. They are wrapped into a Box; system with similar configurations. Open source is key factor
heap allocated abstraction. This also makes static dispatching here, as this devices are responsible for firewall-ing against
effectively possible. attacks that coming from outbound internet access. Nowadays
XMPP standard includes a core specification and lots of these devices include Linux kernel version 2.6 because of
module-like features, called XEPs. There are complex XEPs possible outdated SoC chips, closed-source wireless or xDSL
that depends on other XEP specifications. This design could be drivers. This branch was released in December 2003. Most
mapped directly to Rust module system. By providing attach popular LTS version of this kernel branch, 2.6.32, was released
and detach routines, it is possible to abstract each XEP and in December 2009, has lost the maintenance status in March
by including modules into another module, it is possible to 2016.
emulate depended XEPs. Swapping modules at runtime is also As closed source chip drivers tied to a single kernel version,
possible. Even if this does not benefit from Rusts compile time it is not possible to follow future standards with these kind of
checks, low memory constraints on embedded hardware may hardware. It is sometimes possible to make simpler drivers,
force runtime-loaded modules. Similar to Extensible Firmware like xDSL, to work with radical firmwares by extracting and
Interface concept called dependency expression, each module copying closed-source binary driver files (called blobs) into
may have a dependency string which is evaluated for every a newer operating system (often the opposite happens; called
Rust XEP module and if the result is TRUE, corresponding kernel backports). However this does not provide confidence
module is dispatched. For application startup, the core module about safety or reliability of the system. This is the only way
is hard wired. This recursive operation eliminates need for for most xDSL or DOCSIS modulating hardware, at least for
parent module to have knowledge about subfeatures. now. Wireless world has much better open source support
especially devices supported by Linux kernel itself.
E. Example toolset A. Rust safety
IoT devices are integrated with other smart devices. Rust Billion dollar mistake [10], memory pointers that can be
has very rich standard library and a strong package manager, null, is just one of the memory problems with current systems
Cargo. Existing Rust codebase is much larger for mobile designs. Current paradigm with these languages is a very over-
devices than firmware foundations. For example, with the powered tool which can be very powerful if only used correctly
famous objc crate (Rust packages are called crates) allows and highly depends on skill. Lack only one of memory safety,
Rust to send messages to Objective-C runtime. This infras- type safety or thread safety is enough to introduce runtime cor-
tructure makes most Objective-C resources to be available to ruption. Memory malformation of application state caused by
integrate with Rust projects. On daemon back-end, libstrophe, undefined behaviours of the language may not be detected with
an XMPP library that runs on POSIX threads, may be a tests %99 of time and may yield extreme results, even travel in
great choice. On mobile side, for example for Apple IOS time [11], as it is undefined, but most of the time; just crashes.
operating system, XMPPFramework may be the choice as Rusts compile time ownership semantic prevents well known
it is based on Objective-C and runs on operating systems behaviours like used-after-freed descriptors or invalidation of
native threads. The frameworks logging capabilities can be iterators as unique owner of some data can only access it and
an extended interface of Rusts de-facto logging crate, log. An borrow it immutably – with other languages, similar checks
external log viewers can be connected to named pipe from are not enforced by the compiler. Manual implementations
this setup, resulting various toolsets from multiple disciplines with APIs are inconsistent and can be forgotten – [12] or
utilized in a compatible fashion. borrow it mutably, but then can not access it until borrowing
Through Rust foreign function interface, combined with is handed back. Most checks are impossible to implement
Rust standard library, core library and makes Rust com- without compiler support.
pletely safe application designs combined with low level Not only on application side, Rust is proven to be a
unsafe abstractions over operating system foundations; e.g. solid foundation for building network infrastructure. Network
Grand Central Dispatch. Linker configuration can be achieved Function Virtualization, NFV aims to replace network hard-
through creating a Cargo config file, called .cargo. This is ware, dedicated to specific networking tasks, with simulating
need for configuring the Rust compiler, Rustc, is redundant as software that runs in VMs (similar to container environments
compiler configurations are more complicated than package managed by provisioner tools). Virtual machine environment
managers. Complex resources, like macOS framework bun- is a must as memory sharing should be prohibited.
dles, requires a target triplet in .cargo file; [target.x866 4 − This approach not only increases throughput also provides
apple−[Link]−library] and two flags; -l for library simpler upgradeability and testing with the cost of operating
name and -L for library path, mimicking GCC. system virtualization overhead. A recent study study shows
safety ideas of Rust along with low level memory fine- Here, we also provide a comparison of Rust with several
tuning makes Network Function designs revisited without programming languages based on the concepts that we ex-
consolidating virtual environments [13]. tracted n our literature study. A conceptual map is presented
Rust memory safety semantics checks for every possibility to clarify the understanding of the related concepts of Rust
of memory unsafety. Unsafety of operations on sequential and hence, help the Rust programming language be useful on
memory areas, invalidation of iterators negative indexing or collection of IoT devices for both practitioners and technol-
overflowing are ensured to be non-existent. With lack of ogy developers on their critical-and-safe low-level task with
garbage collector and GC delays, results are much more utilizing high-level programming concepts.
deterministic.
R EFERENCES
B. IoT Security [1] J. A. Holm, “Mozilla’s Rust programming language
at critical stage,” [Link]
IoT devices must comply with security rules such as confi- mozillas-rust-programming-language-critical-stage, 2014.
[2] D. Grossman, G. Morrisett, T. Jim, M. Hicks, Y. Wang, and J. Cheney,
dentiality, integrity, availability, authenticity, non-repudiation; “Region-based memory management in Cyclone,” in Proceedings of the
actually rules apply for any device today. Cryptography is ACM SIGPLAN 2002 Conference on Programming Language Design
at the core of security countermeasures. This requirements and Implementation (PLDI’02), 2002, pp. 282–293.
[3] T. Uzlu and E. Saykol, “Utilizing Rust programming language for EFI-
are adopted by encryption algorithms, hash functions, digital based bootloader design,” in 2nd International Conference on Recent
signatures and key exchange algorithms [14]. Because of Trends and Applications in Computer Science and Information Technol-
always-online nature of IoT hardware and human routines ogy (RTA-CSIT’16), CEUR Workshop Proceedings Volume 1746, 2016,
pp. 100–106.
are concerned; confidentiality is very serious as most of the [4] S. Nagarakatte, M. M. K. Martin, and S. Zdancewic, “Watchdoglite:
subjected devices were not part of any network beforehand. Hardware-accelerated compiler-based pointer checking,” in Proceedings
DARPA started a program in 1999 which predicted that of Annual IEEE/ACM International Symposium on Code Generation and
Optimization (CGO’14), 2014, pp. 175–184.
systems can be built to tolerate successful attacks. However it [5] T. B. L. Jespersen, P. Munksgaard, and K. F. Larsen, “Session types for
is shown that this practice imposed more complexity and high Rust,” in Proceedings of the 11th ACM SIGPLAN Workshop on Generic
resource usage [15]. For example; asymmetric cipher keys can Programming (WGP’2015), 2015, pp. 13–22.
[6] X. Wang, H. Chen, A. Cheung, Z. Jia, N. Zeldovich, and M. F. Kaashoek,
be assigned to home gateways by the service provider of an “Undefined behavior: What happened to my code?” in Proceedings of
IoT smart home provider [16]. With requirements of security, the Asia-Pacific Workshop on Systems (APSYS’12), 2012, pp. 1–7.
these powerful devices may be the center of cryptography at [7] G. Hunt, J. Larus, M. Abadi, M. Aiken, P. Barham, M. Fhndrich,
C. Hawblitzel, O. Hodson, S. Levi, N. Murphy, B. Steensgaard,
home. It is well known that these devices are targets of denial D. Tarditi, T. Wobber, and B. Zill, “An overview of the singularity
of service or zombie attacks along with other smart devices project,” Microsoft Research, Tech. Rep. MSR-TR-2005-135, 2005.
with network access. [8] L. Zhang, “Building Facebook Messenger,” [Link]
com/notes/facebook-engineering/building-facebook-messenger/
10150259350998920, August 2011.
V. C ONCLUSION [9] A. Turon, “Abstraction without overhead: traits in Rust,” [Link]
[Link]/2015/05/11/[Link], 2015.
In this study, we summarize some concepts, employed in [10] T. Hoare, “The billion dollar mis-
Rust, in terms of embedded systems development to clarify the take,” [Link]
Null-References-The-Billion-Dollar-Mistake-Tony-Hoare, 2009.
appropriateness of using Rust within IoT world. Rust, as being [11] R. Chen, “Undefined behavior can result in time travel (among other
the most modern systems programming technology today, is things, but time travel is the funkiest),” [Link]
ready to become the main language for IoT device daemons. com/oldnewthing/20140627-00/?p=633, 2014.
[12] A. Hobden and Y. Coady, “Understanding over guesswork,” https:
Rust’s ability to run incorporated with existing codebase and //[Link]/rust-education-paper/[Link], University of Vic-
development environments is strong. toria, Department of Computer Science, 2015.
Compile time abstractions means no run time performance [13] A. Panda, S. Han, K. Jang, M. Walls, S. Ratnasamy, and S. Shenker,
“Netbricks: Taking the V out of NFV,” in 12th USENIX Symposium on
costs either from compile time safety checks or garbage Operating Systems Design and Implementation (OSDI 16), 2016, pp.
collectors. Rust indeed has some compile time checks, but 203–216.
when it is not possible otherwise. That means lower time and [14] A. Kanuparthi, R. Karri, and S. Addepalli, “Hardware and embedded
security in the context of internet of things,” in Proceedings of the 2013
space complexity in ordinary operations; preserving valuable ACM workshop on Security, Privacy & Dependability for Cyber Vehicles,
CPU cycles for more complicated algorithms, richer user 2013, pp. 61–65.
experience or lower energy consumption with miniscule IoT [15] B. G. P.E. Black, L. Badger and E. Fong, “Dramatically reducing soft-
ware vulnerabilities,” National Institute of Standards and Technology,
hardware. Tech. Rep. Interagency Report 8151, 2016.
Cross compiling Rust and its rich standard library to embed- [16] X. Li, R. Lu, X. Liang, X. Shen, J. Chen, and X. Lin, “Smart community:
ded word is possible and requires less to zero changes on Rust An internet of things application,” IEEE Communications Magazine,
vol. 49, no. 11, pp. 68–75, 2011.
itself. On the other hand Rust indeed decreases possibility of
buffer related attacks, firmware level security is still critical;
from lowest level to applications, security is a whole across
the system. Today memory unsafety causes serious problems
in terms of security and stability. Hence adaptation of Rust is
not economical or social, but rather intellectual.