在之前的博客 ArchLinux调优: 显卡、声卡与电源 - rqdmap | blog中说明了如何使用开源的nvidia驱动并且关闭nvidia的供电来使得笔记本续航能力的提升.
通常来说我们不希望每次开机后都要手动向bbswitch写off字符串, 因而一般委以重任给dm; 不过像ly这样的纯终端dm貌似不具备在X Server加载后、登陆进入系统前的这个时间段执行一些脚本(可能因为ly运行在X Server加载前!), 因而后来出于种种考虑使用的是lightdm加载器, 比较现代, theme支持前端技术, 也比较好看, 最重要的是图形化的启动界面意味着可以在X加载后执行一些脚本.
不过由于向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指令了!
自此得出了一些结论:
-
suid位无法作用于一个shell脚本
-
C语言的system()函数的表现形式与一个shell脚本表现的类似, 因而也无法被suid启用
-
其余像fopen这类的C语言函数可以被suid启用(?… 或许有更好的名词表达)
仅仅解决一个眼前的问题是不足够满足好奇心的, 自然会有大大的疑问:
-
为什么suid无法用于shell脚本, 在执行一般的程序时suid如何起作用? shell脚本的执行和一般的elf程序的区别是什么, 在什么阶段会导致suid不起作用?
-
C语言的system到底是个什么? 更本质的说, system的具体使用了什么系统调用, 如何与Kernel文件系统(suid等)? 进而引出的问题是shell到底是如何实现的?
-
就以fopen为例, 其又如何与suid交互, 如何就能成功借助suid位实现阶级提升?
目前看来, 这些问题涉及的范围包括且不限于fs, elf, shell, 系统调用等方面… 尽管我不太希望挖坑, 但是这个坑有点过大了, 至少等我稍微再读一些kernel相关的代码再继续深挖!