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

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

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

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

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

最佳答案:

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

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

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

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

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

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

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

把碎片放在一起:

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

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

上一篇:android – 将位图放入Bundle


下一篇:parcelablearray传递arraylist