Linux操作系统的权限代码分析【转】
转自:http://blog.csdn.net/lixuyuan/article/details/6217502
现在关于内核的书很少涉及到Linux内核的安全,内核安全大概包括了密码学实现(crypto)和访问控制(security)两个部分。安全系 统作为Linux内核的一个重要的子系统,已经为我们提供了很多的相关接口,这里我们就对安全访问控制做一个简要的分析和介绍。
访问控制的原理注定要和虚拟文件系统和进程管理有着非常紧密的联系,因为作为用户主体的表现形式就是进程,而作为资源客体对象的表现形式就是文件,而访问 控制就是如何实现正确的用户可以访问正确的资源。Linux能够提供给我们许多可信的方式来处理这样的问题。
初始化工作
这个初始化工作在init/main.c中的start_kernel()中security_init()定义了,其具体的实现是在security/security.c中:
int __init security_init(void)
{
printk(KERN_INFO "Security Framework v" SECURITY_FRAMEWORK_VERSION
" initialized/n");
if (verify(&dummy_security_ops)) {
printk(KERN_ERR "%s could not verify "
"dummy_security_ops structure./n", __FUNCTION__);
return -EIO;
}
security_ops = &dummy_security_ops;
do_security_initcalls();
return 0;
}
这个函数首先用verify来验证所指定的访问控制策略(dummy_security_ops)是否为空,如果为空就按“保持默认”的方式进行分 配,这里的“保持沉默”就是对于任何的访问控制采取不管不问的方式处理了。然后就是把dummy_security_ops指定给系统全局安全策略 security_ops。
访问控制策略的相关接口
关于这些接口就是定义在了include/linux/security.h中的security_operations,包括如下一些操作:当父 进程trace子进程时进行的权限检查,对权能的获取、设置检查、设置、有效性检查,对进程做审计的检查,当某个操作使用一般系统接口表时需要的权限检 查,当使用内核消息环或改变登录终端时需要的权限检查,当改变系统时间需要的检查,当分配一个新的虚拟内存页需要的权限检查,当执行二进制程序时需要的各 种权限分配和检查,对文件系统操作时需要的各种访问控制操作,对inode索引节点操作时需要的各种访问控制操作,对文件操作时的各种访问控制操作,对进 程操作的需要的各种访问控制操作,对进程间通信信号灯的权限控制,对消息队列的控制,对进程间通信的共享内存区域的控制,对网络消息处理需要的各种控制, 注册与撤销访问控制策略,对网络连接的控制,对套接字的各种控制,对IPSEC中xfrm用户自定义策略的分配,密钥管理的控制等等,几乎囊括了系统各种 行为的控制。
权限管理
虚拟文件系统为各种类型的文件系统提供统一的操作接口,同时这样的做法也可以简化文件权限的管理。那么Linux时如何巧妙地实现这种想法呢?Linux 采用的是基于列的ACL自主访问控制,即在每个文件里存储对本文件的访问权限信息,这里我们采用索引节点inode(定义在 include/linux/fs.h)作为切入点进行分析。在inode结构体中有i_uid和i_gid元素,还有一个i_mode元素。这个 i_mode是16位的无符号整数表示,由9位权限方式位、3位“粘滞”标志位和4位文件类型标志位,它们的具体的定义在 include/linux/stat.h中:
#define S_IFMT 00170000 /* 用于抽取i_mode域中类型部分的屏蔽位 */
#define S_IFSOCK 0140000 /* 套接字类型码 */
#define S_IFLNK 0120000 /* 符号连接类型码 */
#define S_IFREG 0100000 /* 普通文件类型码 */
#define S_IFBLK 0060000 /* 块特别文件类型码 */
#define S_IFDIR 0040000 /* 目录文件类型码 */
#define S_IFCHR 0020000 /* 字符特别文件类型码 */
#define S_IFIFO 0010000 /* 管道或FIFO类型码 */
#define S_ISUID 0004000 /* 用户粘滞位 */
#define S_ISGID 0002000 /* 用户组粘滞位 */
#define S_ISVTX 0001000 /* 粘滞位 */
#define S_IRWXU 00700 /* 用户读写执行 */
#define S_IRUSR 00400 /* 用户读 */
#define S_IWUSR 00200 /* 用户写 */
#define S_IXUSR 00100 /* 用户执行 */
#define S_IRWXG 00070 /* 用户组读写执行 */
#define S_IRGRP 00040 /* 用户组读 */
#define S_IWGRP 00020 /* 用户组写 */
#define S_IXGRP 00010 /* 用户组执行 */
#define S_IRWXO 00007 /* 其他用户读写执行 */
#define S_IROTH 00004 /* 其他用户读 */
#define S_IWOTH 00002 /* 其他用户写 */
#define S_IXOTH 00001 /* 其他用户执行 */
#define S_IRWXUGO (S_IRWXU|S_IRWXG|S_IRWXO) /* 全部用户读写执行 */
#define S_IALLUGO (S_ISUID|S_ISGID|S_ISVTX|S_IRWXUGO )/* 全部用户全部权限 */
#define S_IRUGO (S_IRUSR|S_IRGRP|S_IROTH) /* 全部用户读 */
#define S_IWUGO (S_IWUSR|S_IWGRP|S_IWOTH) /* 全部用户写 */
#define S_IXUGO (S_IXUSR|S_IXGRP|S_IXOTH) /* 全部用户执行 */
同时,每个进程的task_struct中也有对应的uid,euid,suid,fsuid, gid,egid,sgid,fsgid等元素,当用户登录系统就创建了一个shell进程,它从/etc/passwd中取得对应用户的uid和gid 来唯一标志这个用户,以后所有的进程就代代相传。当内核在执行用户进程访问文件的请求时就要对比进程的uid、gid与文件的访问模式位,由此决定该进程 是否有对文件的操作权限。uid为零的用户为超级用户,可以对任何资源进行管理,当然这也导致了系统安全的不完备性。
判定一个进程是否有对某个文件有某种访问的主要工作是由fs/namei.c中的permission函数决定的,具体的实现方式如下,其中的mask参数是所要求的访问方式位的标志位:
int permission(struct inode *inode, int mask, struct nameidata *nd)
{
umode_t mode = inode->i_mode;
int retval, submask;
if (mask & MAY_WRITE) {
//假如加载的文件系统是只读的就不允许写,比如是磁盘设备
if (IS_RDONLY(inode) &&
(S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
return -EROFS;
//假如加载的文件系统是不可变的就不允许写
if (IS_IMMUTABLE(inode))
return -EACCES;
}
//是否满足可执行
if ((mask & MAY_EXEC) && S_ISREG(mode) && (!(mode & S_IXUGO) ||
(nd && nd->mnt && (nd->mnt->mnt_flags & MNT_NOEXEC))))
return -EACCES;
submask = mask & ~MAY_APPEND;
//返回适应的权限位
if (inode->i_op && inode->i_op->permission)
//交给了具体文件系统实现,比如说ext3文件系统
retval = inode->i_op->permission(inode, submask, nd);
else
//如果当前进程的fsuid与文件uid相同要比对文件属主的权限,否则比对用户组
retval = generic_permission(inode, submask, NULL);
if (retval)
return retval;
//返回适应的访问控制策略的权限位,比如说selinux
return security_inode_permission(inode, mask, nd);
}
转载自:http://blog.csdn.net/nhczp/archive/2008/04/29/2341194.aspx
Linux操作系统的权限代码分析【转】相关推荐
- 关于Linux操作系统的处理机管理分析
关于Linux操作系统的处理机管理分析 1.处理机管理 2.进程管理 进程: Linux系统中的进程(task): 3.处理器调度 概念: 处理机调度层次: 调度算法: Linux的进程调度策略: 调 ...
- Linux内核汇编代码分析
Linux内核汇编代码分析 1.vmlinux.lds.S文件分析 1.2 vmlinux.lds.S文件总体框架 1.3 代码段 1.4 只读数据段 1.5 init段 1.6 数据段 1.7 未初 ...
- linux的watchdog代码分析,Watchdog机制以及问题分析
目录 1. 概览 Watchdog的中文的"看门狗",有保护的意思.最早引入Watchdog是在单片机系统中,由于单片机的工作环境容易受到外界磁场的干扰,导致程序"跑飞& ...
- linux 按键驱动代码分析
原文地址:http://blog.csdn.NET/woshidahuaidan2011/article/details/51695147 二.按键驱动 1.对按键驱动添加设备信息 linux-3.1 ...
- Linux stmac网卡代码分析----probe
probe 主要分析一下驱动的主要框架,必要地方细致分析下 文件位置: drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c 从文件的最后看起: modul ...
- Linux LKM suterusu代码分析(一)
suterusu lkm 代码下载路径: https://github.com/mncoppola/suterusu 虽然这个LKM开发的时间是好几年前的,但是也是值得好好研究其中的hook原理,我这 ...
- 红星Linux操作系统的大部分代码处于被管控的状态
红星(Red Star)操作系统是一款基于 Fedora 的 Linux 衍生版本,其实现了该国前领导人的"国产操作系统"之梦,也表明了该国拥抱互联网的一种态度.据外媒报道,德国安 ...
- Linux stmac网卡代码分析 -- open
Open stmmac_open是在stmmac_netdev_ops结构体里的,这个ops在probe时就已经注册到了net_device结构体里,在网卡对于stmmac_open函数调用的时间我还 ...
- linux SMP启动代码分析
If one replicates an entire CPU to execute a second thread, then the technique is known asmulti-proc ...
最新文章
- sql_INSERT DELETE
- 版本控制工具 svn 一
- 移动端apm关键指标_3个经常被忽视的APM关键功能
- 简单的数据增强代码(C++与opencv)
- C++断言与静态断言
- Java学习之数据类型的转换
- BackBone及其实例探究
- 【python】批量替换文本中的某部分内容
- CE游戏修改器制作游戏修改器教程
- 文盲的Python入门日记:第二十八天,封装一个自定义爬虫类,用来执行日常的采集(二)
- 【软件定义汽车】-【架构篇】-迈向SOA软件架构,软件定义汽车成为现实
- deepin个性化设置
- 烤星 DeFi 课堂 | 去中心化交易所适合小白用吗?
- MySQL必知必会(1)
- 【转载】常备JS操作
- I2C 专题(一)I2C 简介
- SpringBoot2入门教程
- 高温天气计算机维护,路由器最近常断网 专家称跟高温天气有关
- Python机器学习实战教学——基于协同过滤的电影推荐系统(超详细教学,算法分析)
- 宠物小精灵 android游戏,宠物小精灵官方版
热门文章
- ios 简单的计时器游戏 NSUserDefaults NSDate NSTimer
- yum客户端的配置文件的格式
- asp.net C#绘制太极图
- Android图片,PNG还是JPG?用哪种?
- java(20) - 代理模式
- mac 电脑 eclipse 启动停在 org.eclipse.debug.core 导致无法启动
- 自动化测试框架搭建三python环境安装selenium和手动下载安装selenium的方法
- Slim Span UVA - 1395 (并查集)
- 11_HTML5_Local_Storage本地存储
- Facebook Cache Token Issue