您的位置:首页 > 其它

[置顶] 使用mkfs.ubifs制作文件系统时写入文件扩展属性的方法

2017-10-31 20:14 579 查看

背景

Linux系统中,文件的安全上下文是文件扩展属性的一部分。在实施SELinux时,我们可以在策略中为文件定义安全上下文,在系统启动,加载策略文件后,就会根据策略中的定义给对应的文件标记上安全上下文。

但是有时候我们想在制作文件系统时,预先给文件设置好安全上下文,那么当我们把文件系统烧录挂载到target后,文件系统中的文件就已经带有我们预先设置好的安全上下文。

能否在制作文件系统时,把文件的安全上下文一同写入文件系统,取决于该类型的文件系统是否支持扩展属性,同时使用的工具是否支持属性的写入。下面介绍用mkfs.ubifs制作ubifs类型的文件系统时,如何将文件的扩展属性写入。

根据ubifs官网的资料,该类型的文件系统支持扩展属性

UBIFS supports extended attributes if the corresponding configuration option is enabled (no additional mount options are required). It supports the user, trusted, and security name-spaces. However, access control lists (ACL) support is not implemented.

而我们制作ubifs的文件系统时,只能使用mkfs.ubifs,因为这是用户空间唯一一个制作ubi镜像的工具

There is only one UBIFS user-space tool at the moment - mkfs.ubifs, which creates UBIFS images. The tool may be found in the MTD utils repository (the mkfs.ubifs sub-directory):

git://git.infradead.org/mtd-utils.git

麻烦的是,官网上也明确指出mkfs.ubifs会 在制作ubifs类型的镜像时忽略镜像中文件的扩展属性

Note, currently mkfs.ubifs ignores extended attributes and does not write them to the target file-system image.

用户空间的工具不支持扩展属性的写入,是否可以从内核的角度入手?

答案是否定的,因为并不是ubifs这种文件系统不支持扩展属性,而是mkfs.ubifs忽略了扩展属性,即使我们修改了内核中关于ubifs的参数,也没有办法达到我们的目的。所以,只能从mkfs.ubifs下手,尝试修改其源码并重新编译,使其支持文件扩展属性的写入。

源码编译

下载mtd-utils的源代码,里面包含了mkfs.ubifs的源码,根据ubifs官网的说明,下载路径如下:

git://git.infradead.org/mtd-utils.git



打开 mtd-utilis目录,执行autogen.sh脚本,为了防止出现权限问题,从这里开始的执行操作都加上sudo。但是执行时出现错误,提示缺少相应的宏:



为了解决错误,安装libtool工具:



安装成功后再次执行autogen.sh脚本:



成功执行后,生成了configure脚本:



执行configure脚本,但是执行到最后出现了警告和错误:





为了解决错误,安装uuid-dev工具:



下载lzo工具的压缩包:



解压缩,进入lzo-2.06目录,执行configure脚本,生成Makefile 文件:









执行makefile,生成相应的工具后,执行make install安装工具:





安装好以上工具后,再次执行configure脚本,成功生成Makefile文件:



执行Makefile文件,可以看到生成了对应的工具,其中包括了mkfs.ubifs:





执行make install,安装生成的工具:



查看系统当前mkfs.ubifs的版本,发现是2.0.1,对比开始编译前用相同命令查看到的1.5.0版本,说明安装成功了:



再检查/usr/sbin下mkfs.ubifs的信息,却发现并没有更新:



其实这是因为,在make install时,会根据系统的环境变量中的顺序,安装在环境变量的第一个目录中,打印出当前shell的环境变量可以看到:



查看/usr/local/sbin下是否有mkfs.ubifs程序并检查其详细信息,可以看到是刚刚安装上去的:



由于/usr/local/sbin在环境变量中的第一位,所以当我们执行mkfs.ubifs这个程序时,系统会默认地先从/usr/local/sbin下去查找这个程序,因此我们使用-V选项查看版本的时候会发现程序确实是最新的版本。如果想让编译好的mkfs.ubifs安装在/usr/sbin,只需要在执行configure脚本时,加上–prefix=/usr选项就可以了。

在执行configure脚本时,从打印出的日志可以看到,configure提供了很多编译选项,通过修改configure文件,可以达到裁剪工具的目的:



源码分析

通过阅读mtd-utils/ubifs-utils/mkfs.ubifs/ mkfs.ubifs.c,发现mkfs.ubifs是支持打包时带上扩展属性的,可以看到有一个-a选项:











但是在我的Ubuntu上使用的mkfs.ubifs却没有-a的选项,Ubuntu上的mkfs.ubifs是通过“apt-get install mtd-utils”命令安装的:



使用-V选项查看mkfs.ubifs的版本,发现是1.5.0:



而我们自己用源码编译出来的版本,则是2.0.1:



看上去是新版本的工具通过-a选项支持文件扩展属性的写入。

阅读了相关部分的代码后,没有发现有是否打开扩展属性的开关,看起来新版本似乎是默认支持的,于是我们就用自己编译出来的新版本工具测试,是否可以在打包时保留文件的扩展属性,为了验证是否已经使用新版本的mkfs.ubifs,用-V选项查看版本,用-h选项查看是否有-a参数的说明:







验证

从上述结果可以看到mkfs.ubifs已经编译成功,接下来对工具的使用效果进行测试,在打包镜像时,对mkfs.ubifs命令增加-a选项:



接着在ubuntu上给app_ubifs下的文件先定义好安全上下文(到时候把这个目录制作成镜像,烧录到开发板,检查安全上下文是否还在):



接着执行打包,烧录脚本,在开发板上检查/app目录下文件的安全上下文,发现在PC上预先设置好的属性并没有成功写入镜像:



为了确定脚本中使用的mkfs.ubifs是否我们前面编译出来的程序,在mtd-utils/ubifs-utils/mkfs.ubifs/ mkfs.ubifs.c中相关的函数加入打印信息:









重新编译后,执行打包镜像的脚本,mkfs.ubifs可以识别到-a选项,但是其他设置扩展属性相关的函数没有被调用:



思考分析

仔细阅读代码,发现有两个版本的设置扩展属性的函数,其中一个版本的函数没有任何实质性操作。如果定义了WITHOUT_XATTR这个宏,将使用没有实质性操作版本的函数,即不设置文件的扩展属性,在代码中查找WITHOUT_XATTR,发现并没有定义这个宏,所以mkfs.ubifs默认是忽略镜像中文件的扩展属性的:



在前面编译mkfs.ubifs的方法中提到过,mtd-utils/configure文件是编译配置文件,可以通过修改这个文件,裁剪出符合自己需求的工具。检查执行configure脚本过程中产生的log,可以看到扩展属性被disabled:



在configure文件中查找打印上述两个警告的位置,发现是否打印这两个警告,取决于变量xattr_missing的值,如果xattr_missing位xyes,打印了这两个警告后,还会把变量need_xattr就会被设置为no:



在代码中查找xattr_missing的赋值操作,发现有以下三处:





从脚本代码中看到,如果缺乏对应的头文件xattr_missing就会被设置为yes,重新检查执行configure脚本的打印信息,确实显示没有/sys/acl.h这个头文件:



安装libacl1-dev,再次执行configure脚本,观察打印信息,发现/sys/acl.h存在并且可用,并且没有提示disabling扩展属性:





重新编译代码并且安装工具,执行打包镜像脚本,可以看到前面加入到mtd-utils/ubifs-utils/mkfs.ubifs/ mkfs.ubifs.c的log都被打印出来:



烧录镜像文件到开发板,查看/app下文件的安全上下文,发现保留了在PC上设置好的安全上下文:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: