Security of Embedded Java Virtual Machine

Security of Embedded Java Virtual Machine

This article introduces the security of embedded Java virtual machine (EJVM).

Meeting this topic, you may consider it an introduction of J2ME security mechanism. No! Although security model of MIDP 2 seems perfect, it’s only a part of security solution of embedded Java virtual machine.

picture 1: J2ME technical architecture

Picture 1 shows the technical architecture of J2ME, security solution should cover all these levels. In my opinion, I consider security of EJVM in four aspects:

MIDP 2.0 Security Mechanism

Java language

Class files verifying

Implementation of JVM

Let me introduce them respectively.

1 MIDP 2.0 Security Mechanism

MIDP (Mobile Information Device Profile) 2.0 has a complete authorization model.

1.1 Sensitive Operations

In mobile information device, some operations are very sensitive for the users. Network connection is one of them. Because the hardware resource is very limited, and data transferring is expensive.

The MIDP 2.0 specification defines a set of operations as sensitive. To perform any one of it, the application must get approval from user.

javax.microedition.io.Connector.http

javax.microedition.io.Connector.socket

javax.microedition.io.Connector.https

javax.microedition.io.Connector.ssl

javax.microedition.io.Connector.datagram

javax.microedition.io.Connector.serversocket

javax.microedition.io.Connector.datagramreceiver

javax.microedition.io.Connector.comm

javax.microedition.io.PushRegistry

table 1: sensitive operations/permissions list

As table 1 shows, permission names are not same as package names, but they are similar.

For example, if a MIDlet want to connect to some server with HTTP, is must get permission to do that. Because connecting HTTP is a sensitive operation, only when user approve, the MIDlet can go on.

1.2 Permission

Normally, there are several kinds of permission level user can choose. Take WTK 2.0 of SUN for example, three kinds of permission can be selected by user:

Oneshot: The MIDP implementation retains no memory of the user's decision and will ask for a permission every time it is needed.

Session: The implementation remembers the user's decision until the MIDlet is terminated.

Blanket: The user's decision sticks until the MIDlet suite is uninstalled.

1.3 Protection Domain

If user must choose to grant or deny the authorization, it’ll be a lot of trouble. In fact, users don’t have to do that every time, at least for these safe MIDlets. MIDlet suites are classified into different protection domains. Each domain has different permissions authorization. A domain stands for some level of safety, some permissions are granted and some denied by default.

Usually, there will be at least three kinds of protection domain defined:

Manufactory: These MIDlet suites are made by device vendors or operators, they are absolutely safe, so every permission are granted, the MIDlet suite can do any sensitive operation on the platform.

Trusted: These MIDlet suites are made by trusty vendors, but there still be security risk, so some critical permission are denied by default, when such operations are performed, user will be queried.

Untrusted: Vendor of MIDlet suite is unknown, the program may be dangerous, so every sensitive operation must get user’s grant.

2 Java language

As a language, Java has some mechanism to enhance the security inner itself.

2.1 Structured memory access

One measure to enhance the security in language level is structured memory access. It means that developer can’t access memory directly.

Why unrestrained memory access would be a security risk is that a wily cracker could potentially use memory pointer to subvert the security system. If, for example, a cracker could learn where in memory a class loader is stored, it could assign a pointer to that memory and manipulate the class loader's data. By enforcing structured access to memory, the Java virtual machine yields programs that are robust, but also frustrates crackers who dream of harnessing the internal memory of the Java virtual machine for their own devious plots.

2.2 Checking of array boundary

Another aspect of enhanced security is about array. A common error of C/C++ programmer is covering bytes beyond boundary while writing data to an array. Some times, this will cause serious problem, even make the program crash. And this is common method used by crackers to attack a system. But this will never happen in Java language.

According to Java language specification, Java Virtual Machine will check the use of array, if a programmer wants to write or read a member of array by index which is beyond the boundary, an exception will be threw out.

2.3 Garbage collection

Automatic garbage collection is another vantage of Java language. In C/C++ language, programmers have to free the memory blocks which are allocated manually. Memory leakage won’t give attack chances to crackers, but it will bring down the performance of program, especially in embedded system, the memory resource is very limited, memory leakage may cause serious problem.

Java language can release programmers from these troubles. Unused memory collection will be performed by VM. If an object is not referenced by any handle, it’ll be marked as “unreferenced”, and will be freed in some appropriate occasion.

 

3 Class files verifying

To ensure the security, some kinds of class file scanning will be performed before executing. Each scanning is to verify some different content.

However, these verifying are not strictly prescribed in JVM specification, it depends on implementation. Usually, PC JVM will perform all these scanning, but for EJVM it may me different.

3.1 Common Verifying of class files

Although compliant Java compilers should not generate malformed class files, a Java virtual machine can't tell how a particular class file was created. Because a class file is just a sequence of bytes, a virtual machine can't know whether a particular class file was generated by a well-meaning Java compiler or by shady crackers bent on compromising the integrity of the virtual machine. As a consequence, all Java virtual machine implementations have a class file verifier that can be invoked on class files, to make sure the types they define are safe to use.

For common used JVM on PC, four scanning will be performed during loading a class file:

3.1.1 Structural Checks on the Class File

The first scanning is to ensure the structure of class file.

The verifier performs many checks during this pass. For example, every class file must start with the same four bytes, the magic number: 0xCAFEBABE. The purpose of the magic number is to make it easy for the class file parser to reject files that were either damaged or were never intended to be class files in the first place. The verifier also makes sure the major and minor version numbers declared in the class file are within the range supported by that implementation of the Java virtual machine.

Also during pass one, the class file verifier checks to make sure the class file is neither truncated nor enhanced with extra trailing bytes. Although different class files can be different lengths, each individual component contained inside a class file indicates its length as well as its type. The verifier can use the component types and lengths to determine the correct total length for each individual class file.

3.1.2 Semantic Checks on the Type Data

During this pass, the verifier looks at individual components, to make sure they are well-formed instances of their type of component. For example, a method descriptor (its return type and the number and types of its parameters) is stored in the class file as a string that must adhere to a certain context-free grammar. One check the verifier performs on individual components is to make sure each method descriptor is a well-formed string of the appropriate grammar.

3.1.3 Byte code Verification

During this pass, which is commonly called the "byte code verifier," the Java virtual machine performs a data-flow analysis on the streams of byte codes that represent the methods of the class.

This step is the longest one. The byte code verifier does a great deal of checking. It checks to make sure that no matter what path of execution is taken to get to a certain “opcode” in the byte code stream, the operand stack always contains the same number and types of items. It checks to make sure no local variable is accessed before it is known to contain a proper value. It checks that fields of the class are always assigned values of the proper type, and that methods of the class are always invoked with the correct number and types of arguments. The byte code verifier also checks to make sure that each opcode is valid.

After this scanning, the stream of byte code is proved to be safe for the Java virtual machine to execute.

3.1.4 Verification of Symbolic References

Pass four of the class file verifier takes place when the symbolic references contained in a class file are resolved in the process of dynamic linking. During pass four, the Java virtual machine follows the references from the class file being verified to the referenced class files, to make sure the references are correct.

When the Java virtual machine resolves a symbolic reference, pass four of the class file verifier makes sure the reference is valid. If the reference is not valid--for instance, if the class cannot be loaded or if the class exists but doesn't contain the referenced field or method--the class file verifier throws an error.

3.2 Verifying performed by EJVM

For EJVM, if four scanning are all performed each time when loading a new class file, the performance will be greatly reduced. In embedded system, the speed of CPU is much lower then PC, four times of verifying is too time-consuming.

Usually, EJVM use other method to guarantee correctness of class files:

(1) Standard library classes are verified before they are solidified in ROM. During loading period, no verifying is performed.

(2) MIDlet suites are verified during installation. Once they are installed in device, they are considered as safe, no need to verify any more.

4 Implementation of JVM

4.1 Buffer Overflow (Inner JVM)

Buffer overflow, or buffer overrun, is an anomalous condition where a process attempts to store data beyond the boundaries of a fixed-length buffer. The result is that the extra data overwrites adjacent memory locations. The overwritten data may include other buffers, variables and program flow data, and may result in erratic program behavior, a memory access exception, program termination (a crash), incorrect results or a possible breach of system security.

Buffer overflow is the most commonly used method by cracker to infiltrate a system. Usually, cracker will copy more data into the fixed-length buffer, cover the return address of the function. When the function returns, the process will jump to somewhere to go on executing, while a piece of carefully designed code which called “shellcode” is waiting there. Then the system will be managed by cracker.

Although Java language has “array boundary checking” to prevent buffer overflow, for JVM it’s another pair of shoes, because JVM is written in local language (C/C++). Buffer Overflow is not a particular threaten for JVM, but JVM will suffer it as well.

4.2 Native Interface (Out of JVM)

Java Native Interface (JNI) is a topic of J2SE, not J2ME, that’s right! But for EJVM, for the standard library of MIDP, some implementation of EJVM may support JNI to implement features depending on system.

JNI breaks the OO concept of Java language. When EJVM is going to call some native interface, it must load some dynamic link library at first and then call the functions. From view point of security, there is too much risk in this procedure: the library file may be unauthorized, or it may be replaced, the function may be unsafe, etc.

5 Summary

This article summaries the security of embedded Java virtual machine from four aspects. The security solution of J2ME is complete and trustable. But from view of implementation of EJVM, every EJVM is distinguished from each other, so there are still some risks.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
嵌入式鲁棒控制系统设计使用Matlab / Simulink是一种集成开发环境(IDE),用于开发和设计嵌入式控制系统。Matlab是一个高级技术计算语言,可以进行数值计算、数据分析和可视化。Simulink是一个图形化建模工具,可以用来建立动态控制系统的模型。 嵌入式鲁棒控制系统设计是一种设计方法,旨在使控制系统对于模型不确定性和外部干扰具有鲁棒性。这种设计方法可以确保在面对模型参数变化、传感器误差或外部干扰时,系统仍可以稳定运行并实现预期的控制性能。 Matlab / Simulink提供了丰富的工具和函数,用于嵌入式鲁棒控制系统设计。它提供了许多用于建立系统模型、设计控制器和分析系统性能的工具。用户可以使用Simulink的图形化接口来建立系统模型,然后使用Matlab的编程能力来设计控制器和进行分析。 嵌入式鲁棒控制系统设计使用Matlab / Simulink的主要步骤包括: 1. 建立系统模型:使用Simulink的图形化界面来建立控制系统的模型。可以使用不同的控制器、传感器和执行器组件来模拟实际系统。 2. 设计控制器:使用Matlab的控制工具箱来设计控制器。可以使用各种经典和现代控制器设计方法,如PID控制、H∞控制和模糊控制等。 3. 优化控制器:使用Matlab的优化工具箱来优化控制器参数。可以使用优化算法来最小化控制系统的性能指标,如稳定裕度、上升时间和超调量等。 4. 分析系统性能:使用Matlab的分析工具来分析控制系统的性能。可以使用频域分析方法来评估系统的稳定性和鲁棒性能,并使用时域分析方法来评估系统的响应速度和抗干扰能力。 5. 代码生成和实现:使用Matlab的代码生成工具箱将控制器代码生成为嵌入式系统的可执行文件。可以将生成的代码直接加载到目标硬件上,并进行实时控制。 总之,嵌入式鲁棒控制系统设计使用Matlab / Simulink是一种强大的工具,可以帮助工程师设计和实现高性能的嵌入式控制系统。无论是在机器人控制、自动驾驶系统还是工业自动化领域,都可以使用这些工具来实现精确控制和鲁棒性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值