SUID与程序执行

 Linux  Shell  文件系统  程序执行 󰈭 1418字

在之前的博客ArchLinux调优: 显卡、声卡与电源 - rqdmap | blog中说明了如何使用开源的nvidia驱动并且关闭nvidia的供电来使得笔记本续航能力的提升.

通常来说我们不希望每次开机后都要手动向bbswitch写off字符串, 因而一般委以重任给dm; 不过像ly这样的纯终端dm貌似不具备在X Server加载后、登陆进入系统前的这个时间段执行一些脚本(可能因为ly运行在X Server加载前!), 因而后来出于种种考虑使用的是lightdm加载器, 比较现代, theme支持前端技术, 也比较好看, 最重要的是图形化的启动界面意味着可以在X加载后执行一些脚本.

开源驱动下禁用nvidia显卡

不过由于向bbswitch写字符串需要root权限, 因而大多数时候会失败(按理说不应该是个确定事件吗, 但有时候就会莫名其妙成功?).

之前就想到了使用博客Linux文件权限 - rqdmap | blog中所提到suid位, 即chmod u+s xxx.sh即可设置suid位, 其他用户执行该程序时即可以程序所有者的权限执行. 之前的做法是:

  • 一个.sh脚本, 其中有一条tee指令, 用于向bbswitch文件写字符串

  • 放到/usr/local/bin目录下

  • [sudo] 将用户和组设置为root

  • [sudo] 设置u+s位

不过这样的做法并不能成功, 之前怀疑过的方向有:

  • /etc/fstab: 是否与分卷挂载的方式有关? 不过先后在/和/home下试过好像都不行

  • 指令的问题, 是否是tee指令的问题? 不过试过其他的诸如echo, cat也不行

前阵子在写rofi指令功能栏的时候又遇到了这个问题, 因而决心要解决这个问题. 上网查阅后忽然发现有人说到 suid不能用于shell脚本! , 一般会使用C等语言封装一次. 最初的尝试是在C语言中使用system('xxx')间接地调用shell指令, 并在代码中加入一些print打印出getuid()的结果, 结果是: 显示uid为0(root), 但是system执行的指令仍然报错权限不够! 难不成C的system本质上也是调用一些shell或类似的东西来模拟执行一个指令吗, 因而表现的错误与通常的终端下的shell一样.

带着这样的怀疑, 我直接使用了fopen函数打开bbswtich文件, 写入字符串, 关闭文件指针, return.. 重复上述设置所有者为root与setuid的操作, 竟然可以成功以rqdmap执行root指令了!

自此得出了一些结论:

  1. suid位无法作用于一个shell脚本

  2. C语言的system()函数的表现形式与一个shell脚本表现的类似, 因而也无法被suid启用

  3. 其余像fopen这类的C语言函数可以被suid启用(?… 或许有更好的名词表达)

仅仅解决一个眼前的问题是不足够满足好奇心的, 自然会有大大的疑问:

  1. 为什么suid无法用于shell脚本, 在执行一般的程序时suid如何起作用? shell脚本的执行和一般的elf程序的区别是什么, 在什么阶段会导致suid不起作用?

  2. C语言的system到底是个什么? 更本质的说, system的具体使用了什么系统调用, 如何与Kernel文件系统(suid等)? 进而引出的问题是shell到底是如何实现的?

  3. 就以fopen为例, 其又如何与suid交互, 如何就能成功借助suid位实现阶级提升?

目前看来, 这些问题涉及的范围包括且不限于fs, elf, shell, 系统调用等方面… 尽管我不太希望挖坑, 但是这个坑有点过大了, 至少等我稍微再读一些kernel相关的代码再继续深挖!

嗨! 这里是 rqdmap 的个人博客, 我正关注 GNU/Linux 桌面系统, Linux 内核, 后端开发, Python, Rust 以及一切有趣的计算机技术! 希望我的内容能对你有所帮助~
如果你遇到了任何问题, 包括但不限于: 博客内容说明不清楚或错误; 样式版面混乱等问题, 请通过邮箱 rqdmap@gmail.com 联系我!
修改记录:
  • 2023-07-24 21:44:07使用object展示svg图片
  • 2023-07-24 16:32:28修改excalidraw图片格式为svg
  • 2023-07-14 19:20:37SUID与程序执行: 初见