sudo底层实现原理

62 阅读2分钟

哈喽,我是子牙老师

关于sudo,想必大家不陌生了,给我们最直观的感受就是以root权限执行后面的命令,那你是否好奇它底层是如何实现的呢?最近正好备课把这个问题深入研究了一下,分享给大家

以下,enjoy

场景

Linux系统中,你是个普通用户(非root),你想mount,会得到报错信息

提示你,只有root用户才能做这个操作

其实不止是mount,你普通用户想做任何高危操作,都需要root权限

但是你没有root密码,这时候你会怎么办?使用sudo,对吧

输入你自己的密码,就可以了

为什么这样就可以了?

sudo

来看下sudo命令有什么特殊的地方

常见的权限位是rwx,对应的权限是可读可写可执行。你会发现sudo的权限位有个s位,这个是什么呢?这个是SUID,在Linux内核中对应的宏是S_ISUID

这个SUID的信息存储在哪?存储在可执行文件对应的inode节点中

如果你想看源码,存储在inode的属性i_mode中。如图

如果你想知道存储细节,满足你:i_mode是16位的,前4位存放文件类型,中间3位存放特殊权限位如SUID、SGID、Sticky Bit,后面9位就存放所有者所属组其他人的rwx权限

我为什么知道的这么细?Linux内核玩熟了呗你玩到这么熟,你可能比我还细

为什么sudo命令有了s权限就可以如此强大呢?

SUID

SUID的作用是:以文件所有者权限执行这个程序。所以光有SUID还不行,文件的所有者还得是root,两个条件缺一不可

来看看所属用户是root,具备s权限的sudo,Linux系统是如何做到以root权限运行的

Linux系统执行sudo命令的时候,会创建进程,对应的内核对象是task_struct,task_struct中有三个属性与用户权限相关

ptracer_cred与调试相关,real_cred是进程的真实凭证,cred是运行时凭证。SUID作用的就是cred中的属性euid

结构体cred中与uid、gid相关的几个属性

来看Linux内核源码论证,Linux内核真的会根据SUID配置进程的cred中的euid

一个进程为什么要有两个cred?因为Linux系统提供了相关的机制可以去修改程序运行时的所有者与所属组、粘滞位,分开存储。如果不分开,那就会把一个程序变成真正的root权限,存在安全隐患。这部分是Linux安全子系统 LSM 中的内容,感兴趣的小伙伴可以自行深究

至此,自上而上,sudo可以以root权限执行程序的谜底已全部揭晓