Arondight/sudodev

权限问题

abbycin opened this issue · 10 comments

我发现你这两个程序都需要root权限才能运行啊。。。

设计的初衷就是这样, 还是想

setuid(0);

然后chown root:root xxx + chmod u+s xxx ??

另外,我用C++写的已经写好了,不知道对不对,学姐帮我看看行吗?

设计的时候就是这样……

  1. 从可行性上来说,daemon 需要读写/etc/sudoers.d 目录,还需要操作/etc/group/etc/sudoers 文件,必须有root 权限。因为daemon 需要root 权限,所以和用户交互的程序必须要root 权限才能发SIGHUP
  2. 从逻辑上说,如果不需要root 权限就能随便添加移除设备,那还了得……

最后C++ 我也不熟,只能凑凑热闹,不敢说帮看 (:з」∠)

我就当是个练习啊,我也是不懂C++的。。

额,追完番了发现学霸push 了一个同名项目,老实说daemon 的部分没仔细看,因为没敢用root 权限去跑,没装虚拟机……

sdev_ctl 跑了下,代码大致看了一下:

  1. 筛选非本地设备的逻辑太慢了……等线程做的不是不是太好,不及时也不能处理超时,话说回来主程序起线程去做事情而本身去等待,不如不起线程,直接主线程去做。
  2. 扫描fstab 的时候需要去掉所有的阻碍性因素,例如所有的注释行和空行,学霸没做彻底。结合考虑一些其他的情况,例如UUID 并不一定会从第一个字符开始,例如这一行压根是一行注释,因为没做彻底就会出问题……
  3. 本地设备的过滤有点逻辑问题,没有排除可能扫到的非法数据,所以前面学霸没做彻底的部分导致我这里所有的存在fstab 的设备都没有被过滤掉。
  4. 一些其他的问题,没怎么仔细看,例如线程操作全局变量却没有lock,例如一个指向字符串常量的指针却没有被const 修饰等等
  5. 另外就是感觉写的有一些贴近C 的风格……还有一些流程上的逻辑问题,不过这不在编码范围之内了……最后虽然也不算问题,但是学霸的程序在内存使用上太大了(sdevd map 了100M)……

具体的没仔细看,再者自己也不会写几行程序,等回单位跑跑看看(单位的Arch 上装了一堆虚拟机……)

  1. 本来想用两个map,对比一下不同就可以找出外部设备的,但是我不会... 按照学姐的建议,去掉了多余的线程,直接交给了主线程去做了。
  2. fstab这个除去空行和注释,我man了一下,发现还有LABEL开头的格式, 这个就不管了。去掉空行和注释就行。
  3. 这个是什么?什么逻辑问题?
  4. 没有其他的线程了。 我没有找到字符串常量指针没有被const修饰的地方, 我是这样找的grep -n "char *" *
  5. C语言大法好。 另外sdevd map 了100M 怎么看的?
    我是这么看的

ps

 ps -C sdevd -o 'ppid pid stat tty rss sz vsz'
 PPID   PID STAT TT         RSS    SZ    VSZ
    1 12483 S    ?          200  3828  15312

ksysguard
x2.png

学霸我要你和处对象 (:з」∠)

  • 说起来比较过程,晚上没事的时候就按照之前的想法实现了一下,以前是用一个O(n^2)嵌套循环完成的,现在换成了O(nlgn) 的排序,排序之后的一遍去重复杂度为O(n) 可以忽略,现在来看好像比以前更快了点(理论上是这样吧……),可以参见提交 9c400d5 。过程用shell 来表述的话就是酱紫:
a=( 1 3 5 7 0 )
b=( 2 3 5 8 0 )
c=( $(echo ${a[@]} ${b[@]} | tr '[:space:]' "\n" | sort | uniq -c) )
[[ ${#c} -gt 0 ]] && inWork || outWork
  • fstab 这个文件学霸的处理思路不太对,自己处理的时候想到的原则就是只去找想要的东西,因为注释中存在任何东西都是合法的,所以需要干掉注释;学霸的想法是先排除不想要的东西,这种想法不太合适,除了注释以外还要应付各种可能的情况,所以学霸的程序无法处理一个正常的fatab(包含了带/不带UUID 的注释,包含空行(这个处理了),使用设备文件的fstab)
  • 正巧学霸在匹配的时候也没有排除之前可能没排除的非期望因素,这里学霸扫到的设备有很多是#,最终造成的结果就是在fstab 中的设备一个也没有排除掉。
  • 我是直接读/proc 看的,下面第一个是学霸程序的状态,第二个是自己程序的状态:
VmPeak:   162740 kB
VmSize:    97208 kB
VmLck:         0 kB
VmPin:         0 kB
VmHWM:       180 kB
VmRSS:       180 kB
VmData:    82224 kB
VmStk:       136 kB
VmExe:        64 kB
VmLib:      4456 kB
VmPTE:        60 kB
VmPMD:        12 kB
VmSwap:        0 kB
Threads:    3
VmPeak:     6372 kB
VmSize:     6368 kB
VmLck:         0 kB
VmPin:         0 kB
VmHWM:      1648 kB
VmRSS:      1648 kB
VmData:      200 kB
VmStk:       136 kB
VmExe:        24 kB
VmLib:      1876 kB
VmPTE:        36 kB
VmPMD:        12 kB
VmSwap:        0 kB
Threads:    1

不知道学霸程序的VmData 为什么会如此之大,或许C++ 程序都是这样?没注意过。

对了,那个字符串常量没有修饰的地方,又重新看了遍,确定全都没有修饰,例如:

const char *SUDOERS_PATH = "/etc/sudoers";

上面的指针是可变的,指针指向的字符串的内容是不可变的,感觉应该写成

const char * const SUDOERS_PATH = "/etc/sudoers";

或者更规范的话

const char SUDOERS_PATH[] = "/etc/sudoers";

因为和C 语言不同,C++ 不建议使用指针指向字符串常量。

我又push了一个到dev分支里去了。

修改1

cat /etc/fstab

cat /etc/fstab
UUID=9f153db3-2308-4a58-8ad4-ec7306acb8f8 /                    ext4       acl,user_xattr        1 1
UUID=e7bd8650-f5dd-4f08-8c03-616b90e73ad8 swap                 swap       defaults              0 0
UUID=7c9fed17-bf83-4a9f-948a-e962ee277305 /home                ext4       defaults              1 2
#UUID=7c9fed17-bf83-4a9f-948a-e962ee277305 /home                ext4       defaults              1 2

/dev/sda1
     #UUID=7c9fed17-bf83-4a9f-948a-e962ee277305 /home                ext4       defaults              1 2

结果1

./sdev_ctl add
Scaning available devices...
No available device! exit...

修改2

cat /etc/fstab
UUID=9f153db3-2308-4a58-8ad4-ec7306acb8f8 /                    ext4       acl,user_xattr        1 1
UUID=e7bd8650-f5dd-4f08-8c03-616b90e73ad8 swap                 swap       defaults              0 0
UUID=7c9fed17-bf83-4a9f-948a-e962ee277305 /home                ext4       defaults              1 2
#UUID=7c9fed17-bf83-4a9f-948a-e962ee277305 /home                ext4       defaults              1 2

     #UUID=7c9fed17-bf83-4a9f-948a-e962ee277305 /home                ext4       defaults              1 2

结果2

./sdev_ctl add
Scaning available devices...
The following choices are available
[q]. quit
[0]. sda5
[1]. sda4
[2]. sda3
[3]. sda2
[4]. sda1
Please enter a choice: q

这样还不行吗? 只要 这两种格式没问题就行了啊。

另外,感谢学姐科普!

还有, 为什么学学姐会在/proc里面看? 我用psksysguard可以吗? 有什么区别呢?

pull 了下,我这里是没问题了,代码没仔细看,git log -p 看了一下,编码上没发现啥问题,其他的一些问题基本上都是功能上的问题。另外看/proc 是因为我记不住ps 的参数……
(:з」∠) 刚看完《终物语》


另外,学霸你的程序好像有点问题啊……这是刚刚从/proc 里看到的进程状态,你对比前面的感受一下:

VmPeak:   228280 kB
VmSize:   162744 kB
VmLck:         0 kB
VmPin:         0 kB
VmHWM:       180 kB
VmRSS:       180 kB
VmData:   147760 kB
VmStk:       136 kB
VmExe:        64 kB
VmLib:      4456 kB
VmPTE:        64 kB
VmPMD:        12 kB
VmSwap:        0 kB
Threads:    3

翻倍了!看了下自己的什么也没变,学霸你的daemon 里写了啥(那部分代码我没看)……

Chameleon:~ # pgrep sdevd
2255
Chameleon:~ # cat /proc/2255/status
Name:   sdevd
State:  S (sleeping)
Tgid:   2255
Ngid:   0
Pid:    2255
PPid:   1
TracerPid:      0
Uid:    0       0       0       0
Gid:    100     100     100     100
FDSize: 64
Groups: 100 479 
NStgid: 2255
NSpid:  2255
NSpgid: 2254
NSsid:  2254
VmPeak:    13152 kB
VmSize:    13148 kB
VmLck:         0 kB
VmPin:         0 kB
VmHWM:      2840 kB
VmRSS:      2840 kB
VmData:      280 kB
VmStk:       136 kB
VmExe:        68 kB
VmLib:      4384 kB
VmPTE:        48 kB
VmPMD:        12 kB
VmSwap:        0 kB
Threads:        1
SigQ:   0/15526

为什么的你和我的不一样? 我这儿Threads: 1你哪儿为什么是3? 其他地方的差距也好大!!
还有学姐还没告诉我ps 和 这个status的区别啊。

pull 了,好像这个问题确实没有了,线程也变成了一个。

VmPeak:     内存峰值(包括了so 的)
VmSize:     内存使用量
VmLck:      禁止写入磁盘的内存
VmPin:      不清楚
VmHWM:      物理内存峰值
VmRSS:      物理内存
VmData:     程序数据段
VmStk:      程序堆栈段
VmExe:      程序代码段
VmLib:      使用的库
VmPTE:      使用的页表
VmPMD:      不清楚
VmSwap:     使用的swap

学霸之前的代码应该有什么东西导致了vmData 严重超标,而且是不断增大的。