ParcelFileDescritor.createPipe(),又名pipe(2)和安全性

Jef*_*man 5 unix android pipe parcel android-binder

请注意,虽然我在Android的上下文中问这个问题,但更多的是关于pipe(2)的一般unix问题......

要将大量数据从一个进程传输到另一个进程,可以使用ParcelFileDescritor.createPipe(),然后通过绑定器将管道的读取端发送到另一个进程.ParcelFileDescritor.createPipe()直接映射到unix管道(2)系统调用.

虽然FD通过绑定器安全地传输到另一个进程,但由于FD最终只是一个int,它是否有可能被恶意进程发现,甚至猜到,打开并读取?

从我的阅读来看,这似乎归结为通过默默无闻的安全.只要你不知道,并且无法猜出FD int值,那就没关系了.匿名管道不会暴露出以其他方式发现FD的方法.但理论上似乎有人可以编写一个具有大量线程的应用程序,这些线程不断尝试基于随机int值打开整数,可能会利用一些模式来选择数字并最终利用管道(2).

eph*_*ent 7

Linux内核struct fdtable为每个进程(或多或少)跟踪一个文件描述符表().该表中的条目由小整数索引 - 以0,1,2等开始,新条目被赋予最小可用整数 - 并且每个条目指向一个打开文件(struct file).

Linux内核中的文件是inode(struct inode)和某些状态(例如搜索位置)的句柄.

如果多次打开同一文件,则文件描述符表中将有多个条目,每个条目指向不同的文件结构,每个文件结构指向相同的inode结构.

如果打开文件,然后打开文件描述符,则dup文件描述符表中将有多个条目,每个条目指向相同的文件结构.

pipe在两个文件描述符中创建结果:读取结束和写入结束.它们有些神奇:从第一个文件描述符读取将返回写入第二个文件描述符的数据.在创建时,管道的两端只能访问此过程.

将文件描述符传递给另一个进程(通常由带有辅助附加sendmsgAF_UNIX域套接字完成SCM_RIGHTS,但在Android上通过Binder.transacta 完成Parcel.writeFileDescriptor)导致新条目被添加到接收进程的文件描述符表,指向同一文件结构作为发送进程的文件描述符表中的原始条目.注意:两个进程中同一文件的整数索引不相关; 事实上,它可能会有所不同.

通常,在C,你会用fopen获得FILE *的结构,你可以fread/ fwrite/等.上.C运行时库通过打开文件描述符并将其包装为一个结构(包含额外的缓冲等)来完成此操作.fdopen获取已在本地进程中打开的文件描述符,以及FILE *它周围的结构.

把碎片放在一起:

没有其他进程可以通过猜测FD号来打开文件,因为这些数字只在单个进程中有意义.*在进程之间传递文件描述符是安全的,由内核调解,内核操纵只有内核可以访问的对象.

*给定适当的权限,您可以通过/proc/$PID/fd/$FD伪文件系统查找其他进程的文件描述符,并为自己重新打开它们.但是,"适当的权限"是"相同的用户或root".在Android上,所有应用程序都以不同的用户身份运行,没有一个以root身份运行 - 这是不可能的.此外,Android的SELinux策略/proc无论如何都会阻止应用程序与接口进行交互.