acl在内核里的位置_Linux2.6内核 ACL 机制数据结构和实现分析

Linux2.6内核ACL机制数据结构和实现分析

Abstract:This paper makes an analysis on ACL's data structure and implements on Linux 2.6 kernel, which includes

data structure in abstract layer and EXT4 filesystem layer. It will also focus on the inode's access control algorithms

and acl's role or function in these algorithms. At last, this paper will describe the procedure of acl control with an

illustration of open system call.

Key words:ACL; Linux 2.6 kernel; EXT4; Access control algorithm; Open system call

摘 要:本文对Linux2.6内核的ACL机制的数据结构和实现进行分析,包括有抽象标准层面上的ACL数据结构以及其在EXT4具体文件系统层面上的数据结构。本文还将着重分析Linux中对节点的访问权限检查算法以及ACL访问控制机制在其中的位置与作用。本文最后将以Open系统调用为例说明ACL总体控制流程。

关键词:ACL、Linux 2.6内核、EXT4、访问权限检查、Open系统调用

绪 论

自从1991年9月17日Linux v0.01版本发布以来,众多的开源组织和个人加入到Linux的开发和完善中,2001年1月4日推出v2.4版本,2003年12月17日又推出v2.6版本。版本的升级带来的是性能的提升和功能的完善,在目前Linux版本中已经包含了许多先进的技术和机制。

ACL访问控制机制就是其中的一种,它让人们摆脱了继承自Unix的user/group/other粗粒度访问控制模式带来的不便,使得人们可以更加自由的控制文件的访问权限。有关于ACL标准的描述在IEEE的Posix1003.1e草案中,ACL机制的实现在Linux2.4内核上是以补丁的方式存在,而在Linux2.6内核则以标准功能实现。Linux提供了setfacl和getacl等命令供用户对ACL进行设置,而关于如何在程序中应用ACL则没有给出相应的规范,尽管目前也有不少开源小组在开发各种libacl-devel库来支持ACL编程。总的来说,目前对于ACL机制的实现和开发编程方面的研究还很少。

本文将分为四个部分对Linux2.6内核ACL机制的数据结构和实现进行分析:

第一部分:简单介绍ACL命令的用法和其访问控制机制的特点。

第二部分:分析抽象层面上的ACL数据结构,包括有Posix ACL数据结构分析和Posix标准中对ACL的各种操作,并重点分析抽象层面上ACL权限检查算法。

第三部分:分析EXT4文件系统中ACL的数据结构和存储方式,并说明其与抽象ACL相互转化方式,如如何从外存中读取ACL属性到内存中,以及如何将内存中的ACL写入外存中。

第四部分:说明VFS的基本原理,并从整体流程上阐述ACL访问控制的流程。另外分析了与ACL相关的系统调用,以及某些实现。

为了对ACL机制有个完整的了解,本文的分析中会涉及到一些Linux 2.4和2.6内核的特性,以及EXT4文件系统的基本结构。

1.ACL简介

在ACL机制出现以前,人们都是通过user/group/other模式来实现文件的访问控制权限的设置。Linux和Unix使用9个比特来表示这种文件的访问模式,如rwxr-xr--就表示文件的属主拥有对文件的读写执行权限,文件属组中的成员对文件拥有读和执行权限,其他人只有读的权限。这种访问模式简单高效,对于早期简单的应用十分有效。但是随着人们对安全特性的要求提高,这种方式已经不能够满足现代的安全需求。

一个很简单的例子就是如何指定同组用户对文件的不同权限,如文件属于security组,该组的成员对文件都有r-x权限,但是我们需要为其中的某个用户tux添加w权限。在上述模式中,Linux管理员不得不为tux再添加一个组,并设置相应的权限,这样做存在许多的不便和安全隐患。如果使用ACL机制则可以很好的解决上述问题,用户只需要使用命令setfacl -m user:tux:rwx file就能够为tux设置对file的读写执行的权限。另外也可以使用ACL机制对文件进行负授权(或者说权限的撤销),例如使用命令setfacl -m user:tux:--- file就可以使tux对file没有任何权限。

使用命令getfacl file,可以看到如下输出:

user::rwx

user:tux:rwx

group::r-w

other::r--

mask::rwx

其中每一行都是一个ACL实体,对应于某一条具体的访问控制规则,而所有的ACL实体就构成了文件的ACL属性。每一个ACL实体由三部分组成:e_tag、e_id、e_perm。e_tag表示ACL实体的标志,如user:tux:rwx中user就是一个e_tag。e_id是ACL实体限制的用户或组id,如user:tux:rwx中的tux,在某些实体中这个项可以为空。e_perm说明的是具体的访问权限,主要有rwx三种,这和传统的u/g/o模式是一致的。在Posix标准中规定一共有6种e_tag,分别是ACL_USER_OBJ, ACL_USER, ACL_GROUP_OBJ, ACL_GROUP, ACL_MASK, ACL_OTHER。ACL_USER_OBJ是文件属主的ACL实体,ACL_GROUP_OBJ是文件属组的ACL实体,ACL_MASK是掩码ACL实体,ACL_OTHER是其他用户的ACL实体。这四种(个)ACL实体的id都为空,其他类型的ACL实体的e_id都不能为空。

2.抽象ACL表示

2.1.内存中的ACL数据结构

在Linux中,ACL是按照Posix标准来实现,其数据结构和Posix规定的ACL的数据是一致的。其定义在include/linux/posix_acl.h,实现在fs/posix_acl.c中:

struct posix_acl_entry {//acl_entry

shorte_tag;   //tag element,used to present user/group/other

unsigned shorte_perm;//permission element,used to present rwx

unsigned inte_id;//id element,used to present uid/gid

};

struct posix_acl {//file acl,witch contains lot of acl_entry

atomic_ta_refcount;//counter of process who reference this

unsigned inta_count;//count erof acl_entries

struct posix_acl_entrya_entries[0];//real acl_entries

};

首先我们来对上述数据结构作个说明:

我们在使用setfacl(或getfacl)设置(或查看)ACL的时候,我们通常会表示为如下结构user:tux:rwx,这其实就是一个ACL实体(posix_acl_entry)。user对应e_tag,表示ACL的类型。rwx对应的是e_perm,说明的是赋予的权限。tux对应的e_id,说明的是这个实体的id,如果e_tag指定的是user那么e_id表明是用户id,如果e_id指定的是group那么它表示的就是组id。采用这种策略部分原因是为了与原始的9bit模式兼容。

一个文件的ACL属性由多个这样的ACL实体构成,描述文件的ACL属性就是posix_acl数据结构。其中的a_refcount指示有多少个进程在使用该ACL(每有一个新的进程用到这个ACL属性,就将该计数器加一;每当一个进程不再使用这个ACL属性就将该计数器减一,当减到0后就会销毁该ACL)。a_count表示这个ACL属性中包含多少个ACL实体(posix_acl_entry),a_entries为内存中实际存放ACL项的数组。这里有一个问题:为什么要采用数组的方式实现,这样实现对实体的增删改不会很不方便吗?我们将在后面的表述中说明Linux为什么采用数组的方式。

2.2.ACL与内核其他数据结构的关系

上文中我们说到ACL是一个文件的属性,这是我们通常的观点。在Linux中文件这个词的含义稍稍有些变化,File数据结构特指与进程相关联的一个读写物理文件的上下文关联,实际代表物理文件的是另外一个数据结构Inode。这就是为什么你看File的数据结构中不包括9bit位以及ACL属性的原因,它们都是与具体读写上下文无关的属性,是属于物理文件的自身特性的数据。

那么我们来看看内存中的ACL是如何与具体的Inode相关联的吧。查看Inode数据结构(include/linux/fs.h),我们看到:

00779:#ifdef CONFIG_FS_POSIX_ACL

00780:struct posix_acl*i_acl;

00781:struct posix_acl*i_default_acl;

00782:#endif

也就是说通过i_acl和i_default_acl两个posix_acl指针将Inode和具体的ACL属性关联起来。我们注意到有两个ACL属性,acl和default_acl,这两个属性有不同的作用。acl属性是用于访问控制的,对一个文件读写执行都要通过这个acl属性来控制。default_acl属性是目录特有的ACL属性,在此目录中创建的文件和目录都将继承这个default_acl属性。(对于普通文件来说,该指针为空)。在这里我们要注意的是这两个ACL属性都是缓存的ACL的属性,在一开始的时候为空,当某个进程要用到这个ACL属性的时候,内核就从外存中读取ACL属性,并缓存到inode的i_acl和i_default_acl。以后其他进程需要使用到ACL的信息就先在内存缓存中查询。我们将在第二部分介绍如何从外存中读取inode的ACL属性。

2.3.内存中对ACL的操作

下表是Posix中规定的在内存中对ACL的操作,列举如下:

函数申明

描述

posix_acl_dup()

实际上是将acl引用计数加1

posix_acl_release()

释放内核中acl的空间

posix_acl_alloc()

分配一个新的ACL

posix_acl_valid()

检查一个ACL是否合法

posix_acl_permission()

使用acl检查当前进程是否对inode有访问权限

get_posix_acl()

对应于具体文件系统中的操作

set_posix_acl()

对应于具体文件系统中的操作

posix_acl_equiv_mode()

检查acl是否可以完全代表9bit模式

posix_acl_create_masq()

创建新节点时修改其ACL

posix_acl_chmod_masq()

当发生chmod系统调用时修改其ACL

posix_acl_from_mode()

创建能够代表9bit模式的ACL

posix_acl_clon

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值